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