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