Coverage Report

Created: 2025-06-24 06:45

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