* hppa-dis.c (print_insn_hppa): Add space after 'w' in wide-mode
[binutils.git] / cpu / m32c.opc
blob3824118ddce008837d9eeb45182691d10d997bba
1 /* m32c opcode support.  -*- C -*-
3    Copyright 2005 Free Software Foundation, Inc.
5    Contributed by Red Hat Inc; developed under contract from Renesas
7    This file is part of the GNU Binutils.
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.
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
19    You should have received a copy of the GNU General Public License
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.  */
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.
30    Each section is delimited with start and end markers.
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"
39 /* -- opc.h */
41 /* Needed for RTL's 'ext' and 'trunc' operators.  */
42 #include "cgen-types.h"
43 #include "cgen-ops.h"
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
52 extern int m32c_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
54 #define CGEN_ASM_HASH_SIZE 0xffff
55 #define CGEN_ASM_HASH(mnem) m32c_asm_hash ((mnem))
57 /* -- */
59 /* -- opc.c */
60 static unsigned int
61 m32c_asm_hash (const char *mnem)
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;
78 /* -- asm.c */
79 #include <ctype.h>
81 #define MACH_M32C 5             /* Must match md_begin.  */
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      };
96    for (u = 0; m32c_register_names[u]; u++)
97      {
98        int len = strlen (m32c_register_names[u]);
100        if (memcmp (m32c_register_names[u], s, len) == 0
101            && (s[len] == 0 || ! ISALNUM (s[len])))
102         return 1;
103      }
104    return 0;
107 static const char *
108 parse_unsigned6 (CGEN_CPU_DESC cd, const char **strp,
109                  int opindex, unsigned long *valuep)
111   const char *errmsg = 0;
112   unsigned long value;
113   long have_zero = 0;
115   /* Don't successfully parse literals beginning with '[' */
116   if (**strp == '[')
117     return "Invalid literal"; /* anything -- will not be seen */
119   if (strncmp (*strp, "0x0", 3) == 0 
120       || (**strp == '0' && *(*strp + 1) != 'x'))
121     have_zero = 1;
123   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
124   if (errmsg)
125     return errmsg;
127   if (value > 0x3f)
128     return _("imm:6 immediate is out of range");
130   *valuep = value;
131   return 0;
134 static const char *
135 parse_unsigned8 (CGEN_CPU_DESC cd, const char **strp,
136                  int opindex, unsigned long *valuep)
138   const char *errmsg = 0;
139   unsigned long value;
140   long have_zero = 0;
142   /* Don't successfully parse literals beginning with '[' */
143   if (**strp == '[')
144     return "Invalid literal"; /* anything -- will not be seen */
146   if (strncmp (*strp, "0x0", 3) == 0 
147       || (**strp == '0' && *(*strp + 1) != 'x'))
148     have_zero = 1;
150   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
151   if (errmsg)
152     return errmsg;
154   if (value > 0xff)
155     return _("dsp:8 immediate is out of range");
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");
161   *valuep = value;
162   return 0;
165 static const char *
166 parse_signed4 (CGEN_CPU_DESC cd, const char **strp,
167                int opindex, signed long *valuep)
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 */
177   if (strncmp (*strp, "0x0", 3) == 0 
178       || (**strp == '0' && *(*strp + 1) != 'x'))
179     have_zero = 1;
181   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
182   if (errmsg)
183     return errmsg;
185   if (value < -8 || value > 7)
186     return _("Immediate is out of range -8 to 7");
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");
192   *valuep = value;
193   return 0;
196 static const char *
197 parse_signed8 (CGEN_CPU_DESC cd, const char **strp,
198                int opindex, signed long *valuep)
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 */
207   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
208   if (errmsg)
209     return errmsg;
211   if (value <= 255 && value > 127)
212     value -= 0x100;
214   if (value < -128 || value > 127)
215     return _("dsp:8 immediate is out of range");
217   *valuep = value;
218   return 0;
221 static const char *
222 parse_unsigned16 (CGEN_CPU_DESC cd, const char **strp,
223                  int opindex, unsigned long *valuep)
225   const char *errmsg = 0;
226   unsigned long value;
227   long have_zero = 0;
229   /* Don't successfully parse literals beginning with '[' */
230   if (**strp == '[')
231     return "Invalid literal"; /* anything -- will not be seen */
233   /* Don't successfully parse register names */
234   if (m32c_cgen_isa_register (strp))
235     return "Invalid literal"; /* anything -- will not be seen */
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;
245   if (value > 0xffff)
246     return _("dsp:16 immediate is out of range");
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");
255   *valuep = value;
256   return 0;
259 static const char *
260 parse_signed16 (CGEN_CPU_DESC cd, const char **strp,
261                int opindex, signed long *valuep)
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 */
270   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
271   if (errmsg)
272     return errmsg;
274   if (value <= 65535 && value > 32767)
275     value -= 0x10000;
277   if (value < -32768 || value > 32767)
278     return _("dsp:16 immediate is out of range");
280   *valuep = value;
281   return 0;
284 static const char *
285 parse_unsigned20 (CGEN_CPU_DESC cd, const char **strp,
286                  int opindex, unsigned long *valuep)
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 */
295   /* Don't successfully parse register names */
296   if (m32c_cgen_isa_register (strp))
297     return "Invalid literal"; /* anything -- will not be seen */
299   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
300   if (errmsg)
301     return errmsg;
303   if (value > 0xfffff)
304     return _("dsp:20 immediate is out of range");
306   *valuep = value;
307   return 0;
310 static const char *
311 parse_unsigned24 (CGEN_CPU_DESC cd, const char **strp,
312                  int opindex, unsigned long *valuep)
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 */
321   /* Don't successfully parse register names */
322   if (m32c_cgen_isa_register (strp))
323     return "Invalid literal"; /* anything -- will not be seen */
325   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
326   if (errmsg)
327     return errmsg;
329   if (value > 0xffffff)
330     return _("dsp:24 immediate is out of range");
332   *valuep = value;
333   return 0;
336 static const char *
337 parse_signed32 (CGEN_CPU_DESC cd, const char **strp,
338                  int opindex, signed long *valuep)
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 */
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
353   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
354   if (errmsg)
355     return errmsg;
357   *valuep = value;
358   return 0;
361 static const char *
362 parse_imm1_S (CGEN_CPU_DESC cd, const char **strp,
363              int opindex, signed long *valuep)
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 */
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
378   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
379   if (errmsg)
380     return errmsg;
382   if (value < 1 || value > 2)
383     return _("immediate is out of range 1-2");
385   *valuep = value;
386   return 0;
389 static const char *
390 parse_imm3_S (CGEN_CPU_DESC cd, const char **strp,
391              int opindex, signed long *valuep)
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 */
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
406   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
407   if (errmsg)
408     return errmsg;
410   if (value < 1 || value > 8)
411     return _("immediate is out of range 1-8");
413   *valuep = value;
414   return 0;
417 static const char *
418 parse_Bitno16R (CGEN_CPU_DESC cd, const char **strp,
419                 int opindex, unsigned long *valuep)
421   const char *errmsg = 0;
422   unsigned long value;
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
430   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
431   if (errmsg)
432     return errmsg;
434   if (value > 15)
435     return _("Bit number for indexing general register is out of range 0-15");
437   *valuep = value;
438   return 0;
441 static const char *
442 parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp,
443                         int opindex, unsigned long *valuep,
444                         unsigned bits)
446   const char *errmsg = 0;
447   unsigned long bit;
448   unsigned long base;
449   const char *newp = *strp;
450   unsigned long long bitbase;
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
458   errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
459   if (errmsg)
460     return errmsg;
462   if (*newp != ',')
463     return "Missing base for bit,base:8";
465   ++newp;
466   errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & base);
467   if (errmsg)
468     return errmsg;
470   bitbase = (unsigned long long)bit + ((unsigned long long)base * 8);
472   if (bitbase >= (1ull << bits))
473     return _("bit,base is out of range");
475   *valuep = bitbase;
476   *strp = newp;
477   return 0;
480 static const char *
481 parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp,
482                       int opindex, signed long *valuep,
483                       unsigned bits)
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;
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
498   errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit);
499   if (errmsg)
500     return errmsg;
502   if (*newp != ',')
503     return "Missing base for bit,base:8";
505   ++newp;
506   errmsg = cgen_parse_signed_integer (cd, & newp, opindex, & base);
507   if (errmsg)
508     return errmsg;
510   bitbase = (long long)bit + ((long long)base * 8);
512   limit = 1ll << (bits - 1);
513   if (bitbase < -limit || bitbase >= limit)
514     return _("bit,base is out of range");
516   *valuep = bitbase;
517   *strp = newp;
518   return 0;
521 static const char *
522 parse_unsigned_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
523                          int opindex, unsigned long *valuep)
525   return parse_unsigned_bitbase (cd, strp, opindex, valuep, 8);
528 static const char *
529 parse_unsigned_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
530                          int opindex, unsigned long *valuep)
532   return parse_unsigned_bitbase (cd, strp, opindex, valuep, 11);
535 static const char *
536 parse_unsigned_bitbase16 (CGEN_CPU_DESC cd, const char **strp,
537                           int opindex, unsigned long *valuep)
539   return parse_unsigned_bitbase (cd, strp, opindex, valuep, 16);
542 static const char *
543 parse_unsigned_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
544                          int opindex, unsigned long *valuep)
546   return parse_unsigned_bitbase (cd, strp, opindex, valuep, 19);
549 static const char *
550 parse_unsigned_bitbase27 (CGEN_CPU_DESC cd, const char **strp,
551                          int opindex, unsigned long *valuep)
553   return parse_unsigned_bitbase (cd, strp, opindex, valuep, 27);
556 static const char *
557 parse_signed_bitbase8 (CGEN_CPU_DESC cd, const char **strp,
558                        int opindex, signed long *valuep)
560   return parse_signed_bitbase (cd, strp, opindex, valuep, 8);
563 static const char *
564 parse_signed_bitbase11 (CGEN_CPU_DESC cd, const char **strp,
565                        int opindex, signed long *valuep)
567   return parse_signed_bitbase (cd, strp, opindex, valuep, 11);
570 static const char *
571 parse_signed_bitbase19 (CGEN_CPU_DESC cd, const char **strp,
572                        int opindex, signed long *valuep)
574   return parse_signed_bitbase (cd, strp, opindex, valuep, 19);
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)
581   const char *newp = *strp;
582   
583   if (**strp == ':' && tolower (*(*strp + 1)) == suffix)
584     newp = *strp + 2;
586   if (isspace (*newp))
587     {
588       *strp = newp;
589       return 0;
590     }
591         
592   return "Invalid suffix"; /* anything -- will not be seen */
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)
599   return parse_suffix (strp, 's');
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)
606   return parse_suffix (strp, 'g');
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)
613   return parse_suffix (strp, 'q');
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)
620   return parse_suffix (strp, 'z');
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)
628   if (**strp == ':')
629     return "Unexpected suffix";
630   return 0;
633 static const char *
634 parse_r0l_r0h (CGEN_CPU_DESC cd, const char **strp,
635                int opindex ATTRIBUTE_UNUSED, signed long *valuep)
637   const char *errmsg;
638   signed long value;
639   signed long junk;
640   const char *newp = *strp;
642   /* Parse r0[hl] */
643   errmsg = cgen_parse_keyword (cd, & newp, & m32c_cgen_opval_h_r0l_r0h, & value);
644   if (errmsg)
645     return errmsg;
647   if (*newp != ',')
648     return "not a valid r0l/r0h pair";
649   ++newp;
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;
659   *strp = newp;
660   *valuep = ! value;
661   return 0;
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)
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";
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 *); */
690 /* /\* Parse absolute  *\/ */
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 /* } */
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 /* } */
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; */
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.  *\/ */
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 /* } */
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; */
779 /*   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); */
780 /*   *valuep = value; */
781 /*   return errmsg; */
782 /* } */
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; */
794 /*   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); */
795 /*   *valuep = value; */
796 /*   return errmsg; */
797 /* } */
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; */
809 /*   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); */
810 /*   *valuep = value; */
811 /*   return errmsg; */
812 /* } */
814 /* /\* Handle bitfields.  *\/ */
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; */
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 /* } */
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; */
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 /* } */
863 /* Special check to ensure that instruction exists for given machine */
865 m32c_cgen_insn_supported (CGEN_CPU_DESC cd,
866                           const CGEN_INSN *insn)
868   int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
869   int isas = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ISA);
871   /* If attributes are absent, assume no restriction. */
872   if (machs == 0)
873     machs = ~0;
875   return ((machs & cd->machs)
876           && (isas & cd->isas));
879 /* Parse a set of registers, R0,R1,A0,A1,SB,FB.  */
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               )
889   const char *errmsg = 0;
890   int regno = 0;
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;
928       ++*strp;
929       if (**strp == ',')
930         {
931           if (*(*strp + 1) == ')')
932             break;
933           ++*strp;
934         }
935     }
937   if (!*strp)
938     errmsg = _("Register list is not valid");
940   return errmsg;
943 #define POP 0
944 #define PUSH 1
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)
952   return parse_regset (cd, strp, opindex, valuep, POP);
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)
961   return parse_regset (cd, strp, opindex, valuep, PUSH);
964 /* -- dis.c */
966 #include "elf/m32c.h"
967 #include "elf-bfd.h"
969 /* Always print the short insn format suffix as ':<char>' */
970 static void
971 print_suffix (PTR dis_info, char suffix)
973   disassemble_info *info = dis_info;
974   (*info->fprintf_func) (info->stream, ":%c", suffix);
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)
985   print_suffix (dis_info, 's');
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)
997   print_suffix (dis_info, 'g');
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)
1008   print_suffix (dis_info, 'q');
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)
1019   print_suffix (dis_info, 'z');
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)
1031   return;
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)
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");
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)
1057   disassemble_info *info = dis_info;
1058   (*info->fprintf_func) (info->stream, "%ld,0x%lx", value & 0x7, value >> 3);
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)
1069   disassemble_info *info = dis_info;
1070   (*info->fprintf_func) (info->stream, "%ld,%ld", value & 0x7, value >> 3);
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)
1081   /* Always print the size as '.w' */
1082   disassemble_info *info = dis_info;
1083   (*info->fprintf_func) (info->stream, ".w");
1086 #define POP 0
1087 #define PUSH 1
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);
1092 /* Print a set of registers, R0,R1,A0,A1,SB,FB.  */
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)
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 = "";
1112   if (push)
1113     mask = 0x80;
1114   else
1115     mask = 1;
1117   if (value & mask)
1118     {
1119       (*info->fprintf_func) (info->stream, "%s", m16c_register_names [0]);
1120       comma = ",";
1121     }
1123   for (index = 1; index <= 7; ++index)
1124     {
1125       if (push)
1126         mask >>= 1;
1127       else
1128         mask <<= 1;
1130       if (value & mask)
1131         {
1132           (*info->fprintf_func) (info->stream, "%s%s", comma,
1133                                  m16c_register_names [index]);
1134           comma = ",";
1135         }
1136     }
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)
1147   print_regset (cd, dis_info, value, attrs, pc, length, POP);
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)
1158   print_regset (cd, dis_info, value, attrs, pc, length, PUSH);
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)
1169   disassemble_info *info = dis_info;
1170   if (value)
1171     info->fprintf_func (info->stream, "%d,%d", value % 16,
1172                         (value / 16) * 2);
1175 #endif /* not used? */