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