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