/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 | | |