xref: /netbsd-src/external/gpl3/binutils/dist/opcodes/ip2k-desc.c (revision fc4f42693f9b1c31f39f9cf50af1bf2010325808)
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-2018 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 static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
849 static void build_hw_table      (CGEN_CPU_TABLE *);
850 static void build_ifield_table  (CGEN_CPU_TABLE *);
851 static void build_operand_table (CGEN_CPU_TABLE *);
852 static void build_insn_table    (CGEN_CPU_TABLE *);
853 static void ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *);
854 
855 /* Subroutine of ip2k_cgen_cpu_open to look up a mach via its bfd name.  */
856 
857 static const CGEN_MACH *
858 lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
859 {
860   while (table->name)
861     {
862       if (strcmp (name, table->bfd_name) == 0)
863 	return table;
864       ++table;
865     }
866   return NULL;
867 }
868 
869 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
870 
871 static void
872 build_hw_table (CGEN_CPU_TABLE *cd)
873 {
874   int i;
875   int machs = cd->machs;
876   const CGEN_HW_ENTRY *init = & ip2k_cgen_hw_table[0];
877   /* MAX_HW is only an upper bound on the number of selected entries.
878      However each entry is indexed by it's enum so there can be holes in
879      the table.  */
880   const CGEN_HW_ENTRY **selected =
881     (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
882 
883   cd->hw_table.init_entries = init;
884   cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
885   memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
886   /* ??? For now we just use machs to determine which ones we want.  */
887   for (i = 0; init[i].name != NULL; ++i)
888     if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
889 	& machs)
890       selected[init[i].type] = &init[i];
891   cd->hw_table.entries = selected;
892   cd->hw_table.num_entries = MAX_HW;
893 }
894 
895 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
896 
897 static void
898 build_ifield_table (CGEN_CPU_TABLE *cd)
899 {
900   cd->ifld_table = & ip2k_cgen_ifld_table[0];
901 }
902 
903 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
904 
905 static void
906 build_operand_table (CGEN_CPU_TABLE *cd)
907 {
908   int i;
909   int machs = cd->machs;
910   const CGEN_OPERAND *init = & ip2k_cgen_operand_table[0];
911   /* MAX_OPERANDS is only an upper bound on the number of selected entries.
912      However each entry is indexed by it's enum so there can be holes in
913      the table.  */
914   const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
915 
916   cd->operand_table.init_entries = init;
917   cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
918   memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
919   /* ??? For now we just use mach to determine which ones we want.  */
920   for (i = 0; init[i].name != NULL; ++i)
921     if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
922 	& machs)
923       selected[init[i].type] = &init[i];
924   cd->operand_table.entries = selected;
925   cd->operand_table.num_entries = MAX_OPERANDS;
926 }
927 
928 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.
929    ??? This could leave out insns not supported by the specified mach/isa,
930    but that would cause errors like "foo only supported by bar" to become
931    "unknown insn", so for now we include all insns and require the app to
932    do the checking later.
933    ??? On the other hand, parsing of such insns may require their hardware or
934    operand elements to be in the table [which they mightn't be].  */
935 
936 static void
937 build_insn_table (CGEN_CPU_TABLE *cd)
938 {
939   int i;
940   const CGEN_IBASE *ib = & ip2k_cgen_insn_table[0];
941   CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
942 
943   memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
944   for (i = 0; i < MAX_INSNS; ++i)
945     insns[i].base = &ib[i];
946   cd->insn_table.init_entries = insns;
947   cd->insn_table.entry_size = sizeof (CGEN_IBASE);
948   cd->insn_table.num_init_entries = MAX_INSNS;
949 }
950 
951 /* Subroutine of ip2k_cgen_cpu_open to rebuild the tables.  */
952 
953 static void
954 ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
955 {
956   int i;
957   CGEN_BITSET *isas = cd->isas;
958   unsigned int machs = cd->machs;
959 
960   cd->int_insn_p = CGEN_INT_INSN_P;
961 
962   /* Data derived from the isa spec.  */
963 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
964   cd->default_insn_bitsize = UNSET;
965   cd->base_insn_bitsize = UNSET;
966   cd->min_insn_bitsize = 65535; /* Some ridiculously big number.  */
967   cd->max_insn_bitsize = 0;
968   for (i = 0; i < MAX_ISAS; ++i)
969     if (cgen_bitset_contains (isas, i))
970       {
971 	const CGEN_ISA *isa = & ip2k_cgen_isa_table[i];
972 
973 	/* Default insn sizes of all selected isas must be
974 	   equal or we set the result to 0, meaning "unknown".  */
975 	if (cd->default_insn_bitsize == UNSET)
976 	  cd->default_insn_bitsize = isa->default_insn_bitsize;
977 	else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
978 	  ; /* This is ok.  */
979 	else
980 	  cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
981 
982 	/* Base insn sizes of all selected isas must be equal
983 	   or we set the result to 0, meaning "unknown".  */
984 	if (cd->base_insn_bitsize == UNSET)
985 	  cd->base_insn_bitsize = isa->base_insn_bitsize;
986 	else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
987 	  ; /* This is ok.  */
988 	else
989 	  cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
990 
991 	/* Set min,max insn sizes.  */
992 	if (isa->min_insn_bitsize < cd->min_insn_bitsize)
993 	  cd->min_insn_bitsize = isa->min_insn_bitsize;
994 	if (isa->max_insn_bitsize > cd->max_insn_bitsize)
995 	  cd->max_insn_bitsize = isa->max_insn_bitsize;
996       }
997 
998   /* Data derived from the mach spec.  */
999   for (i = 0; i < MAX_MACHS; ++i)
1000     if (((1 << i) & machs) != 0)
1001       {
1002 	const CGEN_MACH *mach = & ip2k_cgen_mach_table[i];
1003 
1004 	if (mach->insn_chunk_bitsize != 0)
1005 	{
1006 	  if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
1007 	    {
1008 	      fprintf (stderr, "ip2k_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
1009 		       cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
1010 	      abort ();
1011 	    }
1012 
1013  	  cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
1014 	}
1015       }
1016 
1017   /* Determine which hw elements are used by MACH.  */
1018   build_hw_table (cd);
1019 
1020   /* Build the ifield table.  */
1021   build_ifield_table (cd);
1022 
1023   /* Determine which operands are used by MACH/ISA.  */
1024   build_operand_table (cd);
1025 
1026   /* Build the instruction table.  */
1027   build_insn_table (cd);
1028 }
1029 
1030 /* Initialize a cpu table and return a descriptor.
1031    It's much like opening a file, and must be the first function called.
1032    The arguments are a set of (type/value) pairs, terminated with
1033    CGEN_CPU_OPEN_END.
1034 
1035    Currently supported values:
1036    CGEN_CPU_OPEN_ISAS:    bitmap of values in enum isa_attr
1037    CGEN_CPU_OPEN_MACHS:   bitmap of values in enum mach_attr
1038    CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
1039    CGEN_CPU_OPEN_ENDIAN:  specify endian choice
1040    CGEN_CPU_OPEN_END:     terminates arguments
1041 
1042    ??? Simultaneous multiple isas might not make sense, but it's not (yet)
1043    precluded.  */
1044 
1045 CGEN_CPU_DESC
1046 ip2k_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
1047 {
1048   CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
1049   static int init_p;
1050   CGEN_BITSET *isas = 0;  /* 0 = "unspecified" */
1051   unsigned int machs = 0; /* 0 = "unspecified" */
1052   enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
1053   va_list ap;
1054 
1055   if (! init_p)
1056     {
1057       init_tables ();
1058       init_p = 1;
1059     }
1060 
1061   memset (cd, 0, sizeof (*cd));
1062 
1063   va_start (ap, arg_type);
1064   while (arg_type != CGEN_CPU_OPEN_END)
1065     {
1066       switch (arg_type)
1067 	{
1068 	case CGEN_CPU_OPEN_ISAS :
1069 	  isas = va_arg (ap, CGEN_BITSET *);
1070 	  break;
1071 	case CGEN_CPU_OPEN_MACHS :
1072 	  machs = va_arg (ap, unsigned int);
1073 	  break;
1074 	case CGEN_CPU_OPEN_BFDMACH :
1075 	  {
1076 	    const char *name = va_arg (ap, const char *);
1077 	    const CGEN_MACH *mach =
1078 	      lookup_mach_via_bfd_name (ip2k_cgen_mach_table, name);
1079 
1080 	    if (mach != NULL)
1081 	      machs |= 1 << mach->num;
1082 	    break;
1083 	  }
1084 	case CGEN_CPU_OPEN_ENDIAN :
1085 	  endian = va_arg (ap, enum cgen_endian);
1086 	  break;
1087 	default :
1088 	  fprintf (stderr, "ip2k_cgen_cpu_open: unsupported argument `%d'\n",
1089 		   arg_type);
1090 	  abort (); /* ??? return NULL? */
1091 	}
1092       arg_type = va_arg (ap, enum cgen_cpu_open_arg);
1093     }
1094   va_end (ap);
1095 
1096   /* Mach unspecified means "all".  */
1097   if (machs == 0)
1098     machs = (1 << MAX_MACHS) - 1;
1099   /* Base mach is always selected.  */
1100   machs |= 1;
1101   if (endian == CGEN_ENDIAN_UNKNOWN)
1102     {
1103       /* ??? If target has only one, could have a default.  */
1104       fprintf (stderr, "ip2k_cgen_cpu_open: no endianness specified\n");
1105       abort ();
1106     }
1107 
1108   cd->isas = cgen_bitset_copy (isas);
1109   cd->machs = machs;
1110   cd->endian = endian;
1111   /* FIXME: for the sparc case we can determine insn-endianness statically.
1112      The worry here is where both data and insn endian can be independently
1113      chosen, in which case this function will need another argument.
1114      Actually, will want to allow for more arguments in the future anyway.  */
1115   cd->insn_endian = endian;
1116 
1117   /* Table (re)builder.  */
1118   cd->rebuild_tables = ip2k_cgen_rebuild_tables;
1119   ip2k_cgen_rebuild_tables (cd);
1120 
1121   /* Default to not allowing signed overflow.  */
1122   cd->signed_overflow_ok_p = 0;
1123 
1124   return (CGEN_CPU_DESC) cd;
1125 }
1126 
1127 /* Cover fn to ip2k_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
1128    MACH_NAME is the bfd name of the mach.  */
1129 
1130 CGEN_CPU_DESC
1131 ip2k_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
1132 {
1133   return ip2k_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
1134 			       CGEN_CPU_OPEN_ENDIAN, endian,
1135 			       CGEN_CPU_OPEN_END);
1136 }
1137 
1138 /* Close a cpu table.
1139    ??? This can live in a machine independent file, but there's currently
1140    no place to put this file (there's no libcgen).  libopcodes is the wrong
1141    place as some simulator ports use this but they don't use libopcodes.  */
1142 
1143 void
1144 ip2k_cgen_cpu_close (CGEN_CPU_DESC cd)
1145 {
1146   unsigned int i;
1147   const CGEN_INSN *insns;
1148 
1149   if (cd->macro_insn_table.init_entries)
1150     {
1151       insns = cd->macro_insn_table.init_entries;
1152       for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
1153 	if (CGEN_INSN_RX ((insns)))
1154 	  regfree (CGEN_INSN_RX (insns));
1155     }
1156 
1157   if (cd->insn_table.init_entries)
1158     {
1159       insns = cd->insn_table.init_entries;
1160       for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
1161 	if (CGEN_INSN_RX (insns))
1162 	  regfree (CGEN_INSN_RX (insns));
1163     }
1164 
1165   if (cd->macro_insn_table.init_entries)
1166     free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
1167 
1168   if (cd->insn_table.init_entries)
1169     free ((CGEN_INSN *) cd->insn_table.init_entries);
1170 
1171   if (cd->hw_table.entries)
1172     free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1173 
1174   if (cd->operand_table.entries)
1175     free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
1176 
1177   free (cd);
1178 }
1179 
1180