* config/tc-hppa.c (CHECK_FIELD_WHERE): Define.
[binutils.git] / opcodes / openrisc-desc.c
blobff6cba251cadf4c8f32a4a6dfbe7993aacd01d5b
1 /* CPU data for openrisc.
3 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
7 This file is part of the GNU Binutils and/or GDB, the GNU debugger.
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.
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.
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.
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"
37 /* Attributes. */
39 static const CGEN_ATTR_ENTRY bool_attr[] =
41 { "#f", 0 },
42 { "#t", 1 },
43 { 0, 0 }
46 static const CGEN_ATTR_ENTRY MACH_attr[] =
48 { "base", MACH_BASE },
49 { "openrisc", MACH_OPENRISC },
50 { "or1300", MACH_OR1300 },
51 { "max", MACH_MAX },
52 { 0, 0 }
55 static const CGEN_ATTR_ENTRY ISA_attr[] =
57 { "or32", ISA_OR32 },
58 { "max", ISA_MAX },
59 { 0, 0 }
62 static const CGEN_ATTR_ENTRY HAS_CACHE_attr[] =
64 { "DATA_CACHE", HAS_CACHE_DATA_CACHE },
65 { "INSN_CACHE", HAS_CACHE_INSN_CACHE },
66 { 0, 0 }
69 const CGEN_ATTR_TABLE openrisc_cgen_ifield_attr_table[] =
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 }
81 const CGEN_ATTR_TABLE openrisc_cgen_hardware_attr_table[] =
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 }
91 const CGEN_ATTR_TABLE openrisc_cgen_operand_attr_table[] =
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 }
105 const CGEN_ATTR_TABLE openrisc_cgen_insn_attr_table[] =
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 }
122 /* Instruction set variants. */
124 static const CGEN_ISA openrisc_cgen_isa_table[] = {
125 { "or32", 32, 32, 32, 32 },
126 { 0, 0, 0, 0, 0 }
129 /* Machine variants. */
131 static const CGEN_MACH openrisc_cgen_mach_table[] = {
132 { "openrisc", "openrisc", MACH_OPENRISC },
133 { "or1300", "openrisc:1300", MACH_OR1300 },
134 { 0, 0, 0 }
137 static CGEN_KEYWORD_ENTRY openrisc_cgen_opval_h_gr_entries[] =
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 }
176 CGEN_KEYWORD openrisc_cgen_opval_h_gr =
178 & openrisc_cgen_opval_h_gr_entries[0],
180 0, 0, 0, 0
184 /* The hardware table. */
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
192 const CGEN_HW_ENTRY openrisc_cgen_hw_table[] =
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}} }
209 #undef A
212 /* The instruction field table. */
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
220 const CGEN_IFLD openrisc_cgen_ifld_table[] =
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}} }
254 #undef A
257 /* The operand table. */
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
270 const CGEN_OPERAND openrisc_cgen_operand_table[] =
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}} }
323 #undef A
326 /* The instruction table. */
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
335 static const CGEN_IBASE openrisc_cgen_insn_table[MAX_INSNS] =
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} */
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) } }
346 /* l.jal ${abs-26} */
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) } }
351 /* l.jr $rA */
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) } }
356 /* l.jalr $rA */
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) } }
361 /* l.bal ${disp-26} */
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) } }
366 /* l.bnf ${disp-26} */
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) } }
371 /* l.bf ${disp-26} */
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) } }
376 /* l.brk ${uimm-16} */
378 OPENRISC_INSN_L_BRK, "l-brk", "l.brk", 32,
379 { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
381 /* l.rfe $rA */
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) } }
386 /* l.sys ${uimm-16} */
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) } }
391 /* l.nop */
393 OPENRISC_INSN_L_NOP, "l-nop", "l.nop", 32,
394 { 0, { (1<<MACH_BASE) } }
396 /* l.movhi $rD,$hi16 */
398 OPENRISC_INSN_L_MOVHI, "l-movhi", "l.movhi", 32,
399 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
401 /* l.mfsr $rD,$rA */
403 OPENRISC_INSN_L_MFSR, "l-mfsr", "l.mfsr", 32,
404 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
406 /* l.mtsr $rA,$rB */
408 OPENRISC_INSN_L_MTSR, "l-mtsr", "l.mtsr", 32,
409 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
411 /* l.lw $rD,${simm-16}($rA) */
413 OPENRISC_INSN_L_LW, "l-lw", "l.lw", 32,
414 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
416 /* l.lbz $rD,${simm-16}($rA) */
418 OPENRISC_INSN_L_LBZ, "l-lbz", "l.lbz", 32,
419 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
421 /* l.lbs $rD,${simm-16}($rA) */
423 OPENRISC_INSN_L_LBS, "l-lbs", "l.lbs", 32,
424 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
426 /* l.lhz $rD,${simm-16}($rA) */
428 OPENRISC_INSN_L_LHZ, "l-lhz", "l.lhz", 32,
429 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
431 /* l.lhs $rD,${simm-16}($rA) */
433 OPENRISC_INSN_L_LHS, "l-lhs", "l.lhs", 32,
434 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
436 /* l.sw ${ui16nc}($rA),$rB */
438 OPENRISC_INSN_L_SW, "l-sw", "l.sw", 32,
439 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
441 /* l.sb ${ui16nc}($rA),$rB */
443 OPENRISC_INSN_L_SB, "l-sb", "l.sb", 32,
444 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
446 /* l.sh ${ui16nc}($rA),$rB */
448 OPENRISC_INSN_L_SH, "l-sh", "l.sh", 32,
449 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
451 /* l.sll $rD,$rA,$rB */
453 OPENRISC_INSN_L_SLL, "l-sll", "l.sll", 32,
454 { 0, { (1<<MACH_BASE) } }
456 /* l.slli $rD,$rA,${uimm-5} */
458 OPENRISC_INSN_L_SLLI, "l-slli", "l.slli", 32,
459 { 0, { (1<<MACH_BASE) } }
461 /* l.srl $rD,$rA,$rB */
463 OPENRISC_INSN_L_SRL, "l-srl", "l.srl", 32,
464 { 0, { (1<<MACH_BASE) } }
466 /* l.srli $rD,$rA,${uimm-5} */
468 OPENRISC_INSN_L_SRLI, "l-srli", "l.srli", 32,
469 { 0, { (1<<MACH_BASE) } }
471 /* l.sra $rD,$rA,$rB */
473 OPENRISC_INSN_L_SRA, "l-sra", "l.sra", 32,
474 { 0, { (1<<MACH_BASE) } }
476 /* l.srai $rD,$rA,${uimm-5} */
478 OPENRISC_INSN_L_SRAI, "l-srai", "l.srai", 32,
479 { 0, { (1<<MACH_BASE) } }
481 /* l.ror $rD,$rA,$rB */
483 OPENRISC_INSN_L_ROR, "l-ror", "l.ror", 32,
484 { 0, { (1<<MACH_BASE) } }
486 /* l.rori $rD,$rA,${uimm-5} */
488 OPENRISC_INSN_L_RORI, "l-rori", "l.rori", 32,
489 { 0, { (1<<MACH_BASE) } }
491 /* l.add $rD,$rA,$rB */
493 OPENRISC_INSN_L_ADD, "l-add", "l.add", 32,
494 { 0, { (1<<MACH_BASE) } }
496 /* l.addi $rD,$rA,$lo16 */
498 OPENRISC_INSN_L_ADDI, "l-addi", "l.addi", 32,
499 { 0, { (1<<MACH_BASE) } }
501 /* l.sub $rD,$rA,$rB */
503 OPENRISC_INSN_L_SUB, "l-sub", "l.sub", 32,
504 { 0, { (1<<MACH_BASE) } }
506 /* l.subi $rD,$rA,$lo16 */
508 OPENRISC_INSN_L_SUBI, "l-subi", "l.subi", 32,
509 { 0, { (1<<MACH_BASE) } }
511 /* l.and $rD,$rA,$rB */
513 OPENRISC_INSN_L_AND, "l-and", "l.and", 32,
514 { 0, { (1<<MACH_BASE) } }
516 /* l.andi $rD,$rA,$lo16 */
518 OPENRISC_INSN_L_ANDI, "l-andi", "l.andi", 32,
519 { 0, { (1<<MACH_BASE) } }
521 /* l.or $rD,$rA,$rB */
523 OPENRISC_INSN_L_OR, "l-or", "l.or", 32,
524 { 0, { (1<<MACH_BASE) } }
526 /* l.ori $rD,$rA,$lo16 */
528 OPENRISC_INSN_L_ORI, "l-ori", "l.ori", 32,
529 { 0, { (1<<MACH_BASE) } }
531 /* l.xor $rD,$rA,$rB */
533 OPENRISC_INSN_L_XOR, "l-xor", "l.xor", 32,
534 { 0, { (1<<MACH_BASE) } }
536 /* l.xori $rD,$rA,$lo16 */
538 OPENRISC_INSN_L_XORI, "l-xori", "l.xori", 32,
539 { 0, { (1<<MACH_BASE) } }
541 /* l.mul $rD,$rA,$rB */
543 OPENRISC_INSN_L_MUL, "l-mul", "l.mul", 32,
544 { 0, { (1<<MACH_BASE) } }
546 /* l.muli $rD,$rA,$lo16 */
548 OPENRISC_INSN_L_MULI, "l-muli", "l.muli", 32,
549 { 0, { (1<<MACH_BASE) } }
551 /* l.div $rD,$rA,$rB */
553 OPENRISC_INSN_L_DIV, "l-div", "l.div", 32,
554 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
556 /* l.divu $rD,$rA,$rB */
558 OPENRISC_INSN_L_DIVU, "l-divu", "l.divu", 32,
559 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
561 /* l.sfgts $rA,$rB */
563 OPENRISC_INSN_L_SFGTS, "l-sfgts", "l.sfgts", 32,
564 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
566 /* l.sfgtu $rA,$rB */
568 OPENRISC_INSN_L_SFGTU, "l-sfgtu", "l.sfgtu", 32,
569 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
571 /* l.sfges $rA,$rB */
573 OPENRISC_INSN_L_SFGES, "l-sfges", "l.sfges", 32,
574 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
576 /* l.sfgeu $rA,$rB */
578 OPENRISC_INSN_L_SFGEU, "l-sfgeu", "l.sfgeu", 32,
579 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
581 /* l.sflts $rA,$rB */
583 OPENRISC_INSN_L_SFLTS, "l-sflts", "l.sflts", 32,
584 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
586 /* l.sfltu $rA,$rB */
588 OPENRISC_INSN_L_SFLTU, "l-sfltu", "l.sfltu", 32,
589 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
591 /* l.sfles $rA,$rB */
593 OPENRISC_INSN_L_SFLES, "l-sfles", "l.sfles", 32,
594 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
596 /* l.sfleu $rA,$rB */
598 OPENRISC_INSN_L_SFLEU, "l-sfleu", "l.sfleu", 32,
599 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
601 /* l.sfgtsi $rA,${simm-16} */
603 OPENRISC_INSN_L_SFGTSI, "l-sfgtsi", "l.sfgtsi", 32,
604 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
606 /* l.sfgtui $rA,${uimm-16} */
608 OPENRISC_INSN_L_SFGTUI, "l-sfgtui", "l.sfgtui", 32,
609 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
611 /* l.sfgesi $rA,${simm-16} */
613 OPENRISC_INSN_L_SFGESI, "l-sfgesi", "l.sfgesi", 32,
614 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
616 /* l.sfgeui $rA,${uimm-16} */
618 OPENRISC_INSN_L_SFGEUI, "l-sfgeui", "l.sfgeui", 32,
619 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
621 /* l.sfltsi $rA,${simm-16} */
623 OPENRISC_INSN_L_SFLTSI, "l-sfltsi", "l.sfltsi", 32,
624 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
626 /* l.sfltui $rA,${uimm-16} */
628 OPENRISC_INSN_L_SFLTUI, "l-sfltui", "l.sfltui", 32,
629 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
631 /* l.sflesi $rA,${simm-16} */
633 OPENRISC_INSN_L_SFLESI, "l-sflesi", "l.sflesi", 32,
634 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
636 /* l.sfleui $rA,${uimm-16} */
638 OPENRISC_INSN_L_SFLEUI, "l-sfleui", "l.sfleui", 32,
639 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
641 /* l.sfeq $rA,$rB */
643 OPENRISC_INSN_L_SFEQ, "l-sfeq", "l.sfeq", 32,
644 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
646 /* l.sfeqi $rA,${simm-16} */
648 OPENRISC_INSN_L_SFEQI, "l-sfeqi", "l.sfeqi", 32,
649 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
651 /* l.sfne $rA,$rB */
653 OPENRISC_INSN_L_SFNE, "l-sfne", "l.sfne", 32,
654 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
656 /* l.sfnei $rA,${simm-16} */
658 OPENRISC_INSN_L_SFNEI, "l-sfnei", "l.sfnei", 32,
659 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
663 #undef OP
664 #undef A
666 /* Initialize anything needed to be done once, before any cpu_open call. */
668 static void
669 init_tables ()
673 /* Subroutine of openrisc_cgen_cpu_open to look up a mach via its bfd name. */
675 static const CGEN_MACH *
676 lookup_mach_via_bfd_name (table, name)
677 const CGEN_MACH *table;
678 const char *name;
680 while (table->name)
682 if (strcmp (name, table->bfd_name) == 0)
683 return table;
684 ++table;
686 abort ();
689 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
691 static void
692 build_hw_table (cd)
693 CGEN_CPU_TABLE *cd;
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 *));
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;
716 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
718 static void
719 build_ifield_table (cd)
720 CGEN_CPU_TABLE *cd;
722 cd->ifld_table = & openrisc_cgen_ifld_table[0];
725 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
727 static void
728 build_operand_table (cd)
729 CGEN_CPU_TABLE *cd;
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 *));
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;
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]. */
760 static void
761 build_insn_table (cd)
762 CGEN_CPU_TABLE *cd;
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));
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;
776 /* Subroutine of openrisc_cgen_cpu_open to rebuild the tables. */
778 static void
779 openrisc_cgen_rebuild_tables (cd)
780 CGEN_CPU_TABLE *cd;
782 int i,n_isas;
783 unsigned int isas = cd->isas;
784 #if 0
785 unsigned int machs = cd->machs;
786 #endif
788 cd->int_insn_p = CGEN_INT_INSN_P;
790 /* Data derived from the isa spec. */
791 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
792 cd->default_insn_bitsize = UNSET;
793 cd->base_insn_bitsize = UNSET;
794 cd->min_insn_bitsize = 65535; /* some ridiculously big number */
795 cd->max_insn_bitsize = 0;
796 for (i = 0; i < MAX_ISAS; ++i)
797 if (((1 << i) & isas) != 0)
799 const CGEN_ISA *isa = & openrisc_cgen_isa_table[i];
801 /* Default insn sizes of all selected isas must be equal or we set
802 the result to 0, meaning "unknown". */
803 if (cd->default_insn_bitsize == UNSET)
804 cd->default_insn_bitsize = isa->default_insn_bitsize;
805 else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
806 ; /* this is ok */
807 else
808 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
810 /* Base insn sizes of all selected isas must be equal or we set
811 the result to 0, meaning "unknown". */
812 if (cd->base_insn_bitsize == UNSET)
813 cd->base_insn_bitsize = isa->base_insn_bitsize;
814 else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
815 ; /* this is ok */
816 else
817 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
819 /* Set min,max insn sizes. */
820 if (isa->min_insn_bitsize < cd->min_insn_bitsize)
821 cd->min_insn_bitsize = isa->min_insn_bitsize;
822 if (isa->max_insn_bitsize > cd->max_insn_bitsize)
823 cd->max_insn_bitsize = isa->max_insn_bitsize;
825 ++n_isas;
828 #if 0 /* Does nothing?? */
829 /* Data derived from the mach spec. */
830 for (i = 0; i < MAX_MACHS; ++i)
831 if (((1 << i) & machs) != 0)
833 const CGEN_MACH *mach = & openrisc_cgen_mach_table[i];
835 ++n_machs;
837 #endif
839 /* Determine which hw elements are used by MACH. */
840 build_hw_table (cd);
842 /* Build the ifield table. */
843 build_ifield_table (cd);
845 /* Determine which operands are used by MACH/ISA. */
846 build_operand_table (cd);
848 /* Build the instruction table. */
849 build_insn_table (cd);
852 /* Initialize a cpu table and return a descriptor.
853 It's much like opening a file, and must be the first function called.
854 The arguments are a set of (type/value) pairs, terminated with
855 CGEN_CPU_OPEN_END.
857 Currently supported values:
858 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
859 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
860 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
861 CGEN_CPU_OPEN_ENDIAN: specify endian choice
862 CGEN_CPU_OPEN_END: terminates arguments
864 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
865 precluded.
867 ??? We only support ISO C stdargs here, not K&R.
868 Laziness, plus experiment to see if anything requires K&R - eventually
869 K&R will no longer be supported - e.g. GDB is currently trying this. */
871 CGEN_CPU_DESC
872 openrisc_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
874 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
875 static int init_p;
876 unsigned int isas = 0; /* 0 = "unspecified" */
877 unsigned int machs = 0; /* 0 = "unspecified" */
878 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
879 va_list ap;
881 if (! init_p)
883 init_tables ();
884 init_p = 1;
887 memset (cd, 0, sizeof (*cd));
889 va_start (ap, arg_type);
890 while (arg_type != CGEN_CPU_OPEN_END)
892 switch (arg_type)
894 case CGEN_CPU_OPEN_ISAS :
895 isas = va_arg (ap, unsigned int);
896 break;
897 case CGEN_CPU_OPEN_MACHS :
898 machs = va_arg (ap, unsigned int);
899 break;
900 case CGEN_CPU_OPEN_BFDMACH :
902 const char *name = va_arg (ap, const char *);
903 const CGEN_MACH *mach =
904 lookup_mach_via_bfd_name (openrisc_cgen_mach_table, name);
906 machs |= 1 << mach->num;
907 break;
909 case CGEN_CPU_OPEN_ENDIAN :
910 endian = va_arg (ap, enum cgen_endian);
911 break;
912 default :
913 fprintf (stderr, "openrisc_cgen_cpu_open: unsupported argument `%d'\n",
914 arg_type);
915 abort (); /* ??? return NULL? */
917 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
919 va_end (ap);
921 /* mach unspecified means "all" */
922 if (machs == 0)
923 machs = (1 << MAX_MACHS) - 1;
924 /* base mach is always selected */
925 machs |= 1;
926 /* isa unspecified means "all" */
927 if (isas == 0)
928 isas = (1 << MAX_ISAS) - 1;
929 if (endian == CGEN_ENDIAN_UNKNOWN)
931 /* ??? If target has only one, could have a default. */
932 fprintf (stderr, "openrisc_cgen_cpu_open: no endianness specified\n");
933 abort ();
936 cd->isas = isas;
937 cd->machs = machs;
938 cd->endian = endian;
939 /* FIXME: for the sparc case we can determine insn-endianness statically.
940 The worry here is where both data and insn endian can be independently
941 chosen, in which case this function will need another argument.
942 Actually, will want to allow for more arguments in the future anyway. */
943 cd->insn_endian = endian;
945 /* Table (re)builder. */
946 cd->rebuild_tables = openrisc_cgen_rebuild_tables;
947 openrisc_cgen_rebuild_tables (cd);
949 /* Default to not allowing signed overflow. */
950 cd->signed_overflow_ok_p = 0;
952 return (CGEN_CPU_DESC) cd;
955 /* Cover fn to openrisc_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
956 MACH_NAME is the bfd name of the mach. */
958 CGEN_CPU_DESC
959 openrisc_cgen_cpu_open_1 (mach_name, endian)
960 const char *mach_name;
961 enum cgen_endian endian;
963 return openrisc_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
964 CGEN_CPU_OPEN_ENDIAN, endian,
965 CGEN_CPU_OPEN_END);
968 /* Close a cpu table.
969 ??? This can live in a machine independent file, but there's currently
970 no place to put this file (there's no libcgen). libopcodes is the wrong
971 place as some simulator ports use this but they don't use libopcodes. */
973 void
974 openrisc_cgen_cpu_close (cd)
975 CGEN_CPU_DESC cd;
977 if (cd->insn_table.init_entries)
978 free ((CGEN_INSN *) cd->insn_table.init_entries);
979 if (cd->hw_table.entries)
980 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
981 free (cd);