1 /* CPU data for openrisc.
3 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 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"
38 static const CGEN_ATTR_ENTRY bool_attr
[] =
45 static const CGEN_ATTR_ENTRY MACH_attr
[] =
47 { "base", MACH_BASE
},
48 { "openrisc", MACH_OPENRISC
},
49 { "or1300", MACH_OR1300
},
54 static const CGEN_ATTR_ENTRY ISA_attr
[] =
61 static const CGEN_ATTR_ENTRY HAS_CACHE_attr
[] =
63 { "DATA_CACHE", HAS_CACHE_DATA_CACHE
},
64 { "INSN_CACHE", HAS_CACHE_INSN_CACHE
},
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] },
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] },
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] },
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] },
121 /* Instruction set variants. */
123 static const CGEN_ISA openrisc_cgen_isa_table
[] = {
124 { "or32", 32, 32, 32, 32 },
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 },
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],
183 /* The hardware table. */
185 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
186 #define A(a) (1 << CGEN_HW_##a)
188 #define A(a) (1 << CGEN_HW_/**/a)
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}} }
211 /* The instruction field table. */
213 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
214 #define A(a) (1 << CGEN_IFLD_##a)
216 #define A(a) (1 << CGEN_IFLD_/**/a)
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}} }
257 /* multi ifield declarations */
259 const CGEN_MAYBE_MULTI_IFLD OPENRISC_F_I16NC_MULTI_IFIELD
[];
262 /* multi ifield definitions */
264 const CGEN_MAYBE_MULTI_IFLD OPENRISC_F_I16NC_MULTI_IFIELD
[] =
266 { 0, &(openrisc_cgen_ifld_table
[19]) },
267 { 0, &(openrisc_cgen_ifld_table
[20]) },
271 /* The operand table. */
273 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
274 #define A(a) (1 << CGEN_OPERAND_##a)
276 #define A(a) (1 << CGEN_OPERAND_/**/a)
278 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
279 #define OPERAND(op) OPENRISC_OPERAND_##op
281 #define OPERAND(op) OPENRISC_OPERAND_/**/op
284 const CGEN_OPERAND openrisc_cgen_operand_table
[] =
286 /* pc: program counter */
287 { "pc", OPENRISC_OPERAND_PC
, HW_H_PC
, 0, 0,
288 { 0, &(openrisc_cgen_ifld_table
[0]) },
289 { 0|A(SEM_ONLY
), { (1<<MACH_BASE
) } } },
290 /* sr: special register */
291 { "sr", OPENRISC_OPERAND_SR
, HW_H_SR
, 0, 0,
293 { 0|A(SEM_ONLY
), { (1<<MACH_BASE
) } } },
294 /* cbit: condition bit */
295 { "cbit", OPENRISC_OPERAND_CBIT
, HW_H_CBIT
, 0, 0,
297 { 0|A(SEM_ONLY
), { (1<<MACH_BASE
) } } },
298 /* simm-16: 16 bit signed immediate */
299 { "simm-16", OPENRISC_OPERAND_SIMM_16
, HW_H_SINT
, 15, 16,
300 { 0, &(openrisc_cgen_ifld_table
[7]) },
301 { 0, { (1<<MACH_BASE
) } } },
302 /* uimm-16: 16 bit unsigned immediate */
303 { "uimm-16", OPENRISC_OPERAND_UIMM_16
, HW_H_UINT
, 15, 16,
304 { 0, &(openrisc_cgen_ifld_table
[8]) },
305 { 0, { (1<<MACH_BASE
) } } },
306 /* disp-26: pc-rel 26 bit */
307 { "disp-26", OPENRISC_OPERAND_DISP_26
, HW_H_IADDR
, 25, 26,
308 { 0, &(openrisc_cgen_ifld_table
[21]) },
309 { 0|A(PCREL_ADDR
), { (1<<MACH_BASE
) } } },
310 /* abs-26: abs 26 bit */
311 { "abs-26", OPENRISC_OPERAND_ABS_26
, HW_H_IADDR
, 25, 26,
312 { 0, &(openrisc_cgen_ifld_table
[22]) },
313 { 0|A(ABS_ADDR
), { (1<<MACH_BASE
) } } },
315 { "uimm-5", OPENRISC_OPERAND_UIMM_5
, HW_H_UINT
, 4, 5,
316 { 0, &(openrisc_cgen_ifld_table
[9]) },
317 { 0, { (1<<MACH_BASE
) } } },
318 /* rD: destination register */
319 { "rD", OPENRISC_OPERAND_RD
, HW_H_GR
, 25, 5,
320 { 0, &(openrisc_cgen_ifld_table
[4]) },
321 { 0, { (1<<MACH_BASE
) } } },
322 /* rA: source register A */
323 { "rA", OPENRISC_OPERAND_RA
, HW_H_GR
, 20, 5,
324 { 0, &(openrisc_cgen_ifld_table
[5]) },
325 { 0, { (1<<MACH_BASE
) } } },
326 /* rB: source register B */
327 { "rB", OPENRISC_OPERAND_RB
, HW_H_GR
, 15, 5,
328 { 0, &(openrisc_cgen_ifld_table
[6]) },
329 { 0, { (1<<MACH_BASE
) } } },
330 /* op-f-23: f-op23 */
331 { "op-f-23", OPENRISC_OPERAND_OP_F_23
, HW_H_UINT
, 23, 3,
332 { 0, &(openrisc_cgen_ifld_table
[15]) },
333 { 0, { (1<<MACH_BASE
) } } },
335 { "op-f-3", OPENRISC_OPERAND_OP_F_3
, HW_H_UINT
, 25, 5,
336 { 0, &(openrisc_cgen_ifld_table
[16]) },
337 { 0, { (1<<MACH_BASE
) } } },
338 /* hi16: high 16 bit immediate, sign optional */
339 { "hi16", OPENRISC_OPERAND_HI16
, HW_H_HI16
, 15, 16,
340 { 0, &(openrisc_cgen_ifld_table
[7]) },
341 { 0|A(SIGN_OPT
), { (1<<MACH_BASE
) } } },
342 /* lo16: low 16 bit immediate, sign optional */
343 { "lo16", OPENRISC_OPERAND_LO16
, HW_H_LO16
, 15, 16,
344 { 0, &(openrisc_cgen_ifld_table
[11]) },
345 { 0|A(SIGN_OPT
), { (1<<MACH_BASE
) } } },
346 /* ui16nc: 16 bit immediate, sign optional */
347 { "ui16nc", OPENRISC_OPERAND_UI16NC
, HW_H_LO16
, 10, 16,
348 { 2, &(OPENRISC_F_I16NC_MULTI_IFIELD
[0]) },
349 { 0|A(SIGN_OPT
)|A(VIRTUAL
), { (1<<MACH_BASE
) } } },
350 { 0, 0, 0, 0, 0, {0, {0}} }
356 /* The instruction table. */
358 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
359 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
360 #define A(a) (1 << CGEN_INSN_##a)
362 #define A(a) (1 << CGEN_INSN_/**/a)
365 static const CGEN_IBASE openrisc_cgen_insn_table
[MAX_INSNS
] =
367 /* Special null first entry.
368 A `num' value of zero is thus invalid.
369 Also, the special `invalid' insn resides here. */
370 { 0, 0, 0, 0, {0, {0}} },
373 OPENRISC_INSN_L_J
, "l-j", "l.j", 32,
374 { 0|A(NOT_IN_DELAY_SLOT
)|A(UNCOND_CTI
)|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
376 /* l.jal ${abs-26} */
378 OPENRISC_INSN_L_JAL
, "l-jal", "l.jal", 32,
379 { 0|A(NOT_IN_DELAY_SLOT
)|A(UNCOND_CTI
)|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
383 OPENRISC_INSN_L_JR
, "l-jr", "l.jr", 32,
384 { 0|A(NOT_IN_DELAY_SLOT
)|A(UNCOND_CTI
)|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
388 OPENRISC_INSN_L_JALR
, "l-jalr", "l.jalr", 32,
389 { 0|A(NOT_IN_DELAY_SLOT
)|A(UNCOND_CTI
)|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
391 /* l.bal ${disp-26} */
393 OPENRISC_INSN_L_BAL
, "l-bal", "l.bal", 32,
394 { 0|A(NOT_IN_DELAY_SLOT
)|A(UNCOND_CTI
)|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
396 /* l.bnf ${disp-26} */
398 OPENRISC_INSN_L_BNF
, "l-bnf", "l.bnf", 32,
399 { 0|A(NOT_IN_DELAY_SLOT
)|A(COND_CTI
)|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
401 /* l.bf ${disp-26} */
403 OPENRISC_INSN_L_BF
, "l-bf", "l.bf", 32,
404 { 0|A(NOT_IN_DELAY_SLOT
)|A(COND_CTI
)|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
406 /* l.brk ${uimm-16} */
408 OPENRISC_INSN_L_BRK
, "l-brk", "l.brk", 32,
409 { 0|A(NOT_IN_DELAY_SLOT
), { (1<<MACH_BASE
) } }
413 OPENRISC_INSN_L_RFE
, "l-rfe", "l.rfe", 32,
414 { 0|A(NOT_IN_DELAY_SLOT
)|A(UNCOND_CTI
)|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
416 /* l.sys ${uimm-16} */
418 OPENRISC_INSN_L_SYS
, "l-sys", "l.sys", 32,
419 { 0|A(NOT_IN_DELAY_SLOT
)|A(UNCOND_CTI
)|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
423 OPENRISC_INSN_L_NOP
, "l-nop", "l.nop", 32,
424 { 0, { (1<<MACH_BASE
) } }
426 /* l.movhi $rD,$hi16 */
428 OPENRISC_INSN_L_MOVHI
, "l-movhi", "l.movhi", 32,
429 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
433 OPENRISC_INSN_L_MFSR
, "l-mfsr", "l.mfsr", 32,
434 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
438 OPENRISC_INSN_L_MTSR
, "l-mtsr", "l.mtsr", 32,
439 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
441 /* l.lw $rD,${simm-16}($rA) */
443 OPENRISC_INSN_L_LW
, "l-lw", "l.lw", 32,
444 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
446 /* l.lbz $rD,${simm-16}($rA) */
448 OPENRISC_INSN_L_LBZ
, "l-lbz", "l.lbz", 32,
449 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
451 /* l.lbs $rD,${simm-16}($rA) */
453 OPENRISC_INSN_L_LBS
, "l-lbs", "l.lbs", 32,
454 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
456 /* l.lhz $rD,${simm-16}($rA) */
458 OPENRISC_INSN_L_LHZ
, "l-lhz", "l.lhz", 32,
459 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
461 /* l.lhs $rD,${simm-16}($rA) */
463 OPENRISC_INSN_L_LHS
, "l-lhs", "l.lhs", 32,
464 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
466 /* l.sw ${ui16nc}($rA),$rB */
468 OPENRISC_INSN_L_SW
, "l-sw", "l.sw", 32,
469 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
471 /* l.sb ${ui16nc}($rA),$rB */
473 OPENRISC_INSN_L_SB
, "l-sb", "l.sb", 32,
474 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
476 /* l.sh ${ui16nc}($rA),$rB */
478 OPENRISC_INSN_L_SH
, "l-sh", "l.sh", 32,
479 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
481 /* l.sll $rD,$rA,$rB */
483 OPENRISC_INSN_L_SLL
, "l-sll", "l.sll", 32,
484 { 0, { (1<<MACH_BASE
) } }
486 /* l.slli $rD,$rA,${uimm-5} */
488 OPENRISC_INSN_L_SLLI
, "l-slli", "l.slli", 32,
489 { 0, { (1<<MACH_BASE
) } }
491 /* l.srl $rD,$rA,$rB */
493 OPENRISC_INSN_L_SRL
, "l-srl", "l.srl", 32,
494 { 0, { (1<<MACH_BASE
) } }
496 /* l.srli $rD,$rA,${uimm-5} */
498 OPENRISC_INSN_L_SRLI
, "l-srli", "l.srli", 32,
499 { 0, { (1<<MACH_BASE
) } }
501 /* l.sra $rD,$rA,$rB */
503 OPENRISC_INSN_L_SRA
, "l-sra", "l.sra", 32,
504 { 0, { (1<<MACH_BASE
) } }
506 /* l.srai $rD,$rA,${uimm-5} */
508 OPENRISC_INSN_L_SRAI
, "l-srai", "l.srai", 32,
509 { 0, { (1<<MACH_BASE
) } }
511 /* l.ror $rD,$rA,$rB */
513 OPENRISC_INSN_L_ROR
, "l-ror", "l.ror", 32,
514 { 0, { (1<<MACH_BASE
) } }
516 /* l.rori $rD,$rA,${uimm-5} */
518 OPENRISC_INSN_L_RORI
, "l-rori", "l.rori", 32,
519 { 0, { (1<<MACH_BASE
) } }
521 /* l.add $rD,$rA,$rB */
523 OPENRISC_INSN_L_ADD
, "l-add", "l.add", 32,
524 { 0, { (1<<MACH_BASE
) } }
526 /* l.addi $rD,$rA,$lo16 */
528 OPENRISC_INSN_L_ADDI
, "l-addi", "l.addi", 32,
529 { 0, { (1<<MACH_BASE
) } }
531 /* l.sub $rD,$rA,$rB */
533 OPENRISC_INSN_L_SUB
, "l-sub", "l.sub", 32,
534 { 0, { (1<<MACH_BASE
) } }
536 /* l.subi $rD,$rA,$lo16 */
538 OPENRISC_INSN_L_SUBI
, "l-subi", "l.subi", 32,
539 { 0, { (1<<MACH_BASE
) } }
541 /* l.and $rD,$rA,$rB */
543 OPENRISC_INSN_L_AND
, "l-and", "l.and", 32,
544 { 0, { (1<<MACH_BASE
) } }
546 /* l.andi $rD,$rA,$lo16 */
548 OPENRISC_INSN_L_ANDI
, "l-andi", "l.andi", 32,
549 { 0, { (1<<MACH_BASE
) } }
551 /* l.or $rD,$rA,$rB */
553 OPENRISC_INSN_L_OR
, "l-or", "l.or", 32,
554 { 0, { (1<<MACH_BASE
) } }
556 /* l.ori $rD,$rA,$lo16 */
558 OPENRISC_INSN_L_ORI
, "l-ori", "l.ori", 32,
559 { 0, { (1<<MACH_BASE
) } }
561 /* l.xor $rD,$rA,$rB */
563 OPENRISC_INSN_L_XOR
, "l-xor", "l.xor", 32,
564 { 0, { (1<<MACH_BASE
) } }
566 /* l.xori $rD,$rA,$lo16 */
568 OPENRISC_INSN_L_XORI
, "l-xori", "l.xori", 32,
569 { 0, { (1<<MACH_BASE
) } }
571 /* l.mul $rD,$rA,$rB */
573 OPENRISC_INSN_L_MUL
, "l-mul", "l.mul", 32,
574 { 0, { (1<<MACH_BASE
) } }
576 /* l.muli $rD,$rA,$lo16 */
578 OPENRISC_INSN_L_MULI
, "l-muli", "l.muli", 32,
579 { 0, { (1<<MACH_BASE
) } }
581 /* l.div $rD,$rA,$rB */
583 OPENRISC_INSN_L_DIV
, "l-div", "l.div", 32,
584 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
586 /* l.divu $rD,$rA,$rB */
588 OPENRISC_INSN_L_DIVU
, "l-divu", "l.divu", 32,
589 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
591 /* l.sfgts $rA,$rB */
593 OPENRISC_INSN_L_SFGTS
, "l-sfgts", "l.sfgts", 32,
594 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
596 /* l.sfgtu $rA,$rB */
598 OPENRISC_INSN_L_SFGTU
, "l-sfgtu", "l.sfgtu", 32,
599 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
601 /* l.sfges $rA,$rB */
603 OPENRISC_INSN_L_SFGES
, "l-sfges", "l.sfges", 32,
604 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
606 /* l.sfgeu $rA,$rB */
608 OPENRISC_INSN_L_SFGEU
, "l-sfgeu", "l.sfgeu", 32,
609 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
611 /* l.sflts $rA,$rB */
613 OPENRISC_INSN_L_SFLTS
, "l-sflts", "l.sflts", 32,
614 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
616 /* l.sfltu $rA,$rB */
618 OPENRISC_INSN_L_SFLTU
, "l-sfltu", "l.sfltu", 32,
619 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
621 /* l.sfles $rA,$rB */
623 OPENRISC_INSN_L_SFLES
, "l-sfles", "l.sfles", 32,
624 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
626 /* l.sfleu $rA,$rB */
628 OPENRISC_INSN_L_SFLEU
, "l-sfleu", "l.sfleu", 32,
629 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
631 /* l.sfgtsi $rA,${simm-16} */
633 OPENRISC_INSN_L_SFGTSI
, "l-sfgtsi", "l.sfgtsi", 32,
634 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
636 /* l.sfgtui $rA,${uimm-16} */
638 OPENRISC_INSN_L_SFGTUI
, "l-sfgtui", "l.sfgtui", 32,
639 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
641 /* l.sfgesi $rA,${simm-16} */
643 OPENRISC_INSN_L_SFGESI
, "l-sfgesi", "l.sfgesi", 32,
644 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
646 /* l.sfgeui $rA,${uimm-16} */
648 OPENRISC_INSN_L_SFGEUI
, "l-sfgeui", "l.sfgeui", 32,
649 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
651 /* l.sfltsi $rA,${simm-16} */
653 OPENRISC_INSN_L_SFLTSI
, "l-sfltsi", "l.sfltsi", 32,
654 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
656 /* l.sfltui $rA,${uimm-16} */
658 OPENRISC_INSN_L_SFLTUI
, "l-sfltui", "l.sfltui", 32,
659 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
661 /* l.sflesi $rA,${simm-16} */
663 OPENRISC_INSN_L_SFLESI
, "l-sflesi", "l.sflesi", 32,
664 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
666 /* l.sfleui $rA,${uimm-16} */
668 OPENRISC_INSN_L_SFLEUI
, "l-sfleui", "l.sfleui", 32,
669 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
673 OPENRISC_INSN_L_SFEQ
, "l-sfeq", "l.sfeq", 32,
674 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
676 /* l.sfeqi $rA,${simm-16} */
678 OPENRISC_INSN_L_SFEQI
, "l-sfeqi", "l.sfeqi", 32,
679 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
683 OPENRISC_INSN_L_SFNE
, "l-sfne", "l.sfne", 32,
684 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
686 /* l.sfnei $rA,${simm-16} */
688 OPENRISC_INSN_L_SFNEI
, "l-sfnei", "l.sfnei", 32,
689 { 0|A(DELAY_SLOT
), { (1<<MACH_BASE
) } }
696 /* Initialize anything needed to be done once, before any cpu_open call. */
697 static void init_tables
PARAMS ((void));
704 static const CGEN_MACH
* lookup_mach_via_bfd_name
705 PARAMS ((const CGEN_MACH
*, const char *));
706 static void build_hw_table
PARAMS ((CGEN_CPU_TABLE
*));
707 static void build_ifield_table
PARAMS ((CGEN_CPU_TABLE
*));
708 static void build_operand_table
PARAMS ((CGEN_CPU_TABLE
*));
709 static void build_insn_table
PARAMS ((CGEN_CPU_TABLE
*));
710 static void openrisc_cgen_rebuild_tables
PARAMS ((CGEN_CPU_TABLE
*));
712 /* Subroutine of openrisc_cgen_cpu_open to look up a mach via its bfd name. */
714 static const CGEN_MACH
*
715 lookup_mach_via_bfd_name (table
, name
)
716 const CGEN_MACH
*table
;
721 if (strcmp (name
, table
->bfd_name
) == 0)
728 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
735 int machs
= cd
->machs
;
736 const CGEN_HW_ENTRY
*init
= & openrisc_cgen_hw_table
[0];
737 /* MAX_HW is only an upper bound on the number of selected entries.
738 However each entry is indexed by it's enum so there can be holes in
740 const CGEN_HW_ENTRY
**selected
=
741 (const CGEN_HW_ENTRY
**) xmalloc (MAX_HW
* sizeof (CGEN_HW_ENTRY
*));
743 cd
->hw_table
.init_entries
= init
;
744 cd
->hw_table
.entry_size
= sizeof (CGEN_HW_ENTRY
);
745 memset (selected
, 0, MAX_HW
* sizeof (CGEN_HW_ENTRY
*));
746 /* ??? For now we just use machs to determine which ones we want. */
747 for (i
= 0; init
[i
].name
!= NULL
; ++i
)
748 if (CGEN_HW_ATTR_VALUE (&init
[i
], CGEN_HW_MACH
)
750 selected
[init
[i
].type
] = &init
[i
];
751 cd
->hw_table
.entries
= selected
;
752 cd
->hw_table
.num_entries
= MAX_HW
;
755 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
758 build_ifield_table (cd
)
761 cd
->ifld_table
= & openrisc_cgen_ifld_table
[0];
764 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
767 build_operand_table (cd
)
771 int machs
= cd
->machs
;
772 const CGEN_OPERAND
*init
= & openrisc_cgen_operand_table
[0];
773 /* MAX_OPERANDS is only an upper bound on the number of selected entries.
774 However each entry is indexed by it's enum so there can be holes in
776 const CGEN_OPERAND
**selected
=
777 (const CGEN_OPERAND
**) xmalloc (MAX_OPERANDS
* sizeof (CGEN_OPERAND
*));
779 cd
->operand_table
.init_entries
= init
;
780 cd
->operand_table
.entry_size
= sizeof (CGEN_OPERAND
);
781 memset (selected
, 0, MAX_OPERANDS
* sizeof (CGEN_OPERAND
*));
782 /* ??? For now we just use mach to determine which ones we want. */
783 for (i
= 0; init
[i
].name
!= NULL
; ++i
)
784 if (CGEN_OPERAND_ATTR_VALUE (&init
[i
], CGEN_OPERAND_MACH
)
786 selected
[init
[i
].type
] = &init
[i
];
787 cd
->operand_table
.entries
= selected
;
788 cd
->operand_table
.num_entries
= MAX_OPERANDS
;
791 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table.
792 ??? This could leave out insns not supported by the specified mach/isa,
793 but that would cause errors like "foo only supported by bar" to become
794 "unknown insn", so for now we include all insns and require the app to
795 do the checking later.
796 ??? On the other hand, parsing of such insns may require their hardware or
797 operand elements to be in the table [which they mightn't be]. */
800 build_insn_table (cd
)
804 const CGEN_IBASE
*ib
= & openrisc_cgen_insn_table
[0];
805 CGEN_INSN
*insns
= (CGEN_INSN
*) xmalloc (MAX_INSNS
* sizeof (CGEN_INSN
));
807 memset (insns
, 0, MAX_INSNS
* sizeof (CGEN_INSN
));
808 for (i
= 0; i
< MAX_INSNS
; ++i
)
809 insns
[i
].base
= &ib
[i
];
810 cd
->insn_table
.init_entries
= insns
;
811 cd
->insn_table
.entry_size
= sizeof (CGEN_IBASE
);
812 cd
->insn_table
.num_init_entries
= MAX_INSNS
;
815 /* Subroutine of openrisc_cgen_cpu_open to rebuild the tables. */
818 openrisc_cgen_rebuild_tables (cd
)
822 unsigned int isas
= cd
->isas
;
823 unsigned int machs
= cd
->machs
;
825 cd
->int_insn_p
= CGEN_INT_INSN_P
;
827 /* Data derived from the isa spec. */
828 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
829 cd
->default_insn_bitsize
= UNSET
;
830 cd
->base_insn_bitsize
= UNSET
;
831 cd
->min_insn_bitsize
= 65535; /* some ridiculously big number */
832 cd
->max_insn_bitsize
= 0;
833 for (i
= 0; i
< MAX_ISAS
; ++i
)
834 if (((1 << i
) & isas
) != 0)
836 const CGEN_ISA
*isa
= & openrisc_cgen_isa_table
[i
];
838 /* Default insn sizes of all selected isas must be
839 equal or we set the result to 0, meaning "unknown". */
840 if (cd
->default_insn_bitsize
== UNSET
)
841 cd
->default_insn_bitsize
= isa
->default_insn_bitsize
;
842 else if (isa
->default_insn_bitsize
== cd
->default_insn_bitsize
)
845 cd
->default_insn_bitsize
= CGEN_SIZE_UNKNOWN
;
847 /* Base insn sizes of all selected isas must be equal
848 or we set the result to 0, meaning "unknown". */
849 if (cd
->base_insn_bitsize
== UNSET
)
850 cd
->base_insn_bitsize
= isa
->base_insn_bitsize
;
851 else if (isa
->base_insn_bitsize
== cd
->base_insn_bitsize
)
854 cd
->base_insn_bitsize
= CGEN_SIZE_UNKNOWN
;
856 /* Set min,max insn sizes. */
857 if (isa
->min_insn_bitsize
< cd
->min_insn_bitsize
)
858 cd
->min_insn_bitsize
= isa
->min_insn_bitsize
;
859 if (isa
->max_insn_bitsize
> cd
->max_insn_bitsize
)
860 cd
->max_insn_bitsize
= isa
->max_insn_bitsize
;
863 /* Data derived from the mach spec. */
864 for (i
= 0; i
< MAX_MACHS
; ++i
)
865 if (((1 << i
) & machs
) != 0)
867 const CGEN_MACH
*mach
= & openrisc_cgen_mach_table
[i
];
869 if (mach
->insn_chunk_bitsize
!= 0)
871 if (cd
->insn_chunk_bitsize
!= 0 && cd
->insn_chunk_bitsize
!= mach
->insn_chunk_bitsize
)
873 fprintf (stderr
, "openrisc_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
874 cd
->insn_chunk_bitsize
, mach
->insn_chunk_bitsize
);
878 cd
->insn_chunk_bitsize
= mach
->insn_chunk_bitsize
;
882 /* Determine which hw elements are used by MACH. */
885 /* Build the ifield table. */
886 build_ifield_table (cd
);
888 /* Determine which operands are used by MACH/ISA. */
889 build_operand_table (cd
);
891 /* Build the instruction table. */
892 build_insn_table (cd
);
895 /* Initialize a cpu table and return a descriptor.
896 It's much like opening a file, and must be the first function called.
897 The arguments are a set of (type/value) pairs, terminated with
900 Currently supported values:
901 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
902 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
903 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
904 CGEN_CPU_OPEN_ENDIAN: specify endian choice
905 CGEN_CPU_OPEN_END: terminates arguments
907 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
910 ??? We only support ISO C stdargs here, not K&R.
911 Laziness, plus experiment to see if anything requires K&R - eventually
912 K&R will no longer be supported - e.g. GDB is currently trying this. */
915 openrisc_cgen_cpu_open (enum cgen_cpu_open_arg arg_type
, ...)
917 CGEN_CPU_TABLE
*cd
= (CGEN_CPU_TABLE
*) xmalloc (sizeof (CGEN_CPU_TABLE
));
919 unsigned int isas
= 0; /* 0 = "unspecified" */
920 unsigned int machs
= 0; /* 0 = "unspecified" */
921 enum cgen_endian endian
= CGEN_ENDIAN_UNKNOWN
;
930 memset (cd
, 0, sizeof (*cd
));
932 va_start (ap
, arg_type
);
933 while (arg_type
!= CGEN_CPU_OPEN_END
)
937 case CGEN_CPU_OPEN_ISAS
:
938 isas
= va_arg (ap
, unsigned int);
940 case CGEN_CPU_OPEN_MACHS
:
941 machs
= va_arg (ap
, unsigned int);
943 case CGEN_CPU_OPEN_BFDMACH
:
945 const char *name
= va_arg (ap
, const char *);
946 const CGEN_MACH
*mach
=
947 lookup_mach_via_bfd_name (openrisc_cgen_mach_table
, name
);
949 machs
|= 1 << mach
->num
;
952 case CGEN_CPU_OPEN_ENDIAN
:
953 endian
= va_arg (ap
, enum cgen_endian
);
956 fprintf (stderr
, "openrisc_cgen_cpu_open: unsupported argument `%d'\n",
958 abort (); /* ??? return NULL? */
960 arg_type
= va_arg (ap
, enum cgen_cpu_open_arg
);
964 /* mach unspecified means "all" */
966 machs
= (1 << MAX_MACHS
) - 1;
967 /* base mach is always selected */
969 /* isa unspecified means "all" */
971 isas
= (1 << MAX_ISAS
) - 1;
972 if (endian
== CGEN_ENDIAN_UNKNOWN
)
974 /* ??? If target has only one, could have a default. */
975 fprintf (stderr
, "openrisc_cgen_cpu_open: no endianness specified\n");
982 /* FIXME: for the sparc case we can determine insn-endianness statically.
983 The worry here is where both data and insn endian can be independently
984 chosen, in which case this function will need another argument.
985 Actually, will want to allow for more arguments in the future anyway. */
986 cd
->insn_endian
= endian
;
988 /* Table (re)builder. */
989 cd
->rebuild_tables
= openrisc_cgen_rebuild_tables
;
990 openrisc_cgen_rebuild_tables (cd
);
992 /* Default to not allowing signed overflow. */
993 cd
->signed_overflow_ok_p
= 0;
995 return (CGEN_CPU_DESC
) cd
;
998 /* Cover fn to openrisc_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
999 MACH_NAME is the bfd name of the mach. */
1002 openrisc_cgen_cpu_open_1 (mach_name
, endian
)
1003 const char *mach_name
;
1004 enum cgen_endian endian
;
1006 return openrisc_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH
, mach_name
,
1007 CGEN_CPU_OPEN_ENDIAN
, endian
,
1011 /* Close a cpu table.
1012 ??? This can live in a machine independent file, but there's currently
1013 no place to put this file (there's no libcgen). libopcodes is the wrong
1014 place as some simulator ports use this but they don't use libopcodes. */
1017 openrisc_cgen_cpu_close (cd
)
1023 if (cd
->macro_insn_table
.init_entries
)
1025 insns
= cd
->macro_insn_table
.init_entries
;
1026 for (i
= 0; i
< cd
->macro_insn_table
.num_init_entries
; ++i
, ++insns
)
1028 if (CGEN_INSN_RX ((insns
)))
1029 regfree(CGEN_INSN_RX (insns
));
1033 if (cd
->insn_table
.init_entries
)
1035 insns
= cd
->insn_table
.init_entries
;
1036 for (i
= 0; i
< cd
->insn_table
.num_init_entries
; ++i
, ++insns
)
1038 if (CGEN_INSN_RX (insns
))
1039 regfree(CGEN_INSN_RX (insns
));
1045 if (cd
->macro_insn_table
.init_entries
)
1046 free ((CGEN_INSN
*) cd
->macro_insn_table
.init_entries
);
1048 if (cd
->insn_table
.init_entries
)
1049 free ((CGEN_INSN
*) cd
->insn_table
.init_entries
);
1051 if (cd
->hw_table
.entries
)
1052 free ((CGEN_HW_ENTRY
*) cd
->hw_table
.entries
);
1054 if (cd
->operand_table
.entries
)
1055 free ((CGEN_HW_ENTRY
*) cd
->operand_table
.entries
);