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)
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.
31 #include "openrisc-desc.h"
32 #include "openrisc-opc.h"
34 #include "libiberty.h"
36 static void init_tables PARAMS ((void));
37 static const CGEN_MACH * lookup_mach_via_bfd_name PARAMS ((const CGEN_MACH *, const char *));
38 static void build_hw_table PARAMS ((CGEN_CPU_TABLE *));
39 static void build_ifield_table PARAMS ((CGEN_CPU_TABLE *));
40 static void build_operand_table PARAMS ((CGEN_CPU_TABLE *));
41 static void build_insn_table PARAMS ((CGEN_CPU_TABLE *));
42 static void openrisc_cgen_rebuild_tables PARAMS ((CGEN_CPU_TABLE *));
45 static const CGEN_ATTR_ENTRY bool_attr[] =
52 static const CGEN_ATTR_ENTRY MACH_attr[] =
54 { "base", MACH_BASE },
55 { "openrisc", MACH_OPENRISC },
56 { "or1300", MACH_OR1300 },
61 static const CGEN_ATTR_ENTRY ISA_attr[] =
68 static const CGEN_ATTR_ENTRY HAS_CACHE_attr[] =
70 { "DATA_CACHE", HAS_CACHE_DATA_CACHE },
71 { "INSN_CACHE", HAS_CACHE_INSN_CACHE },
75 const CGEN_ATTR_TABLE openrisc_cgen_ifield_attr_table[] =
77 { "MACH", & MACH_attr[0], & MACH_attr[0] },
78 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
79 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
80 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
81 { "RESERVED", &bool_attr[0], &bool_attr[0] },
82 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
83 { "SIGNED", &bool_attr[0], &bool_attr[0] },
87 const CGEN_ATTR_TABLE openrisc_cgen_hardware_attr_table[] =
89 { "MACH", & MACH_attr[0], & MACH_attr[0] },
90 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
91 { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
92 { "PC", &bool_attr[0], &bool_attr[0] },
93 { "PROFILE", &bool_attr[0], &bool_attr[0] },
97 const CGEN_ATTR_TABLE openrisc_cgen_operand_attr_table[] =
99 { "MACH", & MACH_attr[0], & MACH_attr[0] },
100 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
101 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
102 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
103 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
104 { "SIGNED", &bool_attr[0], &bool_attr[0] },
105 { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
106 { "RELAX", &bool_attr[0], &bool_attr[0] },
107 { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
111 const CGEN_ATTR_TABLE openrisc_cgen_insn_attr_table[] =
113 { "MACH", & MACH_attr[0], & MACH_attr[0] },
114 { "ALIAS", &bool_attr[0], &bool_attr[0] },
115 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
116 { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
117 { "COND-CTI", &bool_attr[0], &bool_attr[0] },
118 { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
119 { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
120 { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
121 { "RELAX", &bool_attr[0], &bool_attr[0] },
122 { "NO-DIS", &bool_attr[0], &bool_attr[0] },
123 { "PBB", &bool_attr[0], &bool_attr[0] },
124 { "NOT-IN-DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
128 /* Instruction set variants. */
130 static const CGEN_ISA openrisc_cgen_isa_table[] = {
131 { "or32", 32, 32, 32, 32 },
135 /* Machine variants. */
137 static const CGEN_MACH openrisc_cgen_mach_table[] = {
138 { "openrisc", "openrisc", MACH_OPENRISC, 0 },
139 { "or1300", "openrisc:1300", MACH_OR1300, 0 },
143 static CGEN_KEYWORD_ENTRY openrisc_cgen_opval_h_gr_entries[] =
145 { "r0", 0, {0, {0}}, 0, 0 },
146 { "r1", 1, {0, {0}}, 0, 0 },
147 { "r2", 2, {0, {0}}, 0, 0 },
148 { "r3", 3, {0, {0}}, 0, 0 },
149 { "r4", 4, {0, {0}}, 0, 0 },
150 { "r5", 5, {0, {0}}, 0, 0 },
151 { "r6", 6, {0, {0}}, 0, 0 },
152 { "r7", 7, {0, {0}}, 0, 0 },
153 { "r8", 8, {0, {0}}, 0, 0 },
154 { "r9", 9, {0, {0}}, 0, 0 },
155 { "r10", 10, {0, {0}}, 0, 0 },
156 { "r11", 11, {0, {0}}, 0, 0 },
157 { "r12", 12, {0, {0}}, 0, 0 },
158 { "r13", 13, {0, {0}}, 0, 0 },
159 { "r14", 14, {0, {0}}, 0, 0 },
160 { "r15", 15, {0, {0}}, 0, 0 },
161 { "r16", 16, {0, {0}}, 0, 0 },
162 { "r17", 17, {0, {0}}, 0, 0 },
163 { "r18", 18, {0, {0}}, 0, 0 },
164 { "r19", 19, {0, {0}}, 0, 0 },
165 { "r20", 20, {0, {0}}, 0, 0 },
166 { "r21", 21, {0, {0}}, 0, 0 },
167 { "r22", 22, {0, {0}}, 0, 0 },
168 { "r23", 23, {0, {0}}, 0, 0 },
169 { "r24", 24, {0, {0}}, 0, 0 },
170 { "r25", 25, {0, {0}}, 0, 0 },
171 { "r26", 26, {0, {0}}, 0, 0 },
172 { "r27", 27, {0, {0}}, 0, 0 },
173 { "r28", 28, {0, {0}}, 0, 0 },
174 { "r29", 29, {0, {0}}, 0, 0 },
175 { "r30", 30, {0, {0}}, 0, 0 },
176 { "r31", 31, {0, {0}}, 0, 0 },
177 { "lr", 11, {0, {0}}, 0, 0 },
178 { "sp", 1, {0, {0}}, 0, 0 },
179 { "fp", 2, {0, {0}}, 0, 0 }
182 CGEN_KEYWORD openrisc_cgen_opval_h_gr =
184 & openrisc_cgen_opval_h_gr_entries[0],
190 /* The hardware table. */
192 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
193 #define A(a) (1 << CGEN_HW_##a)
195 #define A(a) (1 << CGEN_HW_/**/a)
198 const CGEN_HW_ENTRY openrisc_cgen_hw_table[] =
200 { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
201 { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
202 { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
203 { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
204 { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
205 { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { (1<<MACH_BASE) } } },
206 { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & openrisc_cgen_opval_h_gr, { 0|A(PROFILE), { (1<<MACH_BASE) } } },
207 { "h-sr", HW_H_SR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
208 { "h-hi16", HW_H_HI16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
209 { "h-lo16", HW_H_LO16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
210 { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
211 { "h-delay-insn", HW_H_DELAY_INSN, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
212 { 0, 0, CGEN_ASM_NONE, 0, {0, {0}} }
218 /* The instruction field table. */
220 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
221 #define A(a) (1 << CGEN_IFLD_##a)
223 #define A(a) (1 << CGEN_IFLD_/**/a)
226 const CGEN_IFLD openrisc_cgen_ifld_table[] =
228 { OPENRISC_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
229 { OPENRISC_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
230 { OPENRISC_F_CLASS, "f-class", 0, 32, 31, 2, { 0, { (1<<MACH_BASE) } } },
231 { OPENRISC_F_SUB, "f-sub", 0, 32, 29, 4, { 0, { (1<<MACH_BASE) } } },
232 { OPENRISC_F_R1, "f-r1", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
233 { OPENRISC_F_R2, "f-r2", 0, 32, 20, 5, { 0, { (1<<MACH_BASE) } } },
234 { OPENRISC_F_R3, "f-r3", 0, 32, 15, 5, { 0, { (1<<MACH_BASE) } } },
235 { OPENRISC_F_SIMM16, "f-simm16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
236 { OPENRISC_F_UIMM16, "f-uimm16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
237 { OPENRISC_F_UIMM5, "f-uimm5", 0, 32, 4, 5, { 0, { (1<<MACH_BASE) } } },
238 { OPENRISC_F_HI16, "f-hi16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
239 { OPENRISC_F_LO16, "f-lo16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
240 { OPENRISC_F_OP1, "f-op1", 0, 32, 31, 2, { 0, { (1<<MACH_BASE) } } },
241 { OPENRISC_F_OP2, "f-op2", 0, 32, 29, 4, { 0, { (1<<MACH_BASE) } } },
242 { OPENRISC_F_OP3, "f-op3", 0, 32, 25, 2, { 0, { (1<<MACH_BASE) } } },
243 { OPENRISC_F_OP4, "f-op4", 0, 32, 23, 3, { 0, { (1<<MACH_BASE) } } },
244 { OPENRISC_F_OP5, "f-op5", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
245 { OPENRISC_F_OP6, "f-op6", 0, 32, 7, 3, { 0, { (1<<MACH_BASE) } } },
246 { OPENRISC_F_OP7, "f-op7", 0, 32, 3, 4, { 0, { (1<<MACH_BASE) } } },
247 { OPENRISC_F_I16_1, "f-i16-1", 0, 32, 10, 11, { 0, { (1<<MACH_BASE) } } },
248 { OPENRISC_F_I16_2, "f-i16-2", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
249 { OPENRISC_F_DISP26, "f-disp26", 0, 32, 25, 26, { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
250 { OPENRISC_F_ABS26, "f-abs26", 0, 32, 25, 26, { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
251 { OPENRISC_F_F_15_8, "f-f-15-8", 0, 32, 15, 8, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
252 { OPENRISC_F_F_10_3, "f-f-10-3", 0, 32, 10, 3, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
253 { OPENRISC_F_F_4_1, "f-f-4-1", 0, 32, 4, 1, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
254 { OPENRISC_F_F_7_3, "f-f-7-3", 0, 32, 7, 3, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
255 { OPENRISC_F_F_10_7, "f-f-10-7", 0, 32, 10, 7, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
256 { OPENRISC_F_F_10_11, "f-f-10-11", 0, 32, 10, 11, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
257 { 0, 0, 0, 0, 0, 0, {0, {0}} }
263 /* The operand table. */
265 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
266 #define A(a) (1 << CGEN_OPERAND_##a)
268 #define A(a) (1 << CGEN_OPERAND_/**/a)
270 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
271 #define OPERAND(op) OPENRISC_OPERAND_##op
273 #define OPERAND(op) OPENRISC_OPERAND_/**/op
276 const CGEN_OPERAND openrisc_cgen_operand_table[] =
278 /* pc: program counter */
279 { "pc", OPENRISC_OPERAND_PC, HW_H_PC, 0, 0,
280 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
281 /* sr: special register */
282 { "sr", OPENRISC_OPERAND_SR, HW_H_SR, 0, 0,
283 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
284 /* cbit: condition bit */
285 { "cbit", OPENRISC_OPERAND_CBIT, HW_H_CBIT, 0, 0,
286 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
287 /* simm-16: 16 bit signed immediate */
288 { "simm-16", OPENRISC_OPERAND_SIMM_16, HW_H_SINT, 15, 16,
289 { 0, { (1<<MACH_BASE) } } },
290 /* uimm-16: 16 bit unsigned immediate */
291 { "uimm-16", OPENRISC_OPERAND_UIMM_16, HW_H_UINT, 15, 16,
292 { 0, { (1<<MACH_BASE) } } },
293 /* disp-26: pc-rel 26 bit */
294 { "disp-26", OPENRISC_OPERAND_DISP_26, HW_H_IADDR, 25, 26,
295 { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
296 /* abs-26: abs 26 bit */
297 { "abs-26", OPENRISC_OPERAND_ABS_26, HW_H_IADDR, 25, 26,
298 { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
300 { "uimm-5", OPENRISC_OPERAND_UIMM_5, HW_H_UINT, 4, 5,
301 { 0, { (1<<MACH_BASE) } } },
302 /* rD: destination register */
303 { "rD", OPENRISC_OPERAND_RD, HW_H_GR, 25, 5,
304 { 0, { (1<<MACH_BASE) } } },
305 /* rA: source register A */
306 { "rA", OPENRISC_OPERAND_RA, HW_H_GR, 20, 5,
307 { 0, { (1<<MACH_BASE) } } },
308 /* rB: source register B */
309 { "rB", OPENRISC_OPERAND_RB, HW_H_GR, 15, 5,
310 { 0, { (1<<MACH_BASE) } } },
311 /* op-f-23: f-op23 */
312 { "op-f-23", OPENRISC_OPERAND_OP_F_23, HW_H_UINT, 23, 3,
313 { 0, { (1<<MACH_BASE) } } },
315 { "op-f-3", OPENRISC_OPERAND_OP_F_3, HW_H_UINT, 25, 5,
316 { 0, { (1<<MACH_BASE) } } },
317 /* hi16: high 16 bit immediate, sign optional */
318 { "hi16", OPENRISC_OPERAND_HI16, HW_H_HI16, 15, 16,
319 { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
320 /* lo16: low 16 bit immediate, sign optional */
321 { "lo16", OPENRISC_OPERAND_LO16, HW_H_LO16, 15, 16,
322 { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
323 /* ui16nc: 16 bit immediate, sign optional */
324 { "ui16nc", OPENRISC_OPERAND_UI16NC, HW_H_LO16, 10, 16,
325 { 0|A(SIGN_OPT)|A(VIRTUAL), { (1<<MACH_BASE) } } },
326 { 0, 0, 0, 0, 0, {0, {0}} }
332 /* The instruction table. */
334 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
335 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
336 #define A(a) (1 << CGEN_INSN_##a)
338 #define A(a) (1 << CGEN_INSN_/**/a)
341 static const CGEN_IBASE openrisc_cgen_insn_table[MAX_INSNS] =
343 /* Special null first entry.
344 A `num' value of zero is thus invalid.
345 Also, the special `invalid' insn resides here. */
346 { 0, 0, 0, 0, {0, {0}} },
349 OPENRISC_INSN_L_J, "l-j", "l.j", 32,
350 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
352 /* l.jal ${abs-26} */
354 OPENRISC_INSN_L_JAL, "l-jal", "l.jal", 32,
355 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
359 OPENRISC_INSN_L_JR, "l-jr", "l.jr", 32,
360 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
364 OPENRISC_INSN_L_JALR, "l-jalr", "l.jalr", 32,
365 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
367 /* l.bal ${disp-26} */
369 OPENRISC_INSN_L_BAL, "l-bal", "l.bal", 32,
370 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
372 /* l.bnf ${disp-26} */
374 OPENRISC_INSN_L_BNF, "l-bnf", "l.bnf", 32,
375 { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
377 /* l.bf ${disp-26} */
379 OPENRISC_INSN_L_BF, "l-bf", "l.bf", 32,
380 { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
382 /* l.brk ${uimm-16} */
384 OPENRISC_INSN_L_BRK, "l-brk", "l.brk", 32,
385 { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
389 OPENRISC_INSN_L_RFE, "l-rfe", "l.rfe", 32,
390 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
392 /* l.sys ${uimm-16} */
394 OPENRISC_INSN_L_SYS, "l-sys", "l.sys", 32,
395 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
399 OPENRISC_INSN_L_NOP, "l-nop", "l.nop", 32,
400 { 0, { (1<<MACH_BASE) } }
402 /* l.movhi $rD,$hi16 */
404 OPENRISC_INSN_L_MOVHI, "l-movhi", "l.movhi", 32,
405 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
409 OPENRISC_INSN_L_MFSR, "l-mfsr", "l.mfsr", 32,
410 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
414 OPENRISC_INSN_L_MTSR, "l-mtsr", "l.mtsr", 32,
415 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
417 /* l.lw $rD,${simm-16}($rA) */
419 OPENRISC_INSN_L_LW, "l-lw", "l.lw", 32,
420 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
422 /* l.lbz $rD,${simm-16}($rA) */
424 OPENRISC_INSN_L_LBZ, "l-lbz", "l.lbz", 32,
425 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
427 /* l.lbs $rD,${simm-16}($rA) */
429 OPENRISC_INSN_L_LBS, "l-lbs", "l.lbs", 32,
430 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
432 /* l.lhz $rD,${simm-16}($rA) */
434 OPENRISC_INSN_L_LHZ, "l-lhz", "l.lhz", 32,
435 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
437 /* l.lhs $rD,${simm-16}($rA) */
439 OPENRISC_INSN_L_LHS, "l-lhs", "l.lhs", 32,
440 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
442 /* l.sw ${ui16nc}($rA),$rB */
444 OPENRISC_INSN_L_SW, "l-sw", "l.sw", 32,
445 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
447 /* l.sb ${ui16nc}($rA),$rB */
449 OPENRISC_INSN_L_SB, "l-sb", "l.sb", 32,
450 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
452 /* l.sh ${ui16nc}($rA),$rB */
454 OPENRISC_INSN_L_SH, "l-sh", "l.sh", 32,
455 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
457 /* l.sll $rD,$rA,$rB */
459 OPENRISC_INSN_L_SLL, "l-sll", "l.sll", 32,
460 { 0, { (1<<MACH_BASE) } }
462 /* l.slli $rD,$rA,${uimm-5} */
464 OPENRISC_INSN_L_SLLI, "l-slli", "l.slli", 32,
465 { 0, { (1<<MACH_BASE) } }
467 /* l.srl $rD,$rA,$rB */
469 OPENRISC_INSN_L_SRL, "l-srl", "l.srl", 32,
470 { 0, { (1<<MACH_BASE) } }
472 /* l.srli $rD,$rA,${uimm-5} */
474 OPENRISC_INSN_L_SRLI, "l-srli", "l.srli", 32,
475 { 0, { (1<<MACH_BASE) } }
477 /* l.sra $rD,$rA,$rB */
479 OPENRISC_INSN_L_SRA, "l-sra", "l.sra", 32,
480 { 0, { (1<<MACH_BASE) } }
482 /* l.srai $rD,$rA,${uimm-5} */
484 OPENRISC_INSN_L_SRAI, "l-srai", "l.srai", 32,
485 { 0, { (1<<MACH_BASE) } }
487 /* l.ror $rD,$rA,$rB */
489 OPENRISC_INSN_L_ROR, "l-ror", "l.ror", 32,
490 { 0, { (1<<MACH_BASE) } }
492 /* l.rori $rD,$rA,${uimm-5} */
494 OPENRISC_INSN_L_RORI, "l-rori", "l.rori", 32,
495 { 0, { (1<<MACH_BASE) } }
497 /* l.add $rD,$rA,$rB */
499 OPENRISC_INSN_L_ADD, "l-add", "l.add", 32,
500 { 0, { (1<<MACH_BASE) } }
502 /* l.addi $rD,$rA,$lo16 */
504 OPENRISC_INSN_L_ADDI, "l-addi", "l.addi", 32,
505 { 0, { (1<<MACH_BASE) } }
507 /* l.sub $rD,$rA,$rB */
509 OPENRISC_INSN_L_SUB, "l-sub", "l.sub", 32,
510 { 0, { (1<<MACH_BASE) } }
512 /* l.subi $rD,$rA,$lo16 */
514 OPENRISC_INSN_L_SUBI, "l-subi", "l.subi", 32,
515 { 0, { (1<<MACH_BASE) } }
517 /* l.and $rD,$rA,$rB */
519 OPENRISC_INSN_L_AND, "l-and", "l.and", 32,
520 { 0, { (1<<MACH_BASE) } }
522 /* l.andi $rD,$rA,$lo16 */
524 OPENRISC_INSN_L_ANDI, "l-andi", "l.andi", 32,
525 { 0, { (1<<MACH_BASE) } }
527 /* l.or $rD,$rA,$rB */
529 OPENRISC_INSN_L_OR, "l-or", "l.or", 32,
530 { 0, { (1<<MACH_BASE) } }
532 /* l.ori $rD,$rA,$lo16 */
534 OPENRISC_INSN_L_ORI, "l-ori", "l.ori", 32,
535 { 0, { (1<<MACH_BASE) } }
537 /* l.xor $rD,$rA,$rB */
539 OPENRISC_INSN_L_XOR, "l-xor", "l.xor", 32,
540 { 0, { (1<<MACH_BASE) } }
542 /* l.xori $rD,$rA,$lo16 */
544 OPENRISC_INSN_L_XORI, "l-xori", "l.xori", 32,
545 { 0, { (1<<MACH_BASE) } }
547 /* l.mul $rD,$rA,$rB */
549 OPENRISC_INSN_L_MUL, "l-mul", "l.mul", 32,
550 { 0, { (1<<MACH_BASE) } }
552 /* l.muli $rD,$rA,$lo16 */
554 OPENRISC_INSN_L_MULI, "l-muli", "l.muli", 32,
555 { 0, { (1<<MACH_BASE) } }
557 /* l.div $rD,$rA,$rB */
559 OPENRISC_INSN_L_DIV, "l-div", "l.div", 32,
560 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
562 /* l.divu $rD,$rA,$rB */
564 OPENRISC_INSN_L_DIVU, "l-divu", "l.divu", 32,
565 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
567 /* l.sfgts $rA,$rB */
569 OPENRISC_INSN_L_SFGTS, "l-sfgts", "l.sfgts", 32,
570 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
572 /* l.sfgtu $rA,$rB */
574 OPENRISC_INSN_L_SFGTU, "l-sfgtu", "l.sfgtu", 32,
575 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
577 /* l.sfges $rA,$rB */
579 OPENRISC_INSN_L_SFGES, "l-sfges", "l.sfges", 32,
580 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
582 /* l.sfgeu $rA,$rB */
584 OPENRISC_INSN_L_SFGEU, "l-sfgeu", "l.sfgeu", 32,
585 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
587 /* l.sflts $rA,$rB */
589 OPENRISC_INSN_L_SFLTS, "l-sflts", "l.sflts", 32,
590 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
592 /* l.sfltu $rA,$rB */
594 OPENRISC_INSN_L_SFLTU, "l-sfltu", "l.sfltu", 32,
595 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
597 /* l.sfles $rA,$rB */
599 OPENRISC_INSN_L_SFLES, "l-sfles", "l.sfles", 32,
600 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
602 /* l.sfleu $rA,$rB */
604 OPENRISC_INSN_L_SFLEU, "l-sfleu", "l.sfleu", 32,
605 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
607 /* l.sfgtsi $rA,${simm-16} */
609 OPENRISC_INSN_L_SFGTSI, "l-sfgtsi", "l.sfgtsi", 32,
610 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
612 /* l.sfgtui $rA,${uimm-16} */
614 OPENRISC_INSN_L_SFGTUI, "l-sfgtui", "l.sfgtui", 32,
615 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
617 /* l.sfgesi $rA,${simm-16} */
619 OPENRISC_INSN_L_SFGESI, "l-sfgesi", "l.sfgesi", 32,
620 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
622 /* l.sfgeui $rA,${uimm-16} */
624 OPENRISC_INSN_L_SFGEUI, "l-sfgeui", "l.sfgeui", 32,
625 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
627 /* l.sfltsi $rA,${simm-16} */
629 OPENRISC_INSN_L_SFLTSI, "l-sfltsi", "l.sfltsi", 32,
630 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
632 /* l.sfltui $rA,${uimm-16} */
634 OPENRISC_INSN_L_SFLTUI, "l-sfltui", "l.sfltui", 32,
635 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
637 /* l.sflesi $rA,${simm-16} */
639 OPENRISC_INSN_L_SFLESI, "l-sflesi", "l.sflesi", 32,
640 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
642 /* l.sfleui $rA,${uimm-16} */
644 OPENRISC_INSN_L_SFLEUI, "l-sfleui", "l.sfleui", 32,
645 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
649 OPENRISC_INSN_L_SFEQ, "l-sfeq", "l.sfeq", 32,
650 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
652 /* l.sfeqi $rA,${simm-16} */
654 OPENRISC_INSN_L_SFEQI, "l-sfeqi", "l.sfeqi", 32,
655 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
659 OPENRISC_INSN_L_SFNE, "l-sfne", "l.sfne", 32,
660 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
662 /* l.sfnei $rA,${simm-16} */
664 OPENRISC_INSN_L_SFNEI, "l-sfnei", "l.sfnei", 32,
665 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
672 /* Initialize anything needed to be done once, before any cpu_open call. */
679 /* Subroutine of openrisc_cgen_cpu_open to look up a mach via its bfd name. */
681 static const CGEN_MACH *
682 lookup_mach_via_bfd_name (table, name)
683 const CGEN_MACH *table;
688 if (strcmp (name, table->bfd_name) == 0)
695 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
702 int machs = cd->machs;
703 const CGEN_HW_ENTRY *init = & openrisc_cgen_hw_table[0];
704 /* MAX_HW is only an upper bound on the number of selected entries.
705 However each entry is indexed by it's enum so there can be holes in
707 const CGEN_HW_ENTRY **selected =
708 (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
710 cd->hw_table.init_entries = init;
711 cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
712 memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
713 /* ??? For now we just use machs to determine which ones we want. */
714 for (i = 0; init[i].name != NULL; ++i)
715 if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
717 selected[init[i].type] = &init[i];
718 cd->hw_table.entries = selected;
719 cd->hw_table.num_entries = MAX_HW;
722 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
725 build_ifield_table (cd)
728 cd->ifld_table = & openrisc_cgen_ifld_table[0];
731 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
734 build_operand_table (cd)
738 int machs = cd->machs;
739 const CGEN_OPERAND *init = & openrisc_cgen_operand_table[0];
740 /* MAX_OPERANDS is only an upper bound on the number of selected entries.
741 However each entry is indexed by it's enum so there can be holes in
743 const CGEN_OPERAND **selected =
744 (const CGEN_OPERAND **) xmalloc (MAX_OPERANDS * sizeof (CGEN_OPERAND *));
746 cd->operand_table.init_entries = init;
747 cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
748 memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
749 /* ??? For now we just use mach to determine which ones we want. */
750 for (i = 0; init[i].name != NULL; ++i)
751 if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
753 selected[init[i].type] = &init[i];
754 cd->operand_table.entries = selected;
755 cd->operand_table.num_entries = MAX_OPERANDS;
758 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table.
759 ??? This could leave out insns not supported by the specified mach/isa,
760 but that would cause errors like "foo only supported by bar" to become
761 "unknown insn", so for now we include all insns and require the app to
762 do the checking later.
763 ??? On the other hand, parsing of such insns may require their hardware or
764 operand elements to be in the table [which they mightn't be]. */
767 build_insn_table (cd)
771 const CGEN_IBASE *ib = & openrisc_cgen_insn_table[0];
772 CGEN_INSN *insns = (CGEN_INSN *) xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
774 memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
775 for (i = 0; i < MAX_INSNS; ++i)
776 insns[i].base = &ib[i];
777 cd->insn_table.init_entries = insns;
778 cd->insn_table.entry_size = sizeof (CGEN_IBASE);
779 cd->insn_table.num_init_entries = MAX_INSNS;
782 /* Subroutine of openrisc_cgen_cpu_open to rebuild the tables. */
785 openrisc_cgen_rebuild_tables (cd)
789 unsigned int isas = cd->isas;
790 unsigned int machs = cd->machs;
792 cd->int_insn_p = CGEN_INT_INSN_P;
794 /* Data derived from the isa spec. */
795 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
796 cd->default_insn_bitsize = UNSET;
797 cd->base_insn_bitsize = UNSET;
798 cd->min_insn_bitsize = 65535; /* some ridiculously big number */
799 cd->max_insn_bitsize = 0;
800 for (i = 0; i < MAX_ISAS; ++i)
801 if (((1 << i) & isas) != 0)
803 const CGEN_ISA *isa = & openrisc_cgen_isa_table[i];
805 /* Default insn sizes of all selected isas must be equal or we set
806 the result to 0, meaning "unknown". */
807 if (cd->default_insn_bitsize == UNSET)
808 cd->default_insn_bitsize = isa->default_insn_bitsize;
809 else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
812 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
814 /* Base insn sizes of all selected isas must be equal or we set
815 the result to 0, meaning "unknown". */
816 if (cd->base_insn_bitsize == UNSET)
817 cd->base_insn_bitsize = isa->base_insn_bitsize;
818 else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
821 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
823 /* Set min,max insn sizes. */
824 if (isa->min_insn_bitsize < cd->min_insn_bitsize)
825 cd->min_insn_bitsize = isa->min_insn_bitsize;
826 if (isa->max_insn_bitsize > cd->max_insn_bitsize)
827 cd->max_insn_bitsize = isa->max_insn_bitsize;
830 /* Data derived from the mach spec. */
831 for (i = 0; i < MAX_MACHS; ++i)
832 if (((1 << i) & machs) != 0)
834 const CGEN_MACH *mach = & openrisc_cgen_mach_table[i];
836 if (mach->insn_chunk_bitsize != 0)
838 if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
840 fprintf (stderr, "openrisc_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
841 cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
845 cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
849 /* Determine which hw elements are used by MACH. */
852 /* Build the ifield table. */
853 build_ifield_table (cd);
855 /* Determine which operands are used by MACH/ISA. */
856 build_operand_table (cd);
858 /* Build the instruction table. */
859 build_insn_table (cd);
862 /* Initialize a cpu table and return a descriptor.
863 It's much like opening a file, and must be the first function called.
864 The arguments are a set of (type/value) pairs, terminated with
867 Currently supported values:
868 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
869 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
870 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
871 CGEN_CPU_OPEN_ENDIAN: specify endian choice
872 CGEN_CPU_OPEN_END: terminates arguments
874 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
877 ??? We only support ISO C stdargs here, not K&R.
878 Laziness, plus experiment to see if anything requires K&R - eventually
879 K&R will no longer be supported - e.g. GDB is currently trying this. */
882 openrisc_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
884 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
886 unsigned int isas = 0; /* 0 = "unspecified" */
887 unsigned int machs = 0; /* 0 = "unspecified" */
888 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
897 memset (cd, 0, sizeof (*cd));
899 va_start (ap, arg_type);
900 while (arg_type != CGEN_CPU_OPEN_END)
904 case CGEN_CPU_OPEN_ISAS :
905 isas = va_arg (ap, unsigned int);
907 case CGEN_CPU_OPEN_MACHS :
908 machs = va_arg (ap, unsigned int);
910 case CGEN_CPU_OPEN_BFDMACH :
912 const char *name = va_arg (ap, const char *);
913 const CGEN_MACH *mach =
914 lookup_mach_via_bfd_name (openrisc_cgen_mach_table, name);
916 machs |= 1 << mach->num;
919 case CGEN_CPU_OPEN_ENDIAN :
920 endian = va_arg (ap, enum cgen_endian);
923 fprintf (stderr, "openrisc_cgen_cpu_open: unsupported argument `%d'\n",
925 abort (); /* ??? return NULL? */
927 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
931 /* mach unspecified means "all" */
933 machs = (1 << MAX_MACHS) - 1;
934 /* base mach is always selected */
936 /* isa unspecified means "all" */
938 isas = (1 << MAX_ISAS) - 1;
939 if (endian == CGEN_ENDIAN_UNKNOWN)
941 /* ??? If target has only one, could have a default. */
942 fprintf (stderr, "openrisc_cgen_cpu_open: no endianness specified\n");
949 /* FIXME: for the sparc case we can determine insn-endianness statically.
950 The worry here is where both data and insn endian can be independently
951 chosen, in which case this function will need another argument.
952 Actually, will want to allow for more arguments in the future anyway. */
953 cd->insn_endian = endian;
955 /* Table (re)builder. */
956 cd->rebuild_tables = openrisc_cgen_rebuild_tables;
957 openrisc_cgen_rebuild_tables (cd);
959 /* Default to not allowing signed overflow. */
960 cd->signed_overflow_ok_p = 0;
962 return (CGEN_CPU_DESC) cd;
965 /* Cover fn to openrisc_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
966 MACH_NAME is the bfd name of the mach. */
969 openrisc_cgen_cpu_open_1 (mach_name, endian)
970 const char *mach_name;
971 enum cgen_endian endian;
973 return openrisc_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
974 CGEN_CPU_OPEN_ENDIAN, endian,
978 /* Close a cpu table.
979 ??? This can live in a machine independent file, but there's currently
980 no place to put this file (there's no libcgen). libopcodes is the wrong
981 place as some simulator ports use this but they don't use libopcodes. */
984 openrisc_cgen_cpu_close (cd)
987 if (cd->insn_table.init_entries)
988 free ((CGEN_INSN *) cd->insn_table.init_entries);
989 if (cd->hw_table.entries)
990 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);