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