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