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