3 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 Copyright (C) 1996-2016 Free Software Foundation, Inc.
7 This file is part of the GNU Binutils and/or GDB, the GNU debugger.
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)
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.
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.
31 #include "lm32-desc.h"
34 #include "libiberty.h"
39 static const CGEN_ATTR_ENTRY bool_attr[] =
46 static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED =
48 { "base", MACH_BASE },
49 { "lm32", MACH_LM32 },
54 static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED =
61 const CGEN_ATTR_TABLE lm32_cgen_ifield_attr_table[] =
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] },
73 const CGEN_ATTR_TABLE lm32_cgen_hardware_attr_table[] =
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] },
83 const CGEN_ATTR_TABLE lm32_cgen_operand_attr_table[] =
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] },
97 const CGEN_ATTR_TABLE lm32_cgen_insn_attr_table[] =
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] },
113 /* Instruction set variants. */
115 static const CGEN_ISA lm32_cgen_isa_table[] = {
116 { "lm32", 32, 32, 32, 32 },
120 /* Machine variants. */
122 static const CGEN_MACH lm32_cgen_mach_table[] = {
123 { "lm32", "lm32", MACH_LM32, 0 },
127 static CGEN_KEYWORD_ENTRY lm32_cgen_opval_h_gr_entries[] =
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 }
169 CGEN_KEYWORD lm32_cgen_opval_h_gr =
171 & lm32_cgen_opval_h_gr_entries[0],
176 static CGEN_KEYWORD_ENTRY lm32_cgen_opval_h_csr_entries[] =
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 }
205 CGEN_KEYWORD lm32_cgen_opval_h_csr =
207 & lm32_cgen_opval_h_csr_entries[0],
213 /* The hardware table. */
215 #define A(a) (1 << CGEN_HW_##a)
217 const CGEN_HW_ENTRY lm32_cgen_hw_table[] =
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 } } } } }
233 /* The instruction field table. */
235 #define A(a) (1 << CGEN_IFLD_##a)
237 const CGEN_IFLD lm32_cgen_ifld_table[] =
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 } } } } }
261 /* multi ifield declarations */
265 /* multi ifield definitions */
268 /* The operand table. */
270 #define A(a) (1 << CGEN_OPERAND_##a)
271 #define OPERAND(op) LM32_OPERAND_##op
273 const CGEN_OPERAND lm32_cgen_operand_table[] =
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 } } } } },
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 } } } } },
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 } } } } },
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 } } } } },
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 } } } } },
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 } } } } },
349 { 0, { (const PTR) 0 } },
350 { 0, { { { (1<<MACH_BASE), 0 } } } } }
356 /* The instruction table. */
358 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
359 #define A(a) (1 << CGEN_INSN_##a)
361 static const CGEN_IBASE lm32_cgen_insn_table[MAX_INSNS] =
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 */
369 LM32_INSN_ADD, "add", "add", 32,
370 { 0, { { { (1<<MACH_BASE), 0 } } } }
372 /* addi $r1,$r0,$imm */
374 LM32_INSN_ADDI, "addi", "addi", 32,
375 { 0, { { { (1<<MACH_BASE), 0 } } } }
377 /* and $r2,$r0,$r1 */
379 LM32_INSN_AND, "and", "and", 32,
380 { 0, { { { (1<<MACH_BASE), 0 } } } }
382 /* andi $r1,$r0,$uimm */
384 LM32_INSN_ANDI, "andi", "andi", 32,
385 { 0, { { { (1<<MACH_BASE), 0 } } } }
387 /* andhi $r1,$r0,$hi16 */
389 LM32_INSN_ANDHII, "andhii", "andhi", 32,
390 { 0, { { { (1<<MACH_BASE), 0 } } } }
394 LM32_INSN_B, "b", "b", 32,
395 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
399 LM32_INSN_BI, "bi", "bi", 32,
400 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
402 /* be $r0,$r1,$branch */
404 LM32_INSN_BE, "be", "be", 32,
405 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
407 /* bg $r0,$r1,$branch */
409 LM32_INSN_BG, "bg", "bg", 32,
410 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
412 /* bge $r0,$r1,$branch */
414 LM32_INSN_BGE, "bge", "bge", 32,
415 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
417 /* bgeu $r0,$r1,$branch */
419 LM32_INSN_BGEU, "bgeu", "bgeu", 32,
420 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
422 /* bgu $r0,$r1,$branch */
424 LM32_INSN_BGU, "bgu", "bgu", 32,
425 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
427 /* bne $r0,$r1,$branch */
429 LM32_INSN_BNE, "bne", "bne", 32,
430 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
434 LM32_INSN_CALL, "call", "call", 32,
435 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
439 LM32_INSN_CALLI, "calli", "calli", 32,
440 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
442 /* cmpe $r2,$r0,$r1 */
444 LM32_INSN_CMPE, "cmpe", "cmpe", 32,
445 { 0, { { { (1<<MACH_BASE), 0 } } } }
447 /* cmpei $r1,$r0,$imm */
449 LM32_INSN_CMPEI, "cmpei", "cmpei", 32,
450 { 0, { { { (1<<MACH_BASE), 0 } } } }
452 /* cmpg $r2,$r0,$r1 */
454 LM32_INSN_CMPG, "cmpg", "cmpg", 32,
455 { 0, { { { (1<<MACH_BASE), 0 } } } }
457 /* cmpgi $r1,$r0,$imm */
459 LM32_INSN_CMPGI, "cmpgi", "cmpgi", 32,
460 { 0, { { { (1<<MACH_BASE), 0 } } } }
462 /* cmpge $r2,$r0,$r1 */
464 LM32_INSN_CMPGE, "cmpge", "cmpge", 32,
465 { 0, { { { (1<<MACH_BASE), 0 } } } }
467 /* cmpgei $r1,$r0,$imm */
469 LM32_INSN_CMPGEI, "cmpgei", "cmpgei", 32,
470 { 0, { { { (1<<MACH_BASE), 0 } } } }
472 /* cmpgeu $r2,$r0,$r1 */
474 LM32_INSN_CMPGEU, "cmpgeu", "cmpgeu", 32,
475 { 0, { { { (1<<MACH_BASE), 0 } } } }
477 /* cmpgeui $r1,$r0,$uimm */
479 LM32_INSN_CMPGEUI, "cmpgeui", "cmpgeui", 32,
480 { 0, { { { (1<<MACH_BASE), 0 } } } }
482 /* cmpgu $r2,$r0,$r1 */
484 LM32_INSN_CMPGU, "cmpgu", "cmpgu", 32,
485 { 0, { { { (1<<MACH_BASE), 0 } } } }
487 /* cmpgui $r1,$r0,$uimm */
489 LM32_INSN_CMPGUI, "cmpgui", "cmpgui", 32,
490 { 0, { { { (1<<MACH_BASE), 0 } } } }
492 /* cmpne $r2,$r0,$r1 */
494 LM32_INSN_CMPNE, "cmpne", "cmpne", 32,
495 { 0, { { { (1<<MACH_BASE), 0 } } } }
497 /* cmpnei $r1,$r0,$imm */
499 LM32_INSN_CMPNEI, "cmpnei", "cmpnei", 32,
500 { 0, { { { (1<<MACH_BASE), 0 } } } }
502 /* divu $r2,$r0,$r1 */
504 LM32_INSN_DIVU, "divu", "divu", 32,
505 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
507 /* lb $r1,($r0+$imm) */
509 LM32_INSN_LB, "lb", "lb", 32,
510 { 0, { { { (1<<MACH_BASE), 0 } } } }
512 /* lbu $r1,($r0+$imm) */
514 LM32_INSN_LBU, "lbu", "lbu", 32,
515 { 0, { { { (1<<MACH_BASE), 0 } } } }
517 /* lh $r1,($r0+$imm) */
519 LM32_INSN_LH, "lh", "lh", 32,
520 { 0, { { { (1<<MACH_BASE), 0 } } } }
522 /* lhu $r1,($r0+$imm) */
524 LM32_INSN_LHU, "lhu", "lhu", 32,
525 { 0, { { { (1<<MACH_BASE), 0 } } } }
527 /* lw $r1,($r0+$imm) */
529 LM32_INSN_LW, "lw", "lw", 32,
530 { 0, { { { (1<<MACH_BASE), 0 } } } }
532 /* modu $r2,$r0,$r1 */
534 LM32_INSN_MODU, "modu", "modu", 32,
535 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
537 /* mul $r2,$r0,$r1 */
539 LM32_INSN_MUL, "mul", "mul", 32,
540 { 0, { { { (1<<MACH_BASE), 0 } } } }
542 /* muli $r1,$r0,$imm */
544 LM32_INSN_MULI, "muli", "muli", 32,
545 { 0, { { { (1<<MACH_BASE), 0 } } } }
547 /* nor $r2,$r0,$r1 */
549 LM32_INSN_NOR, "nor", "nor", 32,
550 { 0, { { { (1<<MACH_BASE), 0 } } } }
552 /* nori $r1,$r0,$uimm */
554 LM32_INSN_NORI, "nori", "nori", 32,
555 { 0, { { { (1<<MACH_BASE), 0 } } } }
559 LM32_INSN_OR, "or", "or", 32,
560 { 0, { { { (1<<MACH_BASE), 0 } } } }
562 /* ori $r1,$r0,$lo16 */
564 LM32_INSN_ORI, "ori", "ori", 32,
565 { 0, { { { (1<<MACH_BASE), 0 } } } }
567 /* orhi $r1,$r0,$hi16 */
569 LM32_INSN_ORHII, "orhii", "orhi", 32,
570 { 0, { { { (1<<MACH_BASE), 0 } } } }
574 LM32_INSN_RCSR, "rcsr", "rcsr", 32,
575 { 0, { { { (1<<MACH_BASE), 0 } } } }
577 /* sb ($r0+$imm),$r1 */
579 LM32_INSN_SB, "sb", "sb", 32,
580 { 0, { { { (1<<MACH_BASE), 0 } } } }
584 LM32_INSN_SEXTB, "sextb", "sextb", 32,
585 { 0, { { { (1<<MACH_BASE), 0 } } } }
589 LM32_INSN_SEXTH, "sexth", "sexth", 32,
590 { 0, { { { (1<<MACH_BASE), 0 } } } }
592 /* sh ($r0+$imm),$r1 */
594 LM32_INSN_SH, "sh", "sh", 32,
595 { 0, { { { (1<<MACH_BASE), 0 } } } }
599 LM32_INSN_SL, "sl", "sl", 32,
600 { 0, { { { (1<<MACH_BASE), 0 } } } }
602 /* sli $r1,$r0,$imm */
604 LM32_INSN_SLI, "sli", "sli", 32,
605 { 0, { { { (1<<MACH_BASE), 0 } } } }
609 LM32_INSN_SR, "sr", "sr", 32,
610 { 0, { { { (1<<MACH_BASE), 0 } } } }
612 /* sri $r1,$r0,$imm */
614 LM32_INSN_SRI, "sri", "sri", 32,
615 { 0, { { { (1<<MACH_BASE), 0 } } } }
617 /* sru $r2,$r0,$r1 */
619 LM32_INSN_SRU, "sru", "sru", 32,
620 { 0, { { { (1<<MACH_BASE), 0 } } } }
622 /* srui $r1,$r0,$imm */
624 LM32_INSN_SRUI, "srui", "srui", 32,
625 { 0, { { { (1<<MACH_BASE), 0 } } } }
627 /* sub $r2,$r0,$r1 */
629 LM32_INSN_SUB, "sub", "sub", 32,
630 { 0, { { { (1<<MACH_BASE), 0 } } } }
632 /* sw ($r0+$imm),$r1 */
634 LM32_INSN_SW, "sw", "sw", 32,
635 { 0, { { { (1<<MACH_BASE), 0 } } } }
637 /* user $r2,$r0,$r1,$user */
639 LM32_INSN_USER, "user", "user", 32,
640 { 0, { { { (1<<MACH_BASE), 0 } } } }
644 LM32_INSN_WCSR, "wcsr", "wcsr", 32,
645 { 0, { { { (1<<MACH_BASE), 0 } } } }
647 /* xor $r2,$r0,$r1 */
649 LM32_INSN_XOR, "xor", "xor", 32,
650 { 0, { { { (1<<MACH_BASE), 0 } } } }
652 /* xori $r1,$r0,$uimm */
654 LM32_INSN_XORI, "xori", "xori", 32,
655 { 0, { { { (1<<MACH_BASE), 0 } } } }
657 /* xnor $r2,$r0,$r1 */
659 LM32_INSN_XNOR, "xnor", "xnor", 32,
660 { 0, { { { (1<<MACH_BASE), 0 } } } }
662 /* xnori $r1,$r0,$uimm */
664 LM32_INSN_XNORI, "xnori", "xnori", 32,
665 { 0, { { { (1<<MACH_BASE), 0 } } } }
669 LM32_INSN_BREAK, "break", "break", 32,
670 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
674 LM32_INSN_SCALL, "scall", "scall", 32,
675 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
679 -1, "bret", "bret", 32,
680 { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
684 -1, "eret", "eret", 32,
685 { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
689 -1, "ret", "ret", 32,
690 { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
695 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
699 -1, "mvi", "mvi", 32,
700 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
704 -1, "mvui", "mvu", 32,
705 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
709 -1, "mvhi", "mvhi", 32,
710 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
714 -1, "mva", "mva", 32,
715 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
719 -1, "not", "not", 32,
720 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
724 -1, "nop", "nop", 32,
725 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
729 -1, "lbgprel", "lb", 32,
730 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
734 -1, "lbugprel", "lbu", 32,
735 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
739 -1, "lhgprel", "lh", 32,
740 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
744 -1, "lhugprel", "lhu", 32,
745 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
749 -1, "lwgprel", "lw", 32,
750 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
754 -1, "sbgprel", "sb", 32,
755 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
759 -1, "shgprel", "sh", 32,
760 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
764 -1, "swgprel", "sw", 32,
765 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
767 /* lw $r1,(gp+$got16) */
769 -1, "lwgotrel", "lw", 32,
770 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
772 /* orhi $r1,$r0,$gotoffhi16 */
774 -1, "orhigotoffi", "orhi", 32,
775 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
777 /* addi $r1,$r0,$gotofflo16 */
779 -1, "addgotoff", "addi", 32,
780 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
782 /* sw ($r0+$gotofflo16),$r1 */
784 -1, "swgotoff", "sw", 32,
785 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
787 /* lw $r1,($r0+$gotofflo16) */
789 -1, "lwgotoff", "lw", 32,
790 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
792 /* sh ($r0+$gotofflo16),$r1 */
794 -1, "shgotoff", "sh", 32,
795 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
797 /* lh $r1,($r0+$gotofflo16) */
799 -1, "lhgotoff", "lh", 32,
800 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
802 /* lhu $r1,($r0+$gotofflo16) */
804 -1, "lhugotoff", "lhu", 32,
805 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
807 /* sb ($r0+$gotofflo16),$r1 */
809 -1, "sbgotoff", "sb", 32,
810 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
812 /* lb $r1,($r0+$gotofflo16) */
814 -1, "lbgotoff", "lb", 32,
815 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
817 /* lbu $r1,($r0+$gotofflo16) */
819 -1, "lbugotoff", "lbu", 32,
820 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
827 /* Initialize anything needed to be done once, before any cpu_open call. */
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 *);
841 /* Subroutine of lm32_cgen_cpu_open to look up a mach via its bfd name. */
843 static const CGEN_MACH *
844 lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
848 if (strcmp (name, table->bfd_name) == 0)
855 /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
858 build_hw_table (CGEN_CPU_TABLE *cd)
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
866 const CGEN_HW_ENTRY **selected =
867 (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
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)
876 selected[init[i].type] = &init[i];
877 cd->hw_table.entries = selected;
878 cd->hw_table.num_entries = MAX_HW;
881 /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
884 build_ifield_table (CGEN_CPU_TABLE *cd)
886 cd->ifld_table = & lm32_cgen_ifld_table[0];
889 /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
892 build_operand_table (CGEN_CPU_TABLE *cd)
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
900 const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
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)
909 selected[init[i].type] = &init[i];
910 cd->operand_table.entries = selected;
911 cd->operand_table.num_entries = MAX_OPERANDS;
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]. */
923 build_insn_table (CGEN_CPU_TABLE *cd)
926 const CGEN_IBASE *ib = & lm32_cgen_insn_table[0];
927 CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
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;
937 /* Subroutine of lm32_cgen_cpu_open to rebuild the tables. */
940 lm32_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
943 CGEN_BITSET *isas = cd->isas;
944 unsigned int machs = cd->machs;
946 cd->int_insn_p = CGEN_INT_INSN_P;
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))
957 const CGEN_ISA *isa = & lm32_cgen_isa_table[i];
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)
966 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
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)
975 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
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;
984 /* Data derived from the mach spec. */
985 for (i = 0; i < MAX_MACHS; ++i)
986 if (((1 << i) & machs) != 0)
988 const CGEN_MACH *mach = & lm32_cgen_mach_table[i];
990 if (mach->insn_chunk_bitsize != 0)
992 if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
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);
999 cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
1003 /* Determine which hw elements are used by MACH. */
1004 build_hw_table (cd);
1006 /* Build the ifield table. */
1007 build_ifield_table (cd);
1009 /* Determine which operands are used by MACH/ISA. */
1010 build_operand_table (cd);
1012 /* Build the instruction table. */
1013 build_insn_table (cd);
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
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
1028 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
1032 lm32_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
1034 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
1036 CGEN_BITSET *isas = 0; /* 0 = "unspecified" */
1037 unsigned int machs = 0; /* 0 = "unspecified" */
1038 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
1047 memset (cd, 0, sizeof (*cd));
1049 va_start (ap, arg_type);
1050 while (arg_type != CGEN_CPU_OPEN_END)
1054 case CGEN_CPU_OPEN_ISAS :
1055 isas = va_arg (ap, CGEN_BITSET *);
1057 case CGEN_CPU_OPEN_MACHS :
1058 machs = va_arg (ap, unsigned int);
1060 case CGEN_CPU_OPEN_BFDMACH :
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);
1066 machs |= 1 << mach->num;
1069 case CGEN_CPU_OPEN_ENDIAN :
1070 endian = va_arg (ap, enum cgen_endian);
1073 fprintf (stderr, "lm32_cgen_cpu_open: unsupported argument `%d'\n",
1075 abort (); /* ??? return NULL? */
1077 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
1081 /* Mach unspecified means "all". */
1083 machs = (1 << MAX_MACHS) - 1;
1084 /* Base mach is always selected. */
1086 if (endian == CGEN_ENDIAN_UNKNOWN)
1088 /* ??? If target has only one, could have a default. */
1089 fprintf (stderr, "lm32_cgen_cpu_open: no endianness specified\n");
1093 cd->isas = cgen_bitset_copy (isas);
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;
1102 /* Table (re)builder. */
1103 cd->rebuild_tables = lm32_cgen_rebuild_tables;
1104 lm32_cgen_rebuild_tables (cd);
1106 /* Default to not allowing signed overflow. */
1107 cd->signed_overflow_ok_p = 0;
1109 return (CGEN_CPU_DESC) cd;
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. */
1116 lm32_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
1118 return lm32_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
1119 CGEN_CPU_OPEN_ENDIAN, endian,
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. */
1129 lm32_cgen_cpu_close (CGEN_CPU_DESC cd)
1132 const CGEN_INSN *insns;
1134 if (cd->macro_insn_table.init_entries)
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));
1142 if (cd->insn_table.init_entries)
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));
1150 if (cd->macro_insn_table.init_entries)
1151 free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
1153 if (cd->insn_table.init_entries)
1154 free ((CGEN_INSN *) cd->insn_table.init_entries);
1156 if (cd->hw_table.entries)
1157 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1159 if (cd->operand_table.entries)
1160 free ((CGEN_HW_ENTRY *) cd->operand_table.entries);