Fix assembly of "callt 0x3f"
[binutils.git] / opcodes / ip2k-desc.c
bloba676e77670dc3484234fbef244f3ded13445457c
1 /* CPU data for ip2k.
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)
12 any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License along
20 with this program; if not, write to the Free Software Foundation, Inc.,
21 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include "sysdep.h"
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include "ansidecl.h"
29 #include "bfd.h"
30 #include "symcat.h"
31 #include "ip2k-desc.h"
32 #include "ip2k-opc.h"
33 #include "opintl.h"
34 #include "libiberty.h"
36 /* Attributes. */
38 static const CGEN_ATTR_ENTRY bool_attr[] =
40 { "#f", 0 },
41 { "#t", 1 },
42 { 0, 0 }
45 static const CGEN_ATTR_ENTRY MACH_attr[] =
47 { "base", MACH_BASE },
48 { "ip2022", MACH_IP2022 },
49 { "ip2022ext", MACH_IP2022EXT },
50 { "max", MACH_MAX },
51 { 0, 0 }
54 static const CGEN_ATTR_ENTRY ISA_attr[] =
56 { "ip2k", ISA_IP2K },
57 { "max", ISA_MAX },
58 { 0, 0 }
61 const CGEN_ATTR_TABLE ip2k_cgen_ifield_attr_table[] =
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 }
73 const CGEN_ATTR_TABLE ip2k_cgen_hardware_attr_table[] =
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 }
83 const CGEN_ATTR_TABLE ip2k_cgen_operand_attr_table[] =
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 }
97 const CGEN_ATTR_TABLE ip2k_cgen_insn_attr_table[] =
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 }
115 /* Instruction set variants. */
117 static const CGEN_ISA ip2k_cgen_isa_table[] = {
118 { "ip2k", 16, 16, 16, 16 },
119 { 0, 0, 0, 0, 0 }
122 /* Machine variants. */
124 static const CGEN_MACH ip2k_cgen_mach_table[] = {
125 { "ip2022", "ip2022", MACH_IP2022, 0 },
126 { "ip2022ext", "ip2022ext", MACH_IP2022EXT, 0 },
127 { 0, 0, 0, 0 }
130 static CGEN_KEYWORD_ENTRY ip2k_cgen_opval_register_names_entries[] =
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 }
255 CGEN_KEYWORD ip2k_cgen_opval_register_names =
257 & ip2k_cgen_opval_register_names_entries[0],
258 121,
259 0, 0, 0, 0, ""
263 /* The hardware table. */
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
271 const CGEN_HW_ENTRY ip2k_cgen_hw_table[] =
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}} }
289 #undef A
292 /* The instruction field table. */
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
300 const CGEN_IFLD ip2k_cgen_ifld_table[] =
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}} }
322 #undef A
326 /* multi ifield declarations */
330 /* multi ifield definitions */
333 /* The operand table. */
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
346 const CGEN_OPERAND ip2k_cgen_operand_table[] =
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}} }
403 #undef A
406 /* The instruction table. */
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
415 static const CGEN_IBASE ip2k_cgen_insn_table[MAX_INSNS] =
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 */
423 IP2K_INSN_JMP, "jmp", "jmp", 16,
424 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
426 /* call $addr16cjp */
428 IP2K_INSN_CALL, "call", "call", 16,
429 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
431 /* sb $fr,$bitno */
433 IP2K_INSN_SB, "sb", "sb", 16,
434 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
436 /* snb $fr,$bitno */
438 IP2K_INSN_SNB, "snb", "snb", 16,
439 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
441 /* setb $fr,$bitno */
443 IP2K_INSN_SETB, "setb", "setb", 16,
444 { 0, { (1<<MACH_BASE) } }
446 /* clrb $fr,$bitno */
448 IP2K_INSN_CLRB, "clrb", "clrb", 16,
449 { 0, { (1<<MACH_BASE) } }
451 /* xor W,#$lit8 */
453 IP2K_INSN_XORW_L, "xorw_l", "xor", 16,
454 { 0, { (1<<MACH_BASE) } }
456 /* and W,#$lit8 */
458 IP2K_INSN_ANDW_L, "andw_l", "and", 16,
459 { 0, { (1<<MACH_BASE) } }
461 /* or W,#$lit8 */
463 IP2K_INSN_ORW_L, "orw_l", "or", 16,
464 { 0, { (1<<MACH_BASE) } }
466 /* add W,#$lit8 */
468 IP2K_INSN_ADDW_L, "addw_l", "add", 16,
469 { 0, { (1<<MACH_BASE) } }
471 /* sub W,#$lit8 */
473 IP2K_INSN_SUBW_L, "subw_l", "sub", 16,
474 { 0, { (1<<MACH_BASE) } }
476 /* cmp W,#$lit8 */
478 IP2K_INSN_CMPW_L, "cmpw_l", "cmp", 16,
479 { 0, { (1<<MACH_BASE) } }
481 /* retw #$lit8 */
483 IP2K_INSN_RETW_L, "retw_l", "retw", 16,
484 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
486 /* cse W,#$lit8 */
488 IP2K_INSN_CSEW_L, "csew_l", "cse", 16,
489 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
491 /* csne W,#$lit8 */
493 IP2K_INSN_CSNEW_L, "csnew_l", "csne", 16,
494 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
496 /* push #$lit8 */
498 IP2K_INSN_PUSH_L, "push_l", "push", 16,
499 { 0, { (1<<MACH_BASE) } }
501 /* muls W,#$lit8 */
503 IP2K_INSN_MULSW_L, "mulsw_l", "muls", 16,
504 { 0, { (1<<MACH_BASE) } }
506 /* mulu W,#$lit8 */
508 IP2K_INSN_MULUW_L, "muluw_l", "mulu", 16,
509 { 0, { (1<<MACH_BASE) } }
511 /* loadl #$lit8 */
513 IP2K_INSN_LOADL_L, "loadl_l", "loadl", 16,
514 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
516 /* loadh #$lit8 */
518 IP2K_INSN_LOADH_L, "loadh_l", "loadh", 16,
519 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
521 /* loadl $addr16l */
523 IP2K_INSN_LOADL_A, "loadl_a", "loadl", 16,
524 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
526 /* loadh $addr16h */
528 IP2K_INSN_LOADH_A, "loadh_a", "loadh", 16,
529 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
531 /* addc $fr,W */
533 IP2K_INSN_ADDCFR_W, "addcfr_w", "addc", 16,
534 { 0, { (1<<MACH_BASE) } }
536 /* addc W,$fr */
538 IP2K_INSN_ADDCW_FR, "addcw_fr", "addc", 16,
539 { 0, { (1<<MACH_BASE) } }
541 /* incsnz $fr */
543 IP2K_INSN_INCSNZ_FR, "incsnz_fr", "incsnz", 16,
544 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
546 /* incsnz W,$fr */
548 IP2K_INSN_INCSNZW_FR, "incsnzw_fr", "incsnz", 16,
549 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
551 /* muls W,$fr */
553 IP2K_INSN_MULSW_FR, "mulsw_fr", "muls", 16,
554 { 0, { (1<<MACH_BASE) } }
556 /* mulu W,$fr */
558 IP2K_INSN_MULUW_FR, "muluw_fr", "mulu", 16,
559 { 0, { (1<<MACH_BASE) } }
561 /* decsnz $fr */
563 IP2K_INSN_DECSNZ_FR, "decsnz_fr", "decsnz", 16,
564 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
566 /* decsnz W,$fr */
568 IP2K_INSN_DECSNZW_FR, "decsnzw_fr", "decsnz", 16,
569 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
571 /* subc W,$fr */
573 IP2K_INSN_SUBCW_FR, "subcw_fr", "subc", 16,
574 { 0, { (1<<MACH_BASE) } }
576 /* subc $fr,W */
578 IP2K_INSN_SUBCFR_W, "subcfr_w", "subc", 16,
579 { 0, { (1<<MACH_BASE) } }
581 /* pop $fr */
583 IP2K_INSN_POP_FR, "pop_fr", "pop", 16,
584 { 0, { (1<<MACH_BASE) } }
586 /* push $fr */
588 IP2K_INSN_PUSH_FR, "push_fr", "push", 16,
589 { 0, { (1<<MACH_BASE) } }
591 /* cse W,$fr */
593 IP2K_INSN_CSEW_FR, "csew_fr", "cse", 16,
594 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
596 /* csne W,$fr */
598 IP2K_INSN_CSNEW_FR, "csnew_fr", "csne", 16,
599 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
601 /* incsz $fr */
603 IP2K_INSN_INCSZ_FR, "incsz_fr", "incsz", 16,
604 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
606 /* incsz W,$fr */
608 IP2K_INSN_INCSZW_FR, "incszw_fr", "incsz", 16,
609 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
611 /* swap $fr */
613 IP2K_INSN_SWAP_FR, "swap_fr", "swap", 16,
614 { 0, { (1<<MACH_BASE) } }
616 /* swap W,$fr */
618 IP2K_INSN_SWAPW_FR, "swapw_fr", "swap", 16,
619 { 0, { (1<<MACH_BASE) } }
621 /* rl $fr */
623 IP2K_INSN_RL_FR, "rl_fr", "rl", 16,
624 { 0, { (1<<MACH_BASE) } }
626 /* rl W,$fr */
628 IP2K_INSN_RLW_FR, "rlw_fr", "rl", 16,
629 { 0, { (1<<MACH_BASE) } }
631 /* rr $fr */
633 IP2K_INSN_RR_FR, "rr_fr", "rr", 16,
634 { 0, { (1<<MACH_BASE) } }
636 /* rr W,$fr */
638 IP2K_INSN_RRW_FR, "rrw_fr", "rr", 16,
639 { 0, { (1<<MACH_BASE) } }
641 /* decsz $fr */
643 IP2K_INSN_DECSZ_FR, "decsz_fr", "decsz", 16,
644 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
646 /* decsz W,$fr */
648 IP2K_INSN_DECSZW_FR, "decszw_fr", "decsz", 16,
649 { 0|A(SKIP_CTI), { (1<<MACH_BASE) } }
651 /* inc $fr */
653 IP2K_INSN_INC_FR, "inc_fr", "inc", 16,
654 { 0, { (1<<MACH_BASE) } }
656 /* inc W,$fr */
658 IP2K_INSN_INCW_FR, "incw_fr", "inc", 16,
659 { 0, { (1<<MACH_BASE) } }
661 /* not $fr */
663 IP2K_INSN_NOT_FR, "not_fr", "not", 16,
664 { 0, { (1<<MACH_BASE) } }
666 /* not W,$fr */
668 IP2K_INSN_NOTW_FR, "notw_fr", "not", 16,
669 { 0, { (1<<MACH_BASE) } }
671 /* test $fr */
673 IP2K_INSN_TEST_FR, "test_fr", "test", 16,
674 { 0, { (1<<MACH_BASE) } }
676 /* mov W,#$lit8 */
678 IP2K_INSN_MOVW_L, "movw_l", "mov", 16,
679 { 0, { (1<<MACH_BASE) } }
681 /* mov $fr,W */
683 IP2K_INSN_MOVFR_W, "movfr_w", "mov", 16,
684 { 0, { (1<<MACH_BASE) } }
686 /* mov W,$fr */
688 IP2K_INSN_MOVW_FR, "movw_fr", "mov", 16,
689 { 0, { (1<<MACH_BASE) } }
691 /* add $fr,W */
693 IP2K_INSN_ADDFR_W, "addfr_w", "add", 16,
694 { 0, { (1<<MACH_BASE) } }
696 /* add W,$fr */
698 IP2K_INSN_ADDW_FR, "addw_fr", "add", 16,
699 { 0, { (1<<MACH_BASE) } }
701 /* xor $fr,W */
703 IP2K_INSN_XORFR_W, "xorfr_w", "xor", 16,
704 { 0, { (1<<MACH_BASE) } }
706 /* xor W,$fr */
708 IP2K_INSN_XORW_FR, "xorw_fr", "xor", 16,
709 { 0, { (1<<MACH_BASE) } }
711 /* and $fr,W */
713 IP2K_INSN_ANDFR_W, "andfr_w", "and", 16,
714 { 0, { (1<<MACH_BASE) } }
716 /* and W,$fr */
718 IP2K_INSN_ANDW_FR, "andw_fr", "and", 16,
719 { 0, { (1<<MACH_BASE) } }
721 /* or $fr,W */
723 IP2K_INSN_ORFR_W, "orfr_w", "or", 16,
724 { 0, { (1<<MACH_BASE) } }
726 /* or W,$fr */
728 IP2K_INSN_ORW_FR, "orw_fr", "or", 16,
729 { 0, { (1<<MACH_BASE) } }
731 /* dec $fr */
733 IP2K_INSN_DEC_FR, "dec_fr", "dec", 16,
734 { 0, { (1<<MACH_BASE) } }
736 /* dec W,$fr */
738 IP2K_INSN_DECW_FR, "decw_fr", "dec", 16,
739 { 0, { (1<<MACH_BASE) } }
741 /* sub $fr,W */
743 IP2K_INSN_SUBFR_W, "subfr_w", "sub", 16,
744 { 0, { (1<<MACH_BASE) } }
746 /* sub W,$fr */
748 IP2K_INSN_SUBW_FR, "subw_fr", "sub", 16,
749 { 0, { (1<<MACH_BASE) } }
751 /* clr $fr */
753 IP2K_INSN_CLR_FR, "clr_fr", "clr", 16,
754 { 0, { (1<<MACH_BASE) } }
756 /* cmp W,$fr */
758 IP2K_INSN_CMPW_FR, "cmpw_fr", "cmp", 16,
759 { 0, { (1<<MACH_BASE) } }
761 /* speed #$lit8 */
763 IP2K_INSN_SPEED, "speed", "speed", 16,
764 { 0, { (1<<MACH_BASE) } }
766 /* ireadi */
768 IP2K_INSN_IREADI, "ireadi", "ireadi", 16,
769 { 0, { (1<<MACH_BASE) } }
771 /* iwritei */
773 IP2K_INSN_IWRITEI, "iwritei", "iwritei", 16,
774 { 0, { (1<<MACH_BASE) } }
776 /* fread */
778 IP2K_INSN_FREAD, "fread", "fread", 16,
779 { 0, { (1<<MACH_BASE) } }
781 /* fwrite */
783 IP2K_INSN_FWRITE, "fwrite", "fwrite", 16,
784 { 0, { (1<<MACH_BASE) } }
786 /* iread */
788 IP2K_INSN_IREAD, "iread", "iread", 16,
789 { 0, { (1<<MACH_BASE) } }
791 /* iwrite */
793 IP2K_INSN_IWRITE, "iwrite", "iwrite", 16,
794 { 0, { (1<<MACH_BASE) } }
796 /* page $addr16p */
798 IP2K_INSN_PAGE, "page", "page", 16,
799 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
801 /* system */
803 IP2K_INSN_SYSTEM, "system", "system", 16,
804 { 0, { (1<<MACH_BASE) } }
806 /* reti #$reti3 */
808 IP2K_INSN_RETI, "reti", "reti", 16,
809 { 0, { (1<<MACH_BASE) } }
811 /* ret */
813 IP2K_INSN_RET, "ret", "ret", 16,
814 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
816 /* int */
818 IP2K_INSN_INT, "int", "int", 16,
819 { 0, { (1<<MACH_BASE) } }
821 /* breakx */
823 IP2K_INSN_BREAKX, "breakx", "breakx", 16,
824 { 0|A(EXT_SKIP_INSN), { (1<<MACH_BASE) } }
826 /* cwdt */
828 IP2K_INSN_CWDT, "cwdt", "cwdt", 16,
829 { 0, { (1<<MACH_BASE) } }
831 /* ferase */
833 IP2K_INSN_FERASE, "ferase", "ferase", 16,
834 { 0, { (1<<MACH_BASE) } }
836 /* retnp */
838 IP2K_INSN_RETNP, "retnp", "retnp", 16,
839 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
841 /* break */
843 IP2K_INSN_BREAK, "break", "break", 16,
844 { 0, { (1<<MACH_BASE) } }
846 /* nop */
848 IP2K_INSN_NOP, "nop", "nop", 16,
849 { 0, { (1<<MACH_BASE) } }
853 #undef OP
854 #undef A
856 /* Initialize anything needed to be done once, before any cpu_open call. */
857 static void init_tables PARAMS ((void));
859 static void
860 init_tables ()
864 static const CGEN_MACH * lookup_mach_via_bfd_name
865 PARAMS ((const CGEN_MACH *, const char *));
866 static void build_hw_table PARAMS ((CGEN_CPU_TABLE *));
867 static void build_ifield_table PARAMS ((CGEN_CPU_TABLE *));
868 static void build_operand_table PARAMS ((CGEN_CPU_TABLE *));
869 static void build_insn_table PARAMS ((CGEN_CPU_TABLE *));
870 static void ip2k_cgen_rebuild_tables PARAMS ((CGEN_CPU_TABLE *));
872 /* Subroutine of ip2k_cgen_cpu_open to look up a mach via its bfd name. */
874 static const CGEN_MACH *
875 lookup_mach_via_bfd_name (table, name)
876 const CGEN_MACH *table;
877 const char *name;
879 while (table->name)
881 if (strcmp (name, table->bfd_name) == 0)
882 return table;
883 ++table;
885 abort ();
888 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table. */
890 static void
891 build_hw_table (cd)
892 CGEN_CPU_TABLE *cd;
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 *));
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;
915 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table. */
917 static void
918 build_ifield_table (cd)
919 CGEN_CPU_TABLE *cd;
921 cd->ifld_table = & ip2k_cgen_ifld_table[0];
924 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table. */
926 static void
927 build_operand_table (cd)
928 CGEN_CPU_TABLE *cd;
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 *));
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;
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]. */
959 static void
960 build_insn_table (cd)
961 CGEN_CPU_TABLE *cd;
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));
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;
975 /* Subroutine of ip2k_cgen_cpu_open to rebuild the tables. */
977 static void
978 ip2k_cgen_rebuild_tables (cd)
979 CGEN_CPU_TABLE *cd;
981 int i;
982 unsigned int isas = cd->isas;
983 unsigned int machs = cd->machs;
985 cd->int_insn_p = CGEN_INT_INSN_P;
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)
996 const CGEN_ISA *isa = & ip2k_cgen_isa_table[i];
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;
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;
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;
1023 /* Data derived from the mach spec. */
1024 for (i = 0; i < MAX_MACHS; ++i)
1025 if (((1 << i) & machs) != 0)
1027 const CGEN_MACH *mach = & ip2k_cgen_mach_table[i];
1029 if (mach->insn_chunk_bitsize != 0)
1031 if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
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 ();
1038 cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
1042 /* Determine which hw elements are used by MACH. */
1043 build_hw_table (cd);
1045 /* Build the ifield table. */
1046 build_ifield_table (cd);
1048 /* Determine which operands are used by MACH/ISA. */
1049 build_operand_table (cd);
1051 /* Build the instruction table. */
1052 build_insn_table (cd);
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.
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
1067 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
1068 precluded.
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. */
1074 CGEN_CPU_DESC
1075 ip2k_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
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;
1084 if (! init_p)
1086 init_tables ();
1087 init_p = 1;
1090 memset (cd, 0, sizeof (*cd));
1092 va_start (ap, arg_type);
1093 while (arg_type != CGEN_CPU_OPEN_END)
1095 switch (arg_type)
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 :
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);
1109 machs |= 1 << mach->num;
1110 break;
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? */
1120 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
1122 va_end (ap);
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)
1134 /* ??? If target has only one, could have a default. */
1135 fprintf (stderr, "ip2k_cgen_cpu_open: no endianness specified\n");
1136 abort ();
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;
1148 /* Table (re)builder. */
1149 cd->rebuild_tables = ip2k_cgen_rebuild_tables;
1150 ip2k_cgen_rebuild_tables (cd);
1152 /* Default to not allowing signed overflow. */
1153 cd->signed_overflow_ok_p = 0;
1155 return (CGEN_CPU_DESC) cd;
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. */
1161 CGEN_CPU_DESC
1162 ip2k_cgen_cpu_open_1 (mach_name, endian)
1163 const char *mach_name;
1164 enum cgen_endian endian;
1166 return ip2k_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
1167 CGEN_CPU_OPEN_ENDIAN, endian,
1168 CGEN_CPU_OPEN_END);
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. */
1176 void
1177 ip2k_cgen_cpu_close (cd)
1178 CGEN_CPU_DESC cd;
1180 unsigned int i;
1181 CGEN_INSN *insns;
1183 if (cd->macro_insn_table.init_entries)
1185 insns = cd->macro_insn_table.init_entries;
1186 for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
1188 if (CGEN_INSN_RX ((insns)))
1189 regfree(CGEN_INSN_RX (insns));
1193 if (cd->insn_table.init_entries)
1195 insns = cd->insn_table.init_entries;
1196 for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
1198 if (CGEN_INSN_RX (insns))
1199 regfree(CGEN_INSN_RX (insns));
1205 if (cd->macro_insn_table.init_entries)
1206 free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
1208 if (cd->insn_table.init_entries)
1209 free ((CGEN_INSN *) cd->insn_table.init_entries);
1211 if (cd->hw_table.entries)
1212 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1214 if (cd->operand_table.entries)
1215 free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
1217 free (cd);