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