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