Fix building for MS1 and M32C.
[deliverable/binutils-gdb.git] / cpu / m32c.opc
CommitLineData
49f58d10 1/* m32c opcode support. -*- C -*-
0a665bfd
JB
2
3 Copyright 2005 Free Software Foundation, Inc.
4
5 Contributed by Red Hat Inc; developed under contract from Renesas
6
7 This file is part of the GNU Binutils.
8
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 of the License, or
12 (at your option) any later version.
13
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.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
49f58d10
JB
22
23/* This file is an addendum to m32c.cpu. Heavy use of C code isn't
24 appropriate in .cpu files, so it resides here. This especially applies
25 to assembly/disassembly where parsing/printing can be quite involved.
26 Such things aren't really part of the specification of the cpu, per se,
27 so .cpu files provide the general framework and .opc files handle the
28 nitty-gritty details as necessary.
29
30 Each section is delimited with start and end markers.
31
32 <arch>-opc.h additions use: "-- opc.h"
33 <arch>-opc.c additions use: "-- opc.c"
34 <arch>-asm.c additions use: "-- asm.c"
35 <arch>-dis.c additions use: "-- dis.c"
e729279b 36 <arch>-ibd.h additions use: "-- ibd.h". */
49f58d10
JB
37\f
38/* -- opc.h */
39
40/* Needed for RTL's 'ext' and 'trunc' operators. */
41#include "cgen-types.h"
42#include "cgen-ops.h"
43
44/* We can't use the default hash size because many bits are used by
45 operands. */
46#define CGEN_DIS_HASH_SIZE 1
47#define CGEN_DIS_HASH(buf, value) 0
48#define CGEN_VERBOSE_ASSEMBLER_ERRORS
49#define CGEN_VALIDATE_INSN_SUPPORTED
50
51extern int m32c_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
52
53#define CGEN_ASM_HASH_SIZE 0xffff
54#define CGEN_ASM_HASH(mnem) m32c_asm_hash ((mnem))
55
56/* -- */
57\f
58/* -- opc.c */
59static unsigned int
60m32c_asm_hash (const char *mnem)
61{
62 unsigned int h;
63
64 /* The length of the mnemonic for the Jcnd insns is 1. Hash jsri. */
65 if (mnem[0] == 'j' && mnem[1] != 's')
66 return 'j';
67
68 /* Don't hash scCND */
69 if (mnem[0] == 's' && mnem[1] == 'c')
70 return 's';
71
72 for (h = 0; *mnem && *mnem != ' ' && *mnem != ':'; ++mnem)
73 h += *mnem;
74 return h % CGEN_ASM_HASH_SIZE;
75}
76\f
77/* -- asm.c */
e729279b 78#include "safe-ctype.h"
49f58d10
JB
79
80#define MACH_M32C 5 /* Must match md_begin. */
81
82static int
83m32c_cgen_isa_register (const char **strp)
84 {
85 int u;
86 const char *s = *strp;
87 static char * m32c_register_names [] =
88 {
89 "r0", "r1", "r2", "r3", "r0l", "r0h", "r1l", "r1h",
90 "a0", "a1", "r2r0", "r3r1", "sp", "fb", "dct0", "dct1", "flg", "svf",
91 "drc0", "drc1", "dmd0", "dmd1", "intb", "svp", "vct", "isp", "dma0",
92 "dma1", "dra0", "dra1", "dsa0", "dsa1", 0
93 };
94
95 for (u = 0; m32c_register_names[u]; u++)
96 {
97 int len = strlen (m32c_register_names[u]);
98
99 if (memcmp (m32c_register_names[u], s, len) == 0
100 && (s[len] == 0 || ! ISALNUM (s[len])))
101 return 1;
102 }
103 return 0;
104}
105
e729279b
NC
106#define PARSE_UNSIGNED \
107 do \
108 { \
109 /* Don't successfully parse literals beginning with '['. */ \
110 if (**strp == '[') \
111 return "Invalid literal"; /* Anything -- will not be seen. */ \
112 \
113 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);\
114 if (errmsg) \
115 return errmsg; \
116 } \
117 while (0)
118
119#define PARSE_SIGNED \
120 do \
121 { \
122 /* Don't successfully parse literals beginning with '['. */ \
123 if (**strp == '[') \
124 return "Invalid literal"; /* Anything -- will not be seen. */ \
125 \
126 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); \
127 if (errmsg) \
128 return errmsg; \
129 } \
130 while (0)
131
49f58d10
JB
132static const char *
133parse_unsigned6 (CGEN_CPU_DESC cd, const char **strp,
134 int opindex, unsigned long *valuep)
135{
136 const char *errmsg = 0;
137 unsigned long value;
49f58d10 138
e729279b 139 PARSE_UNSIGNED;
49f58d10
JB
140
141 if (value > 0x3f)
142 return _("imm:6 immediate is out of range");
143
144 *valuep = value;
145 return 0;
146}
147
148static const char *
149parse_unsigned8 (CGEN_CPU_DESC cd, const char **strp,
150 int opindex, unsigned long *valuep)
151{
152 const char *errmsg = 0;
153 unsigned long value;
154 long have_zero = 0;
155
49f58d10
JB
156 if (strncmp (*strp, "0x0", 3) == 0
157 || (**strp == '0' && *(*strp + 1) != 'x'))
158 have_zero = 1;
159
e729279b 160 PARSE_UNSIGNED;
49f58d10
JB
161
162 if (value > 0xff)
163 return _("dsp:8 immediate is out of range");
164
165 /* If this field may require a relocation then use larger dsp16. */
166 if (! have_zero && value == 0)
167 return _("dsp:8 immediate is out of range");
168
169 *valuep = value;
170 return 0;
171}
172
173static const char *
174parse_signed4 (CGEN_CPU_DESC cd, const char **strp,
175 int opindex, signed long *valuep)
176{
177 const char *errmsg = 0;
178 signed long value;
179 long have_zero = 0;
49f58d10
JB
180
181 if (strncmp (*strp, "0x0", 3) == 0
182 || (**strp == '0' && *(*strp + 1) != 'x'))
183 have_zero = 1;
184
e729279b 185 PARSE_SIGNED;
49f58d10
JB
186
187 if (value < -8 || value > 7)
188 return _("Immediate is out of range -8 to 7");
189
190 /* If this field may require a relocation then use larger dsp16. */
191 if (! have_zero && value == 0)
192 return _("Immediate is out of range -8 to 7");
193
194 *valuep = value;
195 return 0;
196}
197
198static const char *
199parse_signed8 (CGEN_CPU_DESC cd, const char **strp,
200 int opindex, signed long *valuep)
201{
202 const char *errmsg = 0;
203 signed long value;
204
e729279b 205 PARSE_SIGNED;
49f58d10
JB
206
207 if (value <= 255 && value > 127)
208 value -= 0x100;
209
210 if (value < -128 || value > 127)
211 return _("dsp:8 immediate is out of range");
212
213 *valuep = value;
214 return 0;
215}
216
217static const char *
218parse_unsigned16 (CGEN_CPU_DESC cd, const char **strp,
219 int opindex, unsigned long *valuep)
220{
221 const char *errmsg = 0;
222 unsigned long value;
223 long have_zero = 0;
224
e729279b 225 /* Don't successfully parse literals beginning with '['. */
49f58d10 226 if (**strp == '[')
e729279b 227 return "Invalid literal"; /* Anything -- will not be seen. */
49f58d10 228
e729279b 229 /* Don't successfully parse register names. */
49f58d10 230 if (m32c_cgen_isa_register (strp))
e729279b 231 return "Invalid literal"; /* Anything -- will not be seen. */
49f58d10
JB
232
233 if (strncmp (*strp, "0x0", 3) == 0
234 || (**strp == '0' && *(*strp + 1) != 'x'))
235 have_zero = 1;
236
237 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
238 if (errmsg)
239 return errmsg;
240
241 if (value > 0xffff)
242 return _("dsp:16 immediate is out of range");
243
244 /* If this field may require a relocation then use larger dsp24. */
245 if (cd->machs == MACH_M32C && ! have_zero && value == 0
246 && (strncmp (*strp, "[a", 2) == 0
247 || **strp == ','
248 || **strp == 0))
249 return _("dsp:16 immediate is out of range");
250
251 *valuep = value;
252 return 0;
253}
254
255static const char *
256parse_signed16 (CGEN_CPU_DESC cd, const char **strp,
257 int opindex, signed long *valuep)
258{
259 const char *errmsg = 0;
260 signed long value;
49f58d10 261
e729279b 262 PARSE_SIGNED;
49f58d10
JB
263
264 if (value <= 65535 && value > 32767)
265 value -= 0x10000;
266
267 if (value < -32768 || value > 32767)
268 return _("dsp:16 immediate is out of range");
269
270 *valuep = value;
271 return 0;
272}
273
274static const char *
275parse_unsigned20 (CGEN_CPU_DESC cd, const char **strp,
276 int opindex, unsigned long *valuep)
277{
278 const char *errmsg = 0;
279 unsigned long value;
280
e729279b 281 /* Don't successfully parse literals beginning with '['. */
49f58d10 282 if (**strp == '[')
e729279b 283 return "Invalid literal"; /* Anything -- will not be seen. */
49f58d10 284
e729279b 285 /* Don't successfully parse register names. */
49f58d10 286 if (m32c_cgen_isa_register (strp))
e729279b 287 return "Invalid literal"; /* Anything -- will not be seen. */
49f58d10
JB
288
289 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
290 if (errmsg)
291 return errmsg;
292
293 if (value > 0xfffff)
294 return _("dsp:20 immediate is out of range");
295
296 *valuep = value;
297 return 0;
298}
299
300static const char *
301parse_unsigned24 (CGEN_CPU_DESC cd, const char **strp,
302 int opindex, unsigned long *valuep)
303{
304 const char *errmsg = 0;
305 unsigned long value;
306
e729279b 307 /* Don't successfully parse literals beginning with '['. */
49f58d10 308 if (**strp == '[')
e729279b 309 return "Invalid literal"; /* Anything -- will not be seen. */
49f58d10 310
e729279b 311 /* Don't successfully parse register names. */
49f58d10 312 if (m32c_cgen_isa_register (strp))
e729279b 313 return "Invalid literal"; /* Anything -- will not be seen. */
49f58d10
JB
314
315 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
316 if (errmsg)
317 return errmsg;
318
319 if (value > 0xffffff)
320 return _("dsp:24 immediate is out of range");
321
322 *valuep = value;
323 return 0;
324}
325
326static const char *
327parse_signed32 (CGEN_CPU_DESC cd, const char **strp,
e729279b 328 int opindex, signed long *valuep)
49f58d10
JB
329{
330 const char *errmsg = 0;
331 signed long value;
332
49f58d10
JB
333 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
334 if (errmsg)
335 return errmsg;
336
337 *valuep = value;
338 return 0;
339}
340
341static const char *
342parse_imm1_S (CGEN_CPU_DESC cd, const char **strp,
343 int opindex, signed long *valuep)
344{
345 const char *errmsg = 0;
346 signed long value;
49f58d10 347
e729279b 348 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
49f58d10
JB
349 if (errmsg)
350 return errmsg;
351
352 if (value < 1 || value > 2)
353 return _("immediate is out of range 1-2");
354
355 *valuep = value;
356 return 0;
357}
358
359static const char *
360parse_imm3_S (CGEN_CPU_DESC cd, const char **strp,
361 int opindex, signed long *valuep)
362{
363 const char *errmsg = 0;
364 signed long value;
365
e729279b 366 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
49f58d10
JB
367 if (errmsg)
368 return errmsg;
369
370 if (value < 1 || value > 8)
371 return _("immediate is out of range 1-8");
372
373 *valuep = value;
374 return 0;
375}
376
e729279b
NC
377static const char *
378parse_lab_5_3 (CGEN_CPU_DESC cd,
379 const char **strp,
380 int opindex ATTRIBUTE_UNUSED,
381 int opinfo,
382 enum cgen_parse_operand_result *type_addr,
383 unsigned long *valuep)
384{
385 const char *errmsg = 0;
386 unsigned long value;
387 enum cgen_parse_operand_result op_res;
388
389 errmsg = cgen_parse_address (cd, strp, M32C_OPERAND_LAB_5_3,
390 opinfo, & op_res, & value);
391
392 if (type_addr)
393 *type_addr = op_res;
394
395 if (op_res == CGEN_PARSE_OPERAND_ADDRESS)
396 {
397 /* This is a hack; the field cannot handle near-zero signed
398 offsets that CGEN wants to put in to indicate an "empty"
399 operand at first. */
400 *valuep = 2;
401 return 0;
402 }
403 if (errmsg)
404 return errmsg;
405
406 if (value < 2 || value > 9)
407 return _("immediate is out of range 2-9");
408
409 *valuep = value;
410 return 0;
411}
412
49f58d10
JB
413static const char *
414parse_Bitno16R (CGEN_CPU_DESC cd, const char **strp,
415 int opindex, unsigned long *valuep)
416{
417 const char *errmsg = 0;
418 unsigned long value;
419
49f58d10
JB
420 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
421 if (errmsg)
422 return errmsg;
423
424 if (value > 15)
425 return _("Bit number for indexing general register is out of range 0-15");
426
427 *valuep = value;
428 return 0;
429}
430
431static const char *
432parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp,
433 int opindex, unsigned long *valuep,
434 unsigned bits)
435{
436 const char *errmsg = 0;
437 unsigned long bit;
438 unsigned long base;
439 const char *newp = *strp;
440 unsigned long long bitbase;
441
49f58d10
JB
442 errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
443 if (errmsg)
444 return errmsg;
445
446 if (*newp != ',')
447 return "Missing base for bit,base:8";
448
449 ++newp;
450 errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & base);
451 if (errmsg)
452 return errmsg;
453
e729279b 454 bitbase = (unsigned long long) bit + ((unsigned long long) base * 8);
49f58d10
JB
455
456 if (bitbase >= (1ull << bits))
457 return _("bit,base is out of range");
458
459 *valuep = bitbase;
460 *strp = newp;
461 return 0;
462}
463
464static const char *
465parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp,
466 int opindex, signed long *valuep,
467 unsigned bits)
468{
469 const char *errmsg = 0;
470 unsigned long bit;
471 signed long base;
472 const char *newp = *strp;
473 long long bitbase;
474 long long limit;
475
49f58d10
JB
476 errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
477 if (errmsg)
478 return errmsg;
479
480 if (*newp != ',')
481 return "Missing base for bit,base:8";
482
483 ++newp;
484 errmsg = cgen_parse_signed_integer (cd, & newp, opindex, & base);
485 if (errmsg)
486 return errmsg;
487
488 bitbase = (long long)bit + ((long long)base * 8);
489
490 limit = 1ll << (bits - 1);
491 if (bitbase < -limit || bitbase >= limit)
492 return _("bit,base is out of range");
493
494 *valuep = bitbase;
495 *strp = newp;
496 return 0;
497}
498
499static const char *
500parse_unsigned_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
501 int opindex, unsigned long *valuep)
502{
503 return parse_unsigned_bitbase (cd, strp, opindex, valuep, 8);
504}
505
506static const char *
507parse_unsigned_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
508 int opindex, unsigned long *valuep)
509{
510 return parse_unsigned_bitbase (cd, strp, opindex, valuep, 11);
511}
512
513static const char *
514parse_unsigned_bitbase16 (CGEN_CPU_DESC cd, const char **strp,
515 int opindex, unsigned long *valuep)
516{
517 return parse_unsigned_bitbase (cd, strp, opindex, valuep, 16);
518}
519
520static const char *
521parse_unsigned_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
522 int opindex, unsigned long *valuep)
523{
524 return parse_unsigned_bitbase (cd, strp, opindex, valuep, 19);
525}
526
527static const char *
528parse_unsigned_bitbase27 (CGEN_CPU_DESC cd, const char **strp,
529 int opindex, unsigned long *valuep)
530{
531 return parse_unsigned_bitbase (cd, strp, opindex, valuep, 27);
532}
533
534static const char *
535parse_signed_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
536 int opindex, signed long *valuep)
537{
538 return parse_signed_bitbase (cd, strp, opindex, valuep, 8);
539}
540
541static const char *
542parse_signed_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
543 int opindex, signed long *valuep)
544{
545 return parse_signed_bitbase (cd, strp, opindex, valuep, 11);
546}
547
548static const char *
549parse_signed_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
550 int opindex, signed long *valuep)
551{
552 return parse_signed_bitbase (cd, strp, opindex, valuep, 19);
553}
554
555/* Parse the suffix as :<char> or as nothing followed by a whitespace. */
e729279b 556
49f58d10
JB
557static const char *
558parse_suffix (const char **strp, char suffix)
559{
560 const char *newp = *strp;
561
e729279b 562 if (**strp == ':' && TOLOWER (*(*strp + 1)) == suffix)
49f58d10
JB
563 newp = *strp + 2;
564
e729279b 565 if (ISSPACE (*newp))
49f58d10
JB
566 {
567 *strp = newp;
568 return 0;
569 }
570
e729279b 571 return "Invalid suffix"; /* Anything -- will not be seen. */
49f58d10
JB
572}
573
574static const char *
575parse_S (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
576 int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
577{
578 return parse_suffix (strp, 's');
579}
580
581static const char *
582parse_G (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
583 int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
584{
585 return parse_suffix (strp, 'g');
586}
587
588static const char *
589parse_Q (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
590 int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
591{
592 return parse_suffix (strp, 'q');
593}
594
595static const char *
596parse_Z (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
597 int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
598{
599 return parse_suffix (strp, 'z');
600}
601
602/* Parse an empty suffix. Fail if the next char is ':'. */
e729279b 603
49f58d10
JB
604static const char *
605parse_X (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
606 int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
607{
608 if (**strp == ':')
609 return "Unexpected suffix";
610 return 0;
611}
612
613static const char *
614parse_r0l_r0h (CGEN_CPU_DESC cd, const char **strp,
615 int opindex ATTRIBUTE_UNUSED, signed long *valuep)
616{
617 const char *errmsg;
618 signed long value;
619 signed long junk;
620 const char *newp = *strp;
621
e729279b 622 /* Parse r0[hl]. */
49f58d10
JB
623 errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0l_r0h, & value);
624 if (errmsg)
625 return errmsg;
626
627 if (*newp != ',')
e729279b 628 return _("not a valid r0l/r0h pair");
49f58d10
JB
629 ++newp;
630
e729279b 631 /* Parse the second register in the pair. */
49f58d10
JB
632 if (value == 0) /* r0l */
633 errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0h, & junk);
634 else
635 errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0l, & junk);
636 if (errmsg)
637 return errmsg;
638
639 *strp = newp;
640 *valuep = ! value;
641 return 0;
642}
643
e729279b
NC
644/* Accept .b or .w in any case. */
645
49f58d10
JB
646static const char *
647parse_size (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp,
648 int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED)
649{
650 if (**strp == '.'
651 && (*(*strp + 1) == 'b' || *(*strp + 1) == 'B'
652 || *(*strp + 1) == 'w' || *(*strp + 1) == 'W'))
653 {
654 *strp += 2;
e729279b 655 return NULL;
49f58d10 656 }
e729279b
NC
657
658 return _("Invalid size specifier");
49f58d10
JB
659}
660
e729279b
NC
661/* Special check to ensure that instruction exists for given machine. */
662
49f58d10
JB
663int
664m32c_cgen_insn_supported (CGEN_CPU_DESC cd,
665 const CGEN_INSN *insn)
666{
667 int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
aa260854 668 int isas = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ISA);
49f58d10 669
e729279b 670 /* If attributes are absent, assume no restriction. */
49f58d10
JB
671 if (machs == 0)
672 machs = ~0;
673
aa260854
JB
674 return ((machs & cd->machs)
675 && (isas & cd->isas));
49f58d10
JB
676}
677
678/* Parse a set of registers, R0,R1,A0,A1,SB,FB. */
679
680static const char *
681parse_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
682 const char **strp,
683 int opindex ATTRIBUTE_UNUSED,
684 unsigned long *valuep,
e729279b 685 int push)
49f58d10
JB
686{
687 const char *errmsg = 0;
688 int regno = 0;
689
690 *valuep = 0;
691 while (**strp && **strp != ')')
692 {
693 if (**strp == 'r' || **strp == 'R')
694 {
695 ++*strp;
696 regno = **strp - '0';
697 if (regno > 4)
698 errmsg = _("Register number is not valid");
699 }
700 else if (**strp == 'a' || **strp == 'A')
701 {
702 ++*strp;
703 regno = **strp - '0';
704 if (regno > 2)
705 errmsg = _("Register number is not valid");
706 regno = **strp - '0' + 4;
707 }
708
709 else if (strncasecmp (*strp, "sb", 2) == 0 || strncasecmp (*strp, "SB", 2) == 0)
710 {
711 regno = 6;
712 ++*strp;
713 }
714
715 else if (strncasecmp (*strp, "fb", 2) == 0 || strncasecmp (*strp, "FB", 2) == 0)
716 {
717 regno = 7;
718 ++*strp;
719 }
720
721 if (push) /* Mask is reversed for push. */
722 *valuep |= 0x80 >> regno;
723 else
724 *valuep |= 1 << regno;
725
726 ++*strp;
727 if (**strp == ',')
728 {
729 if (*(*strp + 1) == ')')
730 break;
731 ++*strp;
732 }
733 }
734
735 if (!*strp)
736 errmsg = _("Register list is not valid");
737
738 return errmsg;
739}
740
e729279b 741#define POP 0
49f58d10
JB
742#define PUSH 1
743
744static const char *
745parse_pop_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b
NC
746 const char **strp,
747 int opindex ATTRIBUTE_UNUSED,
748 unsigned long *valuep)
49f58d10
JB
749{
750 return parse_regset (cd, strp, opindex, valuep, POP);
751}
752
753static const char *
754parse_push_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b
NC
755 const char **strp,
756 int opindex ATTRIBUTE_UNUSED,
757 unsigned long *valuep)
49f58d10
JB
758{
759 return parse_regset (cd, strp, opindex, valuep, PUSH);
760}
761
762/* -- dis.c */
763
764#include "elf/m32c.h"
765#include "elf-bfd.h"
766
e729279b
NC
767/* Always print the short insn format suffix as ':<char>'. */
768
49f58d10 769static void
e729279b 770print_suffix (void * dis_info, char suffix)
49f58d10
JB
771{
772 disassemble_info *info = dis_info;
e729279b 773
49f58d10
JB
774 (*info->fprintf_func) (info->stream, ":%c", suffix);
775}
776
777static void
778print_S (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b 779 void * dis_info,
49f58d10
JB
780 long value ATTRIBUTE_UNUSED,
781 unsigned int attrs ATTRIBUTE_UNUSED,
782 bfd_vma pc ATTRIBUTE_UNUSED,
783 int length ATTRIBUTE_UNUSED)
784{
785 print_suffix (dis_info, 's');
786}
787
788
789static void
790print_G (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b 791 void * dis_info,
49f58d10
JB
792 long value ATTRIBUTE_UNUSED,
793 unsigned int attrs ATTRIBUTE_UNUSED,
794 bfd_vma pc ATTRIBUTE_UNUSED,
795 int length ATTRIBUTE_UNUSED)
796{
797 print_suffix (dis_info, 'g');
798}
799
800static void
801print_Q (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b 802 void * dis_info,
49f58d10
JB
803 long value ATTRIBUTE_UNUSED,
804 unsigned int attrs ATTRIBUTE_UNUSED,
805 bfd_vma pc ATTRIBUTE_UNUSED,
806 int length ATTRIBUTE_UNUSED)
807{
808 print_suffix (dis_info, 'q');
809}
810
811static void
812print_Z (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b 813 void * dis_info,
49f58d10
JB
814 long value ATTRIBUTE_UNUSED,
815 unsigned int attrs ATTRIBUTE_UNUSED,
816 bfd_vma pc ATTRIBUTE_UNUSED,
817 int length ATTRIBUTE_UNUSED)
818{
819 print_suffix (dis_info, 'z');
820}
821
e729279b
NC
822/* Print the empty suffix. */
823
49f58d10
JB
824static void
825print_X (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b 826 void * dis_info ATTRIBUTE_UNUSED,
49f58d10
JB
827 long value ATTRIBUTE_UNUSED,
828 unsigned int attrs ATTRIBUTE_UNUSED,
829 bfd_vma pc ATTRIBUTE_UNUSED,
830 int length ATTRIBUTE_UNUSED)
831{
832 return;
833}
834
835static void
836print_r0l_r0h (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b 837 void * dis_info,
49f58d10
JB
838 long value,
839 unsigned int attrs ATTRIBUTE_UNUSED,
840 bfd_vma pc ATTRIBUTE_UNUSED,
841 int length ATTRIBUTE_UNUSED)
842{
843 disassemble_info *info = dis_info;
e729279b 844
49f58d10
JB
845 if (value == 0)
846 (*info->fprintf_func) (info->stream, "r0h,r0l");
847 else
848 (*info->fprintf_func) (info->stream, "r0l,r0h");
849}
850
851static void
852print_unsigned_bitbase (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b 853 void * dis_info,
49f58d10
JB
854 unsigned long value,
855 unsigned int attrs ATTRIBUTE_UNUSED,
856 bfd_vma pc ATTRIBUTE_UNUSED,
857 int length ATTRIBUTE_UNUSED)
858{
859 disassemble_info *info = dis_info;
e729279b 860
49f58d10
JB
861 (*info->fprintf_func) (info->stream, "%ld,0x%lx", value & 0x7, value >> 3);
862}
863
864static void
865print_signed_bitbase (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b 866 void * dis_info,
49f58d10
JB
867 signed long value,
868 unsigned int attrs ATTRIBUTE_UNUSED,
869 bfd_vma pc ATTRIBUTE_UNUSED,
870 int length ATTRIBUTE_UNUSED)
871{
872 disassemble_info *info = dis_info;
e729279b 873
49f58d10
JB
874 (*info->fprintf_func) (info->stream, "%ld,%ld", value & 0x7, value >> 3);
875}
876
877static void
878print_size (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b 879 void * dis_info,
49f58d10
JB
880 long value ATTRIBUTE_UNUSED,
881 unsigned int attrs ATTRIBUTE_UNUSED,
882 bfd_vma pc ATTRIBUTE_UNUSED,
883 int length ATTRIBUTE_UNUSED)
884{
e729279b 885 /* Always print the size as '.w'. */
49f58d10 886 disassemble_info *info = dis_info;
e729279b 887
49f58d10
JB
888 (*info->fprintf_func) (info->stream, ".w");
889}
890
e729279b 891#define POP 0
49f58d10
JB
892#define PUSH 1
893
e729279b
NC
894static void print_pop_regset (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
895static void print_push_regset (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
49f58d10
JB
896
897/* Print a set of registers, R0,R1,A0,A1,SB,FB. */
898
899static void
900print_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b
NC
901 void * dis_info,
902 long value,
903 unsigned int attrs ATTRIBUTE_UNUSED,
904 bfd_vma pc ATTRIBUTE_UNUSED,
905 int length ATTRIBUTE_UNUSED,
906 int push)
49f58d10
JB
907{
908 static char * m16c_register_names [] =
e729279b
NC
909 {
910 "r0", "r1", "r2", "r3", "a0", "a1", "sb", "fb"
911 };
49f58d10
JB
912 disassemble_info *info = dis_info;
913 int mask;
914 int index = 0;
915 char* comma = "";
916
917 if (push)
918 mask = 0x80;
919 else
920 mask = 1;
921
922 if (value & mask)
923 {
924 (*info->fprintf_func) (info->stream, "%s", m16c_register_names [0]);
925 comma = ",";
926 }
927
928 for (index = 1; index <= 7; ++index)
929 {
930 if (push)
931 mask >>= 1;
932 else
933 mask <<= 1;
934
935 if (value & mask)
936 {
937 (*info->fprintf_func) (info->stream, "%s%s", comma,
938 m16c_register_names [index]);
939 comma = ",";
940 }
941 }
942}
943
944static void
945print_pop_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b
NC
946 void * dis_info,
947 long value,
948 unsigned int attrs ATTRIBUTE_UNUSED,
949 bfd_vma pc ATTRIBUTE_UNUSED,
950 int length ATTRIBUTE_UNUSED)
49f58d10
JB
951{
952 print_regset (cd, dis_info, value, attrs, pc, length, POP);
953}
954
955static void
956print_push_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
e729279b
NC
957 void * dis_info,
958 long value,
959 unsigned int attrs ATTRIBUTE_UNUSED,
960 bfd_vma pc ATTRIBUTE_UNUSED,
961 int length ATTRIBUTE_UNUSED)
49f58d10
JB
962{
963 print_regset (cd, dis_info, value, attrs, pc, length, PUSH);
964}
This page took 0.070418 seconds and 4 git commands to generate.