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