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