lm32-desc.c revision 1.8 1 1.8 christos /* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */
2 1.1 christos /* CPU data for lm32.
3 1.1 christos
4 1.1 christos THIS FILE IS MACHINE GENERATED WITH CGEN.
5 1.1 christos
6 1.8 christos Copyright (C) 1996-2019 Free Software Foundation, Inc.
7 1.1 christos
8 1.1 christos This file is part of the GNU Binutils and/or GDB, the GNU debugger.
9 1.1 christos
10 1.1 christos This file is free software; you can redistribute it and/or modify
11 1.1 christos it under the terms of the GNU General Public License as published by
12 1.1 christos the Free Software Foundation; either version 3, or (at your option)
13 1.1 christos any later version.
14 1.1 christos
15 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
16 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 1.1 christos License for more details.
19 1.1 christos
20 1.1 christos You should have received a copy of the GNU General Public License along
21 1.1 christos with this program; if not, write to the Free Software Foundation, Inc.,
22 1.1 christos 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
23 1.1 christos
24 1.1 christos */
25 1.1 christos
26 1.1 christos #include "sysdep.h"
27 1.1 christos #include <stdio.h>
28 1.1 christos #include <stdarg.h>
29 1.1 christos #include "ansidecl.h"
30 1.1 christos #include "bfd.h"
31 1.1 christos #include "symcat.h"
32 1.1 christos #include "lm32-desc.h"
33 1.1 christos #include "lm32-opc.h"
34 1.1 christos #include "opintl.h"
35 1.1 christos #include "libiberty.h"
36 1.1 christos #include "xregex.h"
37 1.1 christos
38 1.1 christos /* Attributes. */
39 1.1 christos
40 1.1 christos static const CGEN_ATTR_ENTRY bool_attr[] =
41 1.1 christos {
42 1.1 christos { "#f", 0 },
43 1.1 christos { "#t", 1 },
44 1.1 christos { 0, 0 }
45 1.1 christos };
46 1.1 christos
47 1.1 christos static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED =
48 1.1 christos {
49 1.1 christos { "base", MACH_BASE },
50 1.1 christos { "lm32", MACH_LM32 },
51 1.1 christos { "max", MACH_MAX },
52 1.1 christos { 0, 0 }
53 1.1 christos };
54 1.1 christos
55 1.1 christos static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED =
56 1.1 christos {
57 1.1 christos { "lm32", ISA_LM32 },
58 1.1 christos { "max", ISA_MAX },
59 1.1 christos { 0, 0 }
60 1.1 christos };
61 1.1 christos
62 1.1 christos const CGEN_ATTR_TABLE lm32_cgen_ifield_attr_table[] =
63 1.1 christos {
64 1.1 christos { "MACH", & MACH_attr[0], & MACH_attr[0] },
65 1.1 christos { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
66 1.1 christos { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
67 1.1 christos { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
68 1.1 christos { "RESERVED", &bool_attr[0], &bool_attr[0] },
69 1.1 christos { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
70 1.1 christos { "SIGNED", &bool_attr[0], &bool_attr[0] },
71 1.1 christos { 0, 0, 0 }
72 1.1 christos };
73 1.1 christos
74 1.1 christos const CGEN_ATTR_TABLE lm32_cgen_hardware_attr_table[] =
75 1.1 christos {
76 1.1 christos { "MACH", & MACH_attr[0], & MACH_attr[0] },
77 1.1 christos { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
78 1.1 christos { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
79 1.1 christos { "PC", &bool_attr[0], &bool_attr[0] },
80 1.1 christos { "PROFILE", &bool_attr[0], &bool_attr[0] },
81 1.1 christos { 0, 0, 0 }
82 1.1 christos };
83 1.1 christos
84 1.1 christos const CGEN_ATTR_TABLE lm32_cgen_operand_attr_table[] =
85 1.1 christos {
86 1.1 christos { "MACH", & MACH_attr[0], & MACH_attr[0] },
87 1.1 christos { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
88 1.1 christos { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
89 1.1 christos { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
90 1.1 christos { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
91 1.1 christos { "SIGNED", &bool_attr[0], &bool_attr[0] },
92 1.1 christos { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
93 1.1 christos { "RELAX", &bool_attr[0], &bool_attr[0] },
94 1.1 christos { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
95 1.1 christos { 0, 0, 0 }
96 1.1 christos };
97 1.1 christos
98 1.1 christos const CGEN_ATTR_TABLE lm32_cgen_insn_attr_table[] =
99 1.1 christos {
100 1.1 christos { "MACH", & MACH_attr[0], & MACH_attr[0] },
101 1.1 christos { "ALIAS", &bool_attr[0], &bool_attr[0] },
102 1.1 christos { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
103 1.1 christos { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
104 1.1 christos { "COND-CTI", &bool_attr[0], &bool_attr[0] },
105 1.1 christos { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
106 1.1 christos { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
107 1.1 christos { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
108 1.1 christos { "RELAXED", &bool_attr[0], &bool_attr[0] },
109 1.1 christos { "NO-DIS", &bool_attr[0], &bool_attr[0] },
110 1.1 christos { "PBB", &bool_attr[0], &bool_attr[0] },
111 1.1 christos { 0, 0, 0 }
112 1.1 christos };
113 1.1 christos
114 1.1 christos /* Instruction set variants. */
115 1.1 christos
116 1.1 christos static const CGEN_ISA lm32_cgen_isa_table[] = {
117 1.1 christos { "lm32", 32, 32, 32, 32 },
118 1.1 christos { 0, 0, 0, 0, 0 }
119 1.1 christos };
120 1.1 christos
121 1.1 christos /* Machine variants. */
122 1.1 christos
123 1.1 christos static const CGEN_MACH lm32_cgen_mach_table[] = {
124 1.1 christos { "lm32", "lm32", MACH_LM32, 0 },
125 1.1 christos { 0, 0, 0, 0 }
126 1.1 christos };
127 1.1 christos
128 1.1 christos static CGEN_KEYWORD_ENTRY lm32_cgen_opval_h_gr_entries[] =
129 1.1 christos {
130 1.1 christos { "gp", 26, {0, {{{0, 0}}}}, 0, 0 },
131 1.1 christos { "fp", 27, {0, {{{0, 0}}}}, 0, 0 },
132 1.1 christos { "sp", 28, {0, {{{0, 0}}}}, 0, 0 },
133 1.1 christos { "ra", 29, {0, {{{0, 0}}}}, 0, 0 },
134 1.1 christos { "ea", 30, {0, {{{0, 0}}}}, 0, 0 },
135 1.1 christos { "ba", 31, {0, {{{0, 0}}}}, 0, 0 },
136 1.1 christos { "r0", 0, {0, {{{0, 0}}}}, 0, 0 },
137 1.1 christos { "r1", 1, {0, {{{0, 0}}}}, 0, 0 },
138 1.1 christos { "r2", 2, {0, {{{0, 0}}}}, 0, 0 },
139 1.1 christos { "r3", 3, {0, {{{0, 0}}}}, 0, 0 },
140 1.1 christos { "r4", 4, {0, {{{0, 0}}}}, 0, 0 },
141 1.1 christos { "r5", 5, {0, {{{0, 0}}}}, 0, 0 },
142 1.1 christos { "r6", 6, {0, {{{0, 0}}}}, 0, 0 },
143 1.1 christos { "r7", 7, {0, {{{0, 0}}}}, 0, 0 },
144 1.1 christos { "r8", 8, {0, {{{0, 0}}}}, 0, 0 },
145 1.1 christos { "r9", 9, {0, {{{0, 0}}}}, 0, 0 },
146 1.1 christos { "r10", 10, {0, {{{0, 0}}}}, 0, 0 },
147 1.1 christos { "r11", 11, {0, {{{0, 0}}}}, 0, 0 },
148 1.1 christos { "r12", 12, {0, {{{0, 0}}}}, 0, 0 },
149 1.1 christos { "r13", 13, {0, {{{0, 0}}}}, 0, 0 },
150 1.1 christos { "r14", 14, {0, {{{0, 0}}}}, 0, 0 },
151 1.1 christos { "r15", 15, {0, {{{0, 0}}}}, 0, 0 },
152 1.1 christos { "r16", 16, {0, {{{0, 0}}}}, 0, 0 },
153 1.1 christos { "r17", 17, {0, {{{0, 0}}}}, 0, 0 },
154 1.1 christos { "r18", 18, {0, {{{0, 0}}}}, 0, 0 },
155 1.1 christos { "r19", 19, {0, {{{0, 0}}}}, 0, 0 },
156 1.1 christos { "r20", 20, {0, {{{0, 0}}}}, 0, 0 },
157 1.1 christos { "r21", 21, {0, {{{0, 0}}}}, 0, 0 },
158 1.1 christos { "r22", 22, {0, {{{0, 0}}}}, 0, 0 },
159 1.1 christos { "r23", 23, {0, {{{0, 0}}}}, 0, 0 },
160 1.1 christos { "r24", 24, {0, {{{0, 0}}}}, 0, 0 },
161 1.1 christos { "r25", 25, {0, {{{0, 0}}}}, 0, 0 },
162 1.1 christos { "r26", 26, {0, {{{0, 0}}}}, 0, 0 },
163 1.1 christos { "r27", 27, {0, {{{0, 0}}}}, 0, 0 },
164 1.1 christos { "r28", 28, {0, {{{0, 0}}}}, 0, 0 },
165 1.1 christos { "r29", 29, {0, {{{0, 0}}}}, 0, 0 },
166 1.1 christos { "r30", 30, {0, {{{0, 0}}}}, 0, 0 },
167 1.1 christos { "r31", 31, {0, {{{0, 0}}}}, 0, 0 }
168 1.1 christos };
169 1.1 christos
170 1.1 christos CGEN_KEYWORD lm32_cgen_opval_h_gr =
171 1.1 christos {
172 1.1 christos & lm32_cgen_opval_h_gr_entries[0],
173 1.1 christos 38,
174 1.1 christos 0, 0, 0, 0, ""
175 1.1 christos };
176 1.1 christos
177 1.1 christos static CGEN_KEYWORD_ENTRY lm32_cgen_opval_h_csr_entries[] =
178 1.1 christos {
179 1.1 christos { "IE", 0, {0, {{{0, 0}}}}, 0, 0 },
180 1.1 christos { "IM", 1, {0, {{{0, 0}}}}, 0, 0 },
181 1.1 christos { "IP", 2, {0, {{{0, 0}}}}, 0, 0 },
182 1.1 christos { "ICC", 3, {0, {{{0, 0}}}}, 0, 0 },
183 1.1 christos { "DCC", 4, {0, {{{0, 0}}}}, 0, 0 },
184 1.1 christos { "CC", 5, {0, {{{0, 0}}}}, 0, 0 },
185 1.1 christos { "CFG", 6, {0, {{{0, 0}}}}, 0, 0 },
186 1.1 christos { "EBA", 7, {0, {{{0, 0}}}}, 0, 0 },
187 1.1 christos { "DC", 8, {0, {{{0, 0}}}}, 0, 0 },
188 1.1 christos { "DEBA", 9, {0, {{{0, 0}}}}, 0, 0 },
189 1.1 christos { "CFG2", 10, {0, {{{0, 0}}}}, 0, 0 },
190 1.1 christos { "JTX", 14, {0, {{{0, 0}}}}, 0, 0 },
191 1.1 christos { "JRX", 15, {0, {{{0, 0}}}}, 0, 0 },
192 1.1 christos { "BP0", 16, {0, {{{0, 0}}}}, 0, 0 },
193 1.1 christos { "BP1", 17, {0, {{{0, 0}}}}, 0, 0 },
194 1.1 christos { "BP2", 18, {0, {{{0, 0}}}}, 0, 0 },
195 1.1 christos { "BP3", 19, {0, {{{0, 0}}}}, 0, 0 },
196 1.1 christos { "WP0", 24, {0, {{{0, 0}}}}, 0, 0 },
197 1.1 christos { "WP1", 25, {0, {{{0, 0}}}}, 0, 0 },
198 1.1 christos { "WP2", 26, {0, {{{0, 0}}}}, 0, 0 },
199 1.1 christos { "WP3", 27, {0, {{{0, 0}}}}, 0, 0 },
200 1.1 christos { "PSW", 29, {0, {{{0, 0}}}}, 0, 0 },
201 1.1 christos { "TLBVADDR", 30, {0, {{{0, 0}}}}, 0, 0 },
202 1.1 christos { "TLBPADDR", 31, {0, {{{0, 0}}}}, 0, 0 },
203 1.1 christos { "TLBBADVADDR", 31, {0, {{{0, 0}}}}, 0, 0 }
204 1.1 christos };
205 1.1 christos
206 1.1 christos CGEN_KEYWORD lm32_cgen_opval_h_csr =
207 1.1 christos {
208 1.1 christos & lm32_cgen_opval_h_csr_entries[0],
209 1.1 christos 25,
210 1.1 christos 0, 0, 0, 0, ""
211 1.1 christos };
212 1.1 christos
213 1.1 christos
214 1.1 christos /* The hardware table. */
215 1.1 christos
216 1.1 christos #define A(a) (1 << CGEN_HW_##a)
217 1.1 christos
218 1.1 christos const CGEN_HW_ENTRY lm32_cgen_hw_table[] =
219 1.1 christos {
220 1.1 christos { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
221 1.1 christos { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
222 1.1 christos { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
223 1.1 christos { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
224 1.1 christos { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
225 1.1 christos { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PC), { { { (1<<MACH_BASE), 0 } } } } },
226 1.1 christos { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & lm32_cgen_opval_h_gr, { 0, { { { (1<<MACH_BASE), 0 } } } } },
227 1.1 christos { "h-csr", HW_H_CSR, CGEN_ASM_KEYWORD, (PTR) & lm32_cgen_opval_h_csr, { 0, { { { (1<<MACH_BASE), 0 } } } } },
228 1.1 christos { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
229 1.1 christos };
230 1.1 christos
231 1.1 christos #undef A
232 1.1 christos
233 1.1 christos
234 1.1 christos /* The instruction field table. */
235 1.1 christos
236 1.1 christos #define A(a) (1 << CGEN_IFLD_##a)
237 1.1 christos
238 1.1 christos const CGEN_IFLD lm32_cgen_ifld_table[] =
239 1.1 christos {
240 1.1 christos { LM32_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
241 1.1 christos { LM32_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
242 1.1 christos { LM32_F_OPCODE, "f-opcode", 0, 32, 31, 6, { 0, { { { (1<<MACH_BASE), 0 } } } } },
243 1.1 christos { LM32_F_R0, "f-r0", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
244 1.1 christos { LM32_F_R1, "f-r1", 0, 32, 20, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
245 1.1 christos { LM32_F_R2, "f-r2", 0, 32, 15, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
246 1.1 christos { LM32_F_RESV0, "f-resv0", 0, 32, 10, 11, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } } },
247 1.1 christos { LM32_F_SHIFT, "f-shift", 0, 32, 4, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
248 1.1 christos { LM32_F_IMM, "f-imm", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } } },
249 1.1 christos { LM32_F_UIMM, "f-uimm", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } } },
250 1.1 christos { LM32_F_CSR, "f-csr", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } } },
251 1.1 christos { LM32_F_USER, "f-user", 0, 32, 10, 11, { 0, { { { (1<<MACH_BASE), 0 } } } } },
252 1.1 christos { LM32_F_EXCEPTION, "f-exception", 0, 32, 25, 26, { 0, { { { (1<<MACH_BASE), 0 } } } } },
253 1.1 christos { LM32_F_BRANCH, "f-branch", 0, 32, 15, 16, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } },
254 1.1 christos { LM32_F_CALL, "f-call", 0, 32, 25, 26, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } },
255 1.1 christos { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
256 1.1 christos };
257 1.1 christos
258 1.1 christos #undef A
259 1.1 christos
260 1.1 christos
261 1.1 christos
262 1.1 christos /* multi ifield declarations */
263 1.1 christos
264 1.1 christos
265 1.1 christos
266 1.1 christos /* multi ifield definitions */
267 1.1 christos
268 1.1 christos
269 1.1 christos /* The operand table. */
270 1.1 christos
271 1.1 christos #define A(a) (1 << CGEN_OPERAND_##a)
272 1.1 christos #define OPERAND(op) LM32_OPERAND_##op
273 1.1 christos
274 1.1 christos const CGEN_OPERAND lm32_cgen_operand_table[] =
275 1.1 christos {
276 1.1 christos /* pc: program counter */
277 1.1 christos { "pc", LM32_OPERAND_PC, HW_H_PC, 0, 0,
278 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_NIL] } },
279 1.1 christos { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } } },
280 1.1 christos /* r0: register 0 */
281 1.1 christos { "r0", LM32_OPERAND_R0, HW_H_GR, 25, 5,
282 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_R0] } },
283 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
284 1.1 christos /* r1: register 1 */
285 1.1 christos { "r1", LM32_OPERAND_R1, HW_H_GR, 20, 5,
286 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_R1] } },
287 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
288 1.1 christos /* r2: register 2 */
289 1.1 christos { "r2", LM32_OPERAND_R2, HW_H_GR, 15, 5,
290 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_R2] } },
291 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
292 1.1 christos /* shift: shift amout */
293 1.1 christos { "shift", LM32_OPERAND_SHIFT, HW_H_UINT, 4, 5,
294 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_SHIFT] } },
295 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
296 1.1 christos /* imm: signed immediate */
297 1.1 christos { "imm", LM32_OPERAND_IMM, HW_H_SINT, 15, 16,
298 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
299 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
300 1.1 christos /* uimm: unsigned immediate */
301 1.1 christos { "uimm", LM32_OPERAND_UIMM, HW_H_UINT, 15, 16,
302 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_UIMM] } },
303 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
304 1.1 christos /* branch: branch offset */
305 1.1 christos { "branch", LM32_OPERAND_BRANCH, HW_H_IADDR, 15, 16,
306 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_BRANCH] } },
307 1.1 christos { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } },
308 1.1 christos /* call: call offset */
309 1.1 christos { "call", LM32_OPERAND_CALL, HW_H_IADDR, 25, 26,
310 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_CALL] } },
311 1.1 christos { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } } },
312 1.1 christos /* csr: csr */
313 1.1 christos { "csr", LM32_OPERAND_CSR, HW_H_CSR, 25, 5,
314 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_CSR] } },
315 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
316 1.1 christos /* user: user */
317 1.1 christos { "user", LM32_OPERAND_USER, HW_H_UINT, 10, 11,
318 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_USER] } },
319 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
320 1.1 christos /* exception: exception */
321 1.1 christos { "exception", LM32_OPERAND_EXCEPTION, HW_H_UINT, 25, 26,
322 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_EXCEPTION] } },
323 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
324 1.1 christos /* hi16: high 16-bit immediate */
325 1.1 christos { "hi16", LM32_OPERAND_HI16, HW_H_UINT, 15, 16,
326 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_UIMM] } },
327 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
328 1.1 christos /* lo16: low 16-bit immediate */
329 1.1 christos { "lo16", LM32_OPERAND_LO16, HW_H_UINT, 15, 16,
330 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_UIMM] } },
331 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
332 1.1 christos /* gp16: gp relative 16-bit immediate */
333 1.1 christos { "gp16", LM32_OPERAND_GP16, HW_H_SINT, 15, 16,
334 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
335 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
336 1.1 christos /* got16: got 16-bit immediate */
337 1.1 christos { "got16", LM32_OPERAND_GOT16, HW_H_SINT, 15, 16,
338 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
339 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
340 1.1 christos /* gotoffhi16: got offset high 16-bit immediate */
341 1.1 christos { "gotoffhi16", LM32_OPERAND_GOTOFFHI16, HW_H_SINT, 15, 16,
342 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
343 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
344 1.1 christos /* gotofflo16: got offset low 16-bit immediate */
345 1.1 christos { "gotofflo16", LM32_OPERAND_GOTOFFLO16, HW_H_SINT, 15, 16,
346 1.6 christos { 0, { (const PTR) &lm32_cgen_ifld_table[LM32_F_IMM] } },
347 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } },
348 1.1 christos /* sentinel */
349 1.1 christos { 0, 0, 0, 0, 0,
350 1.1 christos { 0, { (const PTR) 0 } },
351 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } } }
352 1.1 christos };
353 1.1 christos
354 1.1 christos #undef A
355 1.1 christos
356 1.1 christos
357 1.1 christos /* The instruction table. */
358 1.1 christos
359 1.1 christos #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
360 1.1 christos #define A(a) (1 << CGEN_INSN_##a)
361 1.1 christos
362 1.1 christos static const CGEN_IBASE lm32_cgen_insn_table[MAX_INSNS] =
363 1.1 christos {
364 1.1 christos /* Special null first entry.
365 1.1 christos A `num' value of zero is thus invalid.
366 1.1 christos Also, the special `invalid' insn resides here. */
367 1.1 christos { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
368 1.1 christos /* add $r2,$r0,$r1 */
369 1.1 christos {
370 1.1 christos LM32_INSN_ADD, "add", "add", 32,
371 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
372 1.1 christos },
373 1.1 christos /* addi $r1,$r0,$imm */
374 1.1 christos {
375 1.1 christos LM32_INSN_ADDI, "addi", "addi", 32,
376 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
377 1.1 christos },
378 1.1 christos /* and $r2,$r0,$r1 */
379 1.1 christos {
380 1.1 christos LM32_INSN_AND, "and", "and", 32,
381 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
382 1.1 christos },
383 1.1 christos /* andi $r1,$r0,$uimm */
384 1.1 christos {
385 1.1 christos LM32_INSN_ANDI, "andi", "andi", 32,
386 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
387 1.1 christos },
388 1.1 christos /* andhi $r1,$r0,$hi16 */
389 1.1 christos {
390 1.1 christos LM32_INSN_ANDHII, "andhii", "andhi", 32,
391 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
392 1.1 christos },
393 1.1 christos /* b $r0 */
394 1.1 christos {
395 1.1 christos LM32_INSN_B, "b", "b", 32,
396 1.1 christos { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
397 1.1 christos },
398 1.1 christos /* bi $call */
399 1.1 christos {
400 1.1 christos LM32_INSN_BI, "bi", "bi", 32,
401 1.1 christos { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
402 1.1 christos },
403 1.1 christos /* be $r0,$r1,$branch */
404 1.1 christos {
405 1.1 christos LM32_INSN_BE, "be", "be", 32,
406 1.1 christos { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
407 1.1 christos },
408 1.1 christos /* bg $r0,$r1,$branch */
409 1.1 christos {
410 1.1 christos LM32_INSN_BG, "bg", "bg", 32,
411 1.1 christos { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
412 1.1 christos },
413 1.1 christos /* bge $r0,$r1,$branch */
414 1.1 christos {
415 1.1 christos LM32_INSN_BGE, "bge", "bge", 32,
416 1.1 christos { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
417 1.1 christos },
418 1.1 christos /* bgeu $r0,$r1,$branch */
419 1.1 christos {
420 1.1 christos LM32_INSN_BGEU, "bgeu", "bgeu", 32,
421 1.1 christos { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
422 1.1 christos },
423 1.1 christos /* bgu $r0,$r1,$branch */
424 1.1 christos {
425 1.1 christos LM32_INSN_BGU, "bgu", "bgu", 32,
426 1.1 christos { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
427 1.1 christos },
428 1.1 christos /* bne $r0,$r1,$branch */
429 1.1 christos {
430 1.1 christos LM32_INSN_BNE, "bne", "bne", 32,
431 1.1 christos { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
432 1.1 christos },
433 1.1 christos /* call $r0 */
434 1.1 christos {
435 1.1 christos LM32_INSN_CALL, "call", "call", 32,
436 1.1 christos { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
437 1.1 christos },
438 1.1 christos /* calli $call */
439 1.1 christos {
440 1.1 christos LM32_INSN_CALLI, "calli", "calli", 32,
441 1.1 christos { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
442 1.1 christos },
443 1.1 christos /* cmpe $r2,$r0,$r1 */
444 1.1 christos {
445 1.1 christos LM32_INSN_CMPE, "cmpe", "cmpe", 32,
446 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
447 1.1 christos },
448 1.1 christos /* cmpei $r1,$r0,$imm */
449 1.1 christos {
450 1.1 christos LM32_INSN_CMPEI, "cmpei", "cmpei", 32,
451 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
452 1.1 christos },
453 1.1 christos /* cmpg $r2,$r0,$r1 */
454 1.1 christos {
455 1.1 christos LM32_INSN_CMPG, "cmpg", "cmpg", 32,
456 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
457 1.1 christos },
458 1.1 christos /* cmpgi $r1,$r0,$imm */
459 1.1 christos {
460 1.1 christos LM32_INSN_CMPGI, "cmpgi", "cmpgi", 32,
461 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
462 1.1 christos },
463 1.1 christos /* cmpge $r2,$r0,$r1 */
464 1.1 christos {
465 1.1 christos LM32_INSN_CMPGE, "cmpge", "cmpge", 32,
466 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
467 1.1 christos },
468 1.1 christos /* cmpgei $r1,$r0,$imm */
469 1.1 christos {
470 1.1 christos LM32_INSN_CMPGEI, "cmpgei", "cmpgei", 32,
471 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
472 1.1 christos },
473 1.1 christos /* cmpgeu $r2,$r0,$r1 */
474 1.1 christos {
475 1.1 christos LM32_INSN_CMPGEU, "cmpgeu", "cmpgeu", 32,
476 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
477 1.1 christos },
478 1.1 christos /* cmpgeui $r1,$r0,$uimm */
479 1.1 christos {
480 1.1 christos LM32_INSN_CMPGEUI, "cmpgeui", "cmpgeui", 32,
481 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
482 1.1 christos },
483 1.1 christos /* cmpgu $r2,$r0,$r1 */
484 1.1 christos {
485 1.1 christos LM32_INSN_CMPGU, "cmpgu", "cmpgu", 32,
486 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
487 1.1 christos },
488 1.1 christos /* cmpgui $r1,$r0,$uimm */
489 1.1 christos {
490 1.1 christos LM32_INSN_CMPGUI, "cmpgui", "cmpgui", 32,
491 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
492 1.1 christos },
493 1.1 christos /* cmpne $r2,$r0,$r1 */
494 1.1 christos {
495 1.1 christos LM32_INSN_CMPNE, "cmpne", "cmpne", 32,
496 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
497 1.1 christos },
498 1.1 christos /* cmpnei $r1,$r0,$imm */
499 1.1 christos {
500 1.1 christos LM32_INSN_CMPNEI, "cmpnei", "cmpnei", 32,
501 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
502 1.1 christos },
503 1.1 christos /* divu $r2,$r0,$r1 */
504 1.1 christos {
505 1.1 christos LM32_INSN_DIVU, "divu", "divu", 32,
506 1.1 christos { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
507 1.1 christos },
508 1.1 christos /* lb $r1,($r0+$imm) */
509 1.1 christos {
510 1.1 christos LM32_INSN_LB, "lb", "lb", 32,
511 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
512 1.1 christos },
513 1.1 christos /* lbu $r1,($r0+$imm) */
514 1.1 christos {
515 1.1 christos LM32_INSN_LBU, "lbu", "lbu", 32,
516 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
517 1.1 christos },
518 1.1 christos /* lh $r1,($r0+$imm) */
519 1.1 christos {
520 1.1 christos LM32_INSN_LH, "lh", "lh", 32,
521 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
522 1.1 christos },
523 1.1 christos /* lhu $r1,($r0+$imm) */
524 1.1 christos {
525 1.1 christos LM32_INSN_LHU, "lhu", "lhu", 32,
526 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
527 1.1 christos },
528 1.1 christos /* lw $r1,($r0+$imm) */
529 1.1 christos {
530 1.1 christos LM32_INSN_LW, "lw", "lw", 32,
531 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
532 1.1 christos },
533 1.1 christos /* modu $r2,$r0,$r1 */
534 1.1 christos {
535 1.1 christos LM32_INSN_MODU, "modu", "modu", 32,
536 1.1 christos { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
537 1.1 christos },
538 1.1 christos /* mul $r2,$r0,$r1 */
539 1.1 christos {
540 1.1 christos LM32_INSN_MUL, "mul", "mul", 32,
541 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
542 1.1 christos },
543 1.1 christos /* muli $r1,$r0,$imm */
544 1.1 christos {
545 1.1 christos LM32_INSN_MULI, "muli", "muli", 32,
546 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
547 1.1 christos },
548 1.1 christos /* nor $r2,$r0,$r1 */
549 1.1 christos {
550 1.1 christos LM32_INSN_NOR, "nor", "nor", 32,
551 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
552 1.1 christos },
553 1.1 christos /* nori $r1,$r0,$uimm */
554 1.1 christos {
555 1.1 christos LM32_INSN_NORI, "nori", "nori", 32,
556 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
557 1.1 christos },
558 1.1 christos /* or $r2,$r0,$r1 */
559 1.1 christos {
560 1.1 christos LM32_INSN_OR, "or", "or", 32,
561 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
562 1.1 christos },
563 1.1 christos /* ori $r1,$r0,$lo16 */
564 1.1 christos {
565 1.1 christos LM32_INSN_ORI, "ori", "ori", 32,
566 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
567 1.1 christos },
568 1.1 christos /* orhi $r1,$r0,$hi16 */
569 1.1 christos {
570 1.1 christos LM32_INSN_ORHII, "orhii", "orhi", 32,
571 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
572 1.1 christos },
573 1.1 christos /* rcsr $r2,$csr */
574 1.1 christos {
575 1.1 christos LM32_INSN_RCSR, "rcsr", "rcsr", 32,
576 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
577 1.1 christos },
578 1.1 christos /* sb ($r0+$imm),$r1 */
579 1.1 christos {
580 1.1 christos LM32_INSN_SB, "sb", "sb", 32,
581 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
582 1.1 christos },
583 1.1 christos /* sextb $r2,$r0 */
584 1.1 christos {
585 1.1 christos LM32_INSN_SEXTB, "sextb", "sextb", 32,
586 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
587 1.1 christos },
588 1.1 christos /* sexth $r2,$r0 */
589 1.1 christos {
590 1.1 christos LM32_INSN_SEXTH, "sexth", "sexth", 32,
591 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
592 1.1 christos },
593 1.1 christos /* sh ($r0+$imm),$r1 */
594 1.1 christos {
595 1.1 christos LM32_INSN_SH, "sh", "sh", 32,
596 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
597 1.1 christos },
598 1.1 christos /* sl $r2,$r0,$r1 */
599 1.1 christos {
600 1.1 christos LM32_INSN_SL, "sl", "sl", 32,
601 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
602 1.1 christos },
603 1.1 christos /* sli $r1,$r0,$imm */
604 1.1 christos {
605 1.1 christos LM32_INSN_SLI, "sli", "sli", 32,
606 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
607 1.1 christos },
608 1.1 christos /* sr $r2,$r0,$r1 */
609 1.1 christos {
610 1.1 christos LM32_INSN_SR, "sr", "sr", 32,
611 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
612 1.1 christos },
613 1.1 christos /* sri $r1,$r0,$imm */
614 1.1 christos {
615 1.1 christos LM32_INSN_SRI, "sri", "sri", 32,
616 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
617 1.1 christos },
618 1.1 christos /* sru $r2,$r0,$r1 */
619 1.1 christos {
620 1.1 christos LM32_INSN_SRU, "sru", "sru", 32,
621 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
622 1.1 christos },
623 1.1 christos /* srui $r1,$r0,$imm */
624 1.1 christos {
625 1.1 christos LM32_INSN_SRUI, "srui", "srui", 32,
626 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
627 1.1 christos },
628 1.1 christos /* sub $r2,$r0,$r1 */
629 1.1 christos {
630 1.1 christos LM32_INSN_SUB, "sub", "sub", 32,
631 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
632 1.1 christos },
633 1.1 christos /* sw ($r0+$imm),$r1 */
634 1.1 christos {
635 1.1 christos LM32_INSN_SW, "sw", "sw", 32,
636 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
637 1.1 christos },
638 1.1 christos /* user $r2,$r0,$r1,$user */
639 1.1 christos {
640 1.1 christos LM32_INSN_USER, "user", "user", 32,
641 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
642 1.1 christos },
643 1.1 christos /* wcsr $csr,$r1 */
644 1.1 christos {
645 1.1 christos LM32_INSN_WCSR, "wcsr", "wcsr", 32,
646 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
647 1.1 christos },
648 1.1 christos /* xor $r2,$r0,$r1 */
649 1.1 christos {
650 1.1 christos LM32_INSN_XOR, "xor", "xor", 32,
651 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
652 1.1 christos },
653 1.1 christos /* xori $r1,$r0,$uimm */
654 1.1 christos {
655 1.1 christos LM32_INSN_XORI, "xori", "xori", 32,
656 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
657 1.1 christos },
658 1.1 christos /* xnor $r2,$r0,$r1 */
659 1.1 christos {
660 1.1 christos LM32_INSN_XNOR, "xnor", "xnor", 32,
661 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
662 1.1 christos },
663 1.1 christos /* xnori $r1,$r0,$uimm */
664 1.1 christos {
665 1.1 christos LM32_INSN_XNORI, "xnori", "xnori", 32,
666 1.1 christos { 0, { { { (1<<MACH_BASE), 0 } } } }
667 1.1 christos },
668 1.1 christos /* break */
669 1.1 christos {
670 1.1 christos LM32_INSN_BREAK, "break", "break", 32,
671 1.1 christos { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
672 1.1 christos },
673 1.1 christos /* scall */
674 1.1 christos {
675 1.1 christos LM32_INSN_SCALL, "scall", "scall", 32,
676 1.1 christos { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
677 1.1 christos },
678 1.1 christos /* bret */
679 1.1 christos {
680 1.1 christos -1, "bret", "bret", 32,
681 1.1 christos { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
682 1.1 christos },
683 1.1 christos /* eret */
684 1.1 christos {
685 1.1 christos -1, "eret", "eret", 32,
686 1.1 christos { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
687 1.1 christos },
688 1.1 christos /* ret */
689 1.1 christos {
690 1.1 christos -1, "ret", "ret", 32,
691 1.1 christos { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
692 1.1 christos },
693 1.1 christos /* mv $r2,$r0 */
694 1.1 christos {
695 1.1 christos -1, "mv", "mv", 32,
696 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
697 1.1 christos },
698 1.1 christos /* mvi $r1,$imm */
699 1.1 christos {
700 1.1 christos -1, "mvi", "mvi", 32,
701 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
702 1.1 christos },
703 1.1 christos /* mvu $r1,$lo16 */
704 1.1 christos {
705 1.1 christos -1, "mvui", "mvu", 32,
706 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
707 1.1 christos },
708 1.1 christos /* mvhi $r1,$hi16 */
709 1.1 christos {
710 1.1 christos -1, "mvhi", "mvhi", 32,
711 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
712 1.1 christos },
713 1.1 christos /* mva $r1,$gp16 */
714 1.1 christos {
715 1.1 christos -1, "mva", "mva", 32,
716 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
717 1.1 christos },
718 1.1 christos /* not $r2,$r0 */
719 1.1 christos {
720 1.1 christos -1, "not", "not", 32,
721 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
722 1.1 christos },
723 1.1 christos /* nop */
724 1.1 christos {
725 1.1 christos -1, "nop", "nop", 32,
726 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
727 1.1 christos },
728 1.1 christos /* lb $r1,$gp16 */
729 1.1 christos {
730 1.1 christos -1, "lbgprel", "lb", 32,
731 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
732 1.1 christos },
733 1.1 christos /* lbu $r1,$gp16 */
734 1.1 christos {
735 1.1 christos -1, "lbugprel", "lbu", 32,
736 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
737 1.1 christos },
738 1.1 christos /* lh $r1,$gp16 */
739 1.1 christos {
740 1.1 christos -1, "lhgprel", "lh", 32,
741 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
742 1.1 christos },
743 1.1 christos /* lhu $r1,$gp16 */
744 1.1 christos {
745 1.1 christos -1, "lhugprel", "lhu", 32,
746 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
747 1.1 christos },
748 1.1 christos /* lw $r1,$gp16 */
749 1.1 christos {
750 1.1 christos -1, "lwgprel", "lw", 32,
751 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
752 1.1 christos },
753 1.1 christos /* sb $gp16,$r1 */
754 1.1 christos {
755 1.1 christos -1, "sbgprel", "sb", 32,
756 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
757 1.1 christos },
758 1.1 christos /* sh $gp16,$r1 */
759 1.1 christos {
760 1.1 christos -1, "shgprel", "sh", 32,
761 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
762 1.1 christos },
763 1.1 christos /* sw $gp16,$r1 */
764 1.1 christos {
765 1.1 christos -1, "swgprel", "sw", 32,
766 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
767 1.1 christos },
768 1.1 christos /* lw $r1,(gp+$got16) */
769 1.1 christos {
770 1.1 christos -1, "lwgotrel", "lw", 32,
771 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
772 1.1 christos },
773 1.1 christos /* orhi $r1,$r0,$gotoffhi16 */
774 1.1 christos {
775 1.1 christos -1, "orhigotoffi", "orhi", 32,
776 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
777 1.1 christos },
778 1.1 christos /* addi $r1,$r0,$gotofflo16 */
779 1.1 christos {
780 1.1 christos -1, "addgotoff", "addi", 32,
781 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
782 1.1 christos },
783 1.1 christos /* sw ($r0+$gotofflo16),$r1 */
784 1.1 christos {
785 1.1 christos -1, "swgotoff", "sw", 32,
786 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
787 1.1 christos },
788 1.1 christos /* lw $r1,($r0+$gotofflo16) */
789 1.1 christos {
790 1.1 christos -1, "lwgotoff", "lw", 32,
791 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
792 1.1 christos },
793 1.1 christos /* sh ($r0+$gotofflo16),$r1 */
794 1.1 christos {
795 1.1 christos -1, "shgotoff", "sh", 32,
796 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
797 1.1 christos },
798 1.1 christos /* lh $r1,($r0+$gotofflo16) */
799 1.1 christos {
800 1.1 christos -1, "lhgotoff", "lh", 32,
801 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
802 1.1 christos },
803 1.1 christos /* lhu $r1,($r0+$gotofflo16) */
804 1.1 christos {
805 1.1 christos -1, "lhugotoff", "lhu", 32,
806 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
807 1.1 christos },
808 1.1 christos /* sb ($r0+$gotofflo16),$r1 */
809 1.1 christos {
810 1.1 christos -1, "sbgotoff", "sb", 32,
811 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
812 1.1 christos },
813 1.1 christos /* lb $r1,($r0+$gotofflo16) */
814 1.1 christos {
815 1.1 christos -1, "lbgotoff", "lb", 32,
816 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
817 1.1 christos },
818 1.1 christos /* lbu $r1,($r0+$gotofflo16) */
819 1.1 christos {
820 1.1 christos -1, "lbugotoff", "lbu", 32,
821 1.1 christos { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
822 1.1 christos },
823 1.1 christos };
824 1.1 christos
825 1.1 christos #undef OP
826 1.1 christos #undef A
827 1.1 christos
828 1.1 christos /* Initialize anything needed to be done once, before any cpu_open call. */
829 1.1 christos
830 1.1 christos static void
831 1.1 christos init_tables (void)
832 1.1 christos {
833 1.1 christos }
834 1.1 christos
835 1.8 christos #ifndef opcodes_error_handler
836 1.8 christos #define opcodes_error_handler(...) \
837 1.8 christos fprintf (stderr, __VA_ARGS__); fputc ('\n', stderr)
838 1.8 christos #endif
839 1.8 christos
840 1.1 christos static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
841 1.1 christos static void build_hw_table (CGEN_CPU_TABLE *);
842 1.1 christos static void build_ifield_table (CGEN_CPU_TABLE *);
843 1.1 christos static void build_operand_table (CGEN_CPU_TABLE *);
844 1.1 christos static void build_insn_table (CGEN_CPU_TABLE *);
845 1.1 christos static void lm32_cgen_rebuild_tables (CGEN_CPU_TABLE *);
846 1.1 christos
847 1.1 christos /* Subroutine of lm32_cgen_cpu_open to look up a mach via its bfd name. */
848 1.1 christos
849 1.1 christos static const CGEN_MACH *
850 1.1 christos lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
851 1.1 christos {
852 1.1 christos while (table->name)
853 1.1 christos {
854 1.1 christos if (strcmp (name, table->bfd_name) == 0)
855 1.1 christos return table;
856 1.1 christos ++table;
857 1.1 christos }
858 1.7 christos return NULL;
859 1.1 christos }
860 1.1 christos
861 1.1 christos /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
862 1.1 christos
863 1.1 christos static void
864 1.1 christos build_hw_table (CGEN_CPU_TABLE *cd)
865 1.1 christos {
866 1.1 christos int i;
867 1.1 christos int machs = cd->machs;
868 1.1 christos const CGEN_HW_ENTRY *init = & lm32_cgen_hw_table[0];
869 1.1 christos /* MAX_HW is only an upper bound on the number of selected entries.
870 1.1 christos However each entry is indexed by it's enum so there can be holes in
871 1.1 christos the table. */
872 1.1 christos const CGEN_HW_ENTRY **selected =
873 1.1 christos (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
874 1.1 christos
875 1.1 christos cd->hw_table.init_entries = init;
876 1.1 christos cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
877 1.1 christos memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
878 1.1 christos /* ??? For now we just use machs to determine which ones we want. */
879 1.1 christos for (i = 0; init[i].name != NULL; ++i)
880 1.1 christos if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
881 1.1 christos & machs)
882 1.1 christos selected[init[i].type] = &init[i];
883 1.1 christos cd->hw_table.entries = selected;
884 1.1 christos cd->hw_table.num_entries = MAX_HW;
885 1.1 christos }
886 1.1 christos
887 1.1 christos /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
888 1.1 christos
889 1.1 christos static void
890 1.1 christos build_ifield_table (CGEN_CPU_TABLE *cd)
891 1.1 christos {
892 1.1 christos cd->ifld_table = & lm32_cgen_ifld_table[0];
893 1.1 christos }
894 1.1 christos
895 1.1 christos /* Subroutine of lm32_cgen_cpu_open to build the hardware table. */
896 1.1 christos
897 1.1 christos static void
898 1.1 christos build_operand_table (CGEN_CPU_TABLE *cd)
899 1.1 christos {
900 1.1 christos int i;
901 1.1 christos int machs = cd->machs;
902 1.1 christos const CGEN_OPERAND *init = & lm32_cgen_operand_table[0];
903 1.1 christos /* MAX_OPERANDS is only an upper bound on the number of selected entries.
904 1.1 christos However each entry is indexed by it's enum so there can be holes in
905 1.1 christos the table. */
906 1.1 christos const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
907 1.1 christos
908 1.1 christos cd->operand_table.init_entries = init;
909 1.1 christos cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
910 1.1 christos memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
911 1.1 christos /* ??? For now we just use mach to determine which ones we want. */
912 1.1 christos for (i = 0; init[i].name != NULL; ++i)
913 1.1 christos if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
914 1.1 christos & machs)
915 1.1 christos selected[init[i].type] = &init[i];
916 1.1 christos cd->operand_table.entries = selected;
917 1.1 christos cd->operand_table.num_entries = MAX_OPERANDS;
918 1.1 christos }
919 1.1 christos
920 1.1 christos /* Subroutine of lm32_cgen_cpu_open to build the hardware table.
921 1.1 christos ??? This could leave out insns not supported by the specified mach/isa,
922 1.1 christos but that would cause errors like "foo only supported by bar" to become
923 1.1 christos "unknown insn", so for now we include all insns and require the app to
924 1.1 christos do the checking later.
925 1.1 christos ??? On the other hand, parsing of such insns may require their hardware or
926 1.1 christos operand elements to be in the table [which they mightn't be]. */
927 1.1 christos
928 1.1 christos static void
929 1.1 christos build_insn_table (CGEN_CPU_TABLE *cd)
930 1.1 christos {
931 1.1 christos int i;
932 1.1 christos const CGEN_IBASE *ib = & lm32_cgen_insn_table[0];
933 1.1 christos CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
934 1.1 christos
935 1.1 christos memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
936 1.1 christos for (i = 0; i < MAX_INSNS; ++i)
937 1.1 christos insns[i].base = &ib[i];
938 1.1 christos cd->insn_table.init_entries = insns;
939 1.1 christos cd->insn_table.entry_size = sizeof (CGEN_IBASE);
940 1.1 christos cd->insn_table.num_init_entries = MAX_INSNS;
941 1.1 christos }
942 1.1 christos
943 1.1 christos /* Subroutine of lm32_cgen_cpu_open to rebuild the tables. */
944 1.1 christos
945 1.1 christos static void
946 1.1 christos lm32_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
947 1.1 christos {
948 1.1 christos int i;
949 1.1 christos CGEN_BITSET *isas = cd->isas;
950 1.1 christos unsigned int machs = cd->machs;
951 1.1 christos
952 1.1 christos cd->int_insn_p = CGEN_INT_INSN_P;
953 1.1 christos
954 1.1 christos /* Data derived from the isa spec. */
955 1.1 christos #define UNSET (CGEN_SIZE_UNKNOWN + 1)
956 1.1 christos cd->default_insn_bitsize = UNSET;
957 1.1 christos cd->base_insn_bitsize = UNSET;
958 1.1 christos cd->min_insn_bitsize = 65535; /* Some ridiculously big number. */
959 1.1 christos cd->max_insn_bitsize = 0;
960 1.1 christos for (i = 0; i < MAX_ISAS; ++i)
961 1.1 christos if (cgen_bitset_contains (isas, i))
962 1.1 christos {
963 1.1 christos const CGEN_ISA *isa = & lm32_cgen_isa_table[i];
964 1.1 christos
965 1.1 christos /* Default insn sizes of all selected isas must be
966 1.1 christos equal or we set the result to 0, meaning "unknown". */
967 1.1 christos if (cd->default_insn_bitsize == UNSET)
968 1.1 christos cd->default_insn_bitsize = isa->default_insn_bitsize;
969 1.1 christos else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
970 1.1 christos ; /* This is ok. */
971 1.1 christos else
972 1.1 christos cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
973 1.1 christos
974 1.1 christos /* Base insn sizes of all selected isas must be equal
975 1.1 christos or we set the result to 0, meaning "unknown". */
976 1.1 christos if (cd->base_insn_bitsize == UNSET)
977 1.1 christos cd->base_insn_bitsize = isa->base_insn_bitsize;
978 1.1 christos else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
979 1.1 christos ; /* This is ok. */
980 1.1 christos else
981 1.1 christos cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
982 1.1 christos
983 1.1 christos /* Set min,max insn sizes. */
984 1.1 christos if (isa->min_insn_bitsize < cd->min_insn_bitsize)
985 1.1 christos cd->min_insn_bitsize = isa->min_insn_bitsize;
986 1.1 christos if (isa->max_insn_bitsize > cd->max_insn_bitsize)
987 1.1 christos cd->max_insn_bitsize = isa->max_insn_bitsize;
988 1.1 christos }
989 1.1 christos
990 1.1 christos /* Data derived from the mach spec. */
991 1.1 christos for (i = 0; i < MAX_MACHS; ++i)
992 1.1 christos if (((1 << i) & machs) != 0)
993 1.1 christos {
994 1.1 christos const CGEN_MACH *mach = & lm32_cgen_mach_table[i];
995 1.1 christos
996 1.1 christos if (mach->insn_chunk_bitsize != 0)
997 1.1 christos {
998 1.1 christos if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
999 1.1 christos {
1000 1.8 christos opcodes_error_handler
1001 1.8 christos (/* xgettext:c-format */
1002 1.8 christos _("internal error: lm32_cgen_rebuild_tables: "
1003 1.8 christos "conflicting insn-chunk-bitsize values: `%d' vs. `%d'"),
1004 1.8 christos cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
1005 1.1 christos abort ();
1006 1.1 christos }
1007 1.1 christos
1008 1.1 christos cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
1009 1.1 christos }
1010 1.1 christos }
1011 1.1 christos
1012 1.1 christos /* Determine which hw elements are used by MACH. */
1013 1.1 christos build_hw_table (cd);
1014 1.1 christos
1015 1.1 christos /* Build the ifield table. */
1016 1.1 christos build_ifield_table (cd);
1017 1.1 christos
1018 1.1 christos /* Determine which operands are used by MACH/ISA. */
1019 1.1 christos build_operand_table (cd);
1020 1.1 christos
1021 1.1 christos /* Build the instruction table. */
1022 1.1 christos build_insn_table (cd);
1023 1.1 christos }
1024 1.1 christos
1025 1.1 christos /* Initialize a cpu table and return a descriptor.
1026 1.1 christos It's much like opening a file, and must be the first function called.
1027 1.1 christos The arguments are a set of (type/value) pairs, terminated with
1028 1.1 christos CGEN_CPU_OPEN_END.
1029 1.1 christos
1030 1.1 christos Currently supported values:
1031 1.1 christos CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
1032 1.1 christos CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
1033 1.1 christos CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
1034 1.1 christos CGEN_CPU_OPEN_ENDIAN: specify endian choice
1035 1.1 christos CGEN_CPU_OPEN_END: terminates arguments
1036 1.1 christos
1037 1.1 christos ??? Simultaneous multiple isas might not make sense, but it's not (yet)
1038 1.1 christos precluded. */
1039 1.1 christos
1040 1.1 christos CGEN_CPU_DESC
1041 1.1 christos lm32_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
1042 1.1 christos {
1043 1.1 christos CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
1044 1.1 christos static int init_p;
1045 1.1 christos CGEN_BITSET *isas = 0; /* 0 = "unspecified" */
1046 1.1 christos unsigned int machs = 0; /* 0 = "unspecified" */
1047 1.1 christos enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
1048 1.1 christos va_list ap;
1049 1.1 christos
1050 1.1 christos if (! init_p)
1051 1.1 christos {
1052 1.1 christos init_tables ();
1053 1.1 christos init_p = 1;
1054 1.1 christos }
1055 1.1 christos
1056 1.1 christos memset (cd, 0, sizeof (*cd));
1057 1.1 christos
1058 1.1 christos va_start (ap, arg_type);
1059 1.1 christos while (arg_type != CGEN_CPU_OPEN_END)
1060 1.1 christos {
1061 1.1 christos switch (arg_type)
1062 1.1 christos {
1063 1.1 christos case CGEN_CPU_OPEN_ISAS :
1064 1.1 christos isas = va_arg (ap, CGEN_BITSET *);
1065 1.1 christos break;
1066 1.1 christos case CGEN_CPU_OPEN_MACHS :
1067 1.1 christos machs = va_arg (ap, unsigned int);
1068 1.1 christos break;
1069 1.1 christos case CGEN_CPU_OPEN_BFDMACH :
1070 1.1 christos {
1071 1.1 christos const char *name = va_arg (ap, const char *);
1072 1.1 christos const CGEN_MACH *mach =
1073 1.1 christos lookup_mach_via_bfd_name (lm32_cgen_mach_table, name);
1074 1.1 christos
1075 1.7 christos if (mach != NULL)
1076 1.7 christos machs |= 1 << mach->num;
1077 1.1 christos break;
1078 1.1 christos }
1079 1.1 christos case CGEN_CPU_OPEN_ENDIAN :
1080 1.1 christos endian = va_arg (ap, enum cgen_endian);
1081 1.1 christos break;
1082 1.1 christos default :
1083 1.8 christos opcodes_error_handler
1084 1.8 christos (/* xgettext:c-format */
1085 1.8 christos _("internal error: lm32_cgen_cpu_open: "
1086 1.8 christos "unsupported argument `%d'"),
1087 1.8 christos arg_type);
1088 1.1 christos abort (); /* ??? return NULL? */
1089 1.1 christos }
1090 1.1 christos arg_type = va_arg (ap, enum cgen_cpu_open_arg);
1091 1.1 christos }
1092 1.1 christos va_end (ap);
1093 1.1 christos
1094 1.1 christos /* Mach unspecified means "all". */
1095 1.1 christos if (machs == 0)
1096 1.1 christos machs = (1 << MAX_MACHS) - 1;
1097 1.1 christos /* Base mach is always selected. */
1098 1.1 christos machs |= 1;
1099 1.1 christos if (endian == CGEN_ENDIAN_UNKNOWN)
1100 1.1 christos {
1101 1.1 christos /* ??? If target has only one, could have a default. */
1102 1.8 christos opcodes_error_handler
1103 1.8 christos (/* xgettext:c-format */
1104 1.8 christos _("internal error: lm32_cgen_cpu_open: no endianness specified"));
1105 1.1 christos abort ();
1106 1.1 christos }
1107 1.1 christos
1108 1.1 christos cd->isas = cgen_bitset_copy (isas);
1109 1.1 christos cd->machs = machs;
1110 1.1 christos cd->endian = endian;
1111 1.1 christos /* FIXME: for the sparc case we can determine insn-endianness statically.
1112 1.1 christos The worry here is where both data and insn endian can be independently
1113 1.1 christos chosen, in which case this function will need another argument.
1114 1.1 christos Actually, will want to allow for more arguments in the future anyway. */
1115 1.1 christos cd->insn_endian = endian;
1116 1.1 christos
1117 1.1 christos /* Table (re)builder. */
1118 1.1 christos cd->rebuild_tables = lm32_cgen_rebuild_tables;
1119 1.1 christos lm32_cgen_rebuild_tables (cd);
1120 1.1 christos
1121 1.1 christos /* Default to not allowing signed overflow. */
1122 1.1 christos cd->signed_overflow_ok_p = 0;
1123 1.6 christos
1124 1.1 christos return (CGEN_CPU_DESC) cd;
1125 1.1 christos }
1126 1.1 christos
1127 1.1 christos /* Cover fn to lm32_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
1128 1.1 christos MACH_NAME is the bfd name of the mach. */
1129 1.1 christos
1130 1.1 christos CGEN_CPU_DESC
1131 1.1 christos lm32_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
1132 1.1 christos {
1133 1.1 christos return lm32_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
1134 1.1 christos CGEN_CPU_OPEN_ENDIAN, endian,
1135 1.1 christos CGEN_CPU_OPEN_END);
1136 1.1 christos }
1137 1.1 christos
1138 1.1 christos /* Close a cpu table.
1139 1.1 christos ??? This can live in a machine independent file, but there's currently
1140 1.1 christos no place to put this file (there's no libcgen). libopcodes is the wrong
1141 1.1 christos place as some simulator ports use this but they don't use libopcodes. */
1142 1.1 christos
1143 1.1 christos void
1144 1.1 christos lm32_cgen_cpu_close (CGEN_CPU_DESC cd)
1145 1.1 christos {
1146 1.1 christos unsigned int i;
1147 1.1 christos const CGEN_INSN *insns;
1148 1.1 christos
1149 1.1 christos if (cd->macro_insn_table.init_entries)
1150 1.1 christos {
1151 1.1 christos insns = cd->macro_insn_table.init_entries;
1152 1.1 christos for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
1153 1.1 christos if (CGEN_INSN_RX ((insns)))
1154 1.1 christos regfree (CGEN_INSN_RX (insns));
1155 1.1 christos }
1156 1.1 christos
1157 1.1 christos if (cd->insn_table.init_entries)
1158 1.1 christos {
1159 1.1 christos insns = cd->insn_table.init_entries;
1160 1.1 christos for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
1161 1.1 christos if (CGEN_INSN_RX (insns))
1162 1.1 christos regfree (CGEN_INSN_RX (insns));
1163 1.6 christos }
1164 1.1 christos
1165 1.1 christos if (cd->macro_insn_table.init_entries)
1166 1.1 christos free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
1167 1.1 christos
1168 1.1 christos if (cd->insn_table.init_entries)
1169 1.1 christos free ((CGEN_INSN *) cd->insn_table.init_entries);
1170 1.1 christos
1171 1.1 christos if (cd->hw_table.entries)
1172 1.1 christos free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1173 1.1 christos
1174 1.1 christos if (cd->operand_table.entries)
1175 1.1 christos free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
1176 1.1 christos
1177 1.1 christos free (cd);
1178 1.1 christos }
1179 1.1 christos
1180