Add comment
[binutils.git] / opcodes / openrisc-desc.c
blobf1fb3abb7cec653364baacf4f7b9838a4944ea79
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 <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"
36 /* Attributes. */
38 static const CGEN_ATTR_ENTRY bool_attr[] =
40 { "#f", 0 },
41 { "#t", 1 },
42 { 0, 0 }
45 static const CGEN_ATTR_ENTRY MACH_attr[] =
47 { "base", MACH_BASE },
48 { "openrisc", MACH_OPENRISC },
49 { "or1300", MACH_OR1300 },
50 { "max", MACH_MAX },
51 { 0, 0 }
54 static const CGEN_ATTR_ENTRY ISA_attr[] =
56 { "or32", ISA_OR32 },
57 { "max", ISA_MAX },
58 { 0, 0 }
61 static const CGEN_ATTR_ENTRY HAS_CACHE_attr[] =
63 { "DATA_CACHE", HAS_CACHE_DATA_CACHE },
64 { "INSN_CACHE", HAS_CACHE_INSN_CACHE },
65 { 0, 0 }
68 const CGEN_ATTR_TABLE openrisc_cgen_ifield_attr_table[] =
70 { "MACH", & MACH_attr[0], & MACH_attr[0] },
71 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
72 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
73 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
74 { "RESERVED", &bool_attr[0], &bool_attr[0] },
75 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
76 { "SIGNED", &bool_attr[0], &bool_attr[0] },
77 { 0, 0, 0 }
80 const CGEN_ATTR_TABLE openrisc_cgen_hardware_attr_table[] =
82 { "MACH", & MACH_attr[0], & MACH_attr[0] },
83 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
84 { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
85 { "PC", &bool_attr[0], &bool_attr[0] },
86 { "PROFILE", &bool_attr[0], &bool_attr[0] },
87 { 0, 0, 0 }
90 const CGEN_ATTR_TABLE openrisc_cgen_operand_attr_table[] =
92 { "MACH", & MACH_attr[0], & MACH_attr[0] },
93 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
94 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
95 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
96 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
97 { "SIGNED", &bool_attr[0], &bool_attr[0] },
98 { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
99 { "RELAX", &bool_attr[0], &bool_attr[0] },
100 { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
101 { 0, 0, 0 }
104 const CGEN_ATTR_TABLE openrisc_cgen_insn_attr_table[] =
106 { "MACH", & MACH_attr[0], & MACH_attr[0] },
107 { "ALIAS", &bool_attr[0], &bool_attr[0] },
108 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
109 { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
110 { "COND-CTI", &bool_attr[0], &bool_attr[0] },
111 { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
112 { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
113 { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
114 { "RELAX", &bool_attr[0], &bool_attr[0] },
115 { "NO-DIS", &bool_attr[0], &bool_attr[0] },
116 { "PBB", &bool_attr[0], &bool_attr[0] },
117 { "NOT-IN-DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
118 { 0, 0, 0 }
121 /* Instruction set variants. */
123 static const CGEN_ISA openrisc_cgen_isa_table[] = {
124 { "or32", 32, 32, 32, 32 },
125 { 0, 0, 0, 0, 0 }
128 /* Machine variants. */
130 static const CGEN_MACH openrisc_cgen_mach_table[] = {
131 { "openrisc", "openrisc", MACH_OPENRISC, 0 },
132 { "or1300", "openrisc:1300", MACH_OR1300, 0 },
133 { 0, 0, 0, 0 }
136 static CGEN_KEYWORD_ENTRY openrisc_cgen_opval_h_gr_entries[] =
138 { "r0", 0, {0, {0}}, 0, 0 },
139 { "r1", 1, {0, {0}}, 0, 0 },
140 { "r2", 2, {0, {0}}, 0, 0 },
141 { "r3", 3, {0, {0}}, 0, 0 },
142 { "r4", 4, {0, {0}}, 0, 0 },
143 { "r5", 5, {0, {0}}, 0, 0 },
144 { "r6", 6, {0, {0}}, 0, 0 },
145 { "r7", 7, {0, {0}}, 0, 0 },
146 { "r8", 8, {0, {0}}, 0, 0 },
147 { "r9", 9, {0, {0}}, 0, 0 },
148 { "r10", 10, {0, {0}}, 0, 0 },
149 { "r11", 11, {0, {0}}, 0, 0 },
150 { "r12", 12, {0, {0}}, 0, 0 },
151 { "r13", 13, {0, {0}}, 0, 0 },
152 { "r14", 14, {0, {0}}, 0, 0 },
153 { "r15", 15, {0, {0}}, 0, 0 },
154 { "r16", 16, {0, {0}}, 0, 0 },
155 { "r17", 17, {0, {0}}, 0, 0 },
156 { "r18", 18, {0, {0}}, 0, 0 },
157 { "r19", 19, {0, {0}}, 0, 0 },
158 { "r20", 20, {0, {0}}, 0, 0 },
159 { "r21", 21, {0, {0}}, 0, 0 },
160 { "r22", 22, {0, {0}}, 0, 0 },
161 { "r23", 23, {0, {0}}, 0, 0 },
162 { "r24", 24, {0, {0}}, 0, 0 },
163 { "r25", 25, {0, {0}}, 0, 0 },
164 { "r26", 26, {0, {0}}, 0, 0 },
165 { "r27", 27, {0, {0}}, 0, 0 },
166 { "r28", 28, {0, {0}}, 0, 0 },
167 { "r29", 29, {0, {0}}, 0, 0 },
168 { "r30", 30, {0, {0}}, 0, 0 },
169 { "r31", 31, {0, {0}}, 0, 0 },
170 { "lr", 11, {0, {0}}, 0, 0 },
171 { "sp", 1, {0, {0}}, 0, 0 },
172 { "fp", 2, {0, {0}}, 0, 0 }
175 CGEN_KEYWORD openrisc_cgen_opval_h_gr =
177 & openrisc_cgen_opval_h_gr_entries[0],
179 0, 0, 0, 0, ""
183 /* The hardware table. */
185 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
186 #define A(a) (1 << CGEN_HW_##a)
187 #else
188 #define A(a) (1 << CGEN_HW_/**/a)
189 #endif
191 const CGEN_HW_ENTRY openrisc_cgen_hw_table[] =
193 { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
194 { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
195 { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
196 { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
197 { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
198 { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { (1<<MACH_BASE) } } },
199 { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & openrisc_cgen_opval_h_gr, { 0|A(PROFILE), { (1<<MACH_BASE) } } },
200 { "h-sr", HW_H_SR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
201 { "h-hi16", HW_H_HI16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
202 { "h-lo16", HW_H_LO16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
203 { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
204 { "h-delay-insn", HW_H_DELAY_INSN, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
205 { 0, 0, CGEN_ASM_NONE, 0, {0, {0}} }
208 #undef A
211 /* The instruction field table. */
213 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
214 #define A(a) (1 << CGEN_IFLD_##a)
215 #else
216 #define A(a) (1 << CGEN_IFLD_/**/a)
217 #endif
219 const CGEN_IFLD openrisc_cgen_ifld_table[] =
221 { OPENRISC_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
222 { OPENRISC_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
223 { OPENRISC_F_CLASS, "f-class", 0, 32, 31, 2, { 0, { (1<<MACH_BASE) } } },
224 { OPENRISC_F_SUB, "f-sub", 0, 32, 29, 4, { 0, { (1<<MACH_BASE) } } },
225 { OPENRISC_F_R1, "f-r1", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
226 { OPENRISC_F_R2, "f-r2", 0, 32, 20, 5, { 0, { (1<<MACH_BASE) } } },
227 { OPENRISC_F_R3, "f-r3", 0, 32, 15, 5, { 0, { (1<<MACH_BASE) } } },
228 { OPENRISC_F_SIMM16, "f-simm16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
229 { OPENRISC_F_UIMM16, "f-uimm16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
230 { OPENRISC_F_UIMM5, "f-uimm5", 0, 32, 4, 5, { 0, { (1<<MACH_BASE) } } },
231 { OPENRISC_F_HI16, "f-hi16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
232 { OPENRISC_F_LO16, "f-lo16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
233 { OPENRISC_F_OP1, "f-op1", 0, 32, 31, 2, { 0, { (1<<MACH_BASE) } } },
234 { OPENRISC_F_OP2, "f-op2", 0, 32, 29, 4, { 0, { (1<<MACH_BASE) } } },
235 { OPENRISC_F_OP3, "f-op3", 0, 32, 25, 2, { 0, { (1<<MACH_BASE) } } },
236 { OPENRISC_F_OP4, "f-op4", 0, 32, 23, 3, { 0, { (1<<MACH_BASE) } } },
237 { OPENRISC_F_OP5, "f-op5", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
238 { OPENRISC_F_OP6, "f-op6", 0, 32, 7, 3, { 0, { (1<<MACH_BASE) } } },
239 { OPENRISC_F_OP7, "f-op7", 0, 32, 3, 4, { 0, { (1<<MACH_BASE) } } },
240 { OPENRISC_F_I16_1, "f-i16-1", 0, 32, 10, 11, { 0, { (1<<MACH_BASE) } } },
241 { OPENRISC_F_I16_2, "f-i16-2", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
242 { OPENRISC_F_DISP26, "f-disp26", 0, 32, 25, 26, { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
243 { OPENRISC_F_ABS26, "f-abs26", 0, 32, 25, 26, { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
244 { OPENRISC_F_F_15_8, "f-f-15-8", 0, 32, 15, 8, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
245 { OPENRISC_F_F_10_3, "f-f-10-3", 0, 32, 10, 3, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
246 { OPENRISC_F_F_4_1, "f-f-4-1", 0, 32, 4, 1, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
247 { OPENRISC_F_F_7_3, "f-f-7-3", 0, 32, 7, 3, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
248 { OPENRISC_F_F_10_7, "f-f-10-7", 0, 32, 10, 7, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
249 { OPENRISC_F_F_10_11, "f-f-10-11", 0, 32, 10, 11, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
250 { 0, 0, 0, 0, 0, 0, {0, {0}} }
253 #undef A
256 /* The operand table. */
258 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
259 #define A(a) (1 << CGEN_OPERAND_##a)
260 #else
261 #define A(a) (1 << CGEN_OPERAND_/**/a)
262 #endif
263 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
264 #define OPERAND(op) OPENRISC_OPERAND_##op
265 #else
266 #define OPERAND(op) OPENRISC_OPERAND_/**/op
267 #endif
269 const CGEN_OPERAND openrisc_cgen_operand_table[] =
271 /* pc: program counter */
272 { "pc", OPENRISC_OPERAND_PC, HW_H_PC, 0, 0,
273 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
274 /* sr: special register */
275 { "sr", OPENRISC_OPERAND_SR, HW_H_SR, 0, 0,
276 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
277 /* cbit: condition bit */
278 { "cbit", OPENRISC_OPERAND_CBIT, HW_H_CBIT, 0, 0,
279 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
280 /* simm-16: 16 bit signed immediate */
281 { "simm-16", OPENRISC_OPERAND_SIMM_16, HW_H_SINT, 15, 16,
282 { 0, { (1<<MACH_BASE) } } },
283 /* uimm-16: 16 bit unsigned immediate */
284 { "uimm-16", OPENRISC_OPERAND_UIMM_16, HW_H_UINT, 15, 16,
285 { 0, { (1<<MACH_BASE) } } },
286 /* disp-26: pc-rel 26 bit */
287 { "disp-26", OPENRISC_OPERAND_DISP_26, HW_H_IADDR, 25, 26,
288 { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
289 /* abs-26: abs 26 bit */
290 { "abs-26", OPENRISC_OPERAND_ABS_26, HW_H_IADDR, 25, 26,
291 { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
292 /* uimm-5: imm5 */
293 { "uimm-5", OPENRISC_OPERAND_UIMM_5, HW_H_UINT, 4, 5,
294 { 0, { (1<<MACH_BASE) } } },
295 /* rD: destination register */
296 { "rD", OPENRISC_OPERAND_RD, HW_H_GR, 25, 5,
297 { 0, { (1<<MACH_BASE) } } },
298 /* rA: source register A */
299 { "rA", OPENRISC_OPERAND_RA, HW_H_GR, 20, 5,
300 { 0, { (1<<MACH_BASE) } } },
301 /* rB: source register B */
302 { "rB", OPENRISC_OPERAND_RB, HW_H_GR, 15, 5,
303 { 0, { (1<<MACH_BASE) } } },
304 /* op-f-23: f-op23 */
305 { "op-f-23", OPENRISC_OPERAND_OP_F_23, HW_H_UINT, 23, 3,
306 { 0, { (1<<MACH_BASE) } } },
307 /* op-f-3: f-op3 */
308 { "op-f-3", OPENRISC_OPERAND_OP_F_3, HW_H_UINT, 25, 5,
309 { 0, { (1<<MACH_BASE) } } },
310 /* hi16: high 16 bit immediate, sign optional */
311 { "hi16", OPENRISC_OPERAND_HI16, HW_H_HI16, 15, 16,
312 { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
313 /* lo16: low 16 bit immediate, sign optional */
314 { "lo16", OPENRISC_OPERAND_LO16, HW_H_LO16, 15, 16,
315 { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
316 /* ui16nc: 16 bit immediate, sign optional */
317 { "ui16nc", OPENRISC_OPERAND_UI16NC, HW_H_LO16, 10, 16,
318 { 0|A(SIGN_OPT)|A(VIRTUAL), { (1<<MACH_BASE) } } },
319 { 0, 0, 0, 0, 0, {0, {0}} }
322 #undef A
325 /* The instruction table. */
327 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
328 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
329 #define A(a) (1 << CGEN_INSN_##a)
330 #else
331 #define A(a) (1 << CGEN_INSN_/**/a)
332 #endif
334 static const CGEN_IBASE openrisc_cgen_insn_table[MAX_INSNS] =
336 /* Special null first entry.
337 A `num' value of zero is thus invalid.
338 Also, the special `invalid' insn resides here. */
339 { 0, 0, 0, 0, {0, {0}} },
340 /* l.j ${abs-26} */
342 OPENRISC_INSN_L_J, "l-j", "l.j", 32,
343 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
345 /* l.jal ${abs-26} */
347 OPENRISC_INSN_L_JAL, "l-jal", "l.jal", 32,
348 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
350 /* l.jr $rA */
352 OPENRISC_INSN_L_JR, "l-jr", "l.jr", 32,
353 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
355 /* l.jalr $rA */
357 OPENRISC_INSN_L_JALR, "l-jalr", "l.jalr", 32,
358 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
360 /* l.bal ${disp-26} */
362 OPENRISC_INSN_L_BAL, "l-bal", "l.bal", 32,
363 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
365 /* l.bnf ${disp-26} */
367 OPENRISC_INSN_L_BNF, "l-bnf", "l.bnf", 32,
368 { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
370 /* l.bf ${disp-26} */
372 OPENRISC_INSN_L_BF, "l-bf", "l.bf", 32,
373 { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
375 /* l.brk ${uimm-16} */
377 OPENRISC_INSN_L_BRK, "l-brk", "l.brk", 32,
378 { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
380 /* l.rfe $rA */
382 OPENRISC_INSN_L_RFE, "l-rfe", "l.rfe", 32,
383 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
385 /* l.sys ${uimm-16} */
387 OPENRISC_INSN_L_SYS, "l-sys", "l.sys", 32,
388 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
390 /* l.nop */
392 OPENRISC_INSN_L_NOP, "l-nop", "l.nop", 32,
393 { 0, { (1<<MACH_BASE) } }
395 /* l.movhi $rD,$hi16 */
397 OPENRISC_INSN_L_MOVHI, "l-movhi", "l.movhi", 32,
398 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
400 /* l.mfsr $rD,$rA */
402 OPENRISC_INSN_L_MFSR, "l-mfsr", "l.mfsr", 32,
403 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
405 /* l.mtsr $rA,$rB */
407 OPENRISC_INSN_L_MTSR, "l-mtsr", "l.mtsr", 32,
408 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
410 /* l.lw $rD,${simm-16}($rA) */
412 OPENRISC_INSN_L_LW, "l-lw", "l.lw", 32,
413 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
415 /* l.lbz $rD,${simm-16}($rA) */
417 OPENRISC_INSN_L_LBZ, "l-lbz", "l.lbz", 32,
418 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
420 /* l.lbs $rD,${simm-16}($rA) */
422 OPENRISC_INSN_L_LBS, "l-lbs", "l.lbs", 32,
423 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
425 /* l.lhz $rD,${simm-16}($rA) */
427 OPENRISC_INSN_L_LHZ, "l-lhz", "l.lhz", 32,
428 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
430 /* l.lhs $rD,${simm-16}($rA) */
432 OPENRISC_INSN_L_LHS, "l-lhs", "l.lhs", 32,
433 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
435 /* l.sw ${ui16nc}($rA),$rB */
437 OPENRISC_INSN_L_SW, "l-sw", "l.sw", 32,
438 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
440 /* l.sb ${ui16nc}($rA),$rB */
442 OPENRISC_INSN_L_SB, "l-sb", "l.sb", 32,
443 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
445 /* l.sh ${ui16nc}($rA),$rB */
447 OPENRISC_INSN_L_SH, "l-sh", "l.sh", 32,
448 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
450 /* l.sll $rD,$rA,$rB */
452 OPENRISC_INSN_L_SLL, "l-sll", "l.sll", 32,
453 { 0, { (1<<MACH_BASE) } }
455 /* l.slli $rD,$rA,${uimm-5} */
457 OPENRISC_INSN_L_SLLI, "l-slli", "l.slli", 32,
458 { 0, { (1<<MACH_BASE) } }
460 /* l.srl $rD,$rA,$rB */
462 OPENRISC_INSN_L_SRL, "l-srl", "l.srl", 32,
463 { 0, { (1<<MACH_BASE) } }
465 /* l.srli $rD,$rA,${uimm-5} */
467 OPENRISC_INSN_L_SRLI, "l-srli", "l.srli", 32,
468 { 0, { (1<<MACH_BASE) } }
470 /* l.sra $rD,$rA,$rB */
472 OPENRISC_INSN_L_SRA, "l-sra", "l.sra", 32,
473 { 0, { (1<<MACH_BASE) } }
475 /* l.srai $rD,$rA,${uimm-5} */
477 OPENRISC_INSN_L_SRAI, "l-srai", "l.srai", 32,
478 { 0, { (1<<MACH_BASE) } }
480 /* l.ror $rD,$rA,$rB */
482 OPENRISC_INSN_L_ROR, "l-ror", "l.ror", 32,
483 { 0, { (1<<MACH_BASE) } }
485 /* l.rori $rD,$rA,${uimm-5} */
487 OPENRISC_INSN_L_RORI, "l-rori", "l.rori", 32,
488 { 0, { (1<<MACH_BASE) } }
490 /* l.add $rD,$rA,$rB */
492 OPENRISC_INSN_L_ADD, "l-add", "l.add", 32,
493 { 0, { (1<<MACH_BASE) } }
495 /* l.addi $rD,$rA,$lo16 */
497 OPENRISC_INSN_L_ADDI, "l-addi", "l.addi", 32,
498 { 0, { (1<<MACH_BASE) } }
500 /* l.sub $rD,$rA,$rB */
502 OPENRISC_INSN_L_SUB, "l-sub", "l.sub", 32,
503 { 0, { (1<<MACH_BASE) } }
505 /* l.subi $rD,$rA,$lo16 */
507 OPENRISC_INSN_L_SUBI, "l-subi", "l.subi", 32,
508 { 0, { (1<<MACH_BASE) } }
510 /* l.and $rD,$rA,$rB */
512 OPENRISC_INSN_L_AND, "l-and", "l.and", 32,
513 { 0, { (1<<MACH_BASE) } }
515 /* l.andi $rD,$rA,$lo16 */
517 OPENRISC_INSN_L_ANDI, "l-andi", "l.andi", 32,
518 { 0, { (1<<MACH_BASE) } }
520 /* l.or $rD,$rA,$rB */
522 OPENRISC_INSN_L_OR, "l-or", "l.or", 32,
523 { 0, { (1<<MACH_BASE) } }
525 /* l.ori $rD,$rA,$lo16 */
527 OPENRISC_INSN_L_ORI, "l-ori", "l.ori", 32,
528 { 0, { (1<<MACH_BASE) } }
530 /* l.xor $rD,$rA,$rB */
532 OPENRISC_INSN_L_XOR, "l-xor", "l.xor", 32,
533 { 0, { (1<<MACH_BASE) } }
535 /* l.xori $rD,$rA,$lo16 */
537 OPENRISC_INSN_L_XORI, "l-xori", "l.xori", 32,
538 { 0, { (1<<MACH_BASE) } }
540 /* l.mul $rD,$rA,$rB */
542 OPENRISC_INSN_L_MUL, "l-mul", "l.mul", 32,
543 { 0, { (1<<MACH_BASE) } }
545 /* l.muli $rD,$rA,$lo16 */
547 OPENRISC_INSN_L_MULI, "l-muli", "l.muli", 32,
548 { 0, { (1<<MACH_BASE) } }
550 /* l.div $rD,$rA,$rB */
552 OPENRISC_INSN_L_DIV, "l-div", "l.div", 32,
553 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
555 /* l.divu $rD,$rA,$rB */
557 OPENRISC_INSN_L_DIVU, "l-divu", "l.divu", 32,
558 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
560 /* l.sfgts $rA,$rB */
562 OPENRISC_INSN_L_SFGTS, "l-sfgts", "l.sfgts", 32,
563 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
565 /* l.sfgtu $rA,$rB */
567 OPENRISC_INSN_L_SFGTU, "l-sfgtu", "l.sfgtu", 32,
568 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
570 /* l.sfges $rA,$rB */
572 OPENRISC_INSN_L_SFGES, "l-sfges", "l.sfges", 32,
573 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
575 /* l.sfgeu $rA,$rB */
577 OPENRISC_INSN_L_SFGEU, "l-sfgeu", "l.sfgeu", 32,
578 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
580 /* l.sflts $rA,$rB */
582 OPENRISC_INSN_L_SFLTS, "l-sflts", "l.sflts", 32,
583 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
585 /* l.sfltu $rA,$rB */
587 OPENRISC_INSN_L_SFLTU, "l-sfltu", "l.sfltu", 32,
588 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
590 /* l.sfles $rA,$rB */
592 OPENRISC_INSN_L_SFLES, "l-sfles", "l.sfles", 32,
593 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
595 /* l.sfleu $rA,$rB */
597 OPENRISC_INSN_L_SFLEU, "l-sfleu", "l.sfleu", 32,
598 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
600 /* l.sfgtsi $rA,${simm-16} */
602 OPENRISC_INSN_L_SFGTSI, "l-sfgtsi", "l.sfgtsi", 32,
603 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
605 /* l.sfgtui $rA,${uimm-16} */
607 OPENRISC_INSN_L_SFGTUI, "l-sfgtui", "l.sfgtui", 32,
608 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
610 /* l.sfgesi $rA,${simm-16} */
612 OPENRISC_INSN_L_SFGESI, "l-sfgesi", "l.sfgesi", 32,
613 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
615 /* l.sfgeui $rA,${uimm-16} */
617 OPENRISC_INSN_L_SFGEUI, "l-sfgeui", "l.sfgeui", 32,
618 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
620 /* l.sfltsi $rA,${simm-16} */
622 OPENRISC_INSN_L_SFLTSI, "l-sfltsi", "l.sfltsi", 32,
623 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
625 /* l.sfltui $rA,${uimm-16} */
627 OPENRISC_INSN_L_SFLTUI, "l-sfltui", "l.sfltui", 32,
628 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
630 /* l.sflesi $rA,${simm-16} */
632 OPENRISC_INSN_L_SFLESI, "l-sflesi", "l.sflesi", 32,
633 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
635 /* l.sfleui $rA,${uimm-16} */
637 OPENRISC_INSN_L_SFLEUI, "l-sfleui", "l.sfleui", 32,
638 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
640 /* l.sfeq $rA,$rB */
642 OPENRISC_INSN_L_SFEQ, "l-sfeq", "l.sfeq", 32,
643 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
645 /* l.sfeqi $rA,${simm-16} */
647 OPENRISC_INSN_L_SFEQI, "l-sfeqi", "l.sfeqi", 32,
648 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
650 /* l.sfne $rA,$rB */
652 OPENRISC_INSN_L_SFNE, "l-sfne", "l.sfne", 32,
653 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
655 /* l.sfnei $rA,${simm-16} */
657 OPENRISC_INSN_L_SFNEI, "l-sfnei", "l.sfnei", 32,
658 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
662 #undef OP
663 #undef A
665 /* Initialize anything needed to be done once, before any cpu_open call. */
666 static void init_tables PARAMS ((void));
668 static void
669 init_tables ()
673 static const CGEN_MACH * lookup_mach_via_bfd_name
674 PARAMS ((const CGEN_MACH *, const char *));
675 static void build_hw_table PARAMS ((CGEN_CPU_TABLE *));
676 static void build_ifield_table PARAMS ((CGEN_CPU_TABLE *));
677 static void build_operand_table PARAMS ((CGEN_CPU_TABLE *));
678 static void build_insn_table PARAMS ((CGEN_CPU_TABLE *));
679 static void openrisc_cgen_rebuild_tables PARAMS ((CGEN_CPU_TABLE *));
681 /* Subroutine of openrisc_cgen_cpu_open to look up a mach via its bfd name. */
683 static const CGEN_MACH *
684 lookup_mach_via_bfd_name (table, name)
685 const CGEN_MACH *table;
686 const char *name;
688 while (table->name)
690 if (strcmp (name, table->bfd_name) == 0)
691 return table;
692 ++table;
694 abort ();
697 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
699 static void
700 build_hw_table (cd)
701 CGEN_CPU_TABLE *cd;
703 int i;
704 int machs = cd->machs;
705 const CGEN_HW_ENTRY *init = & openrisc_cgen_hw_table[0];
706 /* MAX_HW is only an upper bound on the number of selected entries.
707 However each entry is indexed by it's enum so there can be holes in
708 the table. */
709 const CGEN_HW_ENTRY **selected =
710 (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
712 cd->hw_table.init_entries = init;
713 cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
714 memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
715 /* ??? For now we just use machs to determine which ones we want. */
716 for (i = 0; init[i].name != NULL; ++i)
717 if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
718 & machs)
719 selected[init[i].type] = &init[i];
720 cd->hw_table.entries = selected;
721 cd->hw_table.num_entries = MAX_HW;
724 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
726 static void
727 build_ifield_table (cd)
728 CGEN_CPU_TABLE *cd;
730 cd->ifld_table = & openrisc_cgen_ifld_table[0];
733 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
735 static void
736 build_operand_table (cd)
737 CGEN_CPU_TABLE *cd;
739 int i;
740 int machs = cd->machs;
741 const CGEN_OPERAND *init = & openrisc_cgen_operand_table[0];
742 /* MAX_OPERANDS is only an upper bound on the number of selected entries.
743 However each entry is indexed by it's enum so there can be holes in
744 the table. */
745 const CGEN_OPERAND **selected =
746 (const CGEN_OPERAND **) xmalloc (MAX_OPERANDS * sizeof (CGEN_OPERAND *));
748 cd->operand_table.init_entries = init;
749 cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
750 memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
751 /* ??? For now we just use mach to determine which ones we want. */
752 for (i = 0; init[i].name != NULL; ++i)
753 if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
754 & machs)
755 selected[init[i].type] = &init[i];
756 cd->operand_table.entries = selected;
757 cd->operand_table.num_entries = MAX_OPERANDS;
760 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table.
761 ??? This could leave out insns not supported by the specified mach/isa,
762 but that would cause errors like "foo only supported by bar" to become
763 "unknown insn", so for now we include all insns and require the app to
764 do the checking later.
765 ??? On the other hand, parsing of such insns may require their hardware or
766 operand elements to be in the table [which they mightn't be]. */
768 static void
769 build_insn_table (cd)
770 CGEN_CPU_TABLE *cd;
772 int i;
773 const CGEN_IBASE *ib = & openrisc_cgen_insn_table[0];
774 CGEN_INSN *insns = (CGEN_INSN *) xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
776 memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
777 for (i = 0; i < MAX_INSNS; ++i)
778 insns[i].base = &ib[i];
779 cd->insn_table.init_entries = insns;
780 cd->insn_table.entry_size = sizeof (CGEN_IBASE);
781 cd->insn_table.num_init_entries = MAX_INSNS;
784 /* Subroutine of openrisc_cgen_cpu_open to rebuild the tables. */
786 static void
787 openrisc_cgen_rebuild_tables (cd)
788 CGEN_CPU_TABLE *cd;
790 int i;
791 unsigned int isas = cd->isas;
792 unsigned int machs = cd->machs;
794 cd->int_insn_p = CGEN_INT_INSN_P;
796 /* Data derived from the isa spec. */
797 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
798 cd->default_insn_bitsize = UNSET;
799 cd->base_insn_bitsize = UNSET;
800 cd->min_insn_bitsize = 65535; /* some ridiculously big number */
801 cd->max_insn_bitsize = 0;
802 for (i = 0; i < MAX_ISAS; ++i)
803 if (((1 << i) & isas) != 0)
805 const CGEN_ISA *isa = & openrisc_cgen_isa_table[i];
807 /* Default insn sizes of all selected isas must be equal or we set
808 the result to 0, meaning "unknown". */
809 if (cd->default_insn_bitsize == UNSET)
810 cd->default_insn_bitsize = isa->default_insn_bitsize;
811 else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
812 ; /* this is ok */
813 else
814 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
816 /* Base insn sizes of all selected isas must be equal or we set
817 the result to 0, meaning "unknown". */
818 if (cd->base_insn_bitsize == UNSET)
819 cd->base_insn_bitsize = isa->base_insn_bitsize;
820 else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
821 ; /* this is ok */
822 else
823 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
825 /* Set min,max insn sizes. */
826 if (isa->min_insn_bitsize < cd->min_insn_bitsize)
827 cd->min_insn_bitsize = isa->min_insn_bitsize;
828 if (isa->max_insn_bitsize > cd->max_insn_bitsize)
829 cd->max_insn_bitsize = isa->max_insn_bitsize;
832 /* Data derived from the mach spec. */
833 for (i = 0; i < MAX_MACHS; ++i)
834 if (((1 << i) & machs) != 0)
836 const CGEN_MACH *mach = & openrisc_cgen_mach_table[i];
838 if (mach->insn_chunk_bitsize != 0)
840 if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
842 fprintf (stderr, "openrisc_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
843 cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
844 abort ();
847 cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
851 /* Determine which hw elements are used by MACH. */
852 build_hw_table (cd);
854 /* Build the ifield table. */
855 build_ifield_table (cd);
857 /* Determine which operands are used by MACH/ISA. */
858 build_operand_table (cd);
860 /* Build the instruction table. */
861 build_insn_table (cd);
864 /* Initialize a cpu table and return a descriptor.
865 It's much like opening a file, and must be the first function called.
866 The arguments are a set of (type/value) pairs, terminated with
867 CGEN_CPU_OPEN_END.
869 Currently supported values:
870 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
871 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
872 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
873 CGEN_CPU_OPEN_ENDIAN: specify endian choice
874 CGEN_CPU_OPEN_END: terminates arguments
876 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
877 precluded.
879 ??? We only support ISO C stdargs here, not K&R.
880 Laziness, plus experiment to see if anything requires K&R - eventually
881 K&R will no longer be supported - e.g. GDB is currently trying this. */
883 CGEN_CPU_DESC
884 openrisc_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
886 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
887 static int init_p;
888 unsigned int isas = 0; /* 0 = "unspecified" */
889 unsigned int machs = 0; /* 0 = "unspecified" */
890 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
891 va_list ap;
893 if (! init_p)
895 init_tables ();
896 init_p = 1;
899 memset (cd, 0, sizeof (*cd));
901 va_start (ap, arg_type);
902 while (arg_type != CGEN_CPU_OPEN_END)
904 switch (arg_type)
906 case CGEN_CPU_OPEN_ISAS :
907 isas = va_arg (ap, unsigned int);
908 break;
909 case CGEN_CPU_OPEN_MACHS :
910 machs = va_arg (ap, unsigned int);
911 break;
912 case CGEN_CPU_OPEN_BFDMACH :
914 const char *name = va_arg (ap, const char *);
915 const CGEN_MACH *mach =
916 lookup_mach_via_bfd_name (openrisc_cgen_mach_table, name);
918 machs |= 1 << mach->num;
919 break;
921 case CGEN_CPU_OPEN_ENDIAN :
922 endian = va_arg (ap, enum cgen_endian);
923 break;
924 default :
925 fprintf (stderr, "openrisc_cgen_cpu_open: unsupported argument `%d'\n",
926 arg_type);
927 abort (); /* ??? return NULL? */
929 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
931 va_end (ap);
933 /* mach unspecified means "all" */
934 if (machs == 0)
935 machs = (1 << MAX_MACHS) - 1;
936 /* base mach is always selected */
937 machs |= 1;
938 /* isa unspecified means "all" */
939 if (isas == 0)
940 isas = (1 << MAX_ISAS) - 1;
941 if (endian == CGEN_ENDIAN_UNKNOWN)
943 /* ??? If target has only one, could have a default. */
944 fprintf (stderr, "openrisc_cgen_cpu_open: no endianness specified\n");
945 abort ();
948 cd->isas = isas;
949 cd->machs = machs;
950 cd->endian = endian;
951 /* FIXME: for the sparc case we can determine insn-endianness statically.
952 The worry here is where both data and insn endian can be independently
953 chosen, in which case this function will need another argument.
954 Actually, will want to allow for more arguments in the future anyway. */
955 cd->insn_endian = endian;
957 /* Table (re)builder. */
958 cd->rebuild_tables = openrisc_cgen_rebuild_tables;
959 openrisc_cgen_rebuild_tables (cd);
961 /* Default to not allowing signed overflow. */
962 cd->signed_overflow_ok_p = 0;
964 return (CGEN_CPU_DESC) cd;
967 /* Cover fn to openrisc_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
968 MACH_NAME is the bfd name of the mach. */
970 CGEN_CPU_DESC
971 openrisc_cgen_cpu_open_1 (mach_name, endian)
972 const char *mach_name;
973 enum cgen_endian endian;
975 return openrisc_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
976 CGEN_CPU_OPEN_ENDIAN, endian,
977 CGEN_CPU_OPEN_END);
980 /* Close a cpu table.
981 ??? This can live in a machine independent file, but there's currently
982 no place to put this file (there's no libcgen). libopcodes is the wrong
983 place as some simulator ports use this but they don't use libopcodes. */
985 void
986 openrisc_cgen_cpu_close (cd)
987 CGEN_CPU_DESC cd;
989 if (cd->insn_table.init_entries)
990 free ((CGEN_INSN *) cd->insn_table.init_entries);
991 if (cd->hw_table.entries)
992 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
993 free (cd);