1999-09-11 Donn Terry <donn@interix.com>
[binutils.git] / opcodes / m32r-desc.c
blob9cb5462502e2d98f6aebad0117af5c60a4b0fd01
1 /* CPU data for m32r.
3 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
7 This file is part of the GNU Binutils and/or GDB, the GNU debugger.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License along
20 with this program; if not, write to the Free Software Foundation, Inc.,
21 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include "sysdep.h"
26 #include <ctype.h>
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include "ansidecl.h"
30 #include "bfd.h"
31 #include "symcat.h"
32 #include "m32r-desc.h"
33 #include "m32r-opc.h"
34 #include "opintl.h"
36 /* Attributes. */
38 static const CGEN_ATTR_ENTRY bool_attr[] =
40 { "#f", 0 },
41 { "#t", 1 },
42 { 0, 0 }
45 static const CGEN_ATTR_ENTRY MACH_attr[] =
47 { "base", MACH_BASE },
48 { "m32r", MACH_M32R },
49 { "max", MACH_MAX },
50 { 0, 0 }
53 static const CGEN_ATTR_ENTRY ISA_attr[] =
55 { "m32r", ISA_M32R },
56 { "max", ISA_MAX },
57 { 0, 0 }
60 const CGEN_ATTR_TABLE m32r_cgen_ifield_attr_table[] =
62 { "MACH", & MACH_attr[0] },
63 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
64 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
65 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
66 { "RESERVED", &bool_attr[0], &bool_attr[0] },
67 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
68 { "SIGNED", &bool_attr[0], &bool_attr[0] },
69 { "RELOC", &bool_attr[0], &bool_attr[0] },
70 { 0, 0, 0 }
73 const CGEN_ATTR_TABLE m32r_cgen_hardware_attr_table[] =
75 { "MACH", & MACH_attr[0] },
76 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
77 { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
78 { "PC", &bool_attr[0], &bool_attr[0] },
79 { "PROFILE", &bool_attr[0], &bool_attr[0] },
80 { 0, 0, 0 }
83 const CGEN_ATTR_TABLE m32r_cgen_operand_attr_table[] =
85 { "MACH", & MACH_attr[0] },
86 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
87 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
88 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
89 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
90 { "SIGNED", &bool_attr[0], &bool_attr[0] },
91 { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
92 { "RELAX", &bool_attr[0], &bool_attr[0] },
93 { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
94 { "RELOC", &bool_attr[0], &bool_attr[0] },
95 { "HASH-PREFIX", &bool_attr[0], &bool_attr[0] },
96 { 0, 0, 0 }
99 const CGEN_ATTR_TABLE m32r_cgen_insn_attr_table[] =
101 { "MACH", & MACH_attr[0] },
102 { "ALIAS", &bool_attr[0], &bool_attr[0] },
103 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
104 { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
105 { "COND-CTI", &bool_attr[0], &bool_attr[0] },
106 { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
107 { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
108 { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
109 { "RELAX", &bool_attr[0], &bool_attr[0] },
110 { "NO-DIS", &bool_attr[0], &bool_attr[0] },
111 { "PBB", &bool_attr[0], &bool_attr[0] },
112 { "FILL-SLOT", &bool_attr[0], &bool_attr[0] },
113 { 0, 0, 0 }
116 /* Instruction set variants. */
118 static const CGEN_ISA m32r_cgen_isa_table[] = {
119 { "m32r", 32, 32, 16, 32, },
120 { 0 }
123 /* Machine variants. */
125 static const CGEN_MACH m32r_cgen_mach_table[] = {
126 { "m32r", "m32r", MACH_M32R },
127 { 0 }
130 static CGEN_KEYWORD_ENTRY m32r_cgen_opval_gr_names_entries[] =
132 { "fp", 13 },
133 { "lr", 14 },
134 { "sp", 15 },
135 { "r0", 0 },
136 { "r1", 1 },
137 { "r2", 2 },
138 { "r3", 3 },
139 { "r4", 4 },
140 { "r5", 5 },
141 { "r6", 6 },
142 { "r7", 7 },
143 { "r8", 8 },
144 { "r9", 9 },
145 { "r10", 10 },
146 { "r11", 11 },
147 { "r12", 12 },
148 { "r13", 13 },
149 { "r14", 14 },
150 { "r15", 15 }
153 CGEN_KEYWORD m32r_cgen_opval_gr_names =
155 & m32r_cgen_opval_gr_names_entries[0],
159 static CGEN_KEYWORD_ENTRY m32r_cgen_opval_cr_names_entries[] =
161 { "psw", 0 },
162 { "cbr", 1 },
163 { "spi", 2 },
164 { "spu", 3 },
165 { "bpc", 6 },
166 { "bbpsw", 8 },
167 { "bbpc", 14 },
168 { "cr0", 0 },
169 { "cr1", 1 },
170 { "cr2", 2 },
171 { "cr3", 3 },
172 { "cr4", 4 },
173 { "cr5", 5 },
174 { "cr6", 6 },
175 { "cr7", 7 },
176 { "cr8", 8 },
177 { "cr9", 9 },
178 { "cr10", 10 },
179 { "cr11", 11 },
180 { "cr12", 12 },
181 { "cr13", 13 },
182 { "cr14", 14 },
183 { "cr15", 15 }
186 CGEN_KEYWORD m32r_cgen_opval_cr_names =
188 & m32r_cgen_opval_cr_names_entries[0],
194 /* The hardware table. */
196 #define A(a) (1 << CONCAT2 (CGEN_HW_,a))
198 const CGEN_HW_ENTRY m32r_cgen_hw_table[] =
200 { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
201 { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
202 { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
203 { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
204 { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
205 { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { (1<<MACH_BASE) } } },
206 { "h-hi16", HW_H_HI16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
207 { "h-slo16", HW_H_SLO16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
208 { "h-ulo16", HW_H_ULO16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
209 { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & m32r_cgen_opval_gr_names, { 0|A(CACHE_ADDR)|A(PROFILE), { (1<<MACH_BASE) } } },
210 { "h-cr", HW_H_CR, CGEN_ASM_KEYWORD, (PTR) & m32r_cgen_opval_cr_names, { 0, { (1<<MACH_BASE) } } },
211 { "h-accum", HW_H_ACCUM, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
212 { "h-cond", HW_H_COND, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
213 { "h-psw", HW_H_PSW, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
214 { "h-bpsw", HW_H_BPSW, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
215 { "h-bbpsw", HW_H_BBPSW, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
216 { "h-lock", HW_H_LOCK, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
217 { 0 }
220 #undef A
222 /* The instruction field table. */
224 #define A(a) (1 << CONCAT2 (CGEN_IFLD_,a))
226 const CGEN_IFLD m32r_cgen_ifld_table[] =
228 { M32R_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
229 { M32R_F_OP1, "f-op1", 0, 32, 0, 4, { 0, { (1<<MACH_BASE) } } },
230 { M32R_F_OP2, "f-op2", 0, 32, 8, 4, { 0, { (1<<MACH_BASE) } } },
231 { M32R_F_COND, "f-cond", 0, 32, 4, 4, { 0, { (1<<MACH_BASE) } } },
232 { M32R_F_R1, "f-r1", 0, 32, 4, 4, { 0, { (1<<MACH_BASE) } } },
233 { M32R_F_R2, "f-r2", 0, 32, 12, 4, { 0, { (1<<MACH_BASE) } } },
234 { M32R_F_SIMM8, "f-simm8", 0, 32, 8, 8, { 0, { (1<<MACH_BASE) } } },
235 { M32R_F_SIMM16, "f-simm16", 0, 32, 16, 16, { 0, { (1<<MACH_BASE) } } },
236 { M32R_F_SHIFT_OP2, "f-shift-op2", 0, 32, 8, 3, { 0, { (1<<MACH_BASE) } } },
237 { M32R_F_UIMM4, "f-uimm4", 0, 32, 12, 4, { 0, { (1<<MACH_BASE) } } },
238 { M32R_F_UIMM5, "f-uimm5", 0, 32, 11, 5, { 0, { (1<<MACH_BASE) } } },
239 { M32R_F_UIMM16, "f-uimm16", 0, 32, 16, 16, { 0, { (1<<MACH_BASE) } } },
240 { M32R_F_UIMM24, "f-uimm24", 0, 32, 8, 24, { 0|A(RELOC)|A(ABS_ADDR), { (1<<MACH_BASE) } } },
241 { M32R_F_HI16, "f-hi16", 0, 32, 16, 16, { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
242 { M32R_F_DISP8, "f-disp8", 0, 32, 8, 8, { 0|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
243 { M32R_F_DISP16, "f-disp16", 0, 32, 16, 16, { 0|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
244 { M32R_F_DISP24, "f-disp24", 0, 32, 8, 24, { 0|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
245 { 0 }
248 #undef A
250 /* The operand table. */
252 #define A(a) (1 << CONCAT2 (CGEN_OPERAND_,a))
253 #define OPERAND(op) CONCAT2 (M32R_OPERAND_,op)
255 const CGEN_OPERAND m32r_cgen_operand_table[] =
257 /* pc: program counter */
258 { "pc", M32R_OPERAND_PC, HW_H_PC, 0, 0,
259 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
260 /* sr: source register */
261 { "sr", M32R_OPERAND_SR, HW_H_GR, 12, 4,
262 { 0, { (1<<MACH_BASE) } } },
263 /* dr: destination register */
264 { "dr", M32R_OPERAND_DR, HW_H_GR, 4, 4,
265 { 0, { (1<<MACH_BASE) } } },
266 /* src1: source register 1 */
267 { "src1", M32R_OPERAND_SRC1, HW_H_GR, 4, 4,
268 { 0, { (1<<MACH_BASE) } } },
269 /* src2: source register 2 */
270 { "src2", M32R_OPERAND_SRC2, HW_H_GR, 12, 4,
271 { 0, { (1<<MACH_BASE) } } },
272 /* scr: source control register */
273 { "scr", M32R_OPERAND_SCR, HW_H_CR, 12, 4,
274 { 0, { (1<<MACH_BASE) } } },
275 /* dcr: destination control register */
276 { "dcr", M32R_OPERAND_DCR, HW_H_CR, 4, 4,
277 { 0, { (1<<MACH_BASE) } } },
278 /* simm8: 8 bit signed immediate */
279 { "simm8", M32R_OPERAND_SIMM8, HW_H_SINT, 8, 8,
280 { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
281 /* simm16: 16 bit signed immediate */
282 { "simm16", M32R_OPERAND_SIMM16, HW_H_SINT, 16, 16,
283 { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
284 /* uimm4: 4 bit trap number */
285 { "uimm4", M32R_OPERAND_UIMM4, HW_H_UINT, 12, 4,
286 { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
287 /* uimm5: 5 bit shift count */
288 { "uimm5", M32R_OPERAND_UIMM5, HW_H_UINT, 11, 5,
289 { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
290 /* uimm16: 16 bit unsigned immediate */
291 { "uimm16", M32R_OPERAND_UIMM16, HW_H_UINT, 16, 16,
292 { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
293 /* hash: # prefix */
294 { "hash", M32R_OPERAND_HASH, HW_H_SINT, 0, 0,
295 { 0, { (1<<MACH_BASE) } } },
296 /* hi16: high 16 bit immediate, sign optional */
297 { "hi16", M32R_OPERAND_HI16, HW_H_HI16, 16, 16,
298 { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
299 /* slo16: 16 bit signed immediate, for low() */
300 { "slo16", M32R_OPERAND_SLO16, HW_H_SLO16, 16, 16,
301 { 0, { (1<<MACH_BASE) } } },
302 /* ulo16: 16 bit unsigned immediate, for low() */
303 { "ulo16", M32R_OPERAND_ULO16, HW_H_ULO16, 16, 16,
304 { 0, { (1<<MACH_BASE) } } },
305 /* uimm24: 24 bit address */
306 { "uimm24", M32R_OPERAND_UIMM24, HW_H_ADDR, 8, 24,
307 { 0|A(HASH_PREFIX)|A(RELOC)|A(ABS_ADDR), { (1<<MACH_BASE) } } },
308 /* disp8: 8 bit displacement */
309 { "disp8", M32R_OPERAND_DISP8, HW_H_IADDR, 8, 8,
310 { 0|A(RELAX)|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
311 /* disp16: 16 bit displacement */
312 { "disp16", M32R_OPERAND_DISP16, HW_H_IADDR, 16, 16,
313 { 0|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
314 /* disp24: 24 bit displacement */
315 { "disp24", M32R_OPERAND_DISP24, HW_H_IADDR, 8, 24,
316 { 0|A(RELAX)|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
317 /* condbit: condition bit */
318 { "condbit", M32R_OPERAND_CONDBIT, HW_H_COND, 0, 0,
319 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
320 /* accum: accumulator */
321 { "accum", M32R_OPERAND_ACCUM, HW_H_ACCUM, 0, 0,
322 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
323 { 0 }
326 #undef A
328 #define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
329 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
331 /* The instruction table. */
333 static const CGEN_IBASE m32r_cgen_insn_table[MAX_INSNS] =
335 /* Special null first entry.
336 A `num' value of zero is thus invalid.
337 Also, the special `invalid' insn resides here. */
338 { 0, 0, 0 },
339 /* add $dr,$sr */
341 M32R_INSN_ADD, "add", "add", 16,
342 { 0, { (1<<MACH_BASE) } }
344 /* add3 $dr,$sr,$hash$slo16 */
346 M32R_INSN_ADD3, "add3", "add3", 32,
347 { 0, { (1<<MACH_BASE) } }
349 /* and $dr,$sr */
351 M32R_INSN_AND, "and", "and", 16,
352 { 0, { (1<<MACH_BASE) } }
354 /* and3 $dr,$sr,$uimm16 */
356 M32R_INSN_AND3, "and3", "and3", 32,
357 { 0, { (1<<MACH_BASE) } }
359 /* or $dr,$sr */
361 M32R_INSN_OR, "or", "or", 16,
362 { 0, { (1<<MACH_BASE) } }
364 /* or3 $dr,$sr,$hash$ulo16 */
366 M32R_INSN_OR3, "or3", "or3", 32,
367 { 0, { (1<<MACH_BASE) } }
369 /* xor $dr,$sr */
371 M32R_INSN_XOR, "xor", "xor", 16,
372 { 0, { (1<<MACH_BASE) } }
374 /* xor3 $dr,$sr,$uimm16 */
376 M32R_INSN_XOR3, "xor3", "xor3", 32,
377 { 0, { (1<<MACH_BASE) } }
379 /* addi $dr,$simm8 */
381 M32R_INSN_ADDI, "addi", "addi", 16,
382 { 0, { (1<<MACH_BASE) } }
384 /* addv $dr,$sr */
386 M32R_INSN_ADDV, "addv", "addv", 16,
387 { 0, { (1<<MACH_BASE) } }
389 /* addv3 $dr,$sr,$simm16 */
391 M32R_INSN_ADDV3, "addv3", "addv3", 32,
392 { 0, { (1<<MACH_BASE) } }
394 /* addx $dr,$sr */
396 M32R_INSN_ADDX, "addx", "addx", 16,
397 { 0, { (1<<MACH_BASE) } }
399 /* bc.s $disp8 */
401 M32R_INSN_BC8, "bc8", "bc.s", 16,
402 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
404 /* bc.l $disp24 */
406 M32R_INSN_BC24, "bc24", "bc.l", 32,
407 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
409 /* beq $src1,$src2,$disp16 */
411 M32R_INSN_BEQ, "beq", "beq", 32,
412 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
414 /* beqz $src2,$disp16 */
416 M32R_INSN_BEQZ, "beqz", "beqz", 32,
417 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
419 /* bgez $src2,$disp16 */
421 M32R_INSN_BGEZ, "bgez", "bgez", 32,
422 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
424 /* bgtz $src2,$disp16 */
426 M32R_INSN_BGTZ, "bgtz", "bgtz", 32,
427 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
429 /* blez $src2,$disp16 */
431 M32R_INSN_BLEZ, "blez", "blez", 32,
432 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
434 /* bltz $src2,$disp16 */
436 M32R_INSN_BLTZ, "bltz", "bltz", 32,
437 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
439 /* bnez $src2,$disp16 */
441 M32R_INSN_BNEZ, "bnez", "bnez", 32,
442 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
444 /* bl.s $disp8 */
446 M32R_INSN_BL8, "bl8", "bl.s", 16,
447 { 0|A(FILL_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
449 /* bl.l $disp24 */
451 M32R_INSN_BL24, "bl24", "bl.l", 32,
452 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
454 /* bnc.s $disp8 */
456 M32R_INSN_BNC8, "bnc8", "bnc.s", 16,
457 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
459 /* bnc.l $disp24 */
461 M32R_INSN_BNC24, "bnc24", "bnc.l", 32,
462 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
464 /* bne $src1,$src2,$disp16 */
466 M32R_INSN_BNE, "bne", "bne", 32,
467 { 0|A(COND_CTI), { (1<<MACH_BASE) } }
469 /* bra.s $disp8 */
471 M32R_INSN_BRA8, "bra8", "bra.s", 16,
472 { 0|A(FILL_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
474 /* bra.l $disp24 */
476 M32R_INSN_BRA24, "bra24", "bra.l", 32,
477 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
479 /* cmp $src1,$src2 */
481 M32R_INSN_CMP, "cmp", "cmp", 16,
482 { 0, { (1<<MACH_BASE) } }
484 /* cmpi $src2,$simm16 */
486 M32R_INSN_CMPI, "cmpi", "cmpi", 32,
487 { 0, { (1<<MACH_BASE) } }
489 /* cmpu $src1,$src2 */
491 M32R_INSN_CMPU, "cmpu", "cmpu", 16,
492 { 0, { (1<<MACH_BASE) } }
494 /* cmpui $src2,$simm16 */
496 M32R_INSN_CMPUI, "cmpui", "cmpui", 32,
497 { 0, { (1<<MACH_BASE) } }
499 /* div $dr,$sr */
501 M32R_INSN_DIV, "div", "div", 32,
502 { 0, { (1<<MACH_BASE) } }
504 /* divu $dr,$sr */
506 M32R_INSN_DIVU, "divu", "divu", 32,
507 { 0, { (1<<MACH_BASE) } }
509 /* rem $dr,$sr */
511 M32R_INSN_REM, "rem", "rem", 32,
512 { 0, { (1<<MACH_BASE) } }
514 /* remu $dr,$sr */
516 M32R_INSN_REMU, "remu", "remu", 32,
517 { 0, { (1<<MACH_BASE) } }
519 /* jl $sr */
521 M32R_INSN_JL, "jl", "jl", 16,
522 { 0|A(FILL_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
524 /* jmp $sr */
526 M32R_INSN_JMP, "jmp", "jmp", 16,
527 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
529 /* ld $dr,@$sr */
531 M32R_INSN_LD, "ld", "ld", 16,
532 { 0, { (1<<MACH_BASE) } }
534 /* ld $dr,@($slo16,$sr) */
536 M32R_INSN_LD_D, "ld-d", "ld", 32,
537 { 0, { (1<<MACH_BASE) } }
539 /* ldb $dr,@$sr */
541 M32R_INSN_LDB, "ldb", "ldb", 16,
542 { 0, { (1<<MACH_BASE) } }
544 /* ldb $dr,@($slo16,$sr) */
546 M32R_INSN_LDB_D, "ldb-d", "ldb", 32,
547 { 0, { (1<<MACH_BASE) } }
549 /* ldh $dr,@$sr */
551 M32R_INSN_LDH, "ldh", "ldh", 16,
552 { 0, { (1<<MACH_BASE) } }
554 /* ldh $dr,@($slo16,$sr) */
556 M32R_INSN_LDH_D, "ldh-d", "ldh", 32,
557 { 0, { (1<<MACH_BASE) } }
559 /* ldub $dr,@$sr */
561 M32R_INSN_LDUB, "ldub", "ldub", 16,
562 { 0, { (1<<MACH_BASE) } }
564 /* ldub $dr,@($slo16,$sr) */
566 M32R_INSN_LDUB_D, "ldub-d", "ldub", 32,
567 { 0, { (1<<MACH_BASE) } }
569 /* lduh $dr,@$sr */
571 M32R_INSN_LDUH, "lduh", "lduh", 16,
572 { 0, { (1<<MACH_BASE) } }
574 /* lduh $dr,@($slo16,$sr) */
576 M32R_INSN_LDUH_D, "lduh-d", "lduh", 32,
577 { 0, { (1<<MACH_BASE) } }
579 /* ld $dr,@$sr+ */
581 M32R_INSN_LD_PLUS, "ld-plus", "ld", 16,
582 { 0, { (1<<MACH_BASE) } }
584 /* ld24 $dr,$uimm24 */
586 M32R_INSN_LD24, "ld24", "ld24", 32,
587 { 0, { (1<<MACH_BASE) } }
589 /* ldi8 $dr,$simm8 */
591 M32R_INSN_LDI8, "ldi8", "ldi8", 16,
592 { 0, { (1<<MACH_BASE) } }
594 /* ldi16 $dr,$hash$slo16 */
596 M32R_INSN_LDI16, "ldi16", "ldi16", 32,
597 { 0, { (1<<MACH_BASE) } }
599 /* lock $dr,@$sr */
601 M32R_INSN_LOCK, "lock", "lock", 16,
602 { 0, { (1<<MACH_BASE) } }
604 /* machi $src1,$src2 */
606 M32R_INSN_MACHI, "machi", "machi", 16,
607 { 0, { (1<<MACH_M32R) } }
609 /* maclo $src1,$src2 */
611 M32R_INSN_MACLO, "maclo", "maclo", 16,
612 { 0, { (1<<MACH_M32R) } }
614 /* macwhi $src1,$src2 */
616 M32R_INSN_MACWHI, "macwhi", "macwhi", 16,
617 { 0, { (1<<MACH_M32R) } }
619 /* macwlo $src1,$src2 */
621 M32R_INSN_MACWLO, "macwlo", "macwlo", 16,
622 { 0, { (1<<MACH_M32R) } }
624 /* mul $dr,$sr */
626 M32R_INSN_MUL, "mul", "mul", 16,
627 { 0, { (1<<MACH_BASE) } }
629 /* mulhi $src1,$src2 */
631 M32R_INSN_MULHI, "mulhi", "mulhi", 16,
632 { 0, { (1<<MACH_M32R) } }
634 /* mullo $src1,$src2 */
636 M32R_INSN_MULLO, "mullo", "mullo", 16,
637 { 0, { (1<<MACH_M32R) } }
639 /* mulwhi $src1,$src2 */
641 M32R_INSN_MULWHI, "mulwhi", "mulwhi", 16,
642 { 0, { (1<<MACH_M32R) } }
644 /* mulwlo $src1,$src2 */
646 M32R_INSN_MULWLO, "mulwlo", "mulwlo", 16,
647 { 0, { (1<<MACH_M32R) } }
649 /* mv $dr,$sr */
651 M32R_INSN_MV, "mv", "mv", 16,
652 { 0, { (1<<MACH_BASE) } }
654 /* mvfachi $dr */
656 M32R_INSN_MVFACHI, "mvfachi", "mvfachi", 16,
657 { 0, { (1<<MACH_M32R) } }
659 /* mvfaclo $dr */
661 M32R_INSN_MVFACLO, "mvfaclo", "mvfaclo", 16,
662 { 0, { (1<<MACH_M32R) } }
664 /* mvfacmi $dr */
666 M32R_INSN_MVFACMI, "mvfacmi", "mvfacmi", 16,
667 { 0, { (1<<MACH_M32R) } }
669 /* mvfc $dr,$scr */
671 M32R_INSN_MVFC, "mvfc", "mvfc", 16,
672 { 0, { (1<<MACH_BASE) } }
674 /* mvtachi $src1 */
676 M32R_INSN_MVTACHI, "mvtachi", "mvtachi", 16,
677 { 0, { (1<<MACH_M32R) } }
679 /* mvtaclo $src1 */
681 M32R_INSN_MVTACLO, "mvtaclo", "mvtaclo", 16,
682 { 0, { (1<<MACH_M32R) } }
684 /* mvtc $sr,$dcr */
686 M32R_INSN_MVTC, "mvtc", "mvtc", 16,
687 { 0, { (1<<MACH_BASE) } }
689 /* neg $dr,$sr */
691 M32R_INSN_NEG, "neg", "neg", 16,
692 { 0, { (1<<MACH_BASE) } }
694 /* nop */
696 M32R_INSN_NOP, "nop", "nop", 16,
697 { 0, { (1<<MACH_BASE) } }
699 /* not $dr,$sr */
701 M32R_INSN_NOT, "not", "not", 16,
702 { 0, { (1<<MACH_BASE) } }
704 /* rac */
706 M32R_INSN_RAC, "rac", "rac", 16,
707 { 0, { (1<<MACH_M32R) } }
709 /* rach */
711 M32R_INSN_RACH, "rach", "rach", 16,
712 { 0, { (1<<MACH_M32R) } }
714 /* rte */
716 M32R_INSN_RTE, "rte", "rte", 16,
717 { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
719 /* seth $dr,$hash$hi16 */
721 M32R_INSN_SETH, "seth", "seth", 32,
722 { 0, { (1<<MACH_BASE) } }
724 /* sll $dr,$sr */
726 M32R_INSN_SLL, "sll", "sll", 16,
727 { 0, { (1<<MACH_BASE) } }
729 /* sll3 $dr,$sr,$simm16 */
731 M32R_INSN_SLL3, "sll3", "sll3", 32,
732 { 0, { (1<<MACH_BASE) } }
734 /* slli $dr,$uimm5 */
736 M32R_INSN_SLLI, "slli", "slli", 16,
737 { 0, { (1<<MACH_BASE) } }
739 /* sra $dr,$sr */
741 M32R_INSN_SRA, "sra", "sra", 16,
742 { 0, { (1<<MACH_BASE) } }
744 /* sra3 $dr,$sr,$simm16 */
746 M32R_INSN_SRA3, "sra3", "sra3", 32,
747 { 0, { (1<<MACH_BASE) } }
749 /* srai $dr,$uimm5 */
751 M32R_INSN_SRAI, "srai", "srai", 16,
752 { 0, { (1<<MACH_BASE) } }
754 /* srl $dr,$sr */
756 M32R_INSN_SRL, "srl", "srl", 16,
757 { 0, { (1<<MACH_BASE) } }
759 /* srl3 $dr,$sr,$simm16 */
761 M32R_INSN_SRL3, "srl3", "srl3", 32,
762 { 0, { (1<<MACH_BASE) } }
764 /* srli $dr,$uimm5 */
766 M32R_INSN_SRLI, "srli", "srli", 16,
767 { 0, { (1<<MACH_BASE) } }
769 /* st $src1,@$src2 */
771 M32R_INSN_ST, "st", "st", 16,
772 { 0, { (1<<MACH_BASE) } }
774 /* st $src1,@($slo16,$src2) */
776 M32R_INSN_ST_D, "st-d", "st", 32,
777 { 0, { (1<<MACH_BASE) } }
779 /* stb $src1,@$src2 */
781 M32R_INSN_STB, "stb", "stb", 16,
782 { 0, { (1<<MACH_BASE) } }
784 /* stb $src1,@($slo16,$src2) */
786 M32R_INSN_STB_D, "stb-d", "stb", 32,
787 { 0, { (1<<MACH_BASE) } }
789 /* sth $src1,@$src2 */
791 M32R_INSN_STH, "sth", "sth", 16,
792 { 0, { (1<<MACH_BASE) } }
794 /* sth $src1,@($slo16,$src2) */
796 M32R_INSN_STH_D, "sth-d", "sth", 32,
797 { 0, { (1<<MACH_BASE) } }
799 /* st $src1,@+$src2 */
801 M32R_INSN_ST_PLUS, "st-plus", "st", 16,
802 { 0, { (1<<MACH_BASE) } }
804 /* st $src1,@-$src2 */
806 M32R_INSN_ST_MINUS, "st-minus", "st", 16,
807 { 0, { (1<<MACH_BASE) } }
809 /* sub $dr,$sr */
811 M32R_INSN_SUB, "sub", "sub", 16,
812 { 0, { (1<<MACH_BASE) } }
814 /* subv $dr,$sr */
816 M32R_INSN_SUBV, "subv", "subv", 16,
817 { 0, { (1<<MACH_BASE) } }
819 /* subx $dr,$sr */
821 M32R_INSN_SUBX, "subx", "subx", 16,
822 { 0, { (1<<MACH_BASE) } }
824 /* trap $uimm4 */
826 M32R_INSN_TRAP, "trap", "trap", 16,
827 { 0|A(FILL_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
829 /* unlock $src1,@$src2 */
831 M32R_INSN_UNLOCK, "unlock", "unlock", 16,
832 { 0, { (1<<MACH_BASE) } }
836 #undef A
837 #undef MNEM
838 #undef OP
840 /* Initialize anything needed to be done once, before any cpu_open call. */
842 static void
843 init_tables ()
847 /* Subroutine of m32r_cgen_cpu_open to look up a mach via its bfd name. */
849 static const CGEN_MACH *
850 lookup_mach_via_bfd_name (table, name)
851 const CGEN_MACH *table;
852 const char *name;
854 while (table->name)
856 if (strcmp (name, table->bfd_name) == 0)
857 return table;
858 ++table;
860 abort ();
863 /* Subroutine of m32r_cgen_cpu_open to build the hardware table. */
865 static void
866 build_hw_table (cd)
867 CGEN_CPU_TABLE *cd;
869 int i;
870 int machs = cd->machs;
871 const CGEN_HW_ENTRY *init = & m32r_cgen_hw_table[0];
872 /* MAX_HW is only an upper bound on the number of selected entries.
873 However each entry is indexed by it's enum so there can be holes in
874 the table. */
875 const CGEN_HW_ENTRY **selected =
876 (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
878 cd->hw_table.init_entries = init;
879 cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
880 memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
881 /* ??? For now we just use machs to determine which ones we want. */
882 for (i = 0; init[i].name != NULL; ++i)
883 if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
884 & machs)
885 selected[init[i].type] = &init[i];
886 cd->hw_table.entries = selected;
887 cd->hw_table.num_entries = MAX_HW;
890 /* Subroutine of m32r_cgen_cpu_open to build the hardware table. */
892 static void
893 build_ifield_table (cd)
894 CGEN_CPU_TABLE *cd;
896 cd->ifld_table = & m32r_cgen_ifld_table[0];
899 /* Subroutine of m32r_cgen_cpu_open to build the hardware table. */
901 static void
902 build_operand_table (cd)
903 CGEN_CPU_TABLE *cd;
905 int i;
906 int machs = cd->machs;
907 const CGEN_OPERAND *init = & m32r_cgen_operand_table[0];
908 /* MAX_OPERANDS is only an upper bound on the number of selected entries.
909 However each entry is indexed by it's enum so there can be holes in
910 the table. */
911 const CGEN_OPERAND **selected =
912 (const CGEN_OPERAND **) xmalloc (MAX_OPERANDS * sizeof (CGEN_OPERAND *));
914 cd->operand_table.init_entries = init;
915 cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
916 memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
917 /* ??? For now we just use mach to determine which ones we want. */
918 for (i = 0; init[i].name != NULL; ++i)
919 if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
920 & machs)
921 selected[init[i].type] = &init[i];
922 cd->operand_table.entries = selected;
923 cd->operand_table.num_entries = MAX_OPERANDS;
926 /* Subroutine of m32r_cgen_cpu_open to build the hardware table.
927 ??? This could leave out insns not supported by the specified mach/isa,
928 but that would cause errors like "foo only supported by bar" to become
929 "unknown insn", so for now we include all insns and require the app to
930 do the checking later.
931 ??? On the other hand, parsing of such insns may require their hardware or
932 operand elements to be in the table [which they mightn't be]. */
934 static void
935 build_insn_table (cd)
936 CGEN_CPU_TABLE *cd;
938 int i;
939 const CGEN_IBASE *ib = & m32r_cgen_insn_table[0];
940 CGEN_INSN *insns = (CGEN_INSN *) xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
942 memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
943 for (i = 0; i < MAX_INSNS; ++i)
944 insns[i].base = &ib[i];
945 cd->insn_table.init_entries = insns;
946 cd->insn_table.entry_size = sizeof (CGEN_IBASE);
947 cd->insn_table.num_init_entries = MAX_INSNS;
950 /* Subroutine of m32r_cgen_cpu_open to rebuild the tables. */
952 static void
953 m32r_cgen_rebuild_tables (cd)
954 CGEN_CPU_TABLE *cd;
956 int i,n_isas,n_machs;
957 unsigned int isas = cd->isas;
958 unsigned int machs = cd->machs;
960 cd->int_insn_p = CGEN_INT_INSN_P;
962 /* Data derived from the isa spec. */
963 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
964 cd->default_insn_bitsize = UNSET;
965 cd->base_insn_bitsize = UNSET;
966 cd->min_insn_bitsize = 65535; /* some ridiculously big number */
967 cd->max_insn_bitsize = 0;
968 for (i = 0; i < MAX_ISAS; ++i)
969 if (((1 << i) & isas) != 0)
971 const CGEN_ISA *isa = & m32r_cgen_isa_table[i];
973 /* Default insn sizes of all selected isas must be equal or we set
974 the result to 0, meaning "unknown". */
975 if (cd->default_insn_bitsize == UNSET)
976 cd->default_insn_bitsize = isa->default_insn_bitsize;
977 else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
978 ; /* this is ok */
979 else
980 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
982 /* Base insn sizes of all selected isas must be equal or we set
983 the result to 0, meaning "unknown". */
984 if (cd->base_insn_bitsize == UNSET)
985 cd->base_insn_bitsize = isa->base_insn_bitsize;
986 else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
987 ; /* this is ok */
988 else
989 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
991 /* Set min,max insn sizes. */
992 if (isa->min_insn_bitsize < cd->min_insn_bitsize)
993 cd->min_insn_bitsize = isa->min_insn_bitsize;
994 if (isa->max_insn_bitsize > cd->max_insn_bitsize)
995 cd->max_insn_bitsize = isa->max_insn_bitsize;
997 ++n_isas;
1000 /* Data derived from the mach spec. */
1001 for (i = 0; i < MAX_MACHS; ++i)
1002 if (((1 << i) & machs) != 0)
1004 const CGEN_MACH *mach = & m32r_cgen_mach_table[i];
1006 ++n_machs;
1009 /* Determine which hw elements are used by MACH. */
1010 build_hw_table (cd);
1012 /* Build the ifield table. */
1013 build_ifield_table (cd);
1015 /* Determine which operands are used by MACH/ISA. */
1016 build_operand_table (cd);
1018 /* Build the instruction table. */
1019 build_insn_table (cd);
1022 /* Initialize a cpu table and return a descriptor.
1023 It's much like opening a file, and must be the first function called.
1024 The arguments are a set of (type/value) pairs, terminated with
1025 CGEN_CPU_OPEN_END.
1027 Currently supported values:
1028 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
1029 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
1030 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
1031 CGEN_CPU_OPEN_ENDIAN: specify endian choice
1032 CGEN_CPU_OPEN_END: terminates arguments
1034 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
1035 precluded.
1037 ??? We only support ISO C stdargs here, not K&R.
1038 Laziness, plus experiment to see if anything requires K&R - eventually
1039 K&R will no longer be supported - e.g. GDB is currently trying this. */
1041 CGEN_CPU_DESC
1042 m32r_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
1044 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
1045 static int init_p;
1046 unsigned int isas = 0; /* 0 = "unspecified" */
1047 unsigned int machs = 0; /* 0 = "unspecified" */
1048 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
1049 va_list ap;
1051 if (! init_p)
1053 init_tables ();
1054 init_p = 1;
1057 memset (cd, 0, sizeof (*cd));
1059 va_start (ap, arg_type);
1060 while (arg_type != CGEN_CPU_OPEN_END)
1062 switch (arg_type)
1064 case CGEN_CPU_OPEN_ISAS :
1065 isas = va_arg (ap, unsigned int);
1066 break;
1067 case CGEN_CPU_OPEN_MACHS :
1068 machs = va_arg (ap, unsigned int);
1069 break;
1070 case CGEN_CPU_OPEN_BFDMACH :
1072 const char *name = va_arg (ap, const char *);
1073 const CGEN_MACH *mach =
1074 lookup_mach_via_bfd_name (m32r_cgen_mach_table, name);
1076 machs |= mach->num << 1;
1077 break;
1079 case CGEN_CPU_OPEN_ENDIAN :
1080 endian = va_arg (ap, enum cgen_endian);
1081 break;
1082 default :
1083 fprintf (stderr, "m32r_cgen_cpu_open: unsupported argument `%d'\n",
1084 arg_type);
1085 abort (); /* ??? return NULL? */
1087 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
1089 va_end (ap);
1091 /* mach unspecified means "all" */
1092 if (machs == 0)
1093 machs = (1 << MAX_MACHS) - 1;
1094 /* base mach is always selected */
1095 machs |= 1;
1096 /* isa unspecified means "all" */
1097 if (isas == 0)
1098 isas = (1 << MAX_ISAS) - 1;
1099 if (endian == CGEN_ENDIAN_UNKNOWN)
1101 /* ??? If target has only one, could have a default. */
1102 fprintf (stderr, "m32r_cgen_cpu_open: no endianness specified\n");
1103 abort ();
1106 cd->isas = isas;
1107 cd->machs = machs;
1108 cd->endian = endian;
1109 /* FIXME: for the sparc case we can determine insn-endianness statically.
1110 The worry here is where both data and insn endian can be independently
1111 chosen, in which case this function will need another argument.
1112 Actually, will want to allow for more arguments in the future anyway. */
1113 cd->insn_endian = endian;
1115 /* Table (re)builder. */
1116 cd->rebuild_tables = m32r_cgen_rebuild_tables;
1117 m32r_cgen_rebuild_tables (cd);
1119 return (CGEN_CPU_DESC) cd;
1122 /* Cover fn to m32r_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
1123 MACH_NAME is the bfd name of the mach. */
1125 CGEN_CPU_DESC
1126 m32r_cgen_cpu_open_1 (mach_name, endian)
1127 const char *mach_name;
1128 enum cgen_endian endian;
1130 return m32r_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
1131 CGEN_CPU_OPEN_ENDIAN, endian,
1132 CGEN_CPU_OPEN_END);
1135 /* Close a cpu table.
1136 ??? This can live in a machine independent file, but there's currently
1137 no place to put this file (there's no libcgen). libopcodes is the wrong
1138 place as some simulator ports use this but they don't use libopcodes. */
1140 void
1141 m32r_cgen_cpu_close (cd)
1142 CGEN_CPU_DESC cd;
1144 if (cd->insn_table.init_entries)
1145 free ((CGEN_INSN *) cd->insn_table.init_entries);
1146 if (cd->hw_table.entries)
1147 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
1148 free (cd);