OSDN Git Service

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