1 /* CPU data for lm32. 2 3 THIS FILE IS MACHINE GENERATED WITH CGEN. 4 5 Copyright (C) 1996-2017 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 return NULL; 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 if (mach != NULL) 1067 machs |= 1 << mach->num; 1068 break; 1069 } 1070 case CGEN_CPU_OPEN_ENDIAN : 1071 endian = va_arg (ap, enum cgen_endian); 1072 break; 1073 default : 1074 fprintf (stderr, "lm32_cgen_cpu_open: unsupported argument `%d'\n", 1075 arg_type); 1076 abort (); /* ??? return NULL? */ 1077 } 1078 arg_type = va_arg (ap, enum cgen_cpu_open_arg); 1079 } 1080 va_end (ap); 1081 1082 /* Mach unspecified means "all". */ 1083 if (machs == 0) 1084 machs = (1 << MAX_MACHS) - 1; 1085 /* Base mach is always selected. */ 1086 machs |= 1; 1087 if (endian == CGEN_ENDIAN_UNKNOWN) 1088 { 1089 /* ??? If target has only one, could have a default. */ 1090 fprintf (stderr, "lm32_cgen_cpu_open: no endianness specified\n"); 1091 abort (); 1092 } 1093 1094 cd->isas = cgen_bitset_copy (isas); 1095 cd->machs = machs; 1096 cd->endian = endian; 1097 /* FIXME: for the sparc case we can determine insn-endianness statically. 1098 The worry here is where both data and insn endian can be independently 1099 chosen, in which case this function will need another argument. 1100 Actually, will want to allow for more arguments in the future anyway. */ 1101 cd->insn_endian = endian; 1102 1103 /* Table (re)builder. */ 1104 cd->rebuild_tables = lm32_cgen_rebuild_tables; 1105 lm32_cgen_rebuild_tables (cd); 1106 1107 /* Default to not allowing signed overflow. */ 1108 cd->signed_overflow_ok_p = 0; 1109 1110 return (CGEN_CPU_DESC) cd; 1111 } 1112 1113 /* Cover fn to lm32_cgen_cpu_open to handle the simple case of 1 isa, 1 mach. 1114 MACH_NAME is the bfd name of the mach. */ 1115 1116 CGEN_CPU_DESC 1117 lm32_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian) 1118 { 1119 return lm32_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name, 1120 CGEN_CPU_OPEN_ENDIAN, endian, 1121 CGEN_CPU_OPEN_END); 1122 } 1123 1124 /* Close a cpu table. 1125 ??? This can live in a machine independent file, but there's currently 1126 no place to put this file (there's no libcgen). libopcodes is the wrong 1127 place as some simulator ports use this but they don't use libopcodes. */ 1128 1129 void 1130 lm32_cgen_cpu_close (CGEN_CPU_DESC cd) 1131 { 1132 unsigned int i; 1133 const CGEN_INSN *insns; 1134 1135 if (cd->macro_insn_table.init_entries) 1136 { 1137 insns = cd->macro_insn_table.init_entries; 1138 for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns) 1139 if (CGEN_INSN_RX ((insns))) 1140 regfree (CGEN_INSN_RX (insns)); 1141 } 1142 1143 if (cd->insn_table.init_entries) 1144 { 1145 insns = cd->insn_table.init_entries; 1146 for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns) 1147 if (CGEN_INSN_RX (insns)) 1148 regfree (CGEN_INSN_RX (insns)); 1149 } 1150 1151 if (cd->macro_insn_table.init_entries) 1152 free ((CGEN_INSN *) cd->macro_insn_table.init_entries); 1153 1154 if (cd->insn_table.init_entries) 1155 free ((CGEN_INSN *) cd->insn_table.init_entries); 1156 1157 if (cd->hw_table.entries) 1158 free ((CGEN_HW_ENTRY *) cd->hw_table.entries); 1159 1160 if (cd->operand_table.entries) 1161 free ((CGEN_HW_ENTRY *) cd->operand_table.entries); 1162 1163 free (cd); 1164 } 1165 1166