Add LM32 port.
[binutils.git] / opcodes / lm32-desc.c
blobc18f86139d94fa748a1a155baef838a8a827f8de
1 /* CPU data for lm32.
3 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 Copyright 1996-2007 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)
12 any later version.
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.
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"
37 /* Attributes. */
39 static const CGEN_ATTR_ENTRY bool_attr[] =
41 { "#f", 0 },
42 { "#t", 1 },
43 { 0, 0 }
46 static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED =
48 { "base", MACH_BASE },
49 { "lm32", MACH_LM32 },
50 { "max", MACH_MAX },
51 { 0, 0 }
54 static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED =
56 { "lm32", ISA_LM32 },
57 { "max", ISA_MAX },
58 { 0, 0 }
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] },
70 { 0, 0, 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] },
80 { 0, 0, 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] },
94 { 0, 0, 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] },
110 { 0, 0, 0 }
113 /* Instruction set variants. */
115 static const CGEN_ISA lm32_cgen_isa_table[] = {
116 { "lm32", 32, 32, 32, 32 },
117 { 0, 0, 0, 0, 0 }
120 /* Machine variants. */
122 static const CGEN_MACH lm32_cgen_mach_table[] = {
123 { "lm32", "lm32", MACH_LM32, 0 },
124 { 0, 0, 0, 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],
173 0, 0, 0, 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 { "JTX", 14, {0, {{{0, 0}}}}, 0, 0 },
189 { "JRX", 15, {0, {{{0, 0}}}}, 0, 0 },
190 { "BP0", 16, {0, {{{0, 0}}}}, 0, 0 },
191 { "BP1", 17, {0, {{{0, 0}}}}, 0, 0 },
192 { "BP2", 18, {0, {{{0, 0}}}}, 0, 0 },
193 { "BP3", 19, {0, {{{0, 0}}}}, 0, 0 },
194 { "WP0", 24, {0, {{{0, 0}}}}, 0, 0 },
195 { "WP1", 25, {0, {{{0, 0}}}}, 0, 0 },
196 { "WP2", 26, {0, {{{0, 0}}}}, 0, 0 },
197 { "WP3", 27, {0, {{{0, 0}}}}, 0, 0 }
200 CGEN_KEYWORD lm32_cgen_opval_h_csr =
202 & lm32_cgen_opval_h_csr_entries[0],
204 0, 0, 0, 0, ""
208 /* The hardware table. */
210 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
211 #define A(a) (1 << CGEN_HW_##a)
212 #else
213 #define A(a) (1 << CGEN_HW_/**/a)
214 #endif
216 const CGEN_HW_ENTRY lm32_cgen_hw_table[] =
218 { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
219 { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
220 { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
221 { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
222 { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
223 { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PC), { { { (1<<MACH_BASE), 0 } } } } },
224 { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & lm32_cgen_opval_h_gr, { 0, { { { (1<<MACH_BASE), 0 } } } } },
225 { "h-csr", HW_H_CSR, CGEN_ASM_KEYWORD, (PTR) & lm32_cgen_opval_h_csr, { 0, { { { (1<<MACH_BASE), 0 } } } } },
226 { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
229 #undef A
232 /* The instruction field table. */
234 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
235 #define A(a) (1 << CGEN_IFLD_##a)
236 #else
237 #define A(a) (1 << CGEN_IFLD_/**/a)
238 #endif
240 const CGEN_IFLD lm32_cgen_ifld_table[] =
242 { LM32_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
243 { LM32_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
244 { LM32_F_OPCODE, "f-opcode", 0, 32, 31, 6, { 0, { { { (1<<MACH_BASE), 0 } } } } },
245 { LM32_F_R0, "f-r0", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
246 { LM32_F_R1, "f-r1", 0, 32, 20, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
247 { LM32_F_R2, "f-r2", 0, 32, 15, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
248 { LM32_F_RESV0, "f-resv0", 0, 32, 10, 11, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } } },
249 { LM32_F_SHIFT, "f-shift", 0, 32, 4, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
250 { LM32_F_IMM, "f-imm", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } } },
251 { LM32_F_UIMM, "f-uimm", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } } },
252 { LM32_F_CSR, "f-csr", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
253 { LM32_F_USER, "f-user", 0, 32, 10, 11, { 0, { { { (1<<MACH_BASE), 0 } } } } },
254 { LM32_F_EXCEPTION, "f-exception", 0, 32, 25, 26, { 0, { { { (1<<MACH_BASE), 0 } } } } },
255 { LM32_F_BRANCH, "f-branch", 0, 32, 15, 16, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } },
256 { LM32_F_CALL, "f-call", 0, 32, 25, 26, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } },
257 { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
260 #undef A
264 /* multi ifield declarations */
268 /* multi ifield definitions */
271 /* The operand table. */
273 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
274 #define A(a) (1 << CGEN_OPERAND_##a)
275 #else
276 #define A(a) (1 << CGEN_OPERAND_/**/a)
277 #endif
278 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
279 #define OPERAND(op) LM32_OPERAND_##op
280 #else
281 #define OPERAND(op) LM32_OPERAND_/**/op
282 #endif
284 const CGEN_OPERAND lm32_cgen_operand_table[] =
286 /* pc: program counter */
287 { "pc", LM32_OPERAND_PC, HW_H_PC, 0, 0,
288 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_NIL] } },
289 { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } } },
290 /* r0: register 0 */
291 { "r0", LM32_OPERAND_R0, HW_H_GR, 25, 5,
292 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_R0] } },
293 { 0, { { { (1<<MACH_BASE), 0 } } } } },
294 /* r1: register 1 */
295 { "r1", LM32_OPERAND_R1, HW_H_GR, 20, 5,
296 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_R1] } },
297 { 0, { { { (1<<MACH_BASE), 0 } } } } },
298 /* r2: register 2 */
299 { "r2", LM32_OPERAND_R2, HW_H_GR, 15, 5,
300 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_R2] } },
301 { 0, { { { (1<<MACH_BASE), 0 } } } } },
302 /* shift: shift amout */
303 { "shift", LM32_OPERAND_SHIFT, HW_H_UINT, 4, 5,
304 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_SHIFT] } },
305 { 0, { { { (1<<MACH_BASE), 0 } } } } },
306 /* imm: signed immediate */
307 { "imm", LM32_OPERAND_IMM, HW_H_SINT, 15, 16,
308 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
309 { 0, { { { (1<<MACH_BASE), 0 } } } } },
310 /* uimm: unsigned immediate */
311 { "uimm", LM32_OPERAND_UIMM, HW_H_UINT, 15, 16,
312 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_UIMM] } },
313 { 0, { { { (1<<MACH_BASE), 0 } } } } },
314 /* branch: branch offset */
315 { "branch", LM32_OPERAND_BRANCH, HW_H_IADDR, 15, 16,
316 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_BRANCH] } },
317 { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } },
318 /* call: call offset */
319 { "call", LM32_OPERAND_CALL, HW_H_IADDR, 25, 26,
320 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_CALL] } },
321 { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } },
322 /* csr: csr */
323 { "csr", LM32_OPERAND_CSR, HW_H_CSR, 25, 5,
324 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_CSR] } },
325 { 0, { { { (1<<MACH_BASE), 0 } } } } },
326 /* user: user */
327 { "user", LM32_OPERAND_USER, HW_H_UINT, 10, 11,
328 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_USER] } },
329 { 0, { { { (1<<MACH_BASE), 0 } } } } },
330 /* exception: exception */
331 { "exception", LM32_OPERAND_EXCEPTION, HW_H_UINT, 25, 26,
332 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_EXCEPTION] } },
333 { 0, { { { (1<<MACH_BASE), 0 } } } } },
334 /* hi16: high 16-bit immediate */
335 { "hi16", LM32_OPERAND_HI16, HW_H_UINT, 15, 16,
336 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_UIMM] } },
337 { 0, { { { (1<<MACH_BASE), 0 } } } } },
338 /* lo16: low 16-bit immediate */
339 { "lo16", LM32_OPERAND_LO16, HW_H_UINT, 15, 16,
340 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_UIMM] } },
341 { 0, { { { (1<<MACH_BASE), 0 } } } } },
342 /* gp16: gp relative 16-bit immediate */
343 { "gp16", LM32_OPERAND_GP16, HW_H_SINT, 15, 16,
344 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
345 { 0, { { { (1<<MACH_BASE), 0 } } } } },
346 /* got16: got 16-bit immediate */
347 { "got16", LM32_OPERAND_GOT16, HW_H_SINT, 15, 16,
348 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
349 { 0, { { { (1<<MACH_BASE), 0 } } } } },
350 /* gotoffhi16: got offset high 16-bit immediate */
351 { "gotoffhi16", LM32_OPERAND_GOTOFFHI16, HW_H_SINT, 15, 16,
352 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
353 { 0, { { { (1<<MACH_BASE), 0 } } } } },
354 /* gotofflo16: got offset low 16-bit immediate */
355 { "gotofflo16", LM32_OPERAND_GOTOFFLO16, HW_H_SINT, 15, 16,
356 { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
357 { 0, { { { (1<<MACH_BASE), 0 } } } } },
358 /* sentinel */
359 { 0, 0, 0, 0, 0,
360 { 0, { (const PTR) 0 } },
361 { 0, { { { (1<<MACH_BASE), 0 } } } } }
364 #undef A
367 /* The instruction table. */
369 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
370 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
371 #define A(a) (1 << CGEN_INSN_##a)
372 #else
373 #define A(a) (1 << CGEN_INSN_/**/a)
374 #endif
376 static const CGEN_IBASE lm32_cgen_insn_table[MAX_INSNS] =
378 /* Special null first entry.
379 A `num' value of zero is thus invalid.
380 Also, the special `invalid' insn resides here. */
381 { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
382 /* add $r2,$r0,$r1 */
384 LM32_INSN_ADD, "add", "add", 32,
385 { 0, { { { (1<<MACH_BASE), 0 } } } }
387 /* addi $r1,$r0,$imm */
389 LM32_INSN_ADDI, "addi", "addi", 32,
390 { 0, { { { (1<<MACH_BASE), 0 } } } }
392 /* and $r2,$r0,$r1 */
394 LM32_INSN_AND, "and", "and", 32,
395 { 0, { { { (1<<MACH_BASE), 0 } } } }
397 /* andi $r1,$r0,$uimm */
399 LM32_INSN_ANDI, "andi", "andi", 32,
400 { 0, { { { (1<<MACH_BASE), 0 } } } }
402 /* andhi $r1,$r0,$hi16 */
404 LM32_INSN_ANDHII, "andhii", "andhi", 32,
405 { 0, { { { (1<<MACH_BASE), 0 } } } }
407 /* b $r0 */
409 LM32_INSN_B, "b", "b", 32,
410 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
412 /* bi $call */
414 LM32_INSN_BI, "bi", "bi", 32,
415 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
417 /* be $r0,$r1,$branch */
419 LM32_INSN_BE, "be", "be", 32,
420 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
422 /* bg $r0,$r1,$branch */
424 LM32_INSN_BG, "bg", "bg", 32,
425 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
427 /* bge $r0,$r1,$branch */
429 LM32_INSN_BGE, "bge", "bge", 32,
430 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
432 /* bgeu $r0,$r1,$branch */
434 LM32_INSN_BGEU, "bgeu", "bgeu", 32,
435 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
437 /* bgu $r0,$r1,$branch */
439 LM32_INSN_BGU, "bgu", "bgu", 32,
440 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
442 /* bne $r0,$r1,$branch */
444 LM32_INSN_BNE, "bne", "bne", 32,
445 { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
447 /* call $r0 */
449 LM32_INSN_CALL, "call", "call", 32,
450 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
452 /* calli $call */
454 LM32_INSN_CALLI, "calli", "calli", 32,
455 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
457 /* cmpe $r2,$r0,$r1 */
459 LM32_INSN_CMPE, "cmpe", "cmpe", 32,
460 { 0, { { { (1<<MACH_BASE), 0 } } } }
462 /* cmpei $r1,$r0,$imm */
464 LM32_INSN_CMPEI, "cmpei", "cmpei", 32,
465 { 0, { { { (1<<MACH_BASE), 0 } } } }
467 /* cmpg $r2,$r0,$r1 */
469 LM32_INSN_CMPG, "cmpg", "cmpg", 32,
470 { 0, { { { (1<<MACH_BASE), 0 } } } }
472 /* cmpgi $r1,$r0,$imm */
474 LM32_INSN_CMPGI, "cmpgi", "cmpgi", 32,
475 { 0, { { { (1<<MACH_BASE), 0 } } } }
477 /* cmpge $r2,$r0,$r1 */
479 LM32_INSN_CMPGE, "cmpge", "cmpge", 32,
480 { 0, { { { (1<<MACH_BASE), 0 } } } }
482 /* cmpgei $r1,$r0,$imm */
484 LM32_INSN_CMPGEI, "cmpgei", "cmpgei", 32,
485 { 0, { { { (1<<MACH_BASE), 0 } } } }
487 /* cmpgeu $r2,$r0,$r1 */
489 LM32_INSN_CMPGEU, "cmpgeu", "cmpgeu", 32,
490 { 0, { { { (1<<MACH_BASE), 0 } } } }
492 /* cmpgeui $r1,$r0,$uimm */
494 LM32_INSN_CMPGEUI, "cmpgeui", "cmpgeui", 32,
495 { 0, { { { (1<<MACH_BASE), 0 } } } }
497 /* cmpgu $r2,$r0,$r1 */
499 LM32_INSN_CMPGU, "cmpgu", "cmpgu", 32,
500 { 0, { { { (1<<MACH_BASE), 0 } } } }
502 /* cmpgui $r1,$r0,$uimm */
504 LM32_INSN_CMPGUI, "cmpgui", "cmpgui", 32,
505 { 0, { { { (1<<MACH_BASE), 0 } } } }
507 /* cmpne $r2,$r0,$r1 */
509 LM32_INSN_CMPNE, "cmpne", "cmpne", 32,
510 { 0, { { { (1<<MACH_BASE), 0 } } } }
512 /* cmpnei $r1,$r0,$imm */
514 LM32_INSN_CMPNEI, "cmpnei", "cmpnei", 32,
515 { 0, { { { (1<<MACH_BASE), 0 } } } }
517 /* divu $r2,$r0,$r1 */
519 LM32_INSN_DIVU, "divu", "divu", 32,
520 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
522 /* lb $r1,($r0+$imm) */
524 LM32_INSN_LB, "lb", "lb", 32,
525 { 0, { { { (1<<MACH_BASE), 0 } } } }
527 /* lbu $r1,($r0+$imm) */
529 LM32_INSN_LBU, "lbu", "lbu", 32,
530 { 0, { { { (1<<MACH_BASE), 0 } } } }
532 /* lh $r1,($r0+$imm) */
534 LM32_INSN_LH, "lh", "lh", 32,
535 { 0, { { { (1<<MACH_BASE), 0 } } } }
537 /* lhu $r1,($r0+$imm) */
539 LM32_INSN_LHU, "lhu", "lhu", 32,
540 { 0, { { { (1<<MACH_BASE), 0 } } } }
542 /* lw $r1,($r0+$imm) */
544 LM32_INSN_LW, "lw", "lw", 32,
545 { 0, { { { (1<<MACH_BASE), 0 } } } }
547 /* modu $r2,$r0,$r1 */
549 LM32_INSN_MODU, "modu", "modu", 32,
550 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
552 /* mul $r2,$r0,$r1 */
554 LM32_INSN_MUL, "mul", "mul", 32,
555 { 0, { { { (1<<MACH_BASE), 0 } } } }
557 /* muli $r1,$r0,$imm */
559 LM32_INSN_MULI, "muli", "muli", 32,
560 { 0, { { { (1<<MACH_BASE), 0 } } } }
562 /* nor $r2,$r0,$r1 */
564 LM32_INSN_NOR, "nor", "nor", 32,
565 { 0, { { { (1<<MACH_BASE), 0 } } } }
567 /* nori $r1,$r0,$uimm */
569 LM32_INSN_NORI, "nori", "nori", 32,
570 { 0, { { { (1<<MACH_BASE), 0 } } } }
572 /* or $r2,$r0,$r1 */
574 LM32_INSN_OR, "or", "or", 32,
575 { 0, { { { (1<<MACH_BASE), 0 } } } }
577 /* ori $r1,$r0,$lo16 */
579 LM32_INSN_ORI, "ori", "ori", 32,
580 { 0, { { { (1<<MACH_BASE), 0 } } } }
582 /* orhi $r1,$r0,$hi16 */
584 LM32_INSN_ORHII, "orhii", "orhi", 32,
585 { 0, { { { (1<<MACH_BASE), 0 } } } }
587 /* rcsr $r2,$csr */
589 LM32_INSN_RCSR, "rcsr", "rcsr", 32,
590 { 0, { { { (1<<MACH_BASE), 0 } } } }
592 /* sb ($r0+$imm),$r1 */
594 LM32_INSN_SB, "sb", "sb", 32,
595 { 0, { { { (1<<MACH_BASE), 0 } } } }
597 /* sextb $r2,$r0 */
599 LM32_INSN_SEXTB, "sextb", "sextb", 32,
600 { 0, { { { (1<<MACH_BASE), 0 } } } }
602 /* sexth $r2,$r0 */
604 LM32_INSN_SEXTH, "sexth", "sexth", 32,
605 { 0, { { { (1<<MACH_BASE), 0 } } } }
607 /* sh ($r0+$imm),$r1 */
609 LM32_INSN_SH, "sh", "sh", 32,
610 { 0, { { { (1<<MACH_BASE), 0 } } } }
612 /* sl $r2,$r0,$r1 */
614 LM32_INSN_SL, "sl", "sl", 32,
615 { 0, { { { (1<<MACH_BASE), 0 } } } }
617 /* sli $r1,$r0,$imm */
619 LM32_INSN_SLI, "sli", "sli", 32,
620 { 0, { { { (1<<MACH_BASE), 0 } } } }
622 /* sr $r2,$r0,$r1 */
624 LM32_INSN_SR, "sr", "sr", 32,
625 { 0, { { { (1<<MACH_BASE), 0 } } } }
627 /* sri $r1,$r0,$imm */
629 LM32_INSN_SRI, "sri", "sri", 32,
630 { 0, { { { (1<<MACH_BASE), 0 } } } }
632 /* sru $r2,$r0,$r1 */
634 LM32_INSN_SRU, "sru", "sru", 32,
635 { 0, { { { (1<<MACH_BASE), 0 } } } }
637 /* srui $r1,$r0,$imm */
639 LM32_INSN_SRUI, "srui", "srui", 32,
640 { 0, { { { (1<<MACH_BASE), 0 } } } }
642 /* sub $r2,$r0,$r1 */
644 LM32_INSN_SUB, "sub", "sub", 32,
645 { 0, { { { (1<<MACH_BASE), 0 } } } }
647 /* sw ($r0+$imm),$r1 */
649 LM32_INSN_SW, "sw", "sw", 32,
650 { 0, { { { (1<<MACH_BASE), 0 } } } }
652 /* user $r2,$r0,$r1,$user */
654 LM32_INSN_USER, "user", "user", 32,
655 { 0, { { { (1<<MACH_BASE), 0 } } } }
657 /* wcsr $csr,$r1 */
659 LM32_INSN_WCSR, "wcsr", "wcsr", 32,
660 { 0, { { { (1<<MACH_BASE), 0 } } } }
662 /* xor $r2,$r0,$r1 */
664 LM32_INSN_XOR, "xor", "xor", 32,
665 { 0, { { { (1<<MACH_BASE), 0 } } } }
667 /* xori $r1,$r0,$uimm */
669 LM32_INSN_XORI, "xori", "xori", 32,
670 { 0, { { { (1<<MACH_BASE), 0 } } } }
672 /* xnor $r2,$r0,$r1 */
674 LM32_INSN_XNOR, "xnor", "xnor", 32,
675 { 0, { { { (1<<MACH_BASE), 0 } } } }
677 /* xnori $r1,$r0,$uimm */
679 LM32_INSN_XNORI, "xnori", "xnori", 32,
680 { 0, { { { (1<<MACH_BASE), 0 } } } }
682 /* break */
684 LM32_INSN_BREAK, "break", "break", 32,
685 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
687 /* scall */
689 LM32_INSN_SCALL, "scall", "scall", 32,
690 { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
692 /* bret */
694 -1, "bret", "bret", 32,
695 { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
697 /* eret */
699 -1, "eret", "eret", 32,
700 { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
702 /* ret */
704 -1, "ret", "ret", 32,
705 { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
707 /* mv $r2,$r0 */
709 -1, "mv", "mv", 32,
710 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
712 /* mvi $r1,$imm */
714 -1, "mvi", "mvi", 32,
715 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
717 /* mvu $r1,$lo16 */
719 -1, "mvui", "mvu", 32,
720 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
722 /* mvhi $r1,$hi16 */
724 -1, "mvhi", "mvhi", 32,
725 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
727 /* mva $r1,$gp16 */
729 -1, "mva", "mva", 32,
730 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
732 /* not $r2,$r0 */
734 -1, "not", "not", 32,
735 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
737 /* nop */
739 -1, "nop", "nop", 32,
740 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
742 /* lb $r1,$gp16 */
744 -1, "lbgprel", "lb", 32,
745 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
747 /* lbu $r1,$gp16 */
749 -1, "lbugprel", "lbu", 32,
750 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
752 /* lh $r1,$gp16 */
754 -1, "lhgprel", "lh", 32,
755 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
757 /* lhu $r1,$gp16 */
759 -1, "lhugprel", "lhu", 32,
760 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
762 /* lw $r1,$gp16 */
764 -1, "lwgprel", "lw", 32,
765 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
767 /* sb $gp16,$r1 */
769 -1, "sbgprel", "sb", 32,
770 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
772 /* sh $gp16,$r1 */
774 -1, "shgprel", "sh", 32,
775 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
777 /* sw $gp16,$r1 */
779 -1, "swgprel", "sw", 32,
780 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
782 /* lw $r1,(gp+$got16) */
784 -1, "lwgotrel", "lw", 32,
785 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
787 /* orhi $r1,$r0,$gotoffhi16 */
789 -1, "orhigotoffi", "orhi", 32,
790 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
792 /* addi $r1,$r0,$gotofflo16 */
794 -1, "addgotoff", "addi", 32,
795 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
797 /* sw ($r0+$gotofflo16),$r1 */
799 -1, "swgotoff", "sw", 32,
800 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
802 /* lw $r1,($r0+$gotofflo16) */
804 -1, "lwgotoff", "lw", 32,
805 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
807 /* sh ($r0+$gotofflo16),$r1 */
809 -1, "shgotoff", "sh", 32,
810 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
812 /* lh $r1,($r0+$gotofflo16) */
814 -1, "lhgotoff", "lh", 32,
815 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
817 /* lhu $r1,($r0+$gotofflo16) */
819 -1, "lhugotoff", "lhu", 32,
820 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
822 /* sb ($r0+$gotofflo16),$r1 */
824 -1, "sbgotoff", "sb", 32,
825 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
827 /* lb $r1,($r0+$gotofflo16) */
829 -1, "lbgotoff", "lb", 32,
830 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
832 /* lbu $r1,($r0+$gotofflo16) */
834 -1, "lbugotoff", "lbu", 32,
835 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
839 #undef OP
840 #undef A
842 /* Initialize anything needed to be done once, before any cpu_open call. */
844 static void
845 init_tables (void)
849 static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
850 static void build_hw_table (CGEN_CPU_TABLE *);
851 static void build_ifield_table (CGEN_CPU_TABLE *);
852 static void build_operand_table (CGEN_CPU_TABLE *);
853 static void build_insn_table (CGEN_CPU_TABLE *);
854 static void lm32_cgen_rebuild_tables (CGEN_CPU_TABLE *);
856 /* Subroutine of lm32_cgen_cpu_open to look up a mach via its bfd name. */
858 static const CGEN_MACH *
859 lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
861 while (table->name)
863 if (strcmp (name, table->bfd_name) == 0)
864 return table;
865 ++table;
867 abort ();
870 /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
872 static void
873 build_hw_table (CGEN_CPU_TABLE *cd)
875 int i;
876 int machs = cd->machs;
877 const CGEN_HW_ENTRY *init = & lm32_cgen_hw_table[0];
878 /* MAX_HW is only an upper bound on the number of selected entries.
879 However each entry is indexed by it's enum so there can be holes in
880 the table. */
881 const CGEN_HW_ENTRY **selected =
882 (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
884 cd->hw_table.init_entries = init;
885 cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
886 memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
887 /* ??? For now we just use machs to determine which ones we want. */
888 for (i = 0; init[i].name != NULL; ++i)
889 if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
890 & machs)
891 selected[init[i].type] = &init[i];
892 cd->hw_table.entries = selected;
893 cd->hw_table.num_entries = MAX_HW;
896 /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
898 static void
899 build_ifield_table (CGEN_CPU_TABLE *cd)
901 cd->ifld_table = & lm32_cgen_ifld_table[0];
904 /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
906 static void
907 build_operand_table (CGEN_CPU_TABLE *cd)
909 int i;
910 int machs = cd->machs;
911 const CGEN_OPERAND *init = & lm32_cgen_operand_table[0];
912 /* MAX_OPERANDS is only an upper bound on the number of selected entries.
913 However each entry is indexed by it's enum so there can be holes in
914 the table. */
915 const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
917 cd->operand_table.init_entries = init;
918 cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
919 memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
920 /* ??? For now we just use mach to determine which ones we want. */
921 for (i = 0; init[i].name != NULL; ++i)
922 if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
923 & machs)
924 selected[init[i].type] = &init[i];
925 cd->operand_table.entries = selected;
926 cd->operand_table.num_entries = MAX_OPERANDS;
929 /* Subroutine of lm32_cgen_cpu_open to build the hardware table.
930 ??? This could leave out insns not supported by the specified mach/isa,
931 but that would cause errors like "foo only supported by bar" to become
932 "unknown insn", so for now we include all insns and require the app to
933 do the checking later.
934 ??? On the other hand, parsing of such insns may require their hardware or
935 operand elements to be in the table [which they mightn't be]. */
937 static void
938 build_insn_table (CGEN_CPU_TABLE *cd)
940 int i;
941 const CGEN_IBASE *ib = & lm32_cgen_insn_table[0];
942 CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
944 memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
945 for (i = 0; i < MAX_INSNS; ++i)
946 insns[i].base = &ib[i];
947 cd->insn_table.init_entries = insns;
948 cd->insn_table.entry_size = sizeof (CGEN_IBASE);
949 cd->insn_table.num_init_entries = MAX_INSNS;
952 /* Subroutine of lm32_cgen_cpu_open to rebuild the tables. */
954 static void
955 lm32_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
957 int i;
958 CGEN_BITSET *isas = cd->isas;
959 unsigned int machs = cd->machs;
961 cd->int_insn_p = CGEN_INT_INSN_P;
963 /* Data derived from the isa spec. */
964 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
965 cd->default_insn_bitsize = UNSET;
966 cd->base_insn_bitsize = UNSET;
967 cd->min_insn_bitsize = 65535; /* Some ridiculously big number. */
968 cd->max_insn_bitsize = 0;
969 for (i = 0; i < MAX_ISAS; ++i)
970 if (cgen_bitset_contains (isas, i))
972 const CGEN_ISA *isa = & lm32_cgen_isa_table[i];
974 /* Default insn sizes of all selected isas must be
975 equal or we set the result to 0, meaning "unknown". */
976 if (cd->default_insn_bitsize == UNSET)
977 cd->default_insn_bitsize = isa->default_insn_bitsize;
978 else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
979 ; /* This is ok. */
980 else
981 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
983 /* Base insn sizes of all selected isas must be equal
984 or we set the result to 0, meaning "unknown". */
985 if (cd->base_insn_bitsize == UNSET)
986 cd->base_insn_bitsize = isa->base_insn_bitsize;
987 else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
988 ; /* This is ok. */
989 else
990 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
992 /* Set min,max insn sizes. */
993 if (isa->min_insn_bitsize < cd->min_insn_bitsize)
994 cd->min_insn_bitsize = isa->min_insn_bitsize;
995 if (isa->max_insn_bitsize > cd->max_insn_bitsize)
996 cd->max_insn_bitsize = isa->max_insn_bitsize;
999 /* Data derived from the mach spec. */
1000 for (i = 0; i < MAX_MACHS; ++i)
1001 if (((1 << i) & machs) != 0)
1003 const CGEN_MACH *mach = & lm32_cgen_mach_table[i];
1005 if (mach->insn_chunk_bitsize != 0)
1007 if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
1009 fprintf (stderr, "lm32_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
1010 cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
1011 abort ();
1014 cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
1018 /* Determine which hw elements are used by MACH. */
1019 build_hw_table (cd);
1021 /* Build the ifield table. */
1022 build_ifield_table (cd);
1024 /* Determine which operands are used by MACH/ISA. */
1025 build_operand_table (cd);
1027 /* Build the instruction table. */
1028 build_insn_table (cd);
1031 /* Initialize a cpu table and return a descriptor.
1032 It's much like opening a file, and must be the first function called.
1033 The arguments are a set of (type/value) pairs, terminated with
1034 CGEN_CPU_OPEN_END.
1036 Currently supported values:
1037 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
1038 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
1039 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
1040 CGEN_CPU_OPEN_ENDIAN: specify endian choice
1041 CGEN_CPU_OPEN_END: terminates arguments
1043 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
1044 precluded.
1046 ??? We only support ISO C stdargs here, not K&R.
1047 Laziness, plus experiment to see if anything requires K&R - eventually
1048 K&R will no longer be supported - e.g. GDB is currently trying this. */
1050 CGEN_CPU_DESC
1051 lm32_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
1053 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
1054 static int init_p;
1055 CGEN_BITSET *isas = 0; /* 0 = "unspecified" */
1056 unsigned int machs = 0; /* 0 = "unspecified" */
1057 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
1058 va_list ap;
1060 if (! init_p)
1062 init_tables ();
1063 init_p = 1;
1066 memset (cd, 0, sizeof (*cd));
1068 va_start (ap, arg_type);
1069 while (arg_type != CGEN_CPU_OPEN_END)
1071 switch (arg_type)
1073 case CGEN_CPU_OPEN_ISAS :
1074 isas = va_arg (ap, CGEN_BITSET *);
1075 break;
1076 case CGEN_CPU_OPEN_MACHS :
1077 machs = va_arg (ap, unsigned int);
1078 break;
1079 case CGEN_CPU_OPEN_BFDMACH :
1081 const char *name = va_arg (ap, const char *);
1082 const CGEN_MACH *mach =
1083 lookup_mach_via_bfd_name (lm32_cgen_mach_table, name);
1085 machs |= 1 << mach->num;
1086 break;
1088 case CGEN_CPU_OPEN_ENDIAN :
1089 endian = va_arg (ap, enum cgen_endian);
1090 break;
1091 default :
1092 fprintf (stderr, "lm32_cgen_cpu_open: unsupported argument `%d'\n",
1093 arg_type);
1094 abort (); /* ??? return NULL? */
1096 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
1098 va_end (ap);
1100 /* Mach unspecified means "all". */
1101 if (machs == 0)
1102 machs = (1 << MAX_MACHS) - 1;
1103 /* Base mach is always selected. */
1104 machs |= 1;
1105 if (endian == CGEN_ENDIAN_UNKNOWN)
1107 /* ??? If target has only one, could have a default. */
1108 fprintf (stderr, "lm32_cgen_cpu_open: no endianness specified\n");
1109 abort ();
1112 cd->isas = cgen_bitset_copy (isas);
1113 cd->machs = machs;
1114 cd->endian = endian;
1115 /* FIXME: for the sparc case we can determine insn-endianness statically.
1116 The worry here is where both data and insn endian can be independently
1117 chosen, in which case this function will need another argument.
1118 Actually, will want to allow for more arguments in the future anyway. */
1119 cd->insn_endian = endian;
1121 /* Table (re)builder. */
1122 cd->rebuild_tables = lm32_cgen_rebuild_tables;
1123 lm32_cgen_rebuild_tables (cd);
1125 /* Default to not allowing signed overflow. */
1126 cd->signed_overflow_ok_p = 0;
1128 return (CGEN_CPU_DESC) cd;
1131 /* Cover fn to lm32_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
1132 MACH_NAME is the bfd name of the mach. */
1134 CGEN_CPU_DESC
1135 lm32_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
1137 return lm32_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
1138 CGEN_CPU_OPEN_ENDIAN, endian,
1139 CGEN_CPU_OPEN_END);
1142 /* Close a cpu table.
1143 ??? This can live in a machine independent file, but there's currently
1144 no place to put this file (there's no libcgen). libopcodes is the wrong
1145 place as some simulator ports use this but they don't use libopcodes. */
1147 void
1148 lm32_cgen_cpu_close (CGEN_CPU_DESC cd)
1150 unsigned int i;
1151 const CGEN_INSN *insns;
1153 if (cd->macro_insn_table.init_entries)
1155 insns = cd->macro_insn_table.init_entries;
1156 for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
1157 if (CGEN_INSN_RX ((insns)))
1158 regfree (CGEN_INSN_RX (insns));
1161 if (cd->insn_table.init_entries)
1163 insns = cd->insn_table.init_entries;
1164 for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
1165 if (CGEN_INSN_RX (insns))
1166 regfree (CGEN_INSN_RX (insns));
1169 if (cd->macro_insn_table.init_entries)
1170 free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
1172 if (cd->insn_table.init_entries)
1173 free ((CGEN_INSN *) cd->insn_table.init_entries);
1175 if (cd->hw_table.entries)
1176 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1178 if (cd->operand_table.entries)
1179 free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
1181 free (cd);