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