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