* m32c.opc (m32c_cgen_insn_supported): Use int, not CGEN_BITSET,
[platform/upstream/binutils.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? */