1 /* CPU data for lm32.
2
3 THIS FILE IS MACHINE GENERATED WITH CGEN.
4
5 Copyright (C) 1996-2016 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
init_tables(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 *
lookup_mach_via_bfd_name(const CGEN_MACH * table,const char * name)844 lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
845 {
846 while (table->name)
847 {
848 if (strcmp (name, table->bfd_name) == 0)
849 return table;
850 ++table;
851 }
852 abort ();
853 }
854
855 /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
856
857 static void
build_hw_table(CGEN_CPU_TABLE * cd)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
build_ifield_table(CGEN_CPU_TABLE * cd)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
build_operand_table(CGEN_CPU_TABLE * cd)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
build_insn_table(CGEN_CPU_TABLE * cd)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
lm32_cgen_rebuild_tables(CGEN_CPU_TABLE * cd)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
lm32_cgen_cpu_open(enum cgen_cpu_open_arg arg_type,...)1032 lm32_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
1033 {
1034 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
1035 static int init_p;
1036 CGEN_BITSET *isas = 0; /* 0 = "unspecified" */
1037 unsigned int machs = 0; /* 0 = "unspecified" */
1038 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
1039 va_list ap;
1040
1041 if (! init_p)
1042 {
1043 init_tables ();
1044 init_p = 1;
1045 }
1046
1047 memset (cd, 0, sizeof (*cd));
1048
1049 va_start (ap, arg_type);
1050 while (arg_type != CGEN_CPU_OPEN_END)
1051 {
1052 switch (arg_type)
1053 {
1054 case CGEN_CPU_OPEN_ISAS :
1055 isas = va_arg (ap, CGEN_BITSET *);
1056 break;
1057 case CGEN_CPU_OPEN_MACHS :
1058 machs = va_arg (ap, unsigned int);
1059 break;
1060 case CGEN_CPU_OPEN_BFDMACH :
1061 {
1062 const char *name = va_arg (ap, const char *);
1063 const CGEN_MACH *mach =
1064 lookup_mach_via_bfd_name (lm32_cgen_mach_table, name);
1065
1066 machs |= 1 << mach->num;
1067 break;
1068 }
1069 case CGEN_CPU_OPEN_ENDIAN :
1070 endian = va_arg (ap, enum cgen_endian);
1071 break;
1072 default :
1073 fprintf (stderr, "lm32_cgen_cpu_open: unsupported argument `%d'\n",
1074 arg_type);
1075 abort (); /* ??? return NULL? */
1076 }
1077 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
1078 }
1079 va_end (ap);
1080
1081 /* Mach unspecified means "all". */
1082 if (machs == 0)
1083 machs = (1 << MAX_MACHS) - 1;
1084 /* Base mach is always selected. */
1085 machs |= 1;
1086 if (endian == CGEN_ENDIAN_UNKNOWN)
1087 {
1088 /* ??? If target has only one, could have a default. */
1089 fprintf (stderr, "lm32_cgen_cpu_open: no endianness specified\n");
1090 abort ();
1091 }
1092
1093 cd->isas = cgen_bitset_copy (isas);
1094 cd->machs = machs;
1095 cd->endian = endian;
1096 /* FIXME: for the sparc case we can determine insn-endianness statically.
1097 The worry here is where both data and insn endian can be independently
1098 chosen, in which case this function will need another argument.
1099 Actually, will want to allow for more arguments in the future anyway. */
1100 cd->insn_endian = endian;
1101
1102 /* Table (re)builder. */
1103 cd->rebuild_tables = lm32_cgen_rebuild_tables;
1104 lm32_cgen_rebuild_tables (cd);
1105
1106 /* Default to not allowing signed overflow. */
1107 cd->signed_overflow_ok_p = 0;
1108
1109 return (CGEN_CPU_DESC) cd;
1110 }
1111
1112 /* Cover fn to lm32_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
1113 MACH_NAME is the bfd name of the mach. */
1114
1115 CGEN_CPU_DESC
lm32_cgen_cpu_open_1(const char * mach_name,enum cgen_endian endian)1116 lm32_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
1117 {
1118 return lm32_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
1119 CGEN_CPU_OPEN_ENDIAN, endian,
1120 CGEN_CPU_OPEN_END);
1121 }
1122
1123 /* Close a cpu table.
1124 ??? This can live in a machine independent file, but there's currently
1125 no place to put this file (there's no libcgen). libopcodes is the wrong
1126 place as some simulator ports use this but they don't use libopcodes. */
1127
1128 void
lm32_cgen_cpu_close(CGEN_CPU_DESC cd)1129 lm32_cgen_cpu_close (CGEN_CPU_DESC cd)
1130 {
1131 unsigned int i;
1132 const CGEN_INSN *insns;
1133
1134 if (cd->macro_insn_table.init_entries)
1135 {
1136 insns = cd->macro_insn_table.init_entries;
1137 for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
1138 if (CGEN_INSN_RX ((insns)))
1139 regfree (CGEN_INSN_RX (insns));
1140 }
1141
1142 if (cd->insn_table.init_entries)
1143 {
1144 insns = cd->insn_table.init_entries;
1145 for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
1146 if (CGEN_INSN_RX (insns))
1147 regfree (CGEN_INSN_RX (insns));
1148 }
1149
1150 if (cd->macro_insn_table.init_entries)
1151 free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
1152
1153 if (cd->insn_table.init_entries)
1154 free ((CGEN_INSN *) cd->insn_table.init_entries);
1155
1156 if (cd->hw_table.entries)
1157 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1158
1159 if (cd->operand_table.entries)
1160 free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
1161
1162 free (cd);
1163 }
1164
1165