1/* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */ 2/* CPU data for lm32. 3 4THIS FILE IS MACHINE GENERATED WITH CGEN. 5 6Copyright (C) 1996-2022 Free Software Foundation, Inc. 7 8This file is part of the GNU Binutils and/or GDB, the GNU debugger. 9 10 This file is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3, or (at your option) 13 any later version. 14 15 It is distributed in the hope that it will be useful, but WITHOUT 16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 18 License for more details. 19 20 You should have received a copy of the GNU General Public License along 21 with this program; if not, write to the Free Software Foundation, Inc., 22 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 23 24*/ 25 26#include "sysdep.h" 27#include <stdio.h> 28#include <stdarg.h> 29#include <stdlib.h> 30#include "ansidecl.h" 31#include "bfd.h" 32#include "symcat.h" 33#include "lm32-desc.h" 34#include "lm32-opc.h" 35#include "opintl.h" 36#include "libiberty.h" 37#include "xregex.h" 38 39/* Attributes. */ 40 41static const CGEN_ATTR_ENTRY bool_attr[] = 42{ 43 { "#f", 0 }, 44 { "#t", 1 }, 45 { 0, 0 } 46}; 47 48static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED = 49{ 50 { "base", MACH_BASE }, 51 { "lm32", MACH_LM32 }, 52 { "max", MACH_MAX }, 53 { 0, 0 } 54}; 55 56static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED = 57{ 58 { "lm32", ISA_LM32 }, 59 { "max", ISA_MAX }, 60 { 0, 0 } 61}; 62 63const CGEN_ATTR_TABLE lm32_cgen_ifield_attr_table[] = 64{ 65 { "MACH", & MACH_attr[0], & MACH_attr[0] }, 66 { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, 67 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, 68 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, 69 { "RESERVED", &bool_attr[0], &bool_attr[0] }, 70 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, 71 { "SIGNED", &bool_attr[0], &bool_attr[0] }, 72 { 0, 0, 0 } 73}; 74 75const CGEN_ATTR_TABLE lm32_cgen_hardware_attr_table[] = 76{ 77 { "MACH", & MACH_attr[0], & MACH_attr[0] }, 78 { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, 79 { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] }, 80 { "PC", &bool_attr[0], &bool_attr[0] }, 81 { "PROFILE", &bool_attr[0], &bool_attr[0] }, 82 { 0, 0, 0 } 83}; 84 85const CGEN_ATTR_TABLE lm32_cgen_operand_attr_table[] = 86{ 87 { "MACH", & MACH_attr[0], & MACH_attr[0] }, 88 { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, 89 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, 90 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, 91 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, 92 { "SIGNED", &bool_attr[0], &bool_attr[0] }, 93 { "NEGATIVE", &bool_attr[0], &bool_attr[0] }, 94 { "RELAX", &bool_attr[0], &bool_attr[0] }, 95 { "SEM-ONLY", &bool_attr[0], &bool_attr[0] }, 96 { 0, 0, 0 } 97}; 98 99const CGEN_ATTR_TABLE lm32_cgen_insn_attr_table[] = 100{ 101 { "MACH", & MACH_attr[0], & MACH_attr[0] }, 102 { "ALIAS", &bool_attr[0], &bool_attr[0] }, 103 { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, 104 { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] }, 105 { "COND-CTI", &bool_attr[0], &bool_attr[0] }, 106 { "SKIP-CTI", &bool_attr[0], &bool_attr[0] }, 107 { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] }, 108 { "RELAXABLE", &bool_attr[0], &bool_attr[0] }, 109 { "RELAXED", &bool_attr[0], &bool_attr[0] }, 110 { "NO-DIS", &bool_attr[0], &bool_attr[0] }, 111 { "PBB", &bool_attr[0], &bool_attr[0] }, 112 { 0, 0, 0 } 113}; 114 115/* Instruction set variants. */ 116 117static const CGEN_ISA lm32_cgen_isa_table[] = { 118 { "lm32", 32, 32, 32, 32 }, 119 { 0, 0, 0, 0, 0 } 120}; 121 122/* Machine variants. */ 123 124static const CGEN_MACH lm32_cgen_mach_table[] = { 125 { "lm32", "lm32", MACH_LM32, 0 }, 126 { 0, 0, 0, 0 } 127}; 128 129static CGEN_KEYWORD_ENTRY lm32_cgen_opval_h_gr_entries[] = 130{ 131 { "gp", 26, {0, {{{0, 0}}}}, 0, 0 }, 132 { "fp", 27, {0, {{{0, 0}}}}, 0, 0 }, 133 { "sp", 28, {0, {{{0, 0}}}}, 0, 0 }, 134 { "ra", 29, {0, {{{0, 0}}}}, 0, 0 }, 135 { "ea", 30, {0, {{{0, 0}}}}, 0, 0 }, 136 { "ba", 31, {0, {{{0, 0}}}}, 0, 0 }, 137 { "r0", 0, {0, {{{0, 0}}}}, 0, 0 }, 138 { "r1", 1, {0, {{{0, 0}}}}, 0, 0 }, 139 { "r2", 2, {0, {{{0, 0}}}}, 0, 0 }, 140 { "r3", 3, {0, {{{0, 0}}}}, 0, 0 }, 141 { "r4", 4, {0, {{{0, 0}}}}, 0, 0 }, 142 { "r5", 5, {0, {{{0, 0}}}}, 0, 0 }, 143 { "r6", 6, {0, {{{0, 0}}}}, 0, 0 }, 144 { "r7", 7, {0, {{{0, 0}}}}, 0, 0 }, 145 { "r8", 8, {0, {{{0, 0}}}}, 0, 0 }, 146 { "r9", 9, {0, {{{0, 0}}}}, 0, 0 }, 147 { "r10", 10, {0, {{{0, 0}}}}, 0, 0 }, 148 { "r11", 11, {0, {{{0, 0}}}}, 0, 0 }, 149 { "r12", 12, {0, {{{0, 0}}}}, 0, 0 }, 150 { "r13", 13, {0, {{{0, 0}}}}, 0, 0 }, 151 { "r14", 14, {0, {{{0, 0}}}}, 0, 0 }, 152 { "r15", 15, {0, {{{0, 0}}}}, 0, 0 }, 153 { "r16", 16, {0, {{{0, 0}}}}, 0, 0 }, 154 { "r17", 17, {0, {{{0, 0}}}}, 0, 0 }, 155 { "r18", 18, {0, {{{0, 0}}}}, 0, 0 }, 156 { "r19", 19, {0, {{{0, 0}}}}, 0, 0 }, 157 { "r20", 20, {0, {{{0, 0}}}}, 0, 0 }, 158 { "r21", 21, {0, {{{0, 0}}}}, 0, 0 }, 159 { "r22", 22, {0, {{{0, 0}}}}, 0, 0 }, 160 { "r23", 23, {0, {{{0, 0}}}}, 0, 0 }, 161 { "r24", 24, {0, {{{0, 0}}}}, 0, 0 }, 162 { "r25", 25, {0, {{{0, 0}}}}, 0, 0 }, 163 { "r26", 26, {0, {{{0, 0}}}}, 0, 0 }, 164 { "r27", 27, {0, {{{0, 0}}}}, 0, 0 }, 165 { "r28", 28, {0, {{{0, 0}}}}, 0, 0 }, 166 { "r29", 29, {0, {{{0, 0}}}}, 0, 0 }, 167 { "r30", 30, {0, {{{0, 0}}}}, 0, 0 }, 168 { "r31", 31, {0, {{{0, 0}}}}, 0, 0 } 169}; 170 171CGEN_KEYWORD lm32_cgen_opval_h_gr = 172{ 173 & lm32_cgen_opval_h_gr_entries[0], 174 38, 175 0, 0, 0, 0, "" 176}; 177 178static CGEN_KEYWORD_ENTRY lm32_cgen_opval_h_csr_entries[] = 179{ 180 { "IE", 0, {0, {{{0, 0}}}}, 0, 0 }, 181 { "IM", 1, {0, {{{0, 0}}}}, 0, 0 }, 182 { "IP", 2, {0, {{{0, 0}}}}, 0, 0 }, 183 { "ICC", 3, {0, {{{0, 0}}}}, 0, 0 }, 184 { "DCC", 4, {0, {{{0, 0}}}}, 0, 0 }, 185 { "CC", 5, {0, {{{0, 0}}}}, 0, 0 }, 186 { "CFG", 6, {0, {{{0, 0}}}}, 0, 0 }, 187 { "EBA", 7, {0, {{{0, 0}}}}, 0, 0 }, 188 { "DC", 8, {0, {{{0, 0}}}}, 0, 0 }, 189 { "DEBA", 9, {0, {{{0, 0}}}}, 0, 0 }, 190 { "CFG2", 10, {0, {{{0, 0}}}}, 0, 0 }, 191 { "JTX", 14, {0, {{{0, 0}}}}, 0, 0 }, 192 { "JRX", 15, {0, {{{0, 0}}}}, 0, 0 }, 193 { "BP0", 16, {0, {{{0, 0}}}}, 0, 0 }, 194 { "BP1", 17, {0, {{{0, 0}}}}, 0, 0 }, 195 { "BP2", 18, {0, {{{0, 0}}}}, 0, 0 }, 196 { "BP3", 19, {0, {{{0, 0}}}}, 0, 0 }, 197 { "WP0", 24, {0, {{{0, 0}}}}, 0, 0 }, 198 { "WP1", 25, {0, {{{0, 0}}}}, 0, 0 }, 199 { "WP2", 26, {0, {{{0, 0}}}}, 0, 0 }, 200 { "WP3", 27, {0, {{{0, 0}}}}, 0, 0 }, 201 { "PSW", 29, {0, {{{0, 0}}}}, 0, 0 }, 202 { "TLBVADDR", 30, {0, {{{0, 0}}}}, 0, 0 }, 203 { "TLBPADDR", 31, {0, {{{0, 0}}}}, 0, 0 }, 204 { "TLBBADVADDR", 31, {0, {{{0, 0}}}}, 0, 0 } 205}; 206 207CGEN_KEYWORD lm32_cgen_opval_h_csr = 208{ 209 & lm32_cgen_opval_h_csr_entries[0], 210 25, 211 0, 0, 0, 0, "" 212}; 213 214 215/* The hardware table. */ 216 217#define A(a) (1 << CGEN_HW_##a) 218 219const CGEN_HW_ENTRY lm32_cgen_hw_table[] = 220{ 221 { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 222 { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 223 { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 224 { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 225 { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 226 { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PC), { { { (1<<MACH_BASE), 0 } } } } }, 227 { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, & lm32_cgen_opval_h_gr, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 228 { "h-csr", HW_H_CSR, CGEN_ASM_KEYWORD, & lm32_cgen_opval_h_csr, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 229 { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } } 230}; 231 232#undef A 233 234 235/* The instruction field table. */ 236 237#define A(a) (1 << CGEN_IFLD_##a) 238 239const CGEN_IFLD lm32_cgen_ifld_table[] = 240{ 241 { LM32_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 242 { LM32_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 243 { LM32_F_OPCODE, "f-opcode", 0, 32, 31, 6, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 244 { LM32_F_R0, "f-r0", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 245 { LM32_F_R1, "f-r1", 0, 32, 20, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 246 { LM32_F_R2, "f-r2", 0, 32, 15, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 247 { LM32_F_RESV0, "f-resv0", 0, 32, 10, 11, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } } }, 248 { LM32_F_SHIFT, "f-shift", 0, 32, 4, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 249 { LM32_F_IMM, "f-imm", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 250 { LM32_F_UIMM, "f-uimm", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 251 { LM32_F_CSR, "f-csr", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 252 { LM32_F_USER, "f-user", 0, 32, 10, 11, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 253 { LM32_F_EXCEPTION, "f-exception", 0, 32, 25, 26, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 254 { LM32_F_BRANCH, "f-branch", 0, 32, 15, 16, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } }, 255 { LM32_F_CALL, "f-call", 0, 32, 25, 26, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } }, 256 { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } } 257}; 258 259#undef A 260 261 262 263/* multi ifield declarations */ 264 265 266 267/* multi ifield definitions */ 268 269 270/* The operand table. */ 271 272#define A(a) (1 << CGEN_OPERAND_##a) 273#define OPERAND(op) LM32_OPERAND_##op 274 275const CGEN_OPERAND lm32_cgen_operand_table[] = 276{ 277/* pc: program counter */ 278 { "pc", LM32_OPERAND_PC, HW_H_PC, 0, 0, 279 { 0, { &lm32_cgen_ifld_table[LM32_F_NIL] } }, 280 { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } } }, 281/* r0: register 0 */ 282 { "r0", LM32_OPERAND_R0, HW_H_GR, 25, 5, 283 { 0, { &lm32_cgen_ifld_table[LM32_F_R0] } }, 284 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 285/* r1: register 1 */ 286 { "r1", LM32_OPERAND_R1, HW_H_GR, 20, 5, 287 { 0, { &lm32_cgen_ifld_table[LM32_F_R1] } }, 288 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 289/* r2: register 2 */ 290 { "r2", LM32_OPERAND_R2, HW_H_GR, 15, 5, 291 { 0, { &lm32_cgen_ifld_table[LM32_F_R2] } }, 292 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 293/* shift: shift amout */ 294 { "shift", LM32_OPERAND_SHIFT, HW_H_UINT, 4, 5, 295 { 0, { &lm32_cgen_ifld_table[LM32_F_SHIFT] } }, 296 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 297/* imm: signed immediate */ 298 { "imm", LM32_OPERAND_IMM, HW_H_SINT, 15, 16, 299 { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } }, 300 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 301/* uimm: unsigned immediate */ 302 { "uimm", LM32_OPERAND_UIMM, HW_H_UINT, 15, 16, 303 { 0, { &lm32_cgen_ifld_table[LM32_F_UIMM] } }, 304 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 305/* branch: branch offset */ 306 { "branch", LM32_OPERAND_BRANCH, HW_H_IADDR, 15, 16, 307 { 0, { &lm32_cgen_ifld_table[LM32_F_BRANCH] } }, 308 { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } }, 309/* call: call offset */ 310 { "call", LM32_OPERAND_CALL, HW_H_IADDR, 25, 26, 311 { 0, { &lm32_cgen_ifld_table[LM32_F_CALL] } }, 312 { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } }, 313/* csr: csr */ 314 { "csr", LM32_OPERAND_CSR, HW_H_CSR, 25, 5, 315 { 0, { &lm32_cgen_ifld_table[LM32_F_CSR] } }, 316 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 317/* user: user */ 318 { "user", LM32_OPERAND_USER, HW_H_UINT, 10, 11, 319 { 0, { &lm32_cgen_ifld_table[LM32_F_USER] } }, 320 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 321/* exception: exception */ 322 { "exception", LM32_OPERAND_EXCEPTION, HW_H_UINT, 25, 26, 323 { 0, { &lm32_cgen_ifld_table[LM32_F_EXCEPTION] } }, 324 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 325/* hi16: high 16-bit immediate */ 326 { "hi16", LM32_OPERAND_HI16, HW_H_UINT, 15, 16, 327 { 0, { &lm32_cgen_ifld_table[LM32_F_UIMM] } }, 328 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 329/* lo16: low 16-bit immediate */ 330 { "lo16", LM32_OPERAND_LO16, HW_H_UINT, 15, 16, 331 { 0, { &lm32_cgen_ifld_table[LM32_F_UIMM] } }, 332 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 333/* gp16: gp relative 16-bit immediate */ 334 { "gp16", LM32_OPERAND_GP16, HW_H_SINT, 15, 16, 335 { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } }, 336 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 337/* got16: got 16-bit immediate */ 338 { "got16", LM32_OPERAND_GOT16, HW_H_SINT, 15, 16, 339 { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } }, 340 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 341/* gotoffhi16: got offset high 16-bit immediate */ 342 { "gotoffhi16", LM32_OPERAND_GOTOFFHI16, HW_H_SINT, 15, 16, 343 { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } }, 344 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 345/* gotofflo16: got offset low 16-bit immediate */ 346 { "gotofflo16", LM32_OPERAND_GOTOFFLO16, HW_H_SINT, 15, 16, 347 { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } }, 348 { 0, { { { (1<<MACH_BASE), 0 } } } } }, 349/* sentinel */ 350 { 0, 0, 0, 0, 0, 351 { 0, { 0 } }, 352 { 0, { { { (1<<MACH_BASE), 0 } } } } } 353}; 354 355#undef A 356 357 358/* The instruction table. */ 359 360#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) 361#define A(a) (1 << CGEN_INSN_##a) 362 363static const CGEN_IBASE lm32_cgen_insn_table[MAX_INSNS] = 364{ 365 /* Special null first entry. 366 A `num' value of zero is thus invalid. 367 Also, the special `invalid' insn resides here. */ 368 { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }, 369/* add $r2,$r0,$r1 */ 370 { 371 LM32_INSN_ADD, "add", "add", 32, 372 { 0, { { { (1<<MACH_BASE), 0 } } } } 373 }, 374/* addi $r1,$r0,$imm */ 375 { 376 LM32_INSN_ADDI, "addi", "addi", 32, 377 { 0, { { { (1<<MACH_BASE), 0 } } } } 378 }, 379/* and $r2,$r0,$r1 */ 380 { 381 LM32_INSN_AND, "and", "and", 32, 382 { 0, { { { (1<<MACH_BASE), 0 } } } } 383 }, 384/* andi $r1,$r0,$uimm */ 385 { 386 LM32_INSN_ANDI, "andi", "andi", 32, 387 { 0, { { { (1<<MACH_BASE), 0 } } } } 388 }, 389/* andhi $r1,$r0,$hi16 */ 390 { 391 LM32_INSN_ANDHII, "andhii", "andhi", 32, 392 { 0, { { { (1<<MACH_BASE), 0 } } } } 393 }, 394/* b $r0 */ 395 { 396 LM32_INSN_B, "b", "b", 32, 397 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 398 }, 399/* bi $call */ 400 { 401 LM32_INSN_BI, "bi", "bi", 32, 402 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 403 }, 404/* be $r0,$r1,$branch */ 405 { 406 LM32_INSN_BE, "be", "be", 32, 407 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } } 408 }, 409/* bg $r0,$r1,$branch */ 410 { 411 LM32_INSN_BG, "bg", "bg", 32, 412 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } } 413 }, 414/* bge $r0,$r1,$branch */ 415 { 416 LM32_INSN_BGE, "bge", "bge", 32, 417 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } } 418 }, 419/* bgeu $r0,$r1,$branch */ 420 { 421 LM32_INSN_BGEU, "bgeu", "bgeu", 32, 422 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } } 423 }, 424/* bgu $r0,$r1,$branch */ 425 { 426 LM32_INSN_BGU, "bgu", "bgu", 32, 427 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } } 428 }, 429/* bne $r0,$r1,$branch */ 430 { 431 LM32_INSN_BNE, "bne", "bne", 32, 432 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } } 433 }, 434/* call $r0 */ 435 { 436 LM32_INSN_CALL, "call", "call", 32, 437 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 438 }, 439/* calli $call */ 440 { 441 LM32_INSN_CALLI, "calli", "calli", 32, 442 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 443 }, 444/* cmpe $r2,$r0,$r1 */ 445 { 446 LM32_INSN_CMPE, "cmpe", "cmpe", 32, 447 { 0, { { { (1<<MACH_BASE), 0 } } } } 448 }, 449/* cmpei $r1,$r0,$imm */ 450 { 451 LM32_INSN_CMPEI, "cmpei", "cmpei", 32, 452 { 0, { { { (1<<MACH_BASE), 0 } } } } 453 }, 454/* cmpg $r2,$r0,$r1 */ 455 { 456 LM32_INSN_CMPG, "cmpg", "cmpg", 32, 457 { 0, { { { (1<<MACH_BASE), 0 } } } } 458 }, 459/* cmpgi $r1,$r0,$imm */ 460 { 461 LM32_INSN_CMPGI, "cmpgi", "cmpgi", 32, 462 { 0, { { { (1<<MACH_BASE), 0 } } } } 463 }, 464/* cmpge $r2,$r0,$r1 */ 465 { 466 LM32_INSN_CMPGE, "cmpge", "cmpge", 32, 467 { 0, { { { (1<<MACH_BASE), 0 } } } } 468 }, 469/* cmpgei $r1,$r0,$imm */ 470 { 471 LM32_INSN_CMPGEI, "cmpgei", "cmpgei", 32, 472 { 0, { { { (1<<MACH_BASE), 0 } } } } 473 }, 474/* cmpgeu $r2,$r0,$r1 */ 475 { 476 LM32_INSN_CMPGEU, "cmpgeu", "cmpgeu", 32, 477 { 0, { { { (1<<MACH_BASE), 0 } } } } 478 }, 479/* cmpgeui $r1,$r0,$uimm */ 480 { 481 LM32_INSN_CMPGEUI, "cmpgeui", "cmpgeui", 32, 482 { 0, { { { (1<<MACH_BASE), 0 } } } } 483 }, 484/* cmpgu $r2,$r0,$r1 */ 485 { 486 LM32_INSN_CMPGU, "cmpgu", "cmpgu", 32, 487 { 0, { { { (1<<MACH_BASE), 0 } } } } 488 }, 489/* cmpgui $r1,$r0,$uimm */ 490 { 491 LM32_INSN_CMPGUI, "cmpgui", "cmpgui", 32, 492 { 0, { { { (1<<MACH_BASE), 0 } } } } 493 }, 494/* cmpne $r2,$r0,$r1 */ 495 { 496 LM32_INSN_CMPNE, "cmpne", "cmpne", 32, 497 { 0, { { { (1<<MACH_BASE), 0 } } } } 498 }, 499/* cmpnei $r1,$r0,$imm */ 500 { 501 LM32_INSN_CMPNEI, "cmpnei", "cmpnei", 32, 502 { 0, { { { (1<<MACH_BASE), 0 } } } } 503 }, 504/* divu $r2,$r0,$r1 */ 505 { 506 LM32_INSN_DIVU, "divu", "divu", 32, 507 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 508 }, 509/* lb $r1,($r0+$imm) */ 510 { 511 LM32_INSN_LB, "lb", "lb", 32, 512 { 0, { { { (1<<MACH_BASE), 0 } } } } 513 }, 514/* lbu $r1,($r0+$imm) */ 515 { 516 LM32_INSN_LBU, "lbu", "lbu", 32, 517 { 0, { { { (1<<MACH_BASE), 0 } } } } 518 }, 519/* lh $r1,($r0+$imm) */ 520 { 521 LM32_INSN_LH, "lh", "lh", 32, 522 { 0, { { { (1<<MACH_BASE), 0 } } } } 523 }, 524/* lhu $r1,($r0+$imm) */ 525 { 526 LM32_INSN_LHU, "lhu", "lhu", 32, 527 { 0, { { { (1<<MACH_BASE), 0 } } } } 528 }, 529/* lw $r1,($r0+$imm) */ 530 { 531 LM32_INSN_LW, "lw", "lw", 32, 532 { 0, { { { (1<<MACH_BASE), 0 } } } } 533 }, 534/* modu $r2,$r0,$r1 */ 535 { 536 LM32_INSN_MODU, "modu", "modu", 32, 537 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 538 }, 539/* mul $r2,$r0,$r1 */ 540 { 541 LM32_INSN_MUL, "mul", "mul", 32, 542 { 0, { { { (1<<MACH_BASE), 0 } } } } 543 }, 544/* muli $r1,$r0,$imm */ 545 { 546 LM32_INSN_MULI, "muli", "muli", 32, 547 { 0, { { { (1<<MACH_BASE), 0 } } } } 548 }, 549/* nor $r2,$r0,$r1 */ 550 { 551 LM32_INSN_NOR, "nor", "nor", 32, 552 { 0, { { { (1<<MACH_BASE), 0 } } } } 553 }, 554/* nori $r1,$r0,$uimm */ 555 { 556 LM32_INSN_NORI, "nori", "nori", 32, 557 { 0, { { { (1<<MACH_BASE), 0 } } } } 558 }, 559/* or $r2,$r0,$r1 */ 560 { 561 LM32_INSN_OR, "or", "or", 32, 562 { 0, { { { (1<<MACH_BASE), 0 } } } } 563 }, 564/* ori $r1,$r0,$lo16 */ 565 { 566 LM32_INSN_ORI, "ori", "ori", 32, 567 { 0, { { { (1<<MACH_BASE), 0 } } } } 568 }, 569/* orhi $r1,$r0,$hi16 */ 570 { 571 LM32_INSN_ORHII, "orhii", "orhi", 32, 572 { 0, { { { (1<<MACH_BASE), 0 } } } } 573 }, 574/* rcsr $r2,$csr */ 575 { 576 LM32_INSN_RCSR, "rcsr", "rcsr", 32, 577 { 0, { { { (1<<MACH_BASE), 0 } } } } 578 }, 579/* sb ($r0+$imm),$r1 */ 580 { 581 LM32_INSN_SB, "sb", "sb", 32, 582 { 0, { { { (1<<MACH_BASE), 0 } } } } 583 }, 584/* sextb $r2,$r0 */ 585 { 586 LM32_INSN_SEXTB, "sextb", "sextb", 32, 587 { 0, { { { (1<<MACH_BASE), 0 } } } } 588 }, 589/* sexth $r2,$r0 */ 590 { 591 LM32_INSN_SEXTH, "sexth", "sexth", 32, 592 { 0, { { { (1<<MACH_BASE), 0 } } } } 593 }, 594/* sh ($r0+$imm),$r1 */ 595 { 596 LM32_INSN_SH, "sh", "sh", 32, 597 { 0, { { { (1<<MACH_BASE), 0 } } } } 598 }, 599/* sl $r2,$r0,$r1 */ 600 { 601 LM32_INSN_SL, "sl", "sl", 32, 602 { 0, { { { (1<<MACH_BASE), 0 } } } } 603 }, 604/* sli $r1,$r0,$imm */ 605 { 606 LM32_INSN_SLI, "sli", "sli", 32, 607 { 0, { { { (1<<MACH_BASE), 0 } } } } 608 }, 609/* sr $r2,$r0,$r1 */ 610 { 611 LM32_INSN_SR, "sr", "sr", 32, 612 { 0, { { { (1<<MACH_BASE), 0 } } } } 613 }, 614/* sri $r1,$r0,$imm */ 615 { 616 LM32_INSN_SRI, "sri", "sri", 32, 617 { 0, { { { (1<<MACH_BASE), 0 } } } } 618 }, 619/* sru $r2,$r0,$r1 */ 620 { 621 LM32_INSN_SRU, "sru", "sru", 32, 622 { 0, { { { (1<<MACH_BASE), 0 } } } } 623 }, 624/* srui $r1,$r0,$imm */ 625 { 626 LM32_INSN_SRUI, "srui", "srui", 32, 627 { 0, { { { (1<<MACH_BASE), 0 } } } } 628 }, 629/* sub $r2,$r0,$r1 */ 630 { 631 LM32_INSN_SUB, "sub", "sub", 32, 632 { 0, { { { (1<<MACH_BASE), 0 } } } } 633 }, 634/* sw ($r0+$imm),$r1 */ 635 { 636 LM32_INSN_SW, "sw", "sw", 32, 637 { 0, { { { (1<<MACH_BASE), 0 } } } } 638 }, 639/* user $r2,$r0,$r1,$user */ 640 { 641 LM32_INSN_USER, "user", "user", 32, 642 { 0, { { { (1<<MACH_BASE), 0 } } } } 643 }, 644/* wcsr $csr,$r1 */ 645 { 646 LM32_INSN_WCSR, "wcsr", "wcsr", 32, 647 { 0, { { { (1<<MACH_BASE), 0 } } } } 648 }, 649/* xor $r2,$r0,$r1 */ 650 { 651 LM32_INSN_XOR, "xor", "xor", 32, 652 { 0, { { { (1<<MACH_BASE), 0 } } } } 653 }, 654/* xori $r1,$r0,$uimm */ 655 { 656 LM32_INSN_XORI, "xori", "xori", 32, 657 { 0, { { { (1<<MACH_BASE), 0 } } } } 658 }, 659/* xnor $r2,$r0,$r1 */ 660 { 661 LM32_INSN_XNOR, "xnor", "xnor", 32, 662 { 0, { { { (1<<MACH_BASE), 0 } } } } 663 }, 664/* xnori $r1,$r0,$uimm */ 665 { 666 LM32_INSN_XNORI, "xnori", "xnori", 32, 667 { 0, { { { (1<<MACH_BASE), 0 } } } } 668 }, 669/* break */ 670 { 671 LM32_INSN_BREAK, "break", "break", 32, 672 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 673 }, 674/* scall */ 675 { 676 LM32_INSN_SCALL, "scall", "scall", 32, 677 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 678 }, 679/* bret */ 680 { 681 -1, "bret", "bret", 32, 682 { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 683 }, 684/* eret */ 685 { 686 -1, "eret", "eret", 32, 687 { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 688 }, 689/* ret */ 690 { 691 -1, "ret", "ret", 32, 692 { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } } 693 }, 694/* mv $r2,$r0 */ 695 { 696 -1, "mv", "mv", 32, 697 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 698 }, 699/* mvi $r1,$imm */ 700 { 701 -1, "mvi", "mvi", 32, 702 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 703 }, 704/* mvu $r1,$lo16 */ 705 { 706 -1, "mvui", "mvu", 32, 707 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 708 }, 709/* mvhi $r1,$hi16 */ 710 { 711 -1, "mvhi", "mvhi", 32, 712 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 713 }, 714/* mva $r1,$gp16 */ 715 { 716 -1, "mva", "mva", 32, 717 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 718 }, 719/* not $r2,$r0 */ 720 { 721 -1, "not", "not", 32, 722 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 723 }, 724/* nop */ 725 { 726 -1, "nop", "nop", 32, 727 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 728 }, 729/* lb $r1,$gp16 */ 730 { 731 -1, "lbgprel", "lb", 32, 732 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 733 }, 734/* lbu $r1,$gp16 */ 735 { 736 -1, "lbugprel", "lbu", 32, 737 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 738 }, 739/* lh $r1,$gp16 */ 740 { 741 -1, "lhgprel", "lh", 32, 742 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 743 }, 744/* lhu $r1,$gp16 */ 745 { 746 -1, "lhugprel", "lhu", 32, 747 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 748 }, 749/* lw $r1,$gp16 */ 750 { 751 -1, "lwgprel", "lw", 32, 752 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 753 }, 754/* sb $gp16,$r1 */ 755 { 756 -1, "sbgprel", "sb", 32, 757 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 758 }, 759/* sh $gp16,$r1 */ 760 { 761 -1, "shgprel", "sh", 32, 762 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 763 }, 764/* sw $gp16,$r1 */ 765 { 766 -1, "swgprel", "sw", 32, 767 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 768 }, 769/* lw $r1,(gp+$got16) */ 770 { 771 -1, "lwgotrel", "lw", 32, 772 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 773 }, 774/* orhi $r1,$r0,$gotoffhi16 */ 775 { 776 -1, "orhigotoffi", "orhi", 32, 777 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 778 }, 779/* addi $r1,$r0,$gotofflo16 */ 780 { 781 -1, "addgotoff", "addi", 32, 782 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 783 }, 784/* sw ($r0+$gotofflo16),$r1 */ 785 { 786 -1, "swgotoff", "sw", 32, 787 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 788 }, 789/* lw $r1,($r0+$gotofflo16) */ 790 { 791 -1, "lwgotoff", "lw", 32, 792 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 793 }, 794/* sh ($r0+$gotofflo16),$r1 */ 795 { 796 -1, "shgotoff", "sh", 32, 797 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 798 }, 799/* lh $r1,($r0+$gotofflo16) */ 800 { 801 -1, "lhgotoff", "lh", 32, 802 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 803 }, 804/* lhu $r1,($r0+$gotofflo16) */ 805 { 806 -1, "lhugotoff", "lhu", 32, 807 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 808 }, 809/* sb ($r0+$gotofflo16),$r1 */ 810 { 811 -1, "sbgotoff", "sb", 32, 812 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 813 }, 814/* lb $r1,($r0+$gotofflo16) */ 815 { 816 -1, "lbgotoff", "lb", 32, 817 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 818 }, 819/* lbu $r1,($r0+$gotofflo16) */ 820 { 821 -1, "lbugotoff", "lbu", 32, 822 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 823 }, 824}; 825 826#undef OP 827#undef A 828 829/* Initialize anything needed to be done once, before any cpu_open call. */ 830 831static void 832init_tables (void) 833{ 834} 835 836#ifndef opcodes_error_handler 837#define opcodes_error_handler(...) \ 838 fprintf (stderr, __VA_ARGS__); fputc ('\n', stderr) 839#endif 840 841static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *); 842static void build_hw_table (CGEN_CPU_TABLE *); 843static void build_ifield_table (CGEN_CPU_TABLE *); 844static void build_operand_table (CGEN_CPU_TABLE *); 845static void build_insn_table (CGEN_CPU_TABLE *); 846static void lm32_cgen_rebuild_tables (CGEN_CPU_TABLE *); 847 848/* Subroutine of lm32_cgen_cpu_open to look up a mach via its bfd name. */ 849 850static const CGEN_MACH * 851lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name) 852{ 853 while (table->name) 854 { 855 if (strcmp (name, table->bfd_name) == 0) 856 return table; 857 ++table; 858 } 859 return NULL; 860} 861 862/* Subroutine of lm32_cgen_cpu_open to build the hardware table. */ 863 864static void 865build_hw_table (CGEN_CPU_TABLE *cd) 866{ 867 int i; 868 int machs = cd->machs; 869 const CGEN_HW_ENTRY *init = & lm32_cgen_hw_table[0]; 870 /* MAX_HW is only an upper bound on the number of selected entries. 871 However each entry is indexed by it's enum so there can be holes in 872 the table. */ 873 const CGEN_HW_ENTRY **selected = 874 (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *)); 875 876 cd->hw_table.init_entries = init; 877 cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY); 878 memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *)); 879 /* ??? For now we just use machs to determine which ones we want. */ 880 for (i = 0; init[i].name != NULL; ++i) 881 if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH) 882 & machs) 883 selected[init[i].type] = &init[i]; 884 cd->hw_table.entries = selected; 885 cd->hw_table.num_entries = MAX_HW; 886} 887 888/* Subroutine of lm32_cgen_cpu_open to build the hardware table. */ 889 890static void 891build_ifield_table (CGEN_CPU_TABLE *cd) 892{ 893 cd->ifld_table = & lm32_cgen_ifld_table[0]; 894} 895 896/* Subroutine of lm32_cgen_cpu_open to build the hardware table. */ 897 898static void 899build_operand_table (CGEN_CPU_TABLE *cd) 900{ 901 int i; 902 int machs = cd->machs; 903 const CGEN_OPERAND *init = & lm32_cgen_operand_table[0]; 904 /* MAX_OPERANDS is only an upper bound on the number of selected entries. 905 However each entry is indexed by it's enum so there can be holes in 906 the table. */ 907 const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected)); 908 909 cd->operand_table.init_entries = init; 910 cd->operand_table.entry_size = sizeof (CGEN_OPERAND); 911 memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *)); 912 /* ??? For now we just use mach to determine which ones we want. */ 913 for (i = 0; init[i].name != NULL; ++i) 914 if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH) 915 & machs) 916 selected[init[i].type] = &init[i]; 917 cd->operand_table.entries = selected; 918 cd->operand_table.num_entries = MAX_OPERANDS; 919} 920 921/* Subroutine of lm32_cgen_cpu_open to build the hardware table. 922 ??? This could leave out insns not supported by the specified mach/isa, 923 but that would cause errors like "foo only supported by bar" to become 924 "unknown insn", so for now we include all insns and require the app to 925 do the checking later. 926 ??? On the other hand, parsing of such insns may require their hardware or 927 operand elements to be in the table [which they mightn't be]. */ 928 929static void 930build_insn_table (CGEN_CPU_TABLE *cd) 931{ 932 int i; 933 const CGEN_IBASE *ib = & lm32_cgen_insn_table[0]; 934 CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN)); 935 936 memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN)); 937 for (i = 0; i < MAX_INSNS; ++i) 938 insns[i].base = &ib[i]; 939 cd->insn_table.init_entries = insns; 940 cd->insn_table.entry_size = sizeof (CGEN_IBASE); 941 cd->insn_table.num_init_entries = MAX_INSNS; 942} 943 944/* Subroutine of lm32_cgen_cpu_open to rebuild the tables. */ 945 946static void 947lm32_cgen_rebuild_tables (CGEN_CPU_TABLE *cd) 948{ 949 int i; 950 CGEN_BITSET *isas = cd->isas; 951 unsigned int machs = cd->machs; 952 953 cd->int_insn_p = CGEN_INT_INSN_P; 954 955 /* Data derived from the isa spec. */ 956#define UNSET (CGEN_SIZE_UNKNOWN + 1) 957 cd->default_insn_bitsize = UNSET; 958 cd->base_insn_bitsize = UNSET; 959 cd->min_insn_bitsize = 65535; /* Some ridiculously big number. */ 960 cd->max_insn_bitsize = 0; 961 for (i = 0; i < MAX_ISAS; ++i) 962 if (cgen_bitset_contains (isas, i)) 963 { 964 const CGEN_ISA *isa = & lm32_cgen_isa_table[i]; 965 966 /* Default insn sizes of all selected isas must be 967 equal or we set the result to 0, meaning "unknown". */ 968 if (cd->default_insn_bitsize == UNSET) 969 cd->default_insn_bitsize = isa->default_insn_bitsize; 970 else if (isa->default_insn_bitsize == cd->default_insn_bitsize) 971 ; /* This is ok. */ 972 else 973 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN; 974 975 /* Base insn sizes of all selected isas must be equal 976 or we set the result to 0, meaning "unknown". */ 977 if (cd->base_insn_bitsize == UNSET) 978 cd->base_insn_bitsize = isa->base_insn_bitsize; 979 else if (isa->base_insn_bitsize == cd->base_insn_bitsize) 980 ; /* This is ok. */ 981 else 982 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN; 983 984 /* Set min,max insn sizes. */ 985 if (isa->min_insn_bitsize < cd->min_insn_bitsize) 986 cd->min_insn_bitsize = isa->min_insn_bitsize; 987 if (isa->max_insn_bitsize > cd->max_insn_bitsize) 988 cd->max_insn_bitsize = isa->max_insn_bitsize; 989 } 990 991 /* Data derived from the mach spec. */ 992 for (i = 0; i < MAX_MACHS; ++i) 993 if (((1 << i) & machs) != 0) 994 { 995 const CGEN_MACH *mach = & lm32_cgen_mach_table[i]; 996 997 if (mach->insn_chunk_bitsize != 0) 998 { 999 if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize) 1000 { 1001 opcodes_error_handler 1002 (/* xgettext:c-format */ 1003 _("internal error: lm32_cgen_rebuild_tables: " 1004 "conflicting insn-chunk-bitsize values: `%d' vs. `%d'"), 1005 cd->insn_chunk_bitsize, mach->insn_chunk_bitsize); 1006 abort (); 1007 } 1008 1009 cd->insn_chunk_bitsize = mach->insn_chunk_bitsize; 1010 } 1011 } 1012 1013 /* Determine which hw elements are used by MACH. */ 1014 build_hw_table (cd); 1015 1016 /* Build the ifield table. */ 1017 build_ifield_table (cd); 1018 1019 /* Determine which operands are used by MACH/ISA. */ 1020 build_operand_table (cd); 1021 1022 /* Build the instruction table. */ 1023 build_insn_table (cd); 1024} 1025 1026/* Initialize a cpu table and return a descriptor. 1027 It's much like opening a file, and must be the first function called. 1028 The arguments are a set of (type/value) pairs, terminated with 1029 CGEN_CPU_OPEN_END. 1030 1031 Currently supported values: 1032 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr 1033 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr 1034 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name 1035 CGEN_CPU_OPEN_ENDIAN: specify endian choice 1036 CGEN_CPU_OPEN_INSN_ENDIAN: specify instruction endian choice 1037 CGEN_CPU_OPEN_END: terminates arguments 1038 1039 ??? Simultaneous multiple isas might not make sense, but it's not (yet) 1040 precluded. */ 1041 1042CGEN_CPU_DESC 1043lm32_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...) 1044{ 1045 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE)); 1046 static int init_p; 1047 CGEN_BITSET *isas = 0; /* 0 = "unspecified" */ 1048 unsigned int machs = 0; /* 0 = "unspecified" */ 1049 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN; 1050 enum cgen_endian insn_endian = CGEN_ENDIAN_UNKNOWN; 1051 va_list ap; 1052 1053 if (! init_p) 1054 { 1055 init_tables (); 1056 init_p = 1; 1057 } 1058 1059 memset (cd, 0, sizeof (*cd)); 1060 1061 va_start (ap, arg_type); 1062 while (arg_type != CGEN_CPU_OPEN_END) 1063 { 1064 switch (arg_type) 1065 { 1066 case CGEN_CPU_OPEN_ISAS : 1067 isas = va_arg (ap, CGEN_BITSET *); 1068 break; 1069 case CGEN_CPU_OPEN_MACHS : 1070 machs = va_arg (ap, unsigned int); 1071 break; 1072 case CGEN_CPU_OPEN_BFDMACH : 1073 { 1074 const char *name = va_arg (ap, const char *); 1075 const CGEN_MACH *mach = 1076 lookup_mach_via_bfd_name (lm32_cgen_mach_table, name); 1077 1078 if (mach != NULL) 1079 machs |= 1 << mach->num; 1080 break; 1081 } 1082 case CGEN_CPU_OPEN_ENDIAN : 1083 endian = va_arg (ap, enum cgen_endian); 1084 break; 1085 case CGEN_CPU_OPEN_INSN_ENDIAN : 1086 insn_endian = va_arg (ap, enum cgen_endian); 1087 break; 1088 default : 1089 opcodes_error_handler 1090 (/* xgettext:c-format */ 1091 _("internal error: lm32_cgen_cpu_open: " 1092 "unsupported argument `%d'"), 1093 arg_type); 1094 abort (); /* ??? return NULL? */ 1095 } 1096 arg_type = va_arg (ap, enum cgen_cpu_open_arg); 1097 } 1098 va_end (ap); 1099 1100 /* Mach unspecified means "all". */ 1101 if (machs == 0) 1102 machs = (1 << MAX_MACHS) - 1; 1103 /* Base mach is always selected. */ 1104 machs |= 1; 1105 if (endian == CGEN_ENDIAN_UNKNOWN) 1106 { 1107 /* ??? If target has only one, could have a default. */ 1108 opcodes_error_handler 1109 (/* xgettext:c-format */ 1110 _("internal error: lm32_cgen_cpu_open: no endianness specified")); 1111 abort (); 1112 } 1113 1114 cd->isas = cgen_bitset_copy (isas); 1115 cd->machs = machs; 1116 cd->endian = endian; 1117 cd->insn_endian 1118 = (insn_endian == CGEN_ENDIAN_UNKNOWN ? endian : insn_endian); 1119 1120 /* Table (re)builder. */ 1121 cd->rebuild_tables = lm32_cgen_rebuild_tables; 1122 lm32_cgen_rebuild_tables (cd); 1123 1124 /* Default to not allowing signed overflow. */ 1125 cd->signed_overflow_ok_p = 0; 1126 1127 return (CGEN_CPU_DESC) cd; 1128} 1129 1130/* Cover fn to lm32_cgen_cpu_open to handle the simple case of 1 isa, 1 mach. 1131 MACH_NAME is the bfd name of the mach. */ 1132 1133CGEN_CPU_DESC 1134lm32_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian) 1135{ 1136 return lm32_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name, 1137 CGEN_CPU_OPEN_ENDIAN, endian, 1138 CGEN_CPU_OPEN_END); 1139} 1140 1141/* Close a cpu table. 1142 ??? This can live in a machine independent file, but there's currently 1143 no place to put this file (there's no libcgen). libopcodes is the wrong 1144 place as some simulator ports use this but they don't use libopcodes. */ 1145 1146void 1147lm32_cgen_cpu_close (CGEN_CPU_DESC cd) 1148{ 1149 unsigned int i; 1150 const CGEN_INSN *insns; 1151 1152 if (cd->macro_insn_table.init_entries) 1153 { 1154 insns = cd->macro_insn_table.init_entries; 1155 for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns) 1156 if (CGEN_INSN_RX ((insns))) 1157 regfree (CGEN_INSN_RX (insns)); 1158 } 1159 1160 if (cd->insn_table.init_entries) 1161 { 1162 insns = cd->insn_table.init_entries; 1163 for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns) 1164 if (CGEN_INSN_RX (insns)) 1165 regfree (CGEN_INSN_RX (insns)); 1166 } 1167 1168 free ((CGEN_INSN *) cd->macro_insn_table.init_entries); 1169 free ((CGEN_INSN *) cd->insn_table.init_entries); 1170 free ((CGEN_HW_ENTRY *) cd->hw_table.entries); 1171 free ((CGEN_HW_ENTRY *) cd->operand_table.entries); 1172 free (cd); 1173} 1174 1175