OSDN Git Service

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