xref: /netbsd-src/external/gpl3/binutils.old/dist/opcodes/ip2k-desc.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
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-2022 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
init_tables(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 *
lookup_mach_via_bfd_name(const CGEN_MACH * table,const char * name)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
build_hw_table(CGEN_CPU_TABLE * cd)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
build_ifield_table(CGEN_CPU_TABLE * cd)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
build_operand_table(CGEN_CPU_TABLE * cd)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
build_insn_table(CGEN_CPU_TABLE * cd)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
ip2k_cgen_rebuild_tables(CGEN_CPU_TABLE * cd)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
ip2k_cgen_cpu_open(enum cgen_cpu_open_arg arg_type,...)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
ip2k_cgen_cpu_open_1(const char * mach_name,enum cgen_endian endian)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
ip2k_cgen_cpu_close(CGEN_CPU_DESC cd)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 
1188