Fix building for MS1 and M32C.
[deliverable/binutils-gdb.git] / cpu / m32c.opc
1 /* m32c opcode support. -*- C -*-
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. */
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"
36 <arch>-ibd.h additions use: "-- ibd.h". */
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
51 extern 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 */
59 static unsigned int
60 m32c_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 */
78 #include "safe-ctype.h"
79
80 #define MACH_M32C 5 /* Must match md_begin. */
81
82 static int
83 m32c_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
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
132 static const char *
133 parse_unsigned6 (CGEN_CPU_DESC cd, const char **strp,
134 int opindex, unsigned long *valuep)
135 {
136 const char *errmsg = 0;
137 unsigned long value;
138
139 PARSE_UNSIGNED;
140
141 if (value > 0x3f)
142 return _("imm:6 immediate is out of range");
143
144 *valuep = value;
145 return 0;
146 }
147
148 static const char *
149 parse_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
156 if (strncmp (*strp, "0x0", 3) == 0
157 || (**strp == '0' && *(*strp + 1) != 'x'))
158 have_zero = 1;
159
160 PARSE_UNSIGNED;
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
173 static const char *
174 parse_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;
180
181 if (strncmp (*strp, "0x0", 3) == 0
182 || (**strp == '0' && *(*strp + 1) != 'x'))
183 have_zero = 1;
184
185 PARSE_SIGNED;
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
198 static const char *
199 parse_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
205 PARSE_SIGNED;
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
217 static const char *
218 parse_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
225 /* Don't successfully parse literals beginning with '['. */
226 if (**strp == '[')
227 return "Invalid literal"; /* Anything -- will not be seen. */
228
229 /* Don't successfully parse register names. */
230 if (m32c_cgen_isa_register (strp))
231 return "Invalid literal"; /* Anything -- will not be seen. */
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
255 static const char *
256 parse_signed16 (CGEN_CPU_DESC cd, const char **strp,
257 int opindex, signed long *valuep)
258 {
259 const char *errmsg = 0;
260 signed long value;
261
262 PARSE_SIGNED;
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
274 static const char *
275 parse_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
281 /* Don't successfully parse literals beginning with '['. */
282 if (**strp == '[')
283 return "Invalid literal"; /* Anything -- will not be seen. */
284
285 /* Don't successfully parse register names. */
286 if (m32c_cgen_isa_register (strp))
287 return "Invalid literal"; /* Anything -- will not be seen. */
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
300 static const char *
301 parse_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
307 /* Don't successfully parse literals beginning with '['. */
308 if (**strp == '[')
309 return "Invalid literal"; /* Anything -- will not be seen. */
310
311 /* Don't successfully parse register names. */
312 if (m32c_cgen_isa_register (strp))
313 return "Invalid literal"; /* Anything -- will not be seen. */
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
326 static const char *
327 parse_signed32 (CGEN_CPU_DESC cd, const char **strp,
328 int opindex, signed long *valuep)
329 {
330 const char *errmsg = 0;
331 signed long value;
332
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
341 static const char *
342 parse_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;
347
348 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
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
359 static const char *
360 parse_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
366 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
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
377 static const char *
378 parse_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
413 static const char *
414 parse_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
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
431 static const char *
432 parse_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
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
454 bitbase = (unsigned long long) bit + ((unsigned long long) base * 8);
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
464 static const char *
465 parse_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
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
499 static const char *
500 parse_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
506 static const char *
507 parse_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
513 static const char *
514 parse_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
520 static const char *
521 parse_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
527 static const char *
528 parse_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
534 static const char *
535 parse_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
541 static const char *
542 parse_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
548 static const char *
549 parse_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. */
556
557 static const char *
558 parse_suffix (const char **strp, char suffix)
559 {
560 const char *newp = *strp;
561
562 if (**strp == ':' && TOLOWER (*(*strp + 1)) == suffix)
563 newp = *strp + 2;
564
565 if (ISSPACE (*newp))
566 {
567 *strp = newp;
568 return 0;
569 }
570
571 return "Invalid suffix"; /* Anything -- will not be seen. */
572 }
573
574 static const char *
575 parse_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
581 static const char *
582 parse_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
588 static const char *
589 parse_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
595 static const char *
596 parse_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 ':'. */
603
604 static const char *
605 parse_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
613 static const char *
614 parse_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
622 /* Parse r0[hl]. */
623 errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0l_r0h, & value);
624 if (errmsg)
625 return errmsg;
626
627 if (*newp != ',')
628 return _("not a valid r0l/r0h pair");
629 ++newp;
630
631 /* Parse the second register in the pair. */
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
644 /* Accept .b or .w in any case. */
645
646 static const char *
647 parse_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;
655 return NULL;
656 }
657
658 return _("Invalid size specifier");
659 }
660
661 /* Special check to ensure that instruction exists for given machine. */
662
663 int
664 m32c_cgen_insn_supported (CGEN_CPU_DESC cd,
665 const CGEN_INSN *insn)
666 {
667 int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
668 int isas = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ISA);
669
670 /* If attributes are absent, assume no restriction. */
671 if (machs == 0)
672 machs = ~0;
673
674 return ((machs & cd->machs)
675 && (isas & cd->isas));
676 }
677
678 /* Parse a set of registers, R0,R1,A0,A1,SB,FB. */
679
680 static const char *
681 parse_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
682 const char **strp,
683 int opindex ATTRIBUTE_UNUSED,
684 unsigned long *valuep,
685 int push)
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
741 #define POP 0
742 #define PUSH 1
743
744 static const char *
745 parse_pop_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
746 const char **strp,
747 int opindex ATTRIBUTE_UNUSED,
748 unsigned long *valuep)
749 {
750 return parse_regset (cd, strp, opindex, valuep, POP);
751 }
752
753 static const char *
754 parse_push_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
755 const char **strp,
756 int opindex ATTRIBUTE_UNUSED,
757 unsigned long *valuep)
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
767 /* Always print the short insn format suffix as ':<char>'. */
768
769 static void
770 print_suffix (void * dis_info, char suffix)
771 {
772 disassemble_info *info = dis_info;
773
774 (*info->fprintf_func) (info->stream, ":%c", suffix);
775 }
776
777 static void
778 print_S (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
779 void * dis_info,
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
789 static void
790 print_G (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
791 void * dis_info,
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
800 static void
801 print_Q (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
802 void * dis_info,
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
811 static void
812 print_Z (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
813 void * dis_info,
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
822 /* Print the empty suffix. */
823
824 static void
825 print_X (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
826 void * dis_info ATTRIBUTE_UNUSED,
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
835 static void
836 print_r0l_r0h (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
837 void * dis_info,
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;
844
845 if (value == 0)
846 (*info->fprintf_func) (info->stream, "r0h,r0l");
847 else
848 (*info->fprintf_func) (info->stream, "r0l,r0h");
849 }
850
851 static void
852 print_unsigned_bitbase (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
853 void * dis_info,
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;
860
861 (*info->fprintf_func) (info->stream, "%ld,0x%lx", value & 0x7, value >> 3);
862 }
863
864 static void
865 print_signed_bitbase (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
866 void * dis_info,
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;
873
874 (*info->fprintf_func) (info->stream, "%ld,%ld", value & 0x7, value >> 3);
875 }
876
877 static void
878 print_size (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
879 void * dis_info,
880 long value ATTRIBUTE_UNUSED,
881 unsigned int attrs ATTRIBUTE_UNUSED,
882 bfd_vma pc ATTRIBUTE_UNUSED,
883 int length ATTRIBUTE_UNUSED)
884 {
885 /* Always print the size as '.w'. */
886 disassemble_info *info = dis_info;
887
888 (*info->fprintf_func) (info->stream, ".w");
889 }
890
891 #define POP 0
892 #define PUSH 1
893
894 static void print_pop_regset (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
895 static void print_push_regset (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
896
897 /* Print a set of registers, R0,R1,A0,A1,SB,FB. */
898
899 static void
900 print_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
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)
907 {
908 static char * m16c_register_names [] =
909 {
910 "r0", "r1", "r2", "r3", "a0", "a1", "sb", "fb"
911 };
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
944 static void
945 print_pop_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
946 void * dis_info,
947 long value,
948 unsigned int attrs ATTRIBUTE_UNUSED,
949 bfd_vma pc ATTRIBUTE_UNUSED,
950 int length ATTRIBUTE_UNUSED)
951 {
952 print_regset (cd, dis_info, value, attrs, pc, length, POP);
953 }
954
955 static void
956 print_push_regset (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
957 void * dis_info,
958 long value,
959 unsigned int attrs ATTRIBUTE_UNUSED,
960 bfd_vma pc ATTRIBUTE_UNUSED,
961 int length ATTRIBUTE_UNUSED)
962 {
963 print_regset (cd, dis_info, value, attrs, pc, length, PUSH);
964 }
This page took 0.055977 seconds and 4 git commands to generate.