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