1/* CPU data for lm32.
2
3THIS FILE IS MACHINE GENERATED WITH CGEN.
4
5Copyright (C) 1996-2017 Free Software Foundation, Inc.
6
7This 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
39static const CGEN_ATTR_ENTRY bool_attr[] =
40{
41  { "#f", 0 },
42  { "#t", 1 },
43  { 0, 0 }
44};
45
46static 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
54static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED =
55{
56  { "lm32", ISA_LM32 },
57  { "max", ISA_MAX },
58  { 0, 0 }
59};
60
61const 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
73const 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
83const 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
97const 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
115static 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
122static const CGEN_MACH lm32_cgen_mach_table[] = {
123  { "lm32", "lm32", MACH_LM32, 0 },
124  { 0, 0, 0, 0 }
125};
126
127static 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
169CGEN_KEYWORD lm32_cgen_opval_h_gr =
170{
171  & lm32_cgen_opval_h_gr_entries[0],
172  38,
173  0, 0, 0, 0, ""
174};
175
176static 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
205CGEN_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
217const 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
237const 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
273const 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
361static 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
829static void
830init_tables (void)
831{
832}
833
834static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
835static void build_hw_table      (CGEN_CPU_TABLE *);
836static void build_ifield_table  (CGEN_CPU_TABLE *);
837static void build_operand_table (CGEN_CPU_TABLE *);
838static void build_insn_table    (CGEN_CPU_TABLE *);
839static 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
843static const CGEN_MACH *
844lookup_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
857static void
858build_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
883static void
884build_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
891static void
892build_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
922static void
923build_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
939static void
940lm32_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
1031CGEN_CPU_DESC
1032lm32_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
1115CGEN_CPU_DESC
1116lm32_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
1128void
1129lm32_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