1/* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
2/* CPU data for xstormy16.
3
4THIS FILE IS MACHINE GENERATED WITH CGEN.
5
6Copyright (C) 1996-2022 Free Software Foundation, Inc.
7
8This 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 "xstormy16-desc.h"
34#include "xstormy16-opc.h"
35#include "opintl.h"
36#include "libiberty.h"
37#include "xregex.h"
38
39/* Attributes.  */
40
41static const CGEN_ATTR_ENTRY bool_attr[] =
42{
43  { "#f", 0 },
44  { "#t", 1 },
45  { 0, 0 }
46};
47
48static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED =
49{
50  { "base", MACH_BASE },
51  { "xstormy16", MACH_XSTORMY16 },
52  { "max", MACH_MAX },
53  { 0, 0 }
54};
55
56static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED =
57{
58  { "xstormy16", ISA_XSTORMY16 },
59  { "max", ISA_MAX },
60  { 0, 0 }
61};
62
63const CGEN_ATTR_TABLE xstormy16_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
75const CGEN_ATTR_TABLE xstormy16_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
85const CGEN_ATTR_TABLE xstormy16_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
99const CGEN_ATTR_TABLE xstormy16_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  { 0, 0, 0 }
113};
114
115/* Instruction set variants.  */
116
117static const CGEN_ISA xstormy16_cgen_isa_table[] = {
118  { "xstormy16", 32, 32, 16, 32 },
119  { 0, 0, 0, 0, 0 }
120};
121
122/* Machine variants.  */
123
124static const CGEN_MACH xstormy16_cgen_mach_table[] = {
125  { "xstormy16", "xstormy16", MACH_XSTORMY16, 16 },
126  { 0, 0, 0, 0 }
127};
128
129static CGEN_KEYWORD_ENTRY xstormy16_cgen_opval_gr_names_entries[] =
130{
131  { "r0", 0, {0, {{{0, 0}}}}, 0, 0 },
132  { "r1", 1, {0, {{{0, 0}}}}, 0, 0 },
133  { "r2", 2, {0, {{{0, 0}}}}, 0, 0 },
134  { "r3", 3, {0, {{{0, 0}}}}, 0, 0 },
135  { "r4", 4, {0, {{{0, 0}}}}, 0, 0 },
136  { "r5", 5, {0, {{{0, 0}}}}, 0, 0 },
137  { "r6", 6, {0, {{{0, 0}}}}, 0, 0 },
138  { "r7", 7, {0, {{{0, 0}}}}, 0, 0 },
139  { "r8", 8, {0, {{{0, 0}}}}, 0, 0 },
140  { "r9", 9, {0, {{{0, 0}}}}, 0, 0 },
141  { "r10", 10, {0, {{{0, 0}}}}, 0, 0 },
142  { "r11", 11, {0, {{{0, 0}}}}, 0, 0 },
143  { "r12", 12, {0, {{{0, 0}}}}, 0, 0 },
144  { "r13", 13, {0, {{{0, 0}}}}, 0, 0 },
145  { "r14", 14, {0, {{{0, 0}}}}, 0, 0 },
146  { "r15", 15, {0, {{{0, 0}}}}, 0, 0 },
147  { "psw", 14, {0, {{{0, 0}}}}, 0, 0 },
148  { "sp", 15, {0, {{{0, 0}}}}, 0, 0 }
149};
150
151CGEN_KEYWORD xstormy16_cgen_opval_gr_names =
152{
153  & xstormy16_cgen_opval_gr_names_entries[0],
154  18,
155  0, 0, 0, 0, ""
156};
157
158static CGEN_KEYWORD_ENTRY xstormy16_cgen_opval_gr_Rb_names_entries[] =
159{
160  { "r8", 0, {0, {{{0, 0}}}}, 0, 0 },
161  { "r9", 1, {0, {{{0, 0}}}}, 0, 0 },
162  { "r10", 2, {0, {{{0, 0}}}}, 0, 0 },
163  { "r11", 3, {0, {{{0, 0}}}}, 0, 0 },
164  { "r12", 4, {0, {{{0, 0}}}}, 0, 0 },
165  { "r13", 5, {0, {{{0, 0}}}}, 0, 0 },
166  { "r14", 6, {0, {{{0, 0}}}}, 0, 0 },
167  { "r15", 7, {0, {{{0, 0}}}}, 0, 0 },
168  { "psw", 6, {0, {{{0, 0}}}}, 0, 0 },
169  { "sp", 7, {0, {{{0, 0}}}}, 0, 0 }
170};
171
172CGEN_KEYWORD xstormy16_cgen_opval_gr_Rb_names =
173{
174  & xstormy16_cgen_opval_gr_Rb_names_entries[0],
175  10,
176  0, 0, 0, 0, ""
177};
178
179static CGEN_KEYWORD_ENTRY xstormy16_cgen_opval_h_branchcond_entries[] =
180{
181  { "ge", 0, {0, {{{0, 0}}}}, 0, 0 },
182  { "nc", 1, {0, {{{0, 0}}}}, 0, 0 },
183  { "lt", 2, {0, {{{0, 0}}}}, 0, 0 },
184  { "c", 3, {0, {{{0, 0}}}}, 0, 0 },
185  { "gt", 4, {0, {{{0, 0}}}}, 0, 0 },
186  { "hi", 5, {0, {{{0, 0}}}}, 0, 0 },
187  { "le", 6, {0, {{{0, 0}}}}, 0, 0 },
188  { "ls", 7, {0, {{{0, 0}}}}, 0, 0 },
189  { "pl", 8, {0, {{{0, 0}}}}, 0, 0 },
190  { "nv", 9, {0, {{{0, 0}}}}, 0, 0 },
191  { "mi", 10, {0, {{{0, 0}}}}, 0, 0 },
192  { "v", 11, {0, {{{0, 0}}}}, 0, 0 },
193  { "nz.b", 12, {0, {{{0, 0}}}}, 0, 0 },
194  { "nz", 13, {0, {{{0, 0}}}}, 0, 0 },
195  { "z.b", 14, {0, {{{0, 0}}}}, 0, 0 },
196  { "z", 15, {0, {{{0, 0}}}}, 0, 0 }
197};
198
199CGEN_KEYWORD xstormy16_cgen_opval_h_branchcond =
200{
201  & xstormy16_cgen_opval_h_branchcond_entries[0],
202  16,
203  0, 0, 0, 0, ""
204};
205
206static CGEN_KEYWORD_ENTRY xstormy16_cgen_opval_h_wordsize_entries[] =
207{
208  { ".b", 0, {0, {{{0, 0}}}}, 0, 0 },
209  { ".w", 1, {0, {{{0, 0}}}}, 0, 0 },
210  { "", 1, {0, {{{0, 0}}}}, 0, 0 }
211};
212
213CGEN_KEYWORD xstormy16_cgen_opval_h_wordsize =
214{
215  & xstormy16_cgen_opval_h_wordsize_entries[0],
216  3,
217  0, 0, 0, 0, ""
218};
219
220
221/* The hardware table.  */
222
223#define A(a) (1 << CGEN_HW_##a)
224
225const CGEN_HW_ENTRY xstormy16_cgen_hw_table[] =
226{
227  { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
228  { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
229  { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
230  { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
231  { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
232  { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PC), { { { (1<<MACH_BASE), 0 } } } } },
233  { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, & xstormy16_cgen_opval_gr_names, { 0, { { { (1<<MACH_BASE), 0 } } } } },
234  { "h-Rb", HW_H_RB, CGEN_ASM_KEYWORD, & xstormy16_cgen_opval_gr_Rb_names, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
235  { "h-Rbj", HW_H_RBJ, CGEN_ASM_KEYWORD, & xstormy16_cgen_opval_gr_Rb_names, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
236  { "h-Rpsw", HW_H_RPSW, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
237  { "h-z8", HW_H_Z8, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
238  { "h-z16", HW_H_Z16, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
239  { "h-cy", HW_H_CY, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
240  { "h-hc", HW_H_HC, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
241  { "h-ov", HW_H_OV, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
242  { "h-pt", HW_H_PT, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
243  { "h-s", HW_H_S, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
244  { "h-branchcond", HW_H_BRANCHCOND, CGEN_ASM_KEYWORD, & xstormy16_cgen_opval_h_branchcond, { 0, { { { (1<<MACH_BASE), 0 } } } } },
245  { "h-wordsize", HW_H_WORDSIZE, CGEN_ASM_KEYWORD, & xstormy16_cgen_opval_h_wordsize, { 0, { { { (1<<MACH_BASE), 0 } } } } },
246  { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
247};
248
249#undef A
250
251
252/* The instruction field table.  */
253
254#define A(a) (1 << CGEN_IFLD_##a)
255
256const CGEN_IFLD xstormy16_cgen_ifld_table[] =
257{
258  { XSTORMY16_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
259  { XSTORMY16_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
260  { XSTORMY16_F_RD, "f-Rd", 0, 32, 12, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
261  { XSTORMY16_F_RDM, "f-Rdm", 0, 32, 13, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
262  { XSTORMY16_F_RM, "f-Rm", 0, 32, 4, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
263  { XSTORMY16_F_RS, "f-Rs", 0, 32, 8, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
264  { XSTORMY16_F_RB, "f-Rb", 0, 32, 17, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
265  { XSTORMY16_F_RBJ, "f-Rbj", 0, 32, 11, 1, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
266  { XSTORMY16_F_OP1, "f-op1", 0, 32, 0, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
267  { XSTORMY16_F_OP2, "f-op2", 0, 32, 4, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
268  { XSTORMY16_F_OP2A, "f-op2a", 0, 32, 4, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
269  { XSTORMY16_F_OP2M, "f-op2m", 0, 32, 7, 1, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
270  { XSTORMY16_F_OP3, "f-op3", 0, 32, 8, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
271  { XSTORMY16_F_OP3A, "f-op3a", 0, 32, 8, 2, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
272  { XSTORMY16_F_OP3B, "f-op3b", 0, 32, 8, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
273  { XSTORMY16_F_OP4, "f-op4", 0, 32, 12, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
274  { XSTORMY16_F_OP4M, "f-op4m", 0, 32, 12, 1, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
275  { XSTORMY16_F_OP4B, "f-op4b", 0, 32, 15, 1, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
276  { XSTORMY16_F_OP5, "f-op5", 0, 32, 16, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
277  { XSTORMY16_F_OP5A, "f-op5a", 0, 32, 16, 1, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
278  { XSTORMY16_F_OP, "f-op", 0, 32, 0, 16, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
279  { XSTORMY16_F_IMM2, "f-imm2", 0, 32, 10, 2, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
280  { XSTORMY16_F_IMM3, "f-imm3", 0, 32, 4, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
281  { XSTORMY16_F_IMM3B, "f-imm3b", 0, 32, 17, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
282  { XSTORMY16_F_IMM4, "f-imm4", 0, 32, 8, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
283  { XSTORMY16_F_IMM8, "f-imm8", 0, 32, 8, 8, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
284  { XSTORMY16_F_IMM12, "f-imm12", 0, 32, 20, 12, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
285  { XSTORMY16_F_IMM16, "f-imm16", 0, 32, 16, 16, { 0|A(SIGN_OPT), { { { (1<<MACH_BASE), 0 } } } }  },
286  { XSTORMY16_F_LMEM8, "f-lmem8", 0, 32, 8, 8, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
287  { XSTORMY16_F_HMEM8, "f-hmem8", 0, 32, 8, 8, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
288  { XSTORMY16_F_REL8_2, "f-rel8-2", 0, 32, 8, 8, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
289  { XSTORMY16_F_REL8_4, "f-rel8-4", 0, 32, 8, 8, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
290  { XSTORMY16_F_REL12, "f-rel12", 0, 32, 20, 12, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
291  { XSTORMY16_F_REL12A, "f-rel12a", 0, 32, 4, 11, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
292  { XSTORMY16_F_ABS24_1, "f-abs24-1", 0, 32, 8, 8, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
293  { XSTORMY16_F_ABS24_2, "f-abs24-2", 0, 32, 16, 16, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
294  { XSTORMY16_F_ABS24, "f-abs24", 0, 0, 0, 0,{ 0|A(ABS_ADDR)|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } }  },
295  { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
296};
297
298#undef A
299
300
301
302/* multi ifield declarations */
303
304const CGEN_MAYBE_MULTI_IFLD XSTORMY16_F_ABS24_MULTI_IFIELD [];
305
306
307/* multi ifield definitions */
308
309const CGEN_MAYBE_MULTI_IFLD XSTORMY16_F_ABS24_MULTI_IFIELD [] =
310{
311    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_ABS24_1] } },
312    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_ABS24_2] } },
313    { 0, { 0 } }
314};
315
316/* The operand table.  */
317
318#define A(a) (1 << CGEN_OPERAND_##a)
319#define OPERAND(op) XSTORMY16_OPERAND_##op
320
321const CGEN_OPERAND xstormy16_cgen_operand_table[] =
322{
323/* pc: program counter */
324  { "pc", XSTORMY16_OPERAND_PC, HW_H_PC, 0, 0,
325    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_NIL] } },
326    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
327/* psw-z8:  */
328  { "psw-z8", XSTORMY16_OPERAND_PSW_Z8, HW_H_Z8, 0, 0,
329    { 0, { 0 } },
330    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
331/* psw-z16:  */
332  { "psw-z16", XSTORMY16_OPERAND_PSW_Z16, HW_H_Z16, 0, 0,
333    { 0, { 0 } },
334    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
335/* psw-cy:  */
336  { "psw-cy", XSTORMY16_OPERAND_PSW_CY, HW_H_CY, 0, 0,
337    { 0, { 0 } },
338    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
339/* psw-hc:  */
340  { "psw-hc", XSTORMY16_OPERAND_PSW_HC, HW_H_HC, 0, 0,
341    { 0, { 0 } },
342    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
343/* psw-ov:  */
344  { "psw-ov", XSTORMY16_OPERAND_PSW_OV, HW_H_OV, 0, 0,
345    { 0, { 0 } },
346    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
347/* psw-pt:  */
348  { "psw-pt", XSTORMY16_OPERAND_PSW_PT, HW_H_PT, 0, 0,
349    { 0, { 0 } },
350    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
351/* psw-s:  */
352  { "psw-s", XSTORMY16_OPERAND_PSW_S, HW_H_S, 0, 0,
353    { 0, { 0 } },
354    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
355/* Rd: general register destination */
356  { "Rd", XSTORMY16_OPERAND_RD, HW_H_GR, 12, 4,
357    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_RD] } },
358    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
359/* Rdm: general register destination */
360  { "Rdm", XSTORMY16_OPERAND_RDM, HW_H_GR, 13, 3,
361    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_RDM] } },
362    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
363/* Rm: general register for memory */
364  { "Rm", XSTORMY16_OPERAND_RM, HW_H_GR, 4, 3,
365    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_RM] } },
366    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
367/* Rs: general register source */
368  { "Rs", XSTORMY16_OPERAND_RS, HW_H_GR, 8, 4,
369    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_RS] } },
370    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
371/* Rb: base register */
372  { "Rb", XSTORMY16_OPERAND_RB, HW_H_RB, 17, 3,
373    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_RB] } },
374    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
375/* Rbj: base register for jump */
376  { "Rbj", XSTORMY16_OPERAND_RBJ, HW_H_RBJ, 11, 1,
377    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_RBJ] } },
378    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
379/* bcond2: branch condition opcode */
380  { "bcond2", XSTORMY16_OPERAND_BCOND2, HW_H_BRANCHCOND, 4, 4,
381    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_OP2] } },
382    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
383/* ws2: word size opcode */
384  { "ws2", XSTORMY16_OPERAND_WS2, HW_H_WORDSIZE, 7, 1,
385    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_OP2M] } },
386    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
387/* bcond5: branch condition opcode */
388  { "bcond5", XSTORMY16_OPERAND_BCOND5, HW_H_BRANCHCOND, 16, 4,
389    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_OP5] } },
390    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
391/* imm2: 2 bit unsigned immediate */
392  { "imm2", XSTORMY16_OPERAND_IMM2, HW_H_UINT, 10, 2,
393    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_IMM2] } },
394    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
395/* imm3: 3 bit unsigned immediate */
396  { "imm3", XSTORMY16_OPERAND_IMM3, HW_H_UINT, 4, 3,
397    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_IMM3] } },
398    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
399/* imm3b: 3 bit unsigned immediate for bit tests */
400  { "imm3b", XSTORMY16_OPERAND_IMM3B, HW_H_UINT, 17, 3,
401    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_IMM3B] } },
402    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
403/* imm4: 4 bit unsigned immediate */
404  { "imm4", XSTORMY16_OPERAND_IMM4, HW_H_UINT, 8, 4,
405    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_IMM4] } },
406    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
407/* imm8: 8 bit unsigned immediate */
408  { "imm8", XSTORMY16_OPERAND_IMM8, HW_H_UINT, 8, 8,
409    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_IMM8] } },
410    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
411/* imm8small: 8 bit unsigned immediate */
412  { "imm8small", XSTORMY16_OPERAND_IMM8SMALL, HW_H_UINT, 8, 8,
413    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_IMM8] } },
414    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
415/* imm12: 12 bit signed immediate */
416  { "imm12", XSTORMY16_OPERAND_IMM12, HW_H_SINT, 20, 12,
417    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_IMM12] } },
418    { 0, { { { (1<<MACH_BASE), 0 } } } }  },
419/* imm16: 16 bit immediate */
420  { "imm16", XSTORMY16_OPERAND_IMM16, HW_H_UINT, 16, 16,
421    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_IMM16] } },
422    { 0|A(SIGN_OPT), { { { (1<<MACH_BASE), 0 } } } }  },
423/* lmem8: 8 bit unsigned immediate low memory */
424  { "lmem8", XSTORMY16_OPERAND_LMEM8, HW_H_UINT, 8, 8,
425    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_LMEM8] } },
426    { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
427/* hmem8: 8 bit unsigned immediate high memory */
428  { "hmem8", XSTORMY16_OPERAND_HMEM8, HW_H_UINT, 8, 8,
429    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_HMEM8] } },
430    { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
431/* rel8-2: 8 bit relative address */
432  { "rel8-2", XSTORMY16_OPERAND_REL8_2, HW_H_UINT, 8, 8,
433    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_REL8_2] } },
434    { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
435/* rel8-4: 8 bit relative address */
436  { "rel8-4", XSTORMY16_OPERAND_REL8_4, HW_H_UINT, 8, 8,
437    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_REL8_4] } },
438    { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
439/* rel12: 12 bit relative address */
440  { "rel12", XSTORMY16_OPERAND_REL12, HW_H_UINT, 20, 12,
441    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_REL12] } },
442    { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
443/* rel12a: 12 bit relative address */
444  { "rel12a", XSTORMY16_OPERAND_REL12A, HW_H_UINT, 4, 11,
445    { 0, { &xstormy16_cgen_ifld_table[XSTORMY16_F_REL12A] } },
446    { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
447/* abs24: 24 bit absolute address */
448  { "abs24", XSTORMY16_OPERAND_ABS24, HW_H_UINT, 8, 24,
449    { 2, { &XSTORMY16_F_ABS24_MULTI_IFIELD[0] } },
450    { 0|A(ABS_ADDR)|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } }  },
451/* psw: program status word */
452  { "psw", XSTORMY16_OPERAND_PSW, HW_H_GR, 0, 0,
453    { 0, { 0 } },
454    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
455/* Rpsw: N0-N3 of the program status word */
456  { "Rpsw", XSTORMY16_OPERAND_RPSW, HW_H_RPSW, 0, 0,
457    { 0, { 0 } },
458    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
459/* sp: stack pointer */
460  { "sp", XSTORMY16_OPERAND_SP, HW_H_GR, 0, 0,
461    { 0, { 0 } },
462    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
463/* R0: R0 */
464  { "R0", XSTORMY16_OPERAND_R0, HW_H_GR, 0, 0,
465    { 0, { 0 } },
466    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
467/* R1: R1 */
468  { "R1", XSTORMY16_OPERAND_R1, HW_H_GR, 0, 0,
469    { 0, { 0 } },
470    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
471/* R2: R2 */
472  { "R2", XSTORMY16_OPERAND_R2, HW_H_GR, 0, 0,
473    { 0, { 0 } },
474    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
475/* R8: R8 */
476  { "R8", XSTORMY16_OPERAND_R8, HW_H_GR, 0, 0,
477    { 0, { 0 } },
478    { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
479/* sentinel */
480  { 0, 0, 0, 0, 0,
481    { 0, { 0 } },
482    { 0, { { { (1<<MACH_BASE), 0 } } } } }
483};
484
485#undef A
486
487
488/* The instruction table.  */
489
490#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
491#define A(a) (1 << CGEN_INSN_##a)
492
493static const CGEN_IBASE xstormy16_cgen_insn_table[MAX_INSNS] =
494{
495  /* Special null first entry.
496     A `num' value of zero is thus invalid.
497     Also, the special `invalid' insn resides here.  */
498  { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
499/* mov$ws2 $lmem8,#$imm16 */
500  {
501    XSTORMY16_INSN_MOVLMEMIMM, "movlmemimm", "mov", 32,
502    { 0, { { { (1<<MACH_BASE), 0 } } } }
503  },
504/* mov$ws2 $hmem8,#$imm16 */
505  {
506    XSTORMY16_INSN_MOVHMEMIMM, "movhmemimm", "mov", 32,
507    { 0, { { { (1<<MACH_BASE), 0 } } } }
508  },
509/* mov$ws2 $Rm,$lmem8 */
510  {
511    XSTORMY16_INSN_MOVLGRMEM, "movlgrmem", "mov", 16,
512    { 0, { { { (1<<MACH_BASE), 0 } } } }
513  },
514/* mov$ws2 $Rm,$hmem8 */
515  {
516    XSTORMY16_INSN_MOVHGRMEM, "movhgrmem", "mov", 16,
517    { 0, { { { (1<<MACH_BASE), 0 } } } }
518  },
519/* mov$ws2 $lmem8,$Rm */
520  {
521    XSTORMY16_INSN_MOVLMEMGR, "movlmemgr", "mov", 16,
522    { 0, { { { (1<<MACH_BASE), 0 } } } }
523  },
524/* mov$ws2 $hmem8,$Rm */
525  {
526    XSTORMY16_INSN_MOVHMEMGR, "movhmemgr", "mov", 16,
527    { 0, { { { (1<<MACH_BASE), 0 } } } }
528  },
529/* mov$ws2 $Rdm,($Rs) */
530  {
531    XSTORMY16_INSN_MOVGRGRI, "movgrgri", "mov", 16,
532    { 0, { { { (1<<MACH_BASE), 0 } } } }
533  },
534/* mov$ws2 $Rdm,($Rs++) */
535  {
536    XSTORMY16_INSN_MOVGRGRIPOSTINC, "movgrgripostinc", "mov", 16,
537    { 0, { { { (1<<MACH_BASE), 0 } } } }
538  },
539/* mov$ws2 $Rdm,(--$Rs) */
540  {
541    XSTORMY16_INSN_MOVGRGRIPREDEC, "movgrgripredec", "mov", 16,
542    { 0, { { { (1<<MACH_BASE), 0 } } } }
543  },
544/* mov$ws2 ($Rs),$Rdm */
545  {
546    XSTORMY16_INSN_MOVGRIGR, "movgrigr", "mov", 16,
547    { 0, { { { (1<<MACH_BASE), 0 } } } }
548  },
549/* mov$ws2 ($Rs++),$Rdm */
550  {
551    XSTORMY16_INSN_MOVGRIPOSTINCGR, "movgripostincgr", "mov", 16,
552    { 0, { { { (1<<MACH_BASE), 0 } } } }
553  },
554/* mov$ws2 (--$Rs),$Rdm */
555  {
556    XSTORMY16_INSN_MOVGRIPREDECGR, "movgripredecgr", "mov", 16,
557    { 0, { { { (1<<MACH_BASE), 0 } } } }
558  },
559/* mov$ws2 $Rdm,($Rs,$imm12) */
560  {
561    XSTORMY16_INSN_MOVGRGRII, "movgrgrii", "mov", 32,
562    { 0, { { { (1<<MACH_BASE), 0 } } } }
563  },
564/* mov$ws2 $Rdm,($Rs++,$imm12) */
565  {
566    XSTORMY16_INSN_MOVGRGRIIPOSTINC, "movgrgriipostinc", "mov", 32,
567    { 0, { { { (1<<MACH_BASE), 0 } } } }
568  },
569/* mov$ws2 $Rdm,(--$Rs,$imm12) */
570  {
571    XSTORMY16_INSN_MOVGRGRIIPREDEC, "movgrgriipredec", "mov", 32,
572    { 0, { { { (1<<MACH_BASE), 0 } } } }
573  },
574/* mov$ws2 ($Rs,$imm12),$Rdm */
575  {
576    XSTORMY16_INSN_MOVGRIIGR, "movgriigr", "mov", 32,
577    { 0, { { { (1<<MACH_BASE), 0 } } } }
578  },
579/* mov$ws2 ($Rs++,$imm12),$Rdm */
580  {
581    XSTORMY16_INSN_MOVGRIIPOSTINCGR, "movgriipostincgr", "mov", 32,
582    { 0, { { { (1<<MACH_BASE), 0 } } } }
583  },
584/* mov$ws2 (--$Rs,$imm12),$Rdm */
585  {
586    XSTORMY16_INSN_MOVGRIIPREDECGR, "movgriipredecgr", "mov", 32,
587    { 0, { { { (1<<MACH_BASE), 0 } } } }
588  },
589/* mov $Rd,$Rs */
590  {
591    XSTORMY16_INSN_MOVGRGR, "movgrgr", "mov", 16,
592    { 0, { { { (1<<MACH_BASE), 0 } } } }
593  },
594/* mov.w Rx,#$imm8 */
595  {
596    XSTORMY16_INSN_MOVWIMM8, "movwimm8", "mov.w", 16,
597    { 0, { { { (1<<MACH_BASE), 0 } } } }
598  },
599/* mov.w $Rm,#$imm8small */
600  {
601    XSTORMY16_INSN_MOVWGRIMM8, "movwgrimm8", "mov.w", 16,
602    { 0, { { { (1<<MACH_BASE), 0 } } } }
603  },
604/* mov.w $Rd,#$imm16 */
605  {
606    XSTORMY16_INSN_MOVWGRIMM16, "movwgrimm16", "mov.w", 32,
607    { 0, { { { (1<<MACH_BASE), 0 } } } }
608  },
609/* mov.b $Rd,RxL */
610  {
611    XSTORMY16_INSN_MOVLOWGR, "movlowgr", "mov.b", 16,
612    { 0, { { { (1<<MACH_BASE), 0 } } } }
613  },
614/* mov.b $Rd,RxH */
615  {
616    XSTORMY16_INSN_MOVHIGHGR, "movhighgr", "mov.b", 16,
617    { 0, { { { (1<<MACH_BASE), 0 } } } }
618  },
619/* movf$ws2 $Rdm,($Rs) */
620  {
621    XSTORMY16_INSN_MOVFGRGRI, "movfgrgri", "movf", 16,
622    { 0, { { { (1<<MACH_BASE), 0 } } } }
623  },
624/* movf$ws2 $Rdm,($Rs++) */
625  {
626    XSTORMY16_INSN_MOVFGRGRIPOSTINC, "movfgrgripostinc", "movf", 16,
627    { 0, { { { (1<<MACH_BASE), 0 } } } }
628  },
629/* movf$ws2 $Rdm,(--$Rs) */
630  {
631    XSTORMY16_INSN_MOVFGRGRIPREDEC, "movfgrgripredec", "movf", 16,
632    { 0, { { { (1<<MACH_BASE), 0 } } } }
633  },
634/* movf$ws2 ($Rs),$Rdm */
635  {
636    XSTORMY16_INSN_MOVFGRIGR, "movfgrigr", "movf", 16,
637    { 0, { { { (1<<MACH_BASE), 0 } } } }
638  },
639/* movf$ws2 ($Rs++),$Rdm */
640  {
641    XSTORMY16_INSN_MOVFGRIPOSTINCGR, "movfgripostincgr", "movf", 16,
642    { 0, { { { (1<<MACH_BASE), 0 } } } }
643  },
644/* movf$ws2 (--$Rs),$Rdm */
645  {
646    XSTORMY16_INSN_MOVFGRIPREDECGR, "movfgripredecgr", "movf", 16,
647    { 0, { { { (1<<MACH_BASE), 0 } } } }
648  },
649/* movf$ws2 $Rdm,($Rb,$Rs,$imm12) */
650  {
651    XSTORMY16_INSN_MOVFGRGRII, "movfgrgrii", "movf", 32,
652    { 0, { { { (1<<MACH_BASE), 0 } } } }
653  },
654/* movf$ws2 $Rdm,($Rb,$Rs++,$imm12) */
655  {
656    XSTORMY16_INSN_MOVFGRGRIIPOSTINC, "movfgrgriipostinc", "movf", 32,
657    { 0, { { { (1<<MACH_BASE), 0 } } } }
658  },
659/* movf$ws2 $Rdm,($Rb,--$Rs,$imm12) */
660  {
661    XSTORMY16_INSN_MOVFGRGRIIPREDEC, "movfgrgriipredec", "movf", 32,
662    { 0, { { { (1<<MACH_BASE), 0 } } } }
663  },
664/* movf$ws2 ($Rb,$Rs,$imm12),$Rdm */
665  {
666    XSTORMY16_INSN_MOVFGRIIGR, "movfgriigr", "movf", 32,
667    { 0, { { { (1<<MACH_BASE), 0 } } } }
668  },
669/* movf$ws2 ($Rb,$Rs++,$imm12),$Rdm */
670  {
671    XSTORMY16_INSN_MOVFGRIIPOSTINCGR, "movfgriipostincgr", "movf", 32,
672    { 0, { { { (1<<MACH_BASE), 0 } } } }
673  },
674/* movf$ws2 ($Rb,--$Rs,$imm12),$Rdm */
675  {
676    XSTORMY16_INSN_MOVFGRIIPREDECGR, "movfgriipredecgr", "movf", 32,
677    { 0, { { { (1<<MACH_BASE), 0 } } } }
678  },
679/* mask $Rd,$Rs */
680  {
681    XSTORMY16_INSN_MASKGRGR, "maskgrgr", "mask", 16,
682    { 0, { { { (1<<MACH_BASE), 0 } } } }
683  },
684/* mask $Rd,#$imm16 */
685  {
686    XSTORMY16_INSN_MASKGRIMM16, "maskgrimm16", "mask", 32,
687    { 0, { { { (1<<MACH_BASE), 0 } } } }
688  },
689/* push $Rd */
690  {
691    XSTORMY16_INSN_PUSHGR, "pushgr", "push", 16,
692    { 0, { { { (1<<MACH_BASE), 0 } } } }
693  },
694/* pop $Rd */
695  {
696    XSTORMY16_INSN_POPGR, "popgr", "pop", 16,
697    { 0, { { { (1<<MACH_BASE), 0 } } } }
698  },
699/* swpn $Rd */
700  {
701    XSTORMY16_INSN_SWPN, "swpn", "swpn", 16,
702    { 0, { { { (1<<MACH_BASE), 0 } } } }
703  },
704/* swpb $Rd */
705  {
706    XSTORMY16_INSN_SWPB, "swpb", "swpb", 16,
707    { 0, { { { (1<<MACH_BASE), 0 } } } }
708  },
709/* swpw $Rd,$Rs */
710  {
711    XSTORMY16_INSN_SWPW, "swpw", "swpw", 16,
712    { 0, { { { (1<<MACH_BASE), 0 } } } }
713  },
714/* and $Rd,$Rs */
715  {
716    XSTORMY16_INSN_ANDGRGR, "andgrgr", "and", 16,
717    { 0, { { { (1<<MACH_BASE), 0 } } } }
718  },
719/* and Rx,#$imm8 */
720  {
721    XSTORMY16_INSN_ANDIMM8, "andimm8", "and", 16,
722    { 0, { { { (1<<MACH_BASE), 0 } } } }
723  },
724/* and $Rd,#$imm16 */
725  {
726    XSTORMY16_INSN_ANDGRIMM16, "andgrimm16", "and", 32,
727    { 0, { { { (1<<MACH_BASE), 0 } } } }
728  },
729/* or $Rd,$Rs */
730  {
731    XSTORMY16_INSN_ORGRGR, "orgrgr", "or", 16,
732    { 0, { { { (1<<MACH_BASE), 0 } } } }
733  },
734/* or Rx,#$imm8 */
735  {
736    XSTORMY16_INSN_ORIMM8, "orimm8", "or", 16,
737    { 0, { { { (1<<MACH_BASE), 0 } } } }
738  },
739/* or $Rd,#$imm16 */
740  {
741    XSTORMY16_INSN_ORGRIMM16, "orgrimm16", "or", 32,
742    { 0, { { { (1<<MACH_BASE), 0 } } } }
743  },
744/* xor $Rd,$Rs */
745  {
746    XSTORMY16_INSN_XORGRGR, "xorgrgr", "xor", 16,
747    { 0, { { { (1<<MACH_BASE), 0 } } } }
748  },
749/* xor Rx,#$imm8 */
750  {
751    XSTORMY16_INSN_XORIMM8, "xorimm8", "xor", 16,
752    { 0, { { { (1<<MACH_BASE), 0 } } } }
753  },
754/* xor $Rd,#$imm16 */
755  {
756    XSTORMY16_INSN_XORGRIMM16, "xorgrimm16", "xor", 32,
757    { 0, { { { (1<<MACH_BASE), 0 } } } }
758  },
759/* not $Rd */
760  {
761    XSTORMY16_INSN_NOTGR, "notgr", "not", 16,
762    { 0, { { { (1<<MACH_BASE), 0 } } } }
763  },
764/* add $Rd,$Rs */
765  {
766    XSTORMY16_INSN_ADDGRGR, "addgrgr", "add", 16,
767    { 0, { { { (1<<MACH_BASE), 0 } } } }
768  },
769/* add $Rd,#$imm4 */
770  {
771    XSTORMY16_INSN_ADDGRIMM4, "addgrimm4", "add", 16,
772    { 0, { { { (1<<MACH_BASE), 0 } } } }
773  },
774/* add Rx,#$imm8 */
775  {
776    XSTORMY16_INSN_ADDIMM8, "addimm8", "add", 16,
777    { 0, { { { (1<<MACH_BASE), 0 } } } }
778  },
779/* add $Rd,#$imm16 */
780  {
781    XSTORMY16_INSN_ADDGRIMM16, "addgrimm16", "add", 32,
782    { 0, { { { (1<<MACH_BASE), 0 } } } }
783  },
784/* adc $Rd,$Rs */
785  {
786    XSTORMY16_INSN_ADCGRGR, "adcgrgr", "adc", 16,
787    { 0, { { { (1<<MACH_BASE), 0 } } } }
788  },
789/* adc $Rd,#$imm4 */
790  {
791    XSTORMY16_INSN_ADCGRIMM4, "adcgrimm4", "adc", 16,
792    { 0, { { { (1<<MACH_BASE), 0 } } } }
793  },
794/* adc Rx,#$imm8 */
795  {
796    XSTORMY16_INSN_ADCIMM8, "adcimm8", "adc", 16,
797    { 0, { { { (1<<MACH_BASE), 0 } } } }
798  },
799/* adc $Rd,#$imm16 */
800  {
801    XSTORMY16_INSN_ADCGRIMM16, "adcgrimm16", "adc", 32,
802    { 0, { { { (1<<MACH_BASE), 0 } } } }
803  },
804/* sub $Rd,$Rs */
805  {
806    XSTORMY16_INSN_SUBGRGR, "subgrgr", "sub", 16,
807    { 0, { { { (1<<MACH_BASE), 0 } } } }
808  },
809/* sub $Rd,#$imm4 */
810  {
811    XSTORMY16_INSN_SUBGRIMM4, "subgrimm4", "sub", 16,
812    { 0, { { { (1<<MACH_BASE), 0 } } } }
813  },
814/* sub Rx,#$imm8 */
815  {
816    XSTORMY16_INSN_SUBIMM8, "subimm8", "sub", 16,
817    { 0, { { { (1<<MACH_BASE), 0 } } } }
818  },
819/* sub $Rd,#$imm16 */
820  {
821    XSTORMY16_INSN_SUBGRIMM16, "subgrimm16", "sub", 32,
822    { 0, { { { (1<<MACH_BASE), 0 } } } }
823  },
824/* sbc $Rd,$Rs */
825  {
826    XSTORMY16_INSN_SBCGRGR, "sbcgrgr", "sbc", 16,
827    { 0, { { { (1<<MACH_BASE), 0 } } } }
828  },
829/* sbc $Rd,#$imm4 */
830  {
831    XSTORMY16_INSN_SBCGRIMM4, "sbcgrimm4", "sbc", 16,
832    { 0, { { { (1<<MACH_BASE), 0 } } } }
833  },
834/* sbc Rx,#$imm8 */
835  {
836    XSTORMY16_INSN_SBCGRIMM8, "sbcgrimm8", "sbc", 16,
837    { 0, { { { (1<<MACH_BASE), 0 } } } }
838  },
839/* sbc $Rd,#$imm16 */
840  {
841    XSTORMY16_INSN_SBCGRIMM16, "sbcgrimm16", "sbc", 32,
842    { 0, { { { (1<<MACH_BASE), 0 } } } }
843  },
844/* inc $Rd,#$imm2 */
845  {
846    XSTORMY16_INSN_INCGRIMM2, "incgrimm2", "inc", 16,
847    { 0, { { { (1<<MACH_BASE), 0 } } } }
848  },
849/* dec $Rd,#$imm2 */
850  {
851    XSTORMY16_INSN_DECGRIMM2, "decgrimm2", "dec", 16,
852    { 0, { { { (1<<MACH_BASE), 0 } } } }
853  },
854/* rrc $Rd,$Rs */
855  {
856    XSTORMY16_INSN_RRCGRGR, "rrcgrgr", "rrc", 16,
857    { 0, { { { (1<<MACH_BASE), 0 } } } }
858  },
859/* rrc $Rd,#$imm4 */
860  {
861    XSTORMY16_INSN_RRCGRIMM4, "rrcgrimm4", "rrc", 16,
862    { 0, { { { (1<<MACH_BASE), 0 } } } }
863  },
864/* rlc $Rd,$Rs */
865  {
866    XSTORMY16_INSN_RLCGRGR, "rlcgrgr", "rlc", 16,
867    { 0, { { { (1<<MACH_BASE), 0 } } } }
868  },
869/* rlc $Rd,#$imm4 */
870  {
871    XSTORMY16_INSN_RLCGRIMM4, "rlcgrimm4", "rlc", 16,
872    { 0, { { { (1<<MACH_BASE), 0 } } } }
873  },
874/* shr $Rd,$Rs */
875  {
876    XSTORMY16_INSN_SHRGRGR, "shrgrgr", "shr", 16,
877    { 0, { { { (1<<MACH_BASE), 0 } } } }
878  },
879/* shr $Rd,#$imm4 */
880  {
881    XSTORMY16_INSN_SHRGRIMM, "shrgrimm", "shr", 16,
882    { 0, { { { (1<<MACH_BASE), 0 } } } }
883  },
884/* shl $Rd,$Rs */
885  {
886    XSTORMY16_INSN_SHLGRGR, "shlgrgr", "shl", 16,
887    { 0, { { { (1<<MACH_BASE), 0 } } } }
888  },
889/* shl $Rd,#$imm4 */
890  {
891    XSTORMY16_INSN_SHLGRIMM, "shlgrimm", "shl", 16,
892    { 0, { { { (1<<MACH_BASE), 0 } } } }
893  },
894/* asr $Rd,$Rs */
895  {
896    XSTORMY16_INSN_ASRGRGR, "asrgrgr", "asr", 16,
897    { 0, { { { (1<<MACH_BASE), 0 } } } }
898  },
899/* asr $Rd,#$imm4 */
900  {
901    XSTORMY16_INSN_ASRGRIMM, "asrgrimm", "asr", 16,
902    { 0, { { { (1<<MACH_BASE), 0 } } } }
903  },
904/* set1 $Rd,#$imm4 */
905  {
906    XSTORMY16_INSN_SET1GRIMM, "set1grimm", "set1", 16,
907    { 0, { { { (1<<MACH_BASE), 0 } } } }
908  },
909/* set1 $Rd,$Rs */
910  {
911    XSTORMY16_INSN_SET1GRGR, "set1grgr", "set1", 16,
912    { 0, { { { (1<<MACH_BASE), 0 } } } }
913  },
914/* set1 $lmem8,#$imm3 */
915  {
916    XSTORMY16_INSN_SET1LMEMIMM, "set1lmemimm", "set1", 16,
917    { 0, { { { (1<<MACH_BASE), 0 } } } }
918  },
919/* set1 $hmem8,#$imm3 */
920  {
921    XSTORMY16_INSN_SET1HMEMIMM, "set1hmemimm", "set1", 16,
922    { 0, { { { (1<<MACH_BASE), 0 } } } }
923  },
924/* clr1 $Rd,#$imm4 */
925  {
926    XSTORMY16_INSN_CLR1GRIMM, "clr1grimm", "clr1", 16,
927    { 0, { { { (1<<MACH_BASE), 0 } } } }
928  },
929/* clr1 $Rd,$Rs */
930  {
931    XSTORMY16_INSN_CLR1GRGR, "clr1grgr", "clr1", 16,
932    { 0, { { { (1<<MACH_BASE), 0 } } } }
933  },
934/* clr1 $lmem8,#$imm3 */
935  {
936    XSTORMY16_INSN_CLR1LMEMIMM, "clr1lmemimm", "clr1", 16,
937    { 0, { { { (1<<MACH_BASE), 0 } } } }
938  },
939/* clr1 $hmem8,#$imm3 */
940  {
941    XSTORMY16_INSN_CLR1HMEMIMM, "clr1hmemimm", "clr1", 16,
942    { 0, { { { (1<<MACH_BASE), 0 } } } }
943  },
944/* cbw $Rd */
945  {
946    XSTORMY16_INSN_CBWGR, "cbwgr", "cbw", 16,
947    { 0, { { { (1<<MACH_BASE), 0 } } } }
948  },
949/* rev $Rd */
950  {
951    XSTORMY16_INSN_REVGR, "revgr", "rev", 16,
952    { 0, { { { (1<<MACH_BASE), 0 } } } }
953  },
954/* b$bcond5 $Rd,$Rs,$rel12 */
955  {
956    XSTORMY16_INSN_BCCGRGR, "bccgrgr", "b", 32,
957    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
958  },
959/* b$bcond5 $Rm,#$imm8,$rel12 */
960  {
961    XSTORMY16_INSN_BCCGRIMM8, "bccgrimm8", "b", 32,
962    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
963  },
964/* b$bcond2 Rx,#$imm16,${rel8-4} */
965  {
966    XSTORMY16_INSN_BCCIMM16, "bccimm16", "b", 32,
967    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
968  },
969/* bn $Rd,#$imm4,$rel12 */
970  {
971    XSTORMY16_INSN_BNGRIMM4, "bngrimm4", "bn", 32,
972    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
973  },
974/* bn $Rd,$Rs,$rel12 */
975  {
976    XSTORMY16_INSN_BNGRGR, "bngrgr", "bn", 32,
977    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
978  },
979/* bn $lmem8,#$imm3b,$rel12 */
980  {
981    XSTORMY16_INSN_BNLMEMIMM, "bnlmemimm", "bn", 32,
982    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
983  },
984/* bn $hmem8,#$imm3b,$rel12 */
985  {
986    XSTORMY16_INSN_BNHMEMIMM, "bnhmemimm", "bn", 32,
987    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
988  },
989/* bp $Rd,#$imm4,$rel12 */
990  {
991    XSTORMY16_INSN_BPGRIMM4, "bpgrimm4", "bp", 32,
992    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
993  },
994/* bp $Rd,$Rs,$rel12 */
995  {
996    XSTORMY16_INSN_BPGRGR, "bpgrgr", "bp", 32,
997    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
998  },
999/* bp $lmem8,#$imm3b,$rel12 */
1000  {
1001    XSTORMY16_INSN_BPLMEMIMM, "bplmemimm", "bp", 32,
1002    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1003  },
1004/* bp $hmem8,#$imm3b,$rel12 */
1005  {
1006    XSTORMY16_INSN_BPHMEMIMM, "bphmemimm", "bp", 32,
1007    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1008  },
1009/* b$bcond2 ${rel8-2} */
1010  {
1011    XSTORMY16_INSN_BCC, "bcc", "b", 16,
1012    { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1013  },
1014/* br $Rd */
1015  {
1016    XSTORMY16_INSN_BGR, "bgr", "br", 16,
1017    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1018  },
1019/* br $rel12a */
1020  {
1021    XSTORMY16_INSN_BR, "br", "br", 16,
1022    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1023  },
1024/* jmp $Rbj,$Rd */
1025  {
1026    XSTORMY16_INSN_JMP, "jmp", "jmp", 16,
1027    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1028  },
1029/* jmpf $abs24 */
1030  {
1031    XSTORMY16_INSN_JMPF, "jmpf", "jmpf", 32,
1032    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1033  },
1034/* callr $Rd */
1035  {
1036    XSTORMY16_INSN_CALLRGR, "callrgr", "callr", 16,
1037    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1038  },
1039/* callr $rel12a */
1040  {
1041    XSTORMY16_INSN_CALLRIMM, "callrimm", "callr", 16,
1042    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1043  },
1044/* call $Rbj,$Rd */
1045  {
1046    XSTORMY16_INSN_CALLGR, "callgr", "call", 16,
1047    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1048  },
1049/* callf $abs24 */
1050  {
1051    XSTORMY16_INSN_CALLFIMM, "callfimm", "callf", 32,
1052    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1053  },
1054/* icallr $Rd */
1055  {
1056    XSTORMY16_INSN_ICALLRGR, "icallrgr", "icallr", 16,
1057    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1058  },
1059/* icall $Rbj,$Rd */
1060  {
1061    XSTORMY16_INSN_ICALLGR, "icallgr", "icall", 16,
1062    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1063  },
1064/* icallf $abs24 */
1065  {
1066    XSTORMY16_INSN_ICALLFIMM, "icallfimm", "icallf", 32,
1067    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1068  },
1069/* iret */
1070  {
1071    XSTORMY16_INSN_IRET, "iret", "iret", 16,
1072    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1073  },
1074/* ret */
1075  {
1076    XSTORMY16_INSN_RET, "ret", "ret", 16,
1077    { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
1078  },
1079/* mul */
1080  {
1081    XSTORMY16_INSN_MUL, "mul", "mul", 16,
1082    { 0, { { { (1<<MACH_BASE), 0 } } } }
1083  },
1084/* div */
1085  {
1086    XSTORMY16_INSN_DIV, "div", "div", 16,
1087    { 0, { { { (1<<MACH_BASE), 0 } } } }
1088  },
1089/* sdiv */
1090  {
1091    XSTORMY16_INSN_SDIV, "sdiv", "sdiv", 16,
1092    { 0, { { { (1<<MACH_BASE), 0 } } } }
1093  },
1094/* sdivlh */
1095  {
1096    XSTORMY16_INSN_SDIVLH, "sdivlh", "sdivlh", 16,
1097    { 0, { { { (1<<MACH_BASE), 0 } } } }
1098  },
1099/* divlh */
1100  {
1101    XSTORMY16_INSN_DIVLH, "divlh", "divlh", 16,
1102    { 0, { { { (1<<MACH_BASE), 0 } } } }
1103  },
1104/* reset */
1105  {
1106    XSTORMY16_INSN_RESET, "reset", "reset", 16,
1107    { 0, { { { (1<<MACH_BASE), 0 } } } }
1108  },
1109/* nop */
1110  {
1111    XSTORMY16_INSN_NOP, "nop", "nop", 16,
1112    { 0, { { { (1<<MACH_BASE), 0 } } } }
1113  },
1114/* halt */
1115  {
1116    XSTORMY16_INSN_HALT, "halt", "halt", 16,
1117    { 0, { { { (1<<MACH_BASE), 0 } } } }
1118  },
1119/* hold */
1120  {
1121    XSTORMY16_INSN_HOLD, "hold", "hold", 16,
1122    { 0, { { { (1<<MACH_BASE), 0 } } } }
1123  },
1124/* holdx */
1125  {
1126    XSTORMY16_INSN_HOLDX, "holdx", "holdx", 16,
1127    { 0, { { { (1<<MACH_BASE), 0 } } } }
1128  },
1129/* brk */
1130  {
1131    XSTORMY16_INSN_BRK, "brk", "brk", 16,
1132    { 0, { { { (1<<MACH_BASE), 0 } } } }
1133  },
1134/* --unused-- */
1135  {
1136    XSTORMY16_INSN_SYSCALL, "syscall", "--unused--", 16,
1137    { 0, { { { (1<<MACH_BASE), 0 } } } }
1138  },
1139};
1140
1141#undef OP
1142#undef A
1143
1144/* Initialize anything needed to be done once, before any cpu_open call.  */
1145
1146static void
1147init_tables (void)
1148{
1149}
1150
1151#ifndef opcodes_error_handler
1152#define opcodes_error_handler(...) \
1153  fprintf (stderr, __VA_ARGS__); fputc ('\n', stderr)
1154#endif
1155
1156static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
1157static void build_hw_table      (CGEN_CPU_TABLE *);
1158static void build_ifield_table  (CGEN_CPU_TABLE *);
1159static void build_operand_table (CGEN_CPU_TABLE *);
1160static void build_insn_table    (CGEN_CPU_TABLE *);
1161static void xstormy16_cgen_rebuild_tables (CGEN_CPU_TABLE *);
1162
1163/* Subroutine of xstormy16_cgen_cpu_open to look up a mach via its bfd name.  */
1164
1165static const CGEN_MACH *
1166lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
1167{
1168  while (table->name)
1169    {
1170      if (strcmp (name, table->bfd_name) == 0)
1171	return table;
1172      ++table;
1173    }
1174  return NULL;
1175}
1176
1177/* Subroutine of xstormy16_cgen_cpu_open to build the hardware table.  */
1178
1179static void
1180build_hw_table (CGEN_CPU_TABLE *cd)
1181{
1182  int i;
1183  int machs = cd->machs;
1184  const CGEN_HW_ENTRY *init = & xstormy16_cgen_hw_table[0];
1185  /* MAX_HW is only an upper bound on the number of selected entries.
1186     However each entry is indexed by it's enum so there can be holes in
1187     the table.  */
1188  const CGEN_HW_ENTRY **selected =
1189    (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
1190
1191  cd->hw_table.init_entries = init;
1192  cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
1193  memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
1194  /* ??? For now we just use machs to determine which ones we want.  */
1195  for (i = 0; init[i].name != NULL; ++i)
1196    if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
1197	& machs)
1198      selected[init[i].type] = &init[i];
1199  cd->hw_table.entries = selected;
1200  cd->hw_table.num_entries = MAX_HW;
1201}
1202
1203/* Subroutine of xstormy16_cgen_cpu_open to build the hardware table.  */
1204
1205static void
1206build_ifield_table (CGEN_CPU_TABLE *cd)
1207{
1208  cd->ifld_table = & xstormy16_cgen_ifld_table[0];
1209}
1210
1211/* Subroutine of xstormy16_cgen_cpu_open to build the hardware table.  */
1212
1213static void
1214build_operand_table (CGEN_CPU_TABLE *cd)
1215{
1216  int i;
1217  int machs = cd->machs;
1218  const CGEN_OPERAND *init = & xstormy16_cgen_operand_table[0];
1219  /* MAX_OPERANDS is only an upper bound on the number of selected entries.
1220     However each entry is indexed by it's enum so there can be holes in
1221     the table.  */
1222  const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
1223
1224  cd->operand_table.init_entries = init;
1225  cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
1226  memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
1227  /* ??? For now we just use mach to determine which ones we want.  */
1228  for (i = 0; init[i].name != NULL; ++i)
1229    if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
1230	& machs)
1231      selected[init[i].type] = &init[i];
1232  cd->operand_table.entries = selected;
1233  cd->operand_table.num_entries = MAX_OPERANDS;
1234}
1235
1236/* Subroutine of xstormy16_cgen_cpu_open to build the hardware table.
1237   ??? This could leave out insns not supported by the specified mach/isa,
1238   but that would cause errors like "foo only supported by bar" to become
1239   "unknown insn", so for now we include all insns and require the app to
1240   do the checking later.
1241   ??? On the other hand, parsing of such insns may require their hardware or
1242   operand elements to be in the table [which they mightn't be].  */
1243
1244static void
1245build_insn_table (CGEN_CPU_TABLE *cd)
1246{
1247  int i;
1248  const CGEN_IBASE *ib = & xstormy16_cgen_insn_table[0];
1249  CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
1250
1251  memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
1252  for (i = 0; i < MAX_INSNS; ++i)
1253    insns[i].base = &ib[i];
1254  cd->insn_table.init_entries = insns;
1255  cd->insn_table.entry_size = sizeof (CGEN_IBASE);
1256  cd->insn_table.num_init_entries = MAX_INSNS;
1257}
1258
1259/* Subroutine of xstormy16_cgen_cpu_open to rebuild the tables.  */
1260
1261static void
1262xstormy16_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
1263{
1264  int i;
1265  CGEN_BITSET *isas = cd->isas;
1266  unsigned int machs = cd->machs;
1267
1268  cd->int_insn_p = CGEN_INT_INSN_P;
1269
1270  /* Data derived from the isa spec.  */
1271#define UNSET (CGEN_SIZE_UNKNOWN + 1)
1272  cd->default_insn_bitsize = UNSET;
1273  cd->base_insn_bitsize = UNSET;
1274  cd->min_insn_bitsize = 65535; /* Some ridiculously big number.  */
1275  cd->max_insn_bitsize = 0;
1276  for (i = 0; i < MAX_ISAS; ++i)
1277    if (cgen_bitset_contains (isas, i))
1278      {
1279	const CGEN_ISA *isa = & xstormy16_cgen_isa_table[i];
1280
1281	/* Default insn sizes of all selected isas must be
1282	   equal or we set the result to 0, meaning "unknown".  */
1283	if (cd->default_insn_bitsize == UNSET)
1284	  cd->default_insn_bitsize = isa->default_insn_bitsize;
1285	else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
1286	  ; /* This is ok.  */
1287	else
1288	  cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
1289
1290	/* Base insn sizes of all selected isas must be equal
1291	   or we set the result to 0, meaning "unknown".  */
1292	if (cd->base_insn_bitsize == UNSET)
1293	  cd->base_insn_bitsize = isa->base_insn_bitsize;
1294	else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
1295	  ; /* This is ok.  */
1296	else
1297	  cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
1298
1299	/* Set min,max insn sizes.  */
1300	if (isa->min_insn_bitsize < cd->min_insn_bitsize)
1301	  cd->min_insn_bitsize = isa->min_insn_bitsize;
1302	if (isa->max_insn_bitsize > cd->max_insn_bitsize)
1303	  cd->max_insn_bitsize = isa->max_insn_bitsize;
1304      }
1305
1306  /* Data derived from the mach spec.  */
1307  for (i = 0; i < MAX_MACHS; ++i)
1308    if (((1 << i) & machs) != 0)
1309      {
1310	const CGEN_MACH *mach = & xstormy16_cgen_mach_table[i];
1311
1312	if (mach->insn_chunk_bitsize != 0)
1313	{
1314	  if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
1315	    {
1316	      opcodes_error_handler
1317		(/* xgettext:c-format */
1318		 _("internal error: xstormy16_cgen_rebuild_tables: "
1319		   "conflicting insn-chunk-bitsize values: `%d' vs. `%d'"),
1320		 cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
1321	      abort ();
1322	    }
1323
1324 	  cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
1325	}
1326      }
1327
1328  /* Determine which hw elements are used by MACH.  */
1329  build_hw_table (cd);
1330
1331  /* Build the ifield table.  */
1332  build_ifield_table (cd);
1333
1334  /* Determine which operands are used by MACH/ISA.  */
1335  build_operand_table (cd);
1336
1337  /* Build the instruction table.  */
1338  build_insn_table (cd);
1339}
1340
1341/* Initialize a cpu table and return a descriptor.
1342   It's much like opening a file, and must be the first function called.
1343   The arguments are a set of (type/value) pairs, terminated with
1344   CGEN_CPU_OPEN_END.
1345
1346   Currently supported values:
1347   CGEN_CPU_OPEN_ISAS:    bitmap of values in enum isa_attr
1348   CGEN_CPU_OPEN_MACHS:   bitmap of values in enum mach_attr
1349   CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
1350   CGEN_CPU_OPEN_ENDIAN:  specify endian choice
1351   CGEN_CPU_OPEN_INSN_ENDIAN: specify instruction endian choice
1352   CGEN_CPU_OPEN_END:     terminates arguments
1353
1354   ??? Simultaneous multiple isas might not make sense, but it's not (yet)
1355   precluded.  */
1356
1357CGEN_CPU_DESC
1358xstormy16_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
1359{
1360  CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
1361  static int init_p;
1362  CGEN_BITSET *isas = 0;  /* 0 = "unspecified" */
1363  unsigned int machs = 0; /* 0 = "unspecified" */
1364  enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
1365  enum cgen_endian insn_endian = CGEN_ENDIAN_UNKNOWN;
1366  va_list ap;
1367
1368  if (! init_p)
1369    {
1370      init_tables ();
1371      init_p = 1;
1372    }
1373
1374  memset (cd, 0, sizeof (*cd));
1375
1376  va_start (ap, arg_type);
1377  while (arg_type != CGEN_CPU_OPEN_END)
1378    {
1379      switch (arg_type)
1380	{
1381	case CGEN_CPU_OPEN_ISAS :
1382	  isas = va_arg (ap, CGEN_BITSET *);
1383	  break;
1384	case CGEN_CPU_OPEN_MACHS :
1385	  machs = va_arg (ap, unsigned int);
1386	  break;
1387	case CGEN_CPU_OPEN_BFDMACH :
1388	  {
1389	    const char *name = va_arg (ap, const char *);
1390	    const CGEN_MACH *mach =
1391	      lookup_mach_via_bfd_name (xstormy16_cgen_mach_table, name);
1392
1393	    if (mach != NULL)
1394	      machs |= 1 << mach->num;
1395	    break;
1396	  }
1397	case CGEN_CPU_OPEN_ENDIAN :
1398	  endian = va_arg (ap, enum cgen_endian);
1399	  break;
1400	case CGEN_CPU_OPEN_INSN_ENDIAN :
1401	  insn_endian = va_arg (ap, enum cgen_endian);
1402	  break;
1403	default :
1404	  opcodes_error_handler
1405	    (/* xgettext:c-format */
1406	     _("internal error: xstormy16_cgen_cpu_open: "
1407	       "unsupported argument `%d'"),
1408	     arg_type);
1409	  abort (); /* ??? return NULL? */
1410	}
1411      arg_type = va_arg (ap, enum cgen_cpu_open_arg);
1412    }
1413  va_end (ap);
1414
1415  /* Mach unspecified means "all".  */
1416  if (machs == 0)
1417    machs = (1 << MAX_MACHS) - 1;
1418  /* Base mach is always selected.  */
1419  machs |= 1;
1420  if (endian == CGEN_ENDIAN_UNKNOWN)
1421    {
1422      /* ??? If target has only one, could have a default.  */
1423      opcodes_error_handler
1424	(/* xgettext:c-format */
1425	 _("internal error: xstormy16_cgen_cpu_open: no endianness specified"));
1426      abort ();
1427    }
1428
1429  cd->isas = cgen_bitset_copy (isas);
1430  cd->machs = machs;
1431  cd->endian = endian;
1432  cd->insn_endian
1433    = (insn_endian == CGEN_ENDIAN_UNKNOWN ? endian : insn_endian);
1434
1435  /* Table (re)builder.  */
1436  cd->rebuild_tables = xstormy16_cgen_rebuild_tables;
1437  xstormy16_cgen_rebuild_tables (cd);
1438
1439  /* Default to not allowing signed overflow.  */
1440  cd->signed_overflow_ok_p = 0;
1441
1442  return (CGEN_CPU_DESC) cd;
1443}
1444
1445/* Cover fn to xstormy16_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
1446   MACH_NAME is the bfd name of the mach.  */
1447
1448CGEN_CPU_DESC
1449xstormy16_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
1450{
1451  return xstormy16_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
1452			       CGEN_CPU_OPEN_ENDIAN, endian,
1453			       CGEN_CPU_OPEN_END);
1454}
1455
1456/* Close a cpu table.
1457   ??? This can live in a machine independent file, but there's currently
1458   no place to put this file (there's no libcgen).  libopcodes is the wrong
1459   place as some simulator ports use this but they don't use libopcodes.  */
1460
1461void
1462xstormy16_cgen_cpu_close (CGEN_CPU_DESC cd)
1463{
1464  unsigned int i;
1465  const CGEN_INSN *insns;
1466
1467  if (cd->macro_insn_table.init_entries)
1468    {
1469      insns = cd->macro_insn_table.init_entries;
1470      for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
1471	if (CGEN_INSN_RX ((insns)))
1472	  regfree (CGEN_INSN_RX (insns));
1473    }
1474
1475  if (cd->insn_table.init_entries)
1476    {
1477      insns = cd->insn_table.init_entries;
1478      for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
1479	if (CGEN_INSN_RX (insns))
1480	  regfree (CGEN_INSN_RX (insns));
1481    }
1482
1483  free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
1484  free ((CGEN_INSN *) cd->insn_table.init_entries);
1485  free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1486  free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
1487  free (cd);
1488}
1489
1490