1/* CPU data for openrisc.
2
3THIS FILE IS MACHINE GENERATED WITH CGEN.
4
5Copyright 1996-2007 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 "openrisc-desc.h"
32#include "openrisc-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  { "openrisc", MACH_OPENRISC },
50  { "or1300", MACH_OR1300 },
51  { "max", MACH_MAX },
52  { 0, 0 }
53};
54
55static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED =
56{
57  { "or32", ISA_OR32 },
58  { "max", ISA_MAX },
59  { 0, 0 }
60};
61
62static const CGEN_ATTR_ENTRY HAS_CACHE_attr[] ATTRIBUTE_UNUSED =
63{
64  { "DATA_CACHE", HAS_CACHE_DATA_CACHE },
65  { "INSN_CACHE", HAS_CACHE_INSN_CACHE },
66  { 0, 0 }
67};
68
69const CGEN_ATTR_TABLE openrisc_cgen_ifield_attr_table[] =
70{
71  { "MACH", & MACH_attr[0], & MACH_attr[0] },
72  { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
73  { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
74  { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
75  { "RESERVED", &bool_attr[0], &bool_attr[0] },
76  { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
77  { "SIGNED", &bool_attr[0], &bool_attr[0] },
78  { 0, 0, 0 }
79};
80
81const CGEN_ATTR_TABLE openrisc_cgen_hardware_attr_table[] =
82{
83  { "MACH", & MACH_attr[0], & MACH_attr[0] },
84  { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
85  { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
86  { "PC", &bool_attr[0], &bool_attr[0] },
87  { "PROFILE", &bool_attr[0], &bool_attr[0] },
88  { 0, 0, 0 }
89};
90
91const CGEN_ATTR_TABLE openrisc_cgen_operand_attr_table[] =
92{
93  { "MACH", & MACH_attr[0], & MACH_attr[0] },
94  { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
95  { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
96  { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
97  { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
98  { "SIGNED", &bool_attr[0], &bool_attr[0] },
99  { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
100  { "RELAX", &bool_attr[0], &bool_attr[0] },
101  { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
102  { 0, 0, 0 }
103};
104
105const CGEN_ATTR_TABLE openrisc_cgen_insn_attr_table[] =
106{
107  { "MACH", & MACH_attr[0], & MACH_attr[0] },
108  { "ALIAS", &bool_attr[0], &bool_attr[0] },
109  { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
110  { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
111  { "COND-CTI", &bool_attr[0], &bool_attr[0] },
112  { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
113  { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
114  { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
115  { "RELAXED", &bool_attr[0], &bool_attr[0] },
116  { "NO-DIS", &bool_attr[0], &bool_attr[0] },
117  { "PBB", &bool_attr[0], &bool_attr[0] },
118  { "NOT-IN-DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
119  { 0, 0, 0 }
120};
121
122/* Instruction set variants.  */
123
124static const CGEN_ISA openrisc_cgen_isa_table[] = {
125  { "or32", 32, 32, 32, 32 },
126  { 0, 0, 0, 0, 0 }
127};
128
129/* Machine variants.  */
130
131static const CGEN_MACH openrisc_cgen_mach_table[] = {
132  { "openrisc", "openrisc", MACH_OPENRISC, 0 },
133  { "or1300", "openrisc:1300", MACH_OR1300, 0 },
134  { 0, 0, 0, 0 }
135};
136
137static CGEN_KEYWORD_ENTRY openrisc_cgen_opval_h_gr_entries[] =
138{
139  { "r0", 0, {0, {{{0, 0}}}}, 0, 0 },
140  { "r1", 1, {0, {{{0, 0}}}}, 0, 0 },
141  { "r2", 2, {0, {{{0, 0}}}}, 0, 0 },
142  { "r3", 3, {0, {{{0, 0}}}}, 0, 0 },
143  { "r4", 4, {0, {{{0, 0}}}}, 0, 0 },
144  { "r5", 5, {0, {{{0, 0}}}}, 0, 0 },
145  { "r6", 6, {0, {{{0, 0}}}}, 0, 0 },
146  { "r7", 7, {0, {{{0, 0}}}}, 0, 0 },
147  { "r8", 8, {0, {{{0, 0}}}}, 0, 0 },
148  { "r9", 9, {0, {{{0, 0}}}}, 0, 0 },
149  { "r10", 10, {0, {{{0, 0}}}}, 0, 0 },
150  { "r11", 11, {0, {{{0, 0}}}}, 0, 0 },
151  { "r12", 12, {0, {{{0, 0}}}}, 0, 0 },
152  { "r13", 13, {0, {{{0, 0}}}}, 0, 0 },
153  { "r14", 14, {0, {{{0, 0}}}}, 0, 0 },
154  { "r15", 15, {0, {{{0, 0}}}}, 0, 0 },
155  { "r16", 16, {0, {{{0, 0}}}}, 0, 0 },
156  { "r17", 17, {0, {{{0, 0}}}}, 0, 0 },
157  { "r18", 18, {0, {{{0, 0}}}}, 0, 0 },
158  { "r19", 19, {0, {{{0, 0}}}}, 0, 0 },
159  { "r20", 20, {0, {{{0, 0}}}}, 0, 0 },
160  { "r21", 21, {0, {{{0, 0}}}}, 0, 0 },
161  { "r22", 22, {0, {{{0, 0}}}}, 0, 0 },
162  { "r23", 23, {0, {{{0, 0}}}}, 0, 0 },
163  { "r24", 24, {0, {{{0, 0}}}}, 0, 0 },
164  { "r25", 25, {0, {{{0, 0}}}}, 0, 0 },
165  { "r26", 26, {0, {{{0, 0}}}}, 0, 0 },
166  { "r27", 27, {0, {{{0, 0}}}}, 0, 0 },
167  { "r28", 28, {0, {{{0, 0}}}}, 0, 0 },
168  { "r29", 29, {0, {{{0, 0}}}}, 0, 0 },
169  { "r30", 30, {0, {{{0, 0}}}}, 0, 0 },
170  { "r31", 31, {0, {{{0, 0}}}}, 0, 0 },
171  { "lr", 11, {0, {{{0, 0}}}}, 0, 0 },
172  { "sp", 1, {0, {{{0, 0}}}}, 0, 0 },
173  { "fp", 2, {0, {{{0, 0}}}}, 0, 0 }
174};
175
176CGEN_KEYWORD openrisc_cgen_opval_h_gr =
177{
178  & openrisc_cgen_opval_h_gr_entries[0],
179  35,
180  0, 0, 0, 0, ""
181};
182
183
184/* The hardware table.  */
185
186#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
187#define A(a) (1 << CGEN_HW_##a)
188#else
189#define A(a) (1 << CGEN_HW_/**/a)
190#endif
191
192const CGEN_HW_ENTRY openrisc_cgen_hw_table[] =
193{
194  { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
195  { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
196  { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
197  { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
198  { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
199  { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { { { (1<<MACH_BASE), 0 } } } } },
200  { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & openrisc_cgen_opval_h_gr, { 0|A(PROFILE), { { { (1<<MACH_BASE), 0 } } } } },
201  { "h-sr", HW_H_SR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
202  { "h-hi16", HW_H_HI16, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
203  { "h-lo16", HW_H_LO16, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
204  { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
205  { "h-delay-insn", HW_H_DELAY_INSN, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
206  { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
207};
208
209#undef A
210
211
212/* The instruction field table.  */
213
214#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
215#define A(a) (1 << CGEN_IFLD_##a)
216#else
217#define A(a) (1 << CGEN_IFLD_/**/a)
218#endif
219
220const CGEN_IFLD openrisc_cgen_ifld_table[] =
221{
222  { OPENRISC_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
223  { OPENRISC_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
224  { OPENRISC_F_CLASS, "f-class", 0, 32, 31, 2, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
225  { OPENRISC_F_SUB, "f-sub", 0, 32, 29, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
226  { OPENRISC_F_R1, "f-r1", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
227  { OPENRISC_F_R2, "f-r2", 0, 32, 20, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
228  { OPENRISC_F_R3, "f-r3", 0, 32, 15, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
229  { OPENRISC_F_SIMM16, "f-simm16", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
230  { OPENRISC_F_UIMM16, "f-uimm16", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
231  { OPENRISC_F_UIMM5, "f-uimm5", 0, 32, 4, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
232  { OPENRISC_F_HI16, "f-hi16", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
233  { OPENRISC_F_LO16, "f-lo16", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
234  { OPENRISC_F_OP1, "f-op1", 0, 32, 31, 2, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
235  { OPENRISC_F_OP2, "f-op2", 0, 32, 29, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
236  { OPENRISC_F_OP3, "f-op3", 0, 32, 25, 2, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
237  { OPENRISC_F_OP4, "f-op4", 0, 32, 23, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
238  { OPENRISC_F_OP5, "f-op5", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
239  { OPENRISC_F_OP6, "f-op6", 0, 32, 7, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
240  { OPENRISC_F_OP7, "f-op7", 0, 32, 3, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
241  { OPENRISC_F_I16_1, "f-i16-1", 0, 32, 10, 11, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
242  { OPENRISC_F_I16_2, "f-i16-2", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
243  { OPENRISC_F_DISP26, "f-disp26", 0, 32, 25, 26, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
244  { OPENRISC_F_ABS26, "f-abs26", 0, 32, 25, 26, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
245  { OPENRISC_F_I16NC, "f-i16nc", 0, 0, 0, 0,{ 0|A(SIGN_OPT)|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } }  },
246  { OPENRISC_F_F_15_8, "f-f-15-8", 0, 32, 15, 8, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } }  },
247  { OPENRISC_F_F_10_3, "f-f-10-3", 0, 32, 10, 3, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } }  },
248  { OPENRISC_F_F_4_1, "f-f-4-1", 0, 32, 4, 1, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } }  },
249  { OPENRISC_F_F_7_3, "f-f-7-3", 0, 32, 7, 3, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } }  },
250  { OPENRISC_F_F_10_7, "f-f-10-7", 0, 32, 10, 7, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } }  },
251  { OPENRISC_F_F_10_11, "f-f-10-11", 0, 32, 10, 11, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } }  },
252  { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
253};
254
255#undef A
256
257
258
259/* multi ifield declarations */
260
261const CGEN_MAYBE_MULTI_IFLD OPENRISC_F_I16NC_MULTI_IFIELD [];
262
263
264/* multi ifield definitions */
265
266const CGEN_MAYBE_MULTI_IFLD OPENRISC_F_I16NC_MULTI_IFIELD [] =
267{
268    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_I16_1] } },
269    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_I16_2] } },
270    { 0, { (const PTR) 0 } }
271};
272
273/* The operand table.  */
274
275#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
276#define A(a) (1 << CGEN_OPERAND_##a)
277#else
278#define A(a) (1 << CGEN_OPERAND_/**/a)
279#endif
280#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
281#define OPERAND(op) OPENRISC_OPERAND_##op
282#else
283#define OPERAND(op) OPENRISC_OPERAND_/**/op
284#endif
285
286const CGEN_OPERAND openrisc_cgen_operand_table[] =
287{
288/* pc: program counter */
289  { "pc", OPENRISC_OPERAND_PC, HW_H_PC, 0, 0,
290    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_NIL] } },
291    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
292/* sr: special register */
293  { "sr", OPENRISC_OPERAND_SR, HW_H_SR, 0, 0,
294    { 0, { (const PTR) 0 } },
295    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
296/* cbit: condition bit */
297  { "cbit", OPENRISC_OPERAND_CBIT, HW_H_CBIT, 0, 0,
298    { 0, { (const PTR) 0 } },
299    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
300/* simm-16: 16 bit signed immediate */
301  { "simm-16", OPENRISC_OPERAND_SIMM_16, HW_H_SINT, 15, 16,
302    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_SIMM16] } },
303    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
304/* uimm-16: 16 bit unsigned immediate */
305  { "uimm-16", OPENRISC_OPERAND_UIMM_16, HW_H_UINT, 15, 16,
306    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_UIMM16] } },
307    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
308/* disp-26: pc-rel 26 bit */
309  { "disp-26", OPENRISC_OPERAND_DISP_26, HW_H_IADDR, 25, 26,
310    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_DISP26] } },
311    { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
312/* abs-26: abs 26 bit */
313  { "abs-26", OPENRISC_OPERAND_ABS_26, HW_H_IADDR, 25, 26,
314    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_ABS26] } },
315    { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
316/* uimm-5: imm5 */
317  { "uimm-5", OPENRISC_OPERAND_UIMM_5, HW_H_UINT, 4, 5,
318    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_UIMM5] } },
319    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
320/* rD: destination register */
321  { "rD", OPENRISC_OPERAND_RD, HW_H_GR, 25, 5,
322    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_R1] } },
323    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
324/* rA: source register A */
325  { "rA", OPENRISC_OPERAND_RA, HW_H_GR, 20, 5,
326    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_R2] } },
327    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
328/* rB: source register B */
329  { "rB", OPENRISC_OPERAND_RB, HW_H_GR, 15, 5,
330    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_R3] } },
331    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
332/* op-f-23: f-op23 */
333  { "op-f-23", OPENRISC_OPERAND_OP_F_23, HW_H_UINT, 23, 3,
334    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_OP4] } },
335    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
336/* op-f-3: f-op3 */
337  { "op-f-3", OPENRISC_OPERAND_OP_F_3, HW_H_UINT, 25, 5,
338    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_OP5] } },
339    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
340/* hi16: high 16 bit immediate, sign optional */
341  { "hi16", OPENRISC_OPERAND_HI16, HW_H_HI16, 15, 16,
342    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_SIMM16] } },
343    { 0|A(SIGN_OPT), { { { (1<<MACH_BASE), 0 } } } }  },
344/* lo16: low 16 bit immediate, sign optional */
345  { "lo16", OPENRISC_OPERAND_LO16, HW_H_LO16, 15, 16,
346    { 0, { (const PTR) &openrisc_cgen_ifld_table[OPENRISC_F_LO16] } },
347    { 0|A(SIGN_OPT), { { { (1<<MACH_BASE), 0 } } } }  },
348/* ui16nc: 16 bit immediate, sign optional */
349  { "ui16nc", OPENRISC_OPERAND_UI16NC, HW_H_LO16, 10, 16,
350    { 2, { (const PTR) &OPENRISC_F_I16NC_MULTI_IFIELD[0] } },
351    { 0|A(SIGN_OPT)|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } }  },
352/* sentinel */
353  { 0, 0, 0, 0, 0,
354    { 0, { (const PTR) 0 } },
355    { 0, { { { (1<<MACH_BASE), 0 } } } } }
356};
357
358#undef A
359
360
361/* The instruction table.  */
362
363#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
364#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
365#define A(a) (1 << CGEN_INSN_##a)
366#else
367#define A(a) (1 << CGEN_INSN_/**/a)
368#endif
369
370static const CGEN_IBASE openrisc_cgen_insn_table[MAX_INSNS] =
371{
372  /* Special null first entry.
373     A `num' value of zero is thus invalid.
374     Also, the special `invalid' insn resides here.  */
375  { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
376/* l.j ${abs-26} */
377  {
378    OPENRISC_INSN_L_J, "l-j", "l.j", 32,
379    { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
380  },
381/* l.jal ${abs-26} */
382  {
383    OPENRISC_INSN_L_JAL, "l-jal", "l.jal", 32,
384    { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
385  },
386/* l.jr $rA */
387  {
388    OPENRISC_INSN_L_JR, "l-jr", "l.jr", 32,
389    { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
390  },
391/* l.jalr $rA */
392  {
393    OPENRISC_INSN_L_JALR, "l-jalr", "l.jalr", 32,
394    { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
395  },
396/* l.bal ${disp-26} */
397  {
398    OPENRISC_INSN_L_BAL, "l-bal", "l.bal", 32,
399    { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
400  },
401/* l.bnf ${disp-26} */
402  {
403    OPENRISC_INSN_L_BNF, "l-bnf", "l.bnf", 32,
404    { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
405  },
406/* l.bf ${disp-26} */
407  {
408    OPENRISC_INSN_L_BF, "l-bf", "l.bf", 32,
409    { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
410  },
411/* l.brk ${uimm-16} */
412  {
413    OPENRISC_INSN_L_BRK, "l-brk", "l.brk", 32,
414    { 0|A(NOT_IN_DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
415  },
416/* l.rfe $rA */
417  {
418    OPENRISC_INSN_L_RFE, "l-rfe", "l.rfe", 32,
419    { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
420  },
421/* l.sys ${uimm-16} */
422  {
423    OPENRISC_INSN_L_SYS, "l-sys", "l.sys", 32,
424    { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
425  },
426/* l.nop */
427  {
428    OPENRISC_INSN_L_NOP, "l-nop", "l.nop", 32,
429    { 0, { { { (1<<MACH_BASE), 0 } } } }
430  },
431/* l.movhi $rD,$hi16 */
432  {
433    OPENRISC_INSN_L_MOVHI, "l-movhi", "l.movhi", 32,
434    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
435  },
436/* l.mfsr $rD,$rA */
437  {
438    OPENRISC_INSN_L_MFSR, "l-mfsr", "l.mfsr", 32,
439    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
440  },
441/* l.mtsr $rA,$rB */
442  {
443    OPENRISC_INSN_L_MTSR, "l-mtsr", "l.mtsr", 32,
444    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
445  },
446/* l.lw $rD,${simm-16}($rA) */
447  {
448    OPENRISC_INSN_L_LW, "l-lw", "l.lw", 32,
449    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
450  },
451/* l.lbz $rD,${simm-16}($rA) */
452  {
453    OPENRISC_INSN_L_LBZ, "l-lbz", "l.lbz", 32,
454    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
455  },
456/* l.lbs $rD,${simm-16}($rA) */
457  {
458    OPENRISC_INSN_L_LBS, "l-lbs", "l.lbs", 32,
459    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
460  },
461/* l.lhz $rD,${simm-16}($rA) */
462  {
463    OPENRISC_INSN_L_LHZ, "l-lhz", "l.lhz", 32,
464    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
465  },
466/* l.lhs $rD,${simm-16}($rA) */
467  {
468    OPENRISC_INSN_L_LHS, "l-lhs", "l.lhs", 32,
469    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
470  },
471/* l.sw ${ui16nc}($rA),$rB */
472  {
473    OPENRISC_INSN_L_SW, "l-sw", "l.sw", 32,
474    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
475  },
476/* l.sb ${ui16nc}($rA),$rB */
477  {
478    OPENRISC_INSN_L_SB, "l-sb", "l.sb", 32,
479    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
480  },
481/* l.sh ${ui16nc}($rA),$rB */
482  {
483    OPENRISC_INSN_L_SH, "l-sh", "l.sh", 32,
484    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
485  },
486/* l.sll $rD,$rA,$rB */
487  {
488    OPENRISC_INSN_L_SLL, "l-sll", "l.sll", 32,
489    { 0, { { { (1<<MACH_BASE), 0 } } } }
490  },
491/* l.slli $rD,$rA,${uimm-5} */
492  {
493    OPENRISC_INSN_L_SLLI, "l-slli", "l.slli", 32,
494    { 0, { { { (1<<MACH_BASE), 0 } } } }
495  },
496/* l.srl $rD,$rA,$rB */
497  {
498    OPENRISC_INSN_L_SRL, "l-srl", "l.srl", 32,
499    { 0, { { { (1<<MACH_BASE), 0 } } } }
500  },
501/* l.srli $rD,$rA,${uimm-5} */
502  {
503    OPENRISC_INSN_L_SRLI, "l-srli", "l.srli", 32,
504    { 0, { { { (1<<MACH_BASE), 0 } } } }
505  },
506/* l.sra $rD,$rA,$rB */
507  {
508    OPENRISC_INSN_L_SRA, "l-sra", "l.sra", 32,
509    { 0, { { { (1<<MACH_BASE), 0 } } } }
510  },
511/* l.srai $rD,$rA,${uimm-5} */
512  {
513    OPENRISC_INSN_L_SRAI, "l-srai", "l.srai", 32,
514    { 0, { { { (1<<MACH_BASE), 0 } } } }
515  },
516/* l.ror $rD,$rA,$rB */
517  {
518    OPENRISC_INSN_L_ROR, "l-ror", "l.ror", 32,
519    { 0, { { { (1<<MACH_BASE), 0 } } } }
520  },
521/* l.rori $rD,$rA,${uimm-5} */
522  {
523    OPENRISC_INSN_L_RORI, "l-rori", "l.rori", 32,
524    { 0, { { { (1<<MACH_BASE), 0 } } } }
525  },
526/* l.add $rD,$rA,$rB */
527  {
528    OPENRISC_INSN_L_ADD, "l-add", "l.add", 32,
529    { 0, { { { (1<<MACH_BASE), 0 } } } }
530  },
531/* l.addi $rD,$rA,$lo16 */
532  {
533    OPENRISC_INSN_L_ADDI, "l-addi", "l.addi", 32,
534    { 0, { { { (1<<MACH_BASE), 0 } } } }
535  },
536/* l.sub $rD,$rA,$rB */
537  {
538    OPENRISC_INSN_L_SUB, "l-sub", "l.sub", 32,
539    { 0, { { { (1<<MACH_BASE), 0 } } } }
540  },
541/* l.subi $rD,$rA,$lo16 */
542  {
543    OPENRISC_INSN_L_SUBI, "l-subi", "l.subi", 32,
544    { 0, { { { (1<<MACH_BASE), 0 } } } }
545  },
546/* l.and $rD,$rA,$rB */
547  {
548    OPENRISC_INSN_L_AND, "l-and", "l.and", 32,
549    { 0, { { { (1<<MACH_BASE), 0 } } } }
550  },
551/* l.andi $rD,$rA,$lo16 */
552  {
553    OPENRISC_INSN_L_ANDI, "l-andi", "l.andi", 32,
554    { 0, { { { (1<<MACH_BASE), 0 } } } }
555  },
556/* l.or $rD,$rA,$rB */
557  {
558    OPENRISC_INSN_L_OR, "l-or", "l.or", 32,
559    { 0, { { { (1<<MACH_BASE), 0 } } } }
560  },
561/* l.ori $rD,$rA,$lo16 */
562  {
563    OPENRISC_INSN_L_ORI, "l-ori", "l.ori", 32,
564    { 0, { { { (1<<MACH_BASE), 0 } } } }
565  },
566/* l.xor $rD,$rA,$rB */
567  {
568    OPENRISC_INSN_L_XOR, "l-xor", "l.xor", 32,
569    { 0, { { { (1<<MACH_BASE), 0 } } } }
570  },
571/* l.xori $rD,$rA,$lo16 */
572  {
573    OPENRISC_INSN_L_XORI, "l-xori", "l.xori", 32,
574    { 0, { { { (1<<MACH_BASE), 0 } } } }
575  },
576/* l.mul $rD,$rA,$rB */
577  {
578    OPENRISC_INSN_L_MUL, "l-mul", "l.mul", 32,
579    { 0, { { { (1<<MACH_BASE), 0 } } } }
580  },
581/* l.muli $rD,$rA,$lo16 */
582  {
583    OPENRISC_INSN_L_MULI, "l-muli", "l.muli", 32,
584    { 0, { { { (1<<MACH_BASE), 0 } } } }
585  },
586/* l.div $rD,$rA,$rB */
587  {
588    OPENRISC_INSN_L_DIV, "l-div", "l.div", 32,
589    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
590  },
591/* l.divu $rD,$rA,$rB */
592  {
593    OPENRISC_INSN_L_DIVU, "l-divu", "l.divu", 32,
594    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
595  },
596/* l.sfgts $rA,$rB */
597  {
598    OPENRISC_INSN_L_SFGTS, "l-sfgts", "l.sfgts", 32,
599    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
600  },
601/* l.sfgtu $rA,$rB */
602  {
603    OPENRISC_INSN_L_SFGTU, "l-sfgtu", "l.sfgtu", 32,
604    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
605  },
606/* l.sfges $rA,$rB */
607  {
608    OPENRISC_INSN_L_SFGES, "l-sfges", "l.sfges", 32,
609    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
610  },
611/* l.sfgeu $rA,$rB */
612  {
613    OPENRISC_INSN_L_SFGEU, "l-sfgeu", "l.sfgeu", 32,
614    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
615  },
616/* l.sflts $rA,$rB */
617  {
618    OPENRISC_INSN_L_SFLTS, "l-sflts", "l.sflts", 32,
619    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
620  },
621/* l.sfltu $rA,$rB */
622  {
623    OPENRISC_INSN_L_SFLTU, "l-sfltu", "l.sfltu", 32,
624    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
625  },
626/* l.sfles $rA,$rB */
627  {
628    OPENRISC_INSN_L_SFLES, "l-sfles", "l.sfles", 32,
629    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
630  },
631/* l.sfleu $rA,$rB */
632  {
633    OPENRISC_INSN_L_SFLEU, "l-sfleu", "l.sfleu", 32,
634    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
635  },
636/* l.sfgtsi $rA,${simm-16} */
637  {
638    OPENRISC_INSN_L_SFGTSI, "l-sfgtsi", "l.sfgtsi", 32,
639    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
640  },
641/* l.sfgtui $rA,${uimm-16} */
642  {
643    OPENRISC_INSN_L_SFGTUI, "l-sfgtui", "l.sfgtui", 32,
644    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
645  },
646/* l.sfgesi $rA,${simm-16} */
647  {
648    OPENRISC_INSN_L_SFGESI, "l-sfgesi", "l.sfgesi", 32,
649    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
650  },
651/* l.sfgeui $rA,${uimm-16} */
652  {
653    OPENRISC_INSN_L_SFGEUI, "l-sfgeui", "l.sfgeui", 32,
654    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
655  },
656/* l.sfltsi $rA,${simm-16} */
657  {
658    OPENRISC_INSN_L_SFLTSI, "l-sfltsi", "l.sfltsi", 32,
659    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
660  },
661/* l.sfltui $rA,${uimm-16} */
662  {
663    OPENRISC_INSN_L_SFLTUI, "l-sfltui", "l.sfltui", 32,
664    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
665  },
666/* l.sflesi $rA,${simm-16} */
667  {
668    OPENRISC_INSN_L_SFLESI, "l-sflesi", "l.sflesi", 32,
669    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
670  },
671/* l.sfleui $rA,${uimm-16} */
672  {
673    OPENRISC_INSN_L_SFLEUI, "l-sfleui", "l.sfleui", 32,
674    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
675  },
676/* l.sfeq $rA,$rB */
677  {
678    OPENRISC_INSN_L_SFEQ, "l-sfeq", "l.sfeq", 32,
679    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
680  },
681/* l.sfeqi $rA,${simm-16} */
682  {
683    OPENRISC_INSN_L_SFEQI, "l-sfeqi", "l.sfeqi", 32,
684    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
685  },
686/* l.sfne $rA,$rB */
687  {
688    OPENRISC_INSN_L_SFNE, "l-sfne", "l.sfne", 32,
689    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
690  },
691/* l.sfnei $rA,${simm-16} */
692  {
693    OPENRISC_INSN_L_SFNEI, "l-sfnei", "l.sfnei", 32,
694    { 0|A(DELAY_SLOT), { { { (1<<MACH_BASE), 0 } } } }
695  },
696};
697
698#undef OP
699#undef A
700
701/* Initialize anything needed to be done once, before any cpu_open call.  */
702
703static void
704init_tables (void)
705{
706}
707
708static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
709static void build_hw_table      (CGEN_CPU_TABLE *);
710static void build_ifield_table  (CGEN_CPU_TABLE *);
711static void build_operand_table (CGEN_CPU_TABLE *);
712static void build_insn_table    (CGEN_CPU_TABLE *);
713static void openrisc_cgen_rebuild_tables (CGEN_CPU_TABLE *);
714
715/* Subroutine of openrisc_cgen_cpu_open to look up a mach via its bfd name.  */
716
717static const CGEN_MACH *
718lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
719{
720  while (table->name)
721    {
722      if (strcmp (name, table->bfd_name) == 0)
723	return table;
724      ++table;
725    }
726  abort ();
727}
728
729/* Subroutine of openrisc_cgen_cpu_open to build the hardware table.  */
730
731static void
732build_hw_table (CGEN_CPU_TABLE *cd)
733{
734  int i;
735  int machs = cd->machs;
736  const CGEN_HW_ENTRY *init = & openrisc_cgen_hw_table[0];
737  /* MAX_HW is only an upper bound on the number of selected entries.
738     However each entry is indexed by it's enum so there can be holes in
739     the table.  */
740  const CGEN_HW_ENTRY **selected =
741    (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
742
743  cd->hw_table.init_entries = init;
744  cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
745  memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
746  /* ??? For now we just use machs to determine which ones we want.  */
747  for (i = 0; init[i].name != NULL; ++i)
748    if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
749	& machs)
750      selected[init[i].type] = &init[i];
751  cd->hw_table.entries = selected;
752  cd->hw_table.num_entries = MAX_HW;
753}
754
755/* Subroutine of openrisc_cgen_cpu_open to build the hardware table.  */
756
757static void
758build_ifield_table (CGEN_CPU_TABLE *cd)
759{
760  cd->ifld_table = & openrisc_cgen_ifld_table[0];
761}
762
763/* Subroutine of openrisc_cgen_cpu_open to build the hardware table.  */
764
765static void
766build_operand_table (CGEN_CPU_TABLE *cd)
767{
768  int i;
769  int machs = cd->machs;
770  const CGEN_OPERAND *init = & openrisc_cgen_operand_table[0];
771  /* MAX_OPERANDS is only an upper bound on the number of selected entries.
772     However each entry is indexed by it's enum so there can be holes in
773     the table.  */
774  const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
775
776  cd->operand_table.init_entries = init;
777  cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
778  memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
779  /* ??? For now we just use mach to determine which ones we want.  */
780  for (i = 0; init[i].name != NULL; ++i)
781    if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
782	& machs)
783      selected[init[i].type] = &init[i];
784  cd->operand_table.entries = selected;
785  cd->operand_table.num_entries = MAX_OPERANDS;
786}
787
788/* Subroutine of openrisc_cgen_cpu_open to build the hardware table.
789   ??? This could leave out insns not supported by the specified mach/isa,
790   but that would cause errors like "foo only supported by bar" to become
791   "unknown insn", so for now we include all insns and require the app to
792   do the checking later.
793   ??? On the other hand, parsing of such insns may require their hardware or
794   operand elements to be in the table [which they mightn't be].  */
795
796static void
797build_insn_table (CGEN_CPU_TABLE *cd)
798{
799  int i;
800  const CGEN_IBASE *ib = & openrisc_cgen_insn_table[0];
801  CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
802
803  memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
804  for (i = 0; i < MAX_INSNS; ++i)
805    insns[i].base = &ib[i];
806  cd->insn_table.init_entries = insns;
807  cd->insn_table.entry_size = sizeof (CGEN_IBASE);
808  cd->insn_table.num_init_entries = MAX_INSNS;
809}
810
811/* Subroutine of openrisc_cgen_cpu_open to rebuild the tables.  */
812
813static void
814openrisc_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
815{
816  int i;
817  CGEN_BITSET *isas = cd->isas;
818  unsigned int machs = cd->machs;
819
820  cd->int_insn_p = CGEN_INT_INSN_P;
821
822  /* Data derived from the isa spec.  */
823#define UNSET (CGEN_SIZE_UNKNOWN + 1)
824  cd->default_insn_bitsize = UNSET;
825  cd->base_insn_bitsize = UNSET;
826  cd->min_insn_bitsize = 65535; /* Some ridiculously big number.  */
827  cd->max_insn_bitsize = 0;
828  for (i = 0; i < MAX_ISAS; ++i)
829    if (cgen_bitset_contains (isas, i))
830      {
831	const CGEN_ISA *isa = & openrisc_cgen_isa_table[i];
832
833	/* Default insn sizes of all selected isas must be
834	   equal or we set the result to 0, meaning "unknown".  */
835	if (cd->default_insn_bitsize == UNSET)
836	  cd->default_insn_bitsize = isa->default_insn_bitsize;
837	else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
838	  ; /* This is ok.  */
839	else
840	  cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
841
842	/* Base insn sizes of all selected isas must be equal
843	   or we set the result to 0, meaning "unknown".  */
844	if (cd->base_insn_bitsize == UNSET)
845	  cd->base_insn_bitsize = isa->base_insn_bitsize;
846	else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
847	  ; /* This is ok.  */
848	else
849	  cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
850
851	/* Set min,max insn sizes.  */
852	if (isa->min_insn_bitsize < cd->min_insn_bitsize)
853	  cd->min_insn_bitsize = isa->min_insn_bitsize;
854	if (isa->max_insn_bitsize > cd->max_insn_bitsize)
855	  cd->max_insn_bitsize = isa->max_insn_bitsize;
856      }
857
858  /* Data derived from the mach spec.  */
859  for (i = 0; i < MAX_MACHS; ++i)
860    if (((1 << i) & machs) != 0)
861      {
862	const CGEN_MACH *mach = & openrisc_cgen_mach_table[i];
863
864	if (mach->insn_chunk_bitsize != 0)
865	{
866	  if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
867	    {
868	      fprintf (stderr, "openrisc_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
869		       cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
870	      abort ();
871	    }
872
873 	  cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
874	}
875      }
876
877  /* Determine which hw elements are used by MACH.  */
878  build_hw_table (cd);
879
880  /* Build the ifield table.  */
881  build_ifield_table (cd);
882
883  /* Determine which operands are used by MACH/ISA.  */
884  build_operand_table (cd);
885
886  /* Build the instruction table.  */
887  build_insn_table (cd);
888}
889
890/* Initialize a cpu table and return a descriptor.
891   It's much like opening a file, and must be the first function called.
892   The arguments are a set of (type/value) pairs, terminated with
893   CGEN_CPU_OPEN_END.
894
895   Currently supported values:
896   CGEN_CPU_OPEN_ISAS:    bitmap of values in enum isa_attr
897   CGEN_CPU_OPEN_MACHS:   bitmap of values in enum mach_attr
898   CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
899   CGEN_CPU_OPEN_ENDIAN:  specify endian choice
900   CGEN_CPU_OPEN_END:     terminates arguments
901
902   ??? Simultaneous multiple isas might not make sense, but it's not (yet)
903   precluded.
904
905   ??? We only support ISO C stdargs here, not K&R.
906   Laziness, plus experiment to see if anything requires K&R - eventually
907   K&R will no longer be supported - e.g. GDB is currently trying this.  */
908
909CGEN_CPU_DESC
910openrisc_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
911{
912  CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
913  static int init_p;
914  CGEN_BITSET *isas = 0;  /* 0 = "unspecified" */
915  unsigned int machs = 0; /* 0 = "unspecified" */
916  enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
917  va_list ap;
918
919  if (! init_p)
920    {
921      init_tables ();
922      init_p = 1;
923    }
924
925  memset (cd, 0, sizeof (*cd));
926
927  va_start (ap, arg_type);
928  while (arg_type != CGEN_CPU_OPEN_END)
929    {
930      switch (arg_type)
931	{
932	case CGEN_CPU_OPEN_ISAS :
933	  isas = va_arg (ap, CGEN_BITSET *);
934	  break;
935	case CGEN_CPU_OPEN_MACHS :
936	  machs = va_arg (ap, unsigned int);
937	  break;
938	case CGEN_CPU_OPEN_BFDMACH :
939	  {
940	    const char *name = va_arg (ap, const char *);
941	    const CGEN_MACH *mach =
942	      lookup_mach_via_bfd_name (openrisc_cgen_mach_table, name);
943
944	    machs |= 1 << mach->num;
945	    break;
946	  }
947	case CGEN_CPU_OPEN_ENDIAN :
948	  endian = va_arg (ap, enum cgen_endian);
949	  break;
950	default :
951	  fprintf (stderr, "openrisc_cgen_cpu_open: unsupported argument `%d'\n",
952		   arg_type);
953	  abort (); /* ??? return NULL? */
954	}
955      arg_type = va_arg (ap, enum cgen_cpu_open_arg);
956    }
957  va_end (ap);
958
959  /* Mach unspecified means "all".  */
960  if (machs == 0)
961    machs = (1 << MAX_MACHS) - 1;
962  /* Base mach is always selected.  */
963  machs |= 1;
964  if (endian == CGEN_ENDIAN_UNKNOWN)
965    {
966      /* ??? If target has only one, could have a default.  */
967      fprintf (stderr, "openrisc_cgen_cpu_open: no endianness specified\n");
968      abort ();
969    }
970
971  cd->isas = cgen_bitset_copy (isas);
972  cd->machs = machs;
973  cd->endian = endian;
974  /* FIXME: for the sparc case we can determine insn-endianness statically.
975     The worry here is where both data and insn endian can be independently
976     chosen, in which case this function will need another argument.
977     Actually, will want to allow for more arguments in the future anyway.  */
978  cd->insn_endian = endian;
979
980  /* Table (re)builder.  */
981  cd->rebuild_tables = openrisc_cgen_rebuild_tables;
982  openrisc_cgen_rebuild_tables (cd);
983
984  /* Default to not allowing signed overflow.  */
985  cd->signed_overflow_ok_p = 0;
986
987  return (CGEN_CPU_DESC) cd;
988}
989
990/* Cover fn to openrisc_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
991   MACH_NAME is the bfd name of the mach.  */
992
993CGEN_CPU_DESC
994openrisc_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
995{
996  return openrisc_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
997			       CGEN_CPU_OPEN_ENDIAN, endian,
998			       CGEN_CPU_OPEN_END);
999}
1000
1001/* Close a cpu table.
1002   ??? This can live in a machine independent file, but there's currently
1003   no place to put this file (there's no libcgen).  libopcodes is the wrong
1004   place as some simulator ports use this but they don't use libopcodes.  */
1005
1006void
1007openrisc_cgen_cpu_close (CGEN_CPU_DESC cd)
1008{
1009  unsigned int i;
1010  const CGEN_INSN *insns;
1011
1012  if (cd->macro_insn_table.init_entries)
1013    {
1014      insns = cd->macro_insn_table.init_entries;
1015      for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
1016	if (CGEN_INSN_RX ((insns)))
1017	  regfree (CGEN_INSN_RX (insns));
1018    }
1019
1020  if (cd->insn_table.init_entries)
1021    {
1022      insns = cd->insn_table.init_entries;
1023      for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
1024	if (CGEN_INSN_RX (insns))
1025	  regfree (CGEN_INSN_RX (insns));
1026    }
1027
1028  if (cd->macro_insn_table.init_entries)
1029    free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
1030
1031  if (cd->insn_table.init_entries)
1032    free ((CGEN_INSN *) cd->insn_table.init_entries);
1033
1034  if (cd->hw_table.entries)
1035    free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1036
1037  if (cd->operand_table.entries)
1038    free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
1039
1040  free (cd);
1041}
1042
1043