* cgen.h (struct cgen_maybe_multi_ifield): Add "const PTR p" to union.
[deliverable/binutils-gdb.git] / opcodes / ip2k-desc.c
CommitLineData
a40cbfa3
NC
1/* CPU data for ip2k.
2
3THIS FILE IS MACHINE GENERATED WITH CGEN.
4
5Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
6
7This file is part of the GNU Binutils and/or GDB, the GNU debugger.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License along
20with this program; if not, write to the Free Software Foundation, Inc.,
2159 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "ip2k-desc.h"
32#include "ip2k-opc.h"
33#include "opintl.h"
34#include "libiberty.h"
35
36/* Attributes. */
37
38static const CGEN_ATTR_ENTRY bool_attr[] =
39{
40 { "#f", 0 },
41 { "#t", 1 },
42 { 0, 0 }
43};
44
45static const CGEN_ATTR_ENTRY MACH_attr[] =
46{
47 { "base", MACH_BASE },
48 { "ip2022", MACH_IP2022 },
49 { "ip2022ext", MACH_IP2022EXT },
50 { "max", MACH_MAX },
51 { 0, 0 }
52};
53
54static const CGEN_ATTR_ENTRY ISA_attr[] =
55{
56 { "ip2k", ISA_IP2K },
57 { "max", ISA_MAX },
58 { 0, 0 }
59};
60
61const CGEN_ATTR_TABLE ip2k_cgen_ifield_attr_table[] =
62{
63 { "MACH", & MACH_attr[0], & MACH_attr[0] },
64 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
65 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
66 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
67 { "RESERVED", &bool_attr[0], &bool_attr[0] },
68 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
69 { "SIGNED", &bool_attr[0], &bool_attr[0] },
70 { 0, 0, 0 }
71};
72
73const CGEN_ATTR_TABLE ip2k_cgen_hardware_attr_table[] =
74{
75 { "MACH", & MACH_attr[0], & MACH_attr[0] },
76 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
77 { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
78 { "PC", &bool_attr[0], &bool_attr[0] },
79 { "PROFILE", &bool_attr[0], &bool_attr[0] },
80 { 0, 0, 0 }
81};
82
83const CGEN_ATTR_TABLE ip2k_cgen_operand_attr_table[] =
84{
85 { "MACH", & MACH_attr[0], & MACH_attr[0] },
86 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
87 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
88 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
89 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
90 { "SIGNED", &bool_attr[0], &bool_attr[0] },
91 { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
92 { "RELAX", &bool_attr[0], &bool_attr[0] },
93 { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
94 { 0, 0, 0 }
95};
96
97const CGEN_ATTR_TABLE ip2k_cgen_insn_attr_table[] =
98{
99 { "MACH", & MACH_attr[0], & MACH_attr[0] },
100 { "ALIAS", &bool_attr[0], &bool_attr[0] },
101 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
102 { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
103 { "COND-CTI", &bool_attr[0], &bool_attr[0] },
104 { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
105 { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
106 { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
107 { "RELAX", &bool_attr[0], &bool_attr[0] },
108 { "NO-DIS", &bool_attr[0], &bool_attr[0] },
109 { "PBB", &bool_attr[0], &bool_attr[0] },
110 { "EXT-SKIP-INSN", &bool_attr[0], &bool_attr[0] },
111 { "SKIPA", &bool_attr[0], &bool_attr[0] },
112 { 0, 0, 0 }
113};
114
115/* Instruction set variants. */
116
117static const CGEN_ISA ip2k_cgen_isa_table[] = {
118 { "ip2k", 16, 16, 16, 16 },
119 { 0, 0, 0, 0, 0 }
120};
121
122/* Machine variants. */
123
124static const CGEN_MACH ip2k_cgen_mach_table[] = {
125 { "ip2022", "ip2022", MACH_IP2022, 0 },
126 { "ip2022ext", "ip2022ext", MACH_IP2022EXT, 0 },
127 { 0, 0, 0, 0 }
128};
129
130static CGEN_KEYWORD_ENTRY ip2k_cgen_opval_register_names_entries[] =
131{
132 { "ADDRSEL", 2, {0, {0}}, 0, 0 },
133 { "ADDRX", 3, {0, {0}}, 0, 0 },
134 { "IPH", 4, {0, {0}}, 0, 0 },
135 { "IPL", 5, {0, {0}}, 0, 0 },
136 { "SPH", 6, {0, {0}}, 0, 0 },
137 { "SPL", 7, {0, {0}}, 0, 0 },
138 { "PCH", 8, {0, {0}}, 0, 0 },
139 { "PCL", 9, {0, {0}}, 0, 0 },
140 { "WREG", 10, {0, {0}}, 0, 0 },
141 { "STATUS", 11, {0, {0}}, 0, 0 },
142 { "DPH", 12, {0, {0}}, 0, 0 },
143 { "DPL", 13, {0, {0}}, 0, 0 },
144 { "SPDREG", 14, {0, {0}}, 0, 0 },
145 { "MULH", 15, {0, {0}}, 0, 0 },
146 { "ADDRH", 16, {0, {0}}, 0, 0 },
147 { "ADDRL", 17, {0, {0}}, 0, 0 },
148 { "DATAH", 18, {0, {0}}, 0, 0 },
149 { "DATAL", 19, {0, {0}}, 0, 0 },
150 { "INTVECH", 20, {0, {0}}, 0, 0 },
151 { "INTVECL", 21, {0, {0}}, 0, 0 },
152 { "INTSPD", 22, {0, {0}}, 0, 0 },
153 { "INTF", 23, {0, {0}}, 0, 0 },
154 { "INTE", 24, {0, {0}}, 0, 0 },
155 { "INTED", 25, {0, {0}}, 0, 0 },
156 { "FCFG", 26, {0, {0}}, 0, 0 },
157 { "TCTRL", 27, {0, {0}}, 0, 0 },
158 { "XCFG", 28, {0, {0}}, 0, 0 },
159 { "EMCFG", 29, {0, {0}}, 0, 0 },
160 { "IPCH", 30, {0, {0}}, 0, 0 },
161 { "IPCL", 31, {0, {0}}, 0, 0 },
162 { "RAIN", 32, {0, {0}}, 0, 0 },
163 { "RAOUT", 33, {0, {0}}, 0, 0 },
164 { "RADIR", 34, {0, {0}}, 0, 0 },
165 { "LFSRH", 35, {0, {0}}, 0, 0 },
166 { "RBIN", 36, {0, {0}}, 0, 0 },
167 { "RBOUT", 37, {0, {0}}, 0, 0 },
168 { "RBDIR", 38, {0, {0}}, 0, 0 },
169 { "LFSRL", 39, {0, {0}}, 0, 0 },
170 { "RCIN", 40, {0, {0}}, 0, 0 },
171 { "RCOUT", 41, {0, {0}}, 0, 0 },
172 { "RCDIR", 42, {0, {0}}, 0, 0 },
173 { "LFSRA", 43, {0, {0}}, 0, 0 },
174 { "RDIN", 44, {0, {0}}, 0, 0 },
175 { "RDOUT", 45, {0, {0}}, 0, 0 },
176 { "RDDIR", 46, {0, {0}}, 0, 0 },
177 { "REIN", 48, {0, {0}}, 0, 0 },
178 { "REOUT", 49, {0, {0}}, 0, 0 },
179 { "REDIR", 50, {0, {0}}, 0, 0 },
180 { "RFIN", 52, {0, {0}}, 0, 0 },
181 { "RFOUT", 53, {0, {0}}, 0, 0 },
182 { "RFDIR", 54, {0, {0}}, 0, 0 },
183 { "RGOUT", 57, {0, {0}}, 0, 0 },
184 { "RGDIR", 58, {0, {0}}, 0, 0 },
185 { "RTTMR", 64, {0, {0}}, 0, 0 },
186 { "RTCFG", 65, {0, {0}}, 0, 0 },
187 { "T0TMR", 66, {0, {0}}, 0, 0 },
188 { "T0CFG", 67, {0, {0}}, 0, 0 },
189 { "T1CNTH", 68, {0, {0}}, 0, 0 },
190 { "T1CNTL", 69, {0, {0}}, 0, 0 },
191 { "T1CAP1H", 70, {0, {0}}, 0, 0 },
192 { "T1CAP1L", 71, {0, {0}}, 0, 0 },
193 { "T1CAP2H", 72, {0, {0}}, 0, 0 },
194 { "T1CMP2H", 72, {0, {0}}, 0, 0 },
195 { "T1CAP2L", 73, {0, {0}}, 0, 0 },
196 { "T1CMP2L", 73, {0, {0}}, 0, 0 },
197 { "T1CMP1H", 74, {0, {0}}, 0, 0 },
198 { "T1CMP1L", 75, {0, {0}}, 0, 0 },
199 { "T1CFG1H", 76, {0, {0}}, 0, 0 },
200 { "T1CFG1L", 77, {0, {0}}, 0, 0 },
201 { "T1CFG2H", 78, {0, {0}}, 0, 0 },
202 { "T1CFG2L", 79, {0, {0}}, 0, 0 },
203 { "ADCH", 80, {0, {0}}, 0, 0 },
204 { "ADCL", 81, {0, {0}}, 0, 0 },
205 { "ADCCFG", 82, {0, {0}}, 0, 0 },
206 { "ADCTMR", 83, {0, {0}}, 0, 0 },
207 { "T2CNTH", 84, {0, {0}}, 0, 0 },
208 { "T2CNTL", 85, {0, {0}}, 0, 0 },
209 { "T2CAP1H", 86, {0, {0}}, 0, 0 },
210 { "T2CAP1L", 87, {0, {0}}, 0, 0 },
211 { "T2CAP2H", 88, {0, {0}}, 0, 0 },
212 { "T2CMP2H", 88, {0, {0}}, 0, 0 },
213 { "T2CAP2L", 89, {0, {0}}, 0, 0 },
214 { "T2CMP2L", 89, {0, {0}}, 0, 0 },
215 { "T2CMP1H", 90, {0, {0}}, 0, 0 },
216 { "T2CMP1L", 91, {0, {0}}, 0, 0 },
217 { "T2CFG1H", 92, {0, {0}}, 0, 0 },
218 { "T2CFG1L", 93, {0, {0}}, 0, 0 },
219 { "T2CFG2H", 94, {0, {0}}, 0, 0 },
220 { "T2CFG2L", 95, {0, {0}}, 0, 0 },
221 { "S1TMRH", 96, {0, {0}}, 0, 0 },
222 { "S1TMRL", 97, {0, {0}}, 0, 0 },
223 { "S1TBUFH", 98, {0, {0}}, 0, 0 },
224 { "S1TBUFL", 99, {0, {0}}, 0, 0 },
225 { "S1TCFG", 100, {0, {0}}, 0, 0 },
226 { "S1RCNT", 101, {0, {0}}, 0, 0 },
227 { "S1RBUFH", 102, {0, {0}}, 0, 0 },
228 { "S1RBUFL", 103, {0, {0}}, 0, 0 },
229 { "S1RCFG", 104, {0, {0}}, 0, 0 },
230 { "S1RSYNC", 105, {0, {0}}, 0, 0 },
231 { "S1INTF", 106, {0, {0}}, 0, 0 },
232 { "S1INTE", 107, {0, {0}}, 0, 0 },
233 { "S1MODE", 108, {0, {0}}, 0, 0 },
234 { "S1SMASK", 109, {0, {0}}, 0, 0 },
235 { "PSPCFG", 110, {0, {0}}, 0, 0 },
236 { "CMPCFG", 111, {0, {0}}, 0, 0 },
237 { "S2TMRH", 112, {0, {0}}, 0, 0 },
238 { "S2TMRL", 113, {0, {0}}, 0, 0 },
239 { "S2TBUFH", 114, {0, {0}}, 0, 0 },
240 { "S2TBUFL", 115, {0, {0}}, 0, 0 },
241 { "S2TCFG", 116, {0, {0}}, 0, 0 },
242 { "S2RCNT", 117, {0, {0}}, 0, 0 },
243 { "S2RBUFH", 118, {0, {0}}, 0, 0 },
244 { "S2RBUFL", 119, {0, {0}}, 0, 0 },
245 { "S2RCFG", 120, {0, {0}}, 0, 0 },
246 { "S2RSYNC", 121, {0, {0}}, 0, 0 },
247 { "S2INTF", 122, {0, {0}}, 0, 0 },
248 { "S2INTE", 123, {0, {0}}, 0, 0 },
249 { "S2MODE", 124, {0, {0}}, 0, 0 },
250 { "S2SMASK", 125, {0, {0}}, 0, 0 },
251 { "CALLH", 126, {0, {0}}, 0, 0 },
252 { "CALLL", 127, {0, {0}}, 0, 0 }
253};
254
255CGEN_KEYWORD ip2k_cgen_opval_register_names =
256{
257 & ip2k_cgen_opval_register_names_entries[0],
258 121,
259 0, 0, 0, 0, ""
260};
261
262
263/* The hardware table. */
264
265#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
266#define A(a) (1 << CGEN_HW_##a)
267#else
268#define A(a) (1 << CGEN_HW_/**/a)
269#endif
270
271const CGEN_HW_ENTRY ip2k_cgen_hw_table[] =
272{
273 { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
274 { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
275 { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
276 { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
277 { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
278 { "h-spr", HW_H_SPR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
279 { "h-registers", HW_H_REGISTERS, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { (1<<MACH_BASE) } } },
280 { "h-stack", HW_H_STACK, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
281 { "h-pabits", HW_H_PABITS, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
282 { "h-zbit", HW_H_ZBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
283 { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
284 { "h-dcbit", HW_H_DCBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
285 { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { (1<<MACH_BASE) } } },
286 { 0, 0, CGEN_ASM_NONE, 0, {0, {0}} }
287};
288
289#undef A
290
291
292/* The instruction field table. */
293
294#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
295#define A(a) (1 << CGEN_IFLD_##a)
296#else
297#define A(a) (1 << CGEN_IFLD_/**/a)
298#endif
299
300const CGEN_IFLD ip2k_cgen_ifld_table[] =
301{
302 { IP2K_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
303 { IP2K_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
304 { IP2K_F_IMM8, "f-imm8", 0, 16, 7, 8, { 0, { (1<<MACH_BASE) } } },
305 { IP2K_F_REG, "f-reg", 0, 16, 8, 9, { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
306 { IP2K_F_ADDR16CJP, "f-addr16cjp", 0, 16, 12, 13, { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
307 { IP2K_F_DIR, "f-dir", 0, 16, 9, 1, { 0, { (1<<MACH_BASE) } } },
308 { IP2K_F_BITNO, "f-bitno", 0, 16, 11, 3, { 0, { (1<<MACH_BASE) } } },
309 { IP2K_F_OP3, "f-op3", 0, 16, 15, 3, { 0, { (1<<MACH_BASE) } } },
310 { IP2K_F_OP4, "f-op4", 0, 16, 15, 4, { 0, { (1<<MACH_BASE) } } },
311 { IP2K_F_OP4MID, "f-op4mid", 0, 16, 11, 4, { 0, { (1<<MACH_BASE) } } },
312 { IP2K_F_OP6, "f-op6", 0, 16, 15, 6, { 0, { (1<<MACH_BASE) } } },
313 { IP2K_F_OP8, "f-op8", 0, 16, 15, 8, { 0, { (1<<MACH_BASE) } } },
314 { IP2K_F_OP6_10LOW, "f-op6-10low", 0, 16, 9, 10, { 0, { (1<<MACH_BASE) } } },
315 { IP2K_F_OP6_7LOW, "f-op6-7low", 0, 16, 9, 7, { 0, { (1<<MACH_BASE) } } },
316 { IP2K_F_RETI3, "f-reti3", 0, 16, 2, 3, { 0, { (1<<MACH_BASE) } } },
317 { IP2K_F_SKIPB, "f-skipb", 0, 16, 12, 1, { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
318 { IP2K_F_PAGE3, "f-page3", 0, 16, 2, 3, { 0, { (1<<MACH_BASE) } } },
319 { 0, 0, 0, 0, 0, 0, {0, {0}} }
320};
321
322#undef A
323
324
325
326/* multi ifield declarations */
327
328
329
330/* multi ifield definitions */
331
332
333/* The operand table. */
334
335#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
336#define A(a) (1 << CGEN_OPERAND_##a)
337#else
338#define A(a) (1 << CGEN_OPERAND_/**/a)
339#endif
340#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
341#define OPERAND(op) IP2K_OPERAND_##op
342#else
343#define OPERAND(op) IP2K_OPERAND_/**/op
344#endif
345
346const CGEN_OPERAND ip2k_cgen_operand_table[] =
347{
348/* pc: program counter */
349 { "pc", IP2K_OPERAND_PC, HW_H_PC, 0, 0,
350 { 0, &(ip2k_cgen_ifld_table[0]) },
351 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
352/* addr16cjp: 13-bit address */
353 { "addr16cjp", IP2K_OPERAND_ADDR16CJP, HW_H_UINT, 12, 13,
354 { 0, &(ip2k_cgen_ifld_table[4]) },
355 { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
356/* fr: register */
357 { "fr", IP2K_OPERAND_FR, HW_H_REGISTERS, 8, 9,
358 { 0, &(ip2k_cgen_ifld_table[3]) },
359 { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
360/* lit8: 8-bit signed literal */
361 { "lit8", IP2K_OPERAND_LIT8, HW_H_SINT, 7, 8,
362 { 0, &(ip2k_cgen_ifld_table[2]) },
363 { 0, { (1<<MACH_BASE) } } },
364/* bitno: bit number */
365 { "bitno", IP2K_OPERAND_BITNO, HW_H_UINT, 11, 3,
366 { 0, &(ip2k_cgen_ifld_table[6]) },
367 { 0, { (1<<MACH_BASE) } } },
368/* addr16p: page number */
369 { "addr16p", IP2K_OPERAND_ADDR16P, HW_H_UINT, 2, 3,
370 { 0, &(ip2k_cgen_ifld_table[16]) },
371 { 0, { (1<<MACH_BASE) } } },
372/* addr16h: high 8 bits of address */
373 { "addr16h", IP2K_OPERAND_ADDR16H, HW_H_UINT, 7, 8,
374 { 0, &(ip2k_cgen_ifld_table[2]) },
375 { 0, { (1<<MACH_BASE) } } },
376/* addr16l: low 8 bits of address */
377 { "addr16l", IP2K_OPERAND_ADDR16L, HW_H_UINT, 7, 8,
378 { 0, &(ip2k_cgen_ifld_table[2]) },
379 { 0, { (1<<MACH_BASE) } } },
380/* reti3: reti flags */
381 { "reti3", IP2K_OPERAND_RETI3, HW_H_UINT, 2, 3,
382 { 0, &(ip2k_cgen_ifld_table[14]) },
383 { 0, { (1<<MACH_BASE) } } },
384/* pabits: page bits */
385 { "pabits", IP2K_OPERAND_PABITS, HW_H_PABITS, 0, 0,
386 { 0, 0 },
387 { 0, { (1<<MACH_BASE) } } },
388/* zbit: zero bit */
389 { "zbit", IP2K_OPERAND_ZBIT, HW_H_ZBIT, 0, 0,
390 { 0, 0 },
391 { 0, { (1<<MACH_BASE) } } },
392/* cbit: carry bit */
393 { "cbit", IP2K_OPERAND_CBIT, HW_H_CBIT, 0, 0,
394 { 0, 0 },
395 { 0, { (1<<MACH_BASE) } } },
396/* dcbit: digit carry bit */
397 { "dcbit", IP2K_OPERAND_DCBIT, HW_H_DCBIT, 0, 0,
398 { 0, 0 },
399 { 0, { (1<<MACH_BASE) } } },
400 { 0, 0, 0, 0, 0, {0, {0}} }
401};
402
403#undef A
404
405
406/* The instruction table. */
407
408#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
409#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
410#define A(a) (1 << CGEN_INSN_##a)
411#else
412#define A(a) (1 << CGEN_INSN_/**/a)
413#endif
414
415static const CGEN_IBASE ip2k_cgen_insn_table[MAX_INSNS] =
416{
417 /* Special null first entry.
418 A `num' value of zero is thus invalid.
419 Also, the special `invalid' insn resides here. */
420 { 0, 0, 0, 0, {0, {0}} },
421/* jmp $addr16cjp */
422 {
423 IP2K_INSN_JMP, "jmp", "jmp", 16,
424 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
425 },
426/* call $addr16cjp */
427 {
428 IP2K_INSN_CALL, "call", "call", 16,
429 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
430 },
431/* sb $fr,$bitno */
432 {
433 IP2K_INSN_SB, "sb", "sb", 16,
434 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
435 },
436/* snb $fr,$bitno */
437 {
438 IP2K_INSN_SNB, "snb", "snb", 16,
439 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
440 },
441/* setb $fr,$bitno */
442 {
443 IP2K_INSN_SETB, "setb", "setb", 16,
444 { 0, { (1<<MACH_BASE) } }
445 },
446/* clrb $fr,$bitno */
447 {
448 IP2K_INSN_CLRB, "clrb", "clrb", 16,
449 { 0, { (1<<MACH_BASE) } }
450 },
451/* xor W,#$lit8 */
452 {
453 IP2K_INSN_XORW_L, "xorw_l", "xor", 16,
454 { 0, { (1<<MACH_BASE) } }
455 },
456/* and W,#$lit8 */
457 {
458 IP2K_INSN_ANDW_L, "andw_l", "and", 16,
459 { 0, { (1<<MACH_BASE) } }
460 },
461/* or W,#$lit8 */
462 {
463 IP2K_INSN_ORW_L, "orw_l", "or", 16,
464 { 0, { (1<<MACH_BASE) } }
465 },
466/* add W,#$lit8 */
467 {
468 IP2K_INSN_ADDW_L, "addw_l", "add", 16,
469 { 0, { (1<<MACH_BASE) } }
470 },
471/* sub W,#$lit8 */
472 {
473 IP2K_INSN_SUBW_L, "subw_l", "sub", 16,
474 { 0, { (1<<MACH_BASE) } }
475 },
476/* cmp W,#$lit8 */
477 {
478 IP2K_INSN_CMPW_L, "cmpw_l", "cmp", 16,
479 { 0, { (1<<MACH_BASE) } }
480 },
481/* retw #$lit8 */
482 {
483 IP2K_INSN_RETW_L, "retw_l", "retw", 16,
484 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
485 },
486/* cse W,#$lit8 */
487 {
488 IP2K_INSN_CSEW_L, "csew_l", "cse", 16,
489 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
490 },
491/* csne W,#$lit8 */
492 {
493 IP2K_INSN_CSNEW_L, "csnew_l", "csne", 16,
494 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
495 },
496/* push #$lit8 */
497 {
498 IP2K_INSN_PUSH_L, "push_l", "push", 16,
499 { 0, { (1<<MACH_BASE) } }
500 },
501/* muls W,#$lit8 */
502 {
503 IP2K_INSN_MULSW_L, "mulsw_l", "muls", 16,
504 { 0, { (1<<MACH_BASE) } }
505 },
506/* mulu W,#$lit8 */
507 {
508 IP2K_INSN_MULUW_L, "muluw_l", "mulu", 16,
509 { 0, { (1<<MACH_BASE) } }
510 },
511/* loadl #$lit8 */
512 {
513 IP2K_INSN_LOADL_L, "loadl_l", "loadl", 16,
514 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
515 },
516/* loadh #$lit8 */
517 {
518 IP2K_INSN_LOADH_L, "loadh_l", "loadh", 16,
519 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
520 },
521/* loadl $addr16l */
522 {
523 IP2K_INSN_LOADL_A, "loadl_a", "loadl", 16,
524 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
525 },
526/* loadh $addr16h */
527 {
528 IP2K_INSN_LOADH_A, "loadh_a", "loadh", 16,
529 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
530 },
531/* addc $fr,W */
532 {
533 IP2K_INSN_ADDCFR_W, "addcfr_w", "addc", 16,
534 { 0, { (1<<MACH_BASE) } }
535 },
536/* addc W,$fr */
537 {
538 IP2K_INSN_ADDCW_FR, "addcw_fr", "addc", 16,
539 { 0, { (1<<MACH_BASE) } }
540 },
541/* incsnz $fr */
542 {
543 IP2K_INSN_INCSNZ_FR, "incsnz_fr", "incsnz", 16,
544 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
545 },
546/* incsnz W,$fr */
547 {
548 IP2K_INSN_INCSNZW_FR, "incsnzw_fr", "incsnz", 16,
549 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
550 },
551/* muls W,$fr */
552 {
553 IP2K_INSN_MULSW_FR, "mulsw_fr", "muls", 16,
554 { 0, { (1<<MACH_BASE) } }
555 },
556/* mulu W,$fr */
557 {
558 IP2K_INSN_MULUW_FR, "muluw_fr", "mulu", 16,
559 { 0, { (1<<MACH_BASE) } }
560 },
561/* decsnz $fr */
562 {
563 IP2K_INSN_DECSNZ_FR, "decsnz_fr", "decsnz", 16,
564 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
565 },
566/* decsnz W,$fr */
567 {
568 IP2K_INSN_DECSNZW_FR, "decsnzw_fr", "decsnz", 16,
569 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
570 },
571/* subc W,$fr */
572 {
573 IP2K_INSN_SUBCW_FR, "subcw_fr", "subc", 16,
574 { 0, { (1<<MACH_BASE) } }
575 },
576/* subc $fr,W */
577 {
578 IP2K_INSN_SUBCFR_W, "subcfr_w", "subc", 16,
579 { 0, { (1<<MACH_BASE) } }
580 },
581/* pop $fr */
582 {
583 IP2K_INSN_POP_FR, "pop_fr", "pop", 16,
584 { 0, { (1<<MACH_BASE) } }
585 },
586/* push $fr */
587 {
588 IP2K_INSN_PUSH_FR, "push_fr", "push", 16,
589 { 0, { (1<<MACH_BASE) } }
590 },
591/* cse W,$fr */
592 {
593 IP2K_INSN_CSEW_FR, "csew_fr", "cse", 16,
594 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
595 },
596/* csne W,$fr */
597 {
598 IP2K_INSN_CSNEW_FR, "csnew_fr", "csne", 16,
599 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
600 },
601/* incsz $fr */
602 {
603 IP2K_INSN_INCSZ_FR, "incsz_fr", "incsz", 16,
604 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
605 },
606/* incsz W,$fr */
607 {
608 IP2K_INSN_INCSZW_FR, "incszw_fr", "incsz", 16,
609 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
610 },
611/* swap $fr */
612 {
613 IP2K_INSN_SWAP_FR, "swap_fr", "swap", 16,
614 { 0, { (1<<MACH_BASE) } }
615 },
616/* swap W,$fr */
617 {
618 IP2K_INSN_SWAPW_FR, "swapw_fr", "swap", 16,
619 { 0, { (1<<MACH_BASE) } }
620 },
621/* rl $fr */
622 {
623 IP2K_INSN_RL_FR, "rl_fr", "rl", 16,
624 { 0, { (1<<MACH_BASE) } }
625 },
626/* rl W,$fr */
627 {
628 IP2K_INSN_RLW_FR, "rlw_fr", "rl", 16,
629 { 0, { (1<<MACH_BASE) } }
630 },
631/* rr $fr */
632 {
633 IP2K_INSN_RR_FR, "rr_fr", "rr", 16,
634 { 0, { (1<<MACH_BASE) } }
635 },
636/* rr W,$fr */
637 {
638 IP2K_INSN_RRW_FR, "rrw_fr", "rr", 16,
639 { 0, { (1<<MACH_BASE) } }
640 },
641/* decsz $fr */
642 {
643 IP2K_INSN_DECSZ_FR, "decsz_fr", "decsz", 16,
644 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
645 },
646/* decsz W,$fr */
647 {
648 IP2K_INSN_DECSZW_FR, "decszw_fr", "decsz", 16,
649 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
650 },
651/* inc $fr */
652 {
653 IP2K_INSN_INC_FR, "inc_fr", "inc", 16,
654 { 0, { (1<<MACH_BASE) } }
655 },
656/* inc W,$fr */
657 {
658 IP2K_INSN_INCW_FR, "incw_fr", "inc", 16,
659 { 0, { (1<<MACH_BASE) } }
660 },
661/* not $fr */
662 {
663 IP2K_INSN_NOT_FR, "not_fr", "not", 16,
664 { 0, { (1<<MACH_BASE) } }
665 },
666/* not W,$fr */
667 {
668 IP2K_INSN_NOTW_FR, "notw_fr", "not", 16,
669 { 0, { (1<<MACH_BASE) } }
670 },
671/* test $fr */
672 {
673 IP2K_INSN_TEST_FR, "test_fr", "test", 16,
674 { 0, { (1<<MACH_BASE) } }
675 },
676/* mov W,#$lit8 */
677 {
678 IP2K_INSN_MOVW_L, "movw_l", "mov", 16,
679 { 0, { (1<<MACH_BASE) } }
680 },
681/* mov $fr,W */
682 {
683 IP2K_INSN_MOVFR_W, "movfr_w", "mov", 16,
684 { 0, { (1<<MACH_BASE) } }
685 },
686/* mov W,$fr */
687 {
688 IP2K_INSN_MOVW_FR, "movw_fr", "mov", 16,
689 { 0, { (1<<MACH_BASE) } }
690 },
691/* add $fr,W */
692 {
693 IP2K_INSN_ADDFR_W, "addfr_w", "add", 16,
694 { 0, { (1<<MACH_BASE) } }
695 },
696/* add W,$fr */
697 {
698 IP2K_INSN_ADDW_FR, "addw_fr", "add", 16,
699 { 0, { (1<<MACH_BASE) } }
700 },
701/* xor $fr,W */
702 {
703 IP2K_INSN_XORFR_W, "xorfr_w", "xor", 16,
704 { 0, { (1<<MACH_BASE) } }
705 },
706/* xor W,$fr */
707 {
708 IP2K_INSN_XORW_FR, "xorw_fr", "xor", 16,
709 { 0, { (1<<MACH_BASE) } }
710 },
711/* and $fr,W */
712 {
713 IP2K_INSN_ANDFR_W, "andfr_w", "and", 16,
714 { 0, { (1<<MACH_BASE) } }
715 },
716/* and W,$fr */
717 {
718 IP2K_INSN_ANDW_FR, "andw_fr", "and", 16,
719 { 0, { (1<<MACH_BASE) } }
720 },
721/* or $fr,W */
722 {
723 IP2K_INSN_ORFR_W, "orfr_w", "or", 16,
724 { 0, { (1<<MACH_BASE) } }
725 },
726/* or W,$fr */
727 {
728 IP2K_INSN_ORW_FR, "orw_fr", "or", 16,
729 { 0, { (1<<MACH_BASE) } }
730 },
731/* dec $fr */
732 {
733 IP2K_INSN_DEC_FR, "dec_fr", "dec", 16,
734 { 0, { (1<<MACH_BASE) } }
735 },
736/* dec W,$fr */
737 {
738 IP2K_INSN_DECW_FR, "decw_fr", "dec", 16,
739 { 0, { (1<<MACH_BASE) } }
740 },
741/* sub $fr,W */
742 {
743 IP2K_INSN_SUBFR_W, "subfr_w", "sub", 16,
744 { 0, { (1<<MACH_BASE) } }
745 },
746/* sub W,$fr */
747 {
748 IP2K_INSN_SUBW_FR, "subw_fr", "sub", 16,
749 { 0, { (1<<MACH_BASE) } }
750 },
751/* clr $fr */
752 {
753 IP2K_INSN_CLR_FR, "clr_fr", "clr", 16,
754 { 0, { (1<<MACH_BASE) } }
755 },
756/* cmp W,$fr */
757 {
758 IP2K_INSN_CMPW_FR, "cmpw_fr", "cmp", 16,
759 { 0, { (1<<MACH_BASE) } }
760 },
761/* speed #$lit8 */
762 {
763 IP2K_INSN_SPEED, "speed", "speed", 16,
764 { 0, { (1<<MACH_BASE) } }
765 },
766/* ireadi */
767 {
768 IP2K_INSN_IREADI, "ireadi", "ireadi", 16,
769 { 0, { (1<<MACH_BASE) } }
770 },
771/* iwritei */
772 {
773 IP2K_INSN_IWRITEI, "iwritei", "iwritei", 16,
774 { 0, { (1<<MACH_BASE) } }
775 },
776/* fread */
777 {
778 IP2K_INSN_FREAD, "fread", "fread", 16,
779 { 0, { (1<<MACH_BASE) } }
780 },
781/* fwrite */
782 {
783 IP2K_INSN_FWRITE, "fwrite", "fwrite", 16,
784 { 0, { (1<<MACH_BASE) } }
785 },
786/* iread */
787 {
788 IP2K_INSN_IREAD, "iread", "iread", 16,
789 { 0, { (1<<MACH_BASE) } }
790 },
791/* iwrite */
792 {
793 IP2K_INSN_IWRITE, "iwrite", "iwrite", 16,
794 { 0, { (1<<MACH_BASE) } }
795 },
796/* page $addr16p */
797 {
798 IP2K_INSN_PAGE, "page", "page", 16,
799 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
800 },
801/* system */
802 {
803 IP2K_INSN_SYSTEM, "system", "system", 16,
804 { 0, { (1<<MACH_BASE) } }
805 },
806/* reti #$reti3 */
807 {
808 IP2K_INSN_RETI, "reti", "reti", 16,
809 { 0, { (1<<MACH_BASE) } }
810 },
811/* ret */
812 {
813 IP2K_INSN_RET, "ret", "ret", 16,
814 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
815 },
816/* int */
817 {
818 IP2K_INSN_INT, "int", "int", 16,
819 { 0, { (1<<MACH_BASE) } }
820 },
821/* breakx */
822 {
823 IP2K_INSN_BREAKX, "breakx", "breakx", 16,
824 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
825 },
826/* cwdt */
827 {
828 IP2K_INSN_CWDT, "cwdt", "cwdt", 16,
829 { 0, { (1<<MACH_BASE) } }
830 },
831/* ferase */
832 {
833 IP2K_INSN_FERASE, "ferase", "ferase", 16,
834 { 0, { (1<<MACH_BASE) } }
835 },
836/* retnp */
837 {
838 IP2K_INSN_RETNP, "retnp", "retnp", 16,
839 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
840 },
841/* break */
842 {
843 IP2K_INSN_BREAK, "break", "break", 16,
844 { 0, { (1<<MACH_BASE) } }
845 },
846/* nop */
847 {
848 IP2K_INSN_NOP, "nop", "nop", 16,
849 { 0, { (1<<MACH_BASE) } }
850 },
851};
852
853#undef OP
854#undef A
855
856/* Initialize anything needed to be done once, before any cpu_open call. */
857static void init_tables PARAMS ((void));
858
859static void
860init_tables ()
861{
862}
863
864static const CGEN_MACH * lookup_mach_via_bfd_name
865 PARAMS ((const CGEN_MACH *, const char *));
866static void build_hw_table PARAMS ((CGEN_CPU_TABLE *));
867static void build_ifield_table PARAMS ((CGEN_CPU_TABLE *));
868static void build_operand_table PARAMS ((CGEN_CPU_TABLE *));
869static void build_insn_table PARAMS ((CGEN_CPU_TABLE *));
870static void ip2k_cgen_rebuild_tables PARAMS ((CGEN_CPU_TABLE *));
871
872/* Subroutine of ip2k_cgen_cpu_open to look up a mach via its bfd name. */
873
874static const CGEN_MACH *
875lookup_mach_via_bfd_name (table, name)
876 const CGEN_MACH *table;
877 const char *name;
878{
879 while (table->name)
880 {
881 if (strcmp (name, table->bfd_name) == 0)
882 return table;
883 ++table;
884 }
885 abort ();
886}
887
888/* Subroutine of ip2k_cgen_cpu_open to build the hardware table. */
889
890static void
891build_hw_table (cd)
892 CGEN_CPU_TABLE *cd;
893{
894 int i;
895 int machs = cd->machs;
896 const CGEN_HW_ENTRY *init = & ip2k_cgen_hw_table[0];
897 /* MAX_HW is only an upper bound on the number of selected entries.
898 However each entry is indexed by it's enum so there can be holes in
899 the table. */
900 const CGEN_HW_ENTRY **selected =
901 (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
902
903 cd->hw_table.init_entries = init;
904 cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
905 memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
906 /* ??? For now we just use machs to determine which ones we want. */
907 for (i = 0; init[i].name != NULL; ++i)
908 if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
909 & machs)
910 selected[init[i].type] = &init[i];
911 cd->hw_table.entries = selected;
912 cd->hw_table.num_entries = MAX_HW;
913}
914
915/* Subroutine of ip2k_cgen_cpu_open to build the hardware table. */
916
917static void
918build_ifield_table (cd)
919 CGEN_CPU_TABLE *cd;
920{
921 cd->ifld_table = & ip2k_cgen_ifld_table[0];
922}
923
924/* Subroutine of ip2k_cgen_cpu_open to build the hardware table. */
925
926static void
927build_operand_table (cd)
928 CGEN_CPU_TABLE *cd;
929{
930 int i;
931 int machs = cd->machs;
932 const CGEN_OPERAND *init = & ip2k_cgen_operand_table[0];
933 /* MAX_OPERANDS is only an upper bound on the number of selected entries.
934 However each entry is indexed by it's enum so there can be holes in
935 the table. */
936 const CGEN_OPERAND **selected =
937 (const CGEN_OPERAND **) xmalloc (MAX_OPERANDS * sizeof (CGEN_OPERAND *));
938
939 cd->operand_table.init_entries = init;
940 cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
941 memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
942 /* ??? For now we just use mach to determine which ones we want. */
943 for (i = 0; init[i].name != NULL; ++i)
944 if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
945 & machs)
946 selected[init[i].type] = &init[i];
947 cd->operand_table.entries = selected;
948 cd->operand_table.num_entries = MAX_OPERANDS;
949}
950
951/* Subroutine of ip2k_cgen_cpu_open to build the hardware table.
952 ??? This could leave out insns not supported by the specified mach/isa,
953 but that would cause errors like "foo only supported by bar" to become
954 "unknown insn", so for now we include all insns and require the app to
955 do the checking later.
956 ??? On the other hand, parsing of such insns may require their hardware or
957 operand elements to be in the table [which they mightn't be]. */
958
959static void
960build_insn_table (cd)
961 CGEN_CPU_TABLE *cd;
962{
963 int i;
964 const CGEN_IBASE *ib = & ip2k_cgen_insn_table[0];
965 CGEN_INSN *insns = (CGEN_INSN *) xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
966
967 memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
968 for (i = 0; i < MAX_INSNS; ++i)
969 insns[i].base = &ib[i];
970 cd->insn_table.init_entries = insns;
971 cd->insn_table.entry_size = sizeof (CGEN_IBASE);
972 cd->insn_table.num_init_entries = MAX_INSNS;
973}
974
975/* Subroutine of ip2k_cgen_cpu_open to rebuild the tables. */
976
977static void
978ip2k_cgen_rebuild_tables (cd)
979 CGEN_CPU_TABLE *cd;
980{
981 int i;
982 unsigned int isas = cd->isas;
983 unsigned int machs = cd->machs;
984
985 cd->int_insn_p = CGEN_INT_INSN_P;
986
987 /* Data derived from the isa spec. */
988#define UNSET (CGEN_SIZE_UNKNOWN + 1)
989 cd->default_insn_bitsize = UNSET;
990 cd->base_insn_bitsize = UNSET;
991 cd->min_insn_bitsize = 65535; /* some ridiculously big number */
992 cd->max_insn_bitsize = 0;
993 for (i = 0; i < MAX_ISAS; ++i)
994 if (((1 << i) & isas) != 0)
995 {
996 const CGEN_ISA *isa = & ip2k_cgen_isa_table[i];
997
998 /* Default insn sizes of all selected isas must be
999 equal or we set the result to 0, meaning "unknown". */
1000 if (cd->default_insn_bitsize == UNSET)
1001 cd->default_insn_bitsize = isa->default_insn_bitsize;
1002 else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
1003 ; /* this is ok */
1004 else
1005 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
1006
1007 /* Base insn sizes of all selected isas must be equal
1008 or we set the result to 0, meaning "unknown". */
1009 if (cd->base_insn_bitsize == UNSET)
1010 cd->base_insn_bitsize = isa->base_insn_bitsize;
1011 else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
1012 ; /* this is ok */
1013 else
1014 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
1015
1016 /* Set min,max insn sizes. */
1017 if (isa->min_insn_bitsize < cd->min_insn_bitsize)
1018 cd->min_insn_bitsize = isa->min_insn_bitsize;
1019 if (isa->max_insn_bitsize > cd->max_insn_bitsize)
1020 cd->max_insn_bitsize = isa->max_insn_bitsize;
1021 }
1022
1023 /* Data derived from the mach spec. */
1024 for (i = 0; i < MAX_MACHS; ++i)
1025 if (((1 << i) & machs) != 0)
1026 {
1027 const CGEN_MACH *mach = & ip2k_cgen_mach_table[i];
1028
1029 if (mach->insn_chunk_bitsize != 0)
1030 {
1031 if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
1032 {
1033 fprintf (stderr, "ip2k_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
1034 cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
1035 abort ();
1036 }
1037
1038 cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
1039 }
1040 }
1041
1042 /* Determine which hw elements are used by MACH. */
1043 build_hw_table (cd);
1044
1045 /* Build the ifield table. */
1046 build_ifield_table (cd);
1047
1048 /* Determine which operands are used by MACH/ISA. */
1049 build_operand_table (cd);
1050
1051 /* Build the instruction table. */
1052 build_insn_table (cd);
1053}
1054
1055/* Initialize a cpu table and return a descriptor.
1056 It's much like opening a file, and must be the first function called.
1057 The arguments are a set of (type/value) pairs, terminated with
1058 CGEN_CPU_OPEN_END.
1059
1060 Currently supported values:
1061 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
1062 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
1063 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
1064 CGEN_CPU_OPEN_ENDIAN: specify endian choice
1065 CGEN_CPU_OPEN_END: terminates arguments
1066
1067 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
1068 precluded.
1069
1070 ??? We only support ISO C stdargs here, not K&R.
1071 Laziness, plus experiment to see if anything requires K&R - eventually
1072 K&R will no longer be supported - e.g. GDB is currently trying this. */
1073
1074CGEN_CPU_DESC
1075ip2k_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
1076{
1077 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
1078 static int init_p;
1079 unsigned int isas = 0; /* 0 = "unspecified" */
1080 unsigned int machs = 0; /* 0 = "unspecified" */
1081 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
1082 va_list ap;
1083
1084 if (! init_p)
1085 {
1086 init_tables ();
1087 init_p = 1;
1088 }
1089
1090 memset (cd, 0, sizeof (*cd));
1091
1092 va_start (ap, arg_type);
1093 while (arg_type != CGEN_CPU_OPEN_END)
1094 {
1095 switch (arg_type)
1096 {
1097 case CGEN_CPU_OPEN_ISAS :
1098 isas = va_arg (ap, unsigned int);
1099 break;
1100 case CGEN_CPU_OPEN_MACHS :
1101 machs = va_arg (ap, unsigned int);
1102 break;
1103 case CGEN_CPU_OPEN_BFDMACH :
1104 {
1105 const char *name = va_arg (ap, const char *);
1106 const CGEN_MACH *mach =
1107 lookup_mach_via_bfd_name (ip2k_cgen_mach_table, name);
1108
1109 machs |= 1 << mach->num;
1110 break;
1111 }
1112 case CGEN_CPU_OPEN_ENDIAN :
1113 endian = va_arg (ap, enum cgen_endian);
1114 break;
1115 default :
1116 fprintf (stderr, "ip2k_cgen_cpu_open: unsupported argument `%d'\n",
1117 arg_type);
1118 abort (); /* ??? return NULL? */
1119 }
1120 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
1121 }
1122 va_end (ap);
1123
1124 /* mach unspecified means "all" */
1125 if (machs == 0)
1126 machs = (1 << MAX_MACHS) - 1;
1127 /* base mach is always selected */
1128 machs |= 1;
1129 /* isa unspecified means "all" */
1130 if (isas == 0)
1131 isas = (1 << MAX_ISAS) - 1;
1132 if (endian == CGEN_ENDIAN_UNKNOWN)
1133 {
1134 /* ??? If target has only one, could have a default. */
1135 fprintf (stderr, "ip2k_cgen_cpu_open: no endianness specified\n");
1136 abort ();
1137 }
1138
1139 cd->isas = isas;
1140 cd->machs = machs;
1141 cd->endian = endian;
1142 /* FIXME: for the sparc case we can determine insn-endianness statically.
1143 The worry here is where both data and insn endian can be independently
1144 chosen, in which case this function will need another argument.
1145 Actually, will want to allow for more arguments in the future anyway. */
1146 cd->insn_endian = endian;
1147
1148 /* Table (re)builder. */
1149 cd->rebuild_tables = ip2k_cgen_rebuild_tables;
1150 ip2k_cgen_rebuild_tables (cd);
1151
1152 /* Default to not allowing signed overflow. */
1153 cd->signed_overflow_ok_p = 0;
1154
1155 return (CGEN_CPU_DESC) cd;
1156}
1157
1158/* Cover fn to ip2k_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
1159 MACH_NAME is the bfd name of the mach. */
1160
1161CGEN_CPU_DESC
1162ip2k_cgen_cpu_open_1 (mach_name, endian)
1163 const char *mach_name;
1164 enum cgen_endian endian;
1165{
1166 return ip2k_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
1167 CGEN_CPU_OPEN_ENDIAN, endian,
1168 CGEN_CPU_OPEN_END);
1169}
1170
1171/* Close a cpu table.
1172 ??? This can live in a machine independent file, but there's currently
1173 no place to put this file (there's no libcgen). libopcodes is the wrong
1174 place as some simulator ports use this but they don't use libopcodes. */
1175
1176void
1177ip2k_cgen_cpu_close (cd)
1178 CGEN_CPU_DESC cd;
1179{
1180 unsigned int i;
1181 CGEN_INSN *insns;
1182
1183 if (cd->macro_insn_table.init_entries)
1184 {
1185 insns = cd->macro_insn_table.init_entries;
1186 for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
1187 {
1188 if (CGEN_INSN_RX ((insns)))
1189 regfree(CGEN_INSN_RX (insns));
1190 }
1191 }
1192
1193 if (cd->insn_table.init_entries)
1194 {
1195 insns = cd->insn_table.init_entries;
1196 for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
1197 {
1198 if (CGEN_INSN_RX (insns))
1199 regfree(CGEN_INSN_RX (insns));
1200 }
1201 }
1202
1203
1204
1205 if (cd->macro_insn_table.init_entries)
1206 free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
1207
1208 if (cd->insn_table.init_entries)
1209 free ((CGEN_INSN *) cd->insn_table.init_entries);
1210
1211 if (cd->hw_table.entries)
1212 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1213
1214 if (cd->operand_table.entries)
1215 free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
1216
1217 free (cd);
1218}
1219
This page took 0.085734 seconds and 4 git commands to generate.