OSDN Git Service

Update function declarations to ISO C90 formatting
[pf3gnuchains/pf3gnuchains4x.git] / opcodes / h8300-dis.c
1 /* Disassemble h8300 instructions.
2    Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
3    Free Software Foundation, Inc.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18    MA 02110-1301, USA.  */
19
20 #define DEFINE_TABLE
21
22 #include "sysdep.h"
23 #define h8_opcodes h8ops
24 #include "opcode/h8300.h"
25 #include "dis-asm.h"
26 #include "opintl.h"
27 #include "libiberty.h"
28
29 struct h8_instruction
30 {
31   int length;
32   const struct h8_opcode *opcode;
33 };
34
35 struct h8_instruction *h8_instructions;
36
37 /* Run through the opcodes and sort them into order to make them easy
38    to disassemble.  */
39
40 static void
41 bfd_h8_disassemble_init (void)
42 {
43   unsigned int i;
44   unsigned int nopcodes;
45   const struct h8_opcode *p;
46   struct h8_instruction *pi;
47
48   nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
49
50   h8_instructions = xmalloc (nopcodes * sizeof (struct h8_instruction));
51
52   for (p = h8_opcodes, pi = h8_instructions; p->name; p++, pi++)
53     {
54       int n1 = 0;
55       int n2 = 0;
56
57       if ((int) p->data.nib[0] < 16)
58         n1 = (int) p->data.nib[0];
59       else
60         n1 = 0;
61
62       if ((int) p->data.nib[1] < 16)
63         n2 = (int) p->data.nib[1];
64       else
65         n2 = 0;
66
67       /* Just make sure there are an even number of nibbles in it, and
68          that the count is the same as the length.  */
69       for (i = 0; p->data.nib[i] != (op_type) E; i++)
70         ;
71
72       if (i & 1)
73         {
74           fprintf (stderr, "Internal error, h8_disassemble_init.\n");
75           abort ();
76         }
77
78       pi->length = i / 2;
79       pi->opcode = p;
80     }
81
82   /* Add entry for the NULL vector terminator.  */
83   pi->length = 0;
84   pi->opcode = p;
85 }
86
87 static void
88 extract_immediate (FILE *stream,
89                    op_type looking_for,
90                    int thisnib,
91                    unsigned char *data,
92                    int *cst,
93                    int *len,
94                    const struct h8_opcode *q)
95 {
96   switch (looking_for & SIZE)
97     {
98     case L_2:
99       *len = 2;
100       *cst = thisnib & 3;
101
102       /* DISP2 special treatment.  */
103       if ((looking_for & MODE) == DISP)
104         {
105           if (OP_KIND (q->how) == O_MOVAB
106               || OP_KIND (q->how) == O_MOVAW
107               || OP_KIND (q->how) == O_MOVAL)
108             {
109               /* Handling for mova insn.  */
110               switch (q->args.nib[0] & MODE)
111                 {
112                 case INDEXB:
113                 default:
114                   break;
115                 case INDEXW:
116                   *cst *= 2;
117                   break;
118                 case INDEXL:
119                   *cst *= 4;
120                   break;
121                 }
122             }
123           else
124             {
125               /* Handling for non-mova insn.  */
126               switch (OP_SIZE (q->how))
127                 {
128                 default: break;
129                 case SW:
130                   *cst *= 2;
131                   break;
132                 case SL:
133                   *cst *= 4;
134                   break;
135                 }
136             }
137         }
138       break;
139     case L_8:
140       *len = 8;
141       *cst = data[0];
142       break;
143     case L_16:
144     case L_16U:
145       *len = 16;
146       *cst = (data[0] << 8) + data [1];
147 #if 0
148       if ((looking_for & SIZE) == L_16)
149         *cst = (short) *cst;    /* Sign extend.  */
150 #endif
151       break;
152     case L_32:
153       *len = 32;
154       *cst = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
155       break;
156     default:
157       *len = 0;
158       *cst = 0;
159       fprintf (stream, "DISP bad size\n");
160       break;
161     }
162 }
163
164 static const char *regnames[] =
165 {
166   "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
167   "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"
168 };
169 static const char *wregnames[] =
170 {
171   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
172   "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
173 };
174 static const char *lregnames[] =
175 {
176   "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
177   "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
178 };
179 static const char *cregnames[] =
180 {
181   "ccr", "exr", "mach", "macl", "", "", "vbr", "sbr"
182 };
183
184 static void
185 print_one_arg (disassemble_info *info,
186                bfd_vma addr,
187                op_type x,
188                int cst,
189                int cstlen,
190                int rdisp_n,
191                int rn,
192                const char **pregnames,
193                int len)
194 {
195   void * stream = info->stream;
196   fprintf_ftype outfn = info->fprintf_func;
197
198   if ((x & SIZE) == L_3 || (x & SIZE) == L_3NZ)
199     outfn (stream, "#0x%x", (unsigned) cst);
200   else if ((x & MODE) == IMM)
201     outfn (stream, "#0x%x", (unsigned) cst);
202   else if ((x & MODE) == DBIT || (x & MODE) == KBIT)
203     outfn (stream, "#%d", (unsigned) cst);
204   else if ((x & MODE) == CONST_2)
205     outfn (stream, "#2");
206   else if ((x & MODE) == CONST_4)
207     outfn (stream, "#4");
208   else if ((x & MODE) == CONST_8)
209     outfn (stream, "#8");
210   else if ((x & MODE) == CONST_16)
211     outfn (stream, "#16");
212   else if ((x & MODE) == REG)
213     {
214       switch (x & SIZE)
215         {
216         case L_8:
217           outfn (stream, "%s", regnames[rn]);
218           break;
219         case L_16:
220         case L_16U:
221           outfn (stream, "%s", wregnames[rn]);
222           break;
223         case L_P:
224         case L_32:
225           outfn (stream, "%s", lregnames[rn]);
226           break;
227         }
228     }
229   else if ((x & MODE) == LOWREG)
230     {
231       switch (x & SIZE)
232         {
233         case L_8:
234           /* Always take low half of reg.  */
235           outfn (stream, "%s.b", regnames[rn < 8 ? rn + 8 : rn]);
236           break;
237         case L_16:
238         case L_16U:
239           /* Always take low half of reg.  */
240           outfn (stream, "%s.w", wregnames[rn < 8 ? rn : rn - 8]);
241           break;
242         case L_P:
243         case L_32:
244           outfn (stream, "%s.l", lregnames[rn]);
245           break;
246         }
247     }
248   else if ((x & MODE) == POSTINC)
249     outfn (stream, "@%s+", pregnames[rn]);
250
251   else if ((x & MODE) == POSTDEC)
252     outfn (stream, "@%s-", pregnames[rn]);
253
254   else if ((x & MODE) == PREINC)
255     outfn (stream, "@+%s", pregnames[rn]);
256
257   else if ((x & MODE) == PREDEC)
258     outfn (stream, "@-%s", pregnames[rn]);
259
260   else if ((x & MODE) == IND)
261     outfn (stream, "@%s", pregnames[rn]);
262
263   else if ((x & MODE) == ABS || (x & ABSJMP))
264     outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen);
265
266   else if ((x & MODE) == MEMIND)
267     outfn (stream, "@@%d (0x%x)", cst, cst);
268
269   else if ((x & MODE) == VECIND)
270     {
271       /* FIXME Multiplier should be 2 or 4, depending on processor mode,
272          by which is meant "normal" vs. "middle", "advanced", "maximum".  */
273
274       int offset = (cst + 0x80) * 4;
275       outfn (stream, "@@%d (0x%x)", offset, offset);
276     }
277   else if ((x & MODE) == PCREL)
278     {
279       if ((x & SIZE) == L_16 ||
280           (x & SIZE) == L_16U)
281         {
282           outfn (stream, ".%s%d (0x%x)",
283                    (short) cst > 0 ? "+" : "",
284                    (short) cst, 
285                    addr + (short) cst + len);
286         }
287       else
288         {
289           outfn (stream, ".%s%d (0x%x)",
290                    (char) cst > 0 ? "+" : "",
291                    (char) cst, 
292                    addr + (char) cst + len);
293         }
294     }
295   else if ((x & MODE) == DISP)
296     outfn (stream, "@(0x%x:%d,%s)", cst, cstlen, pregnames[rdisp_n]);
297
298   else if ((x & MODE) == INDEXB)
299     /* Always take low half of reg.  */
300     outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen, 
301            regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]);
302
303   else if ((x & MODE) == INDEXW)
304     /* Always take low half of reg.  */
305     outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen, 
306            wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]);
307
308   else if ((x & MODE) == INDEXL)
309     outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen, lregnames[rdisp_n]);
310
311   else if (x & CTRL)
312     outfn (stream, cregnames[rn]);
313
314   else if ((x & MODE) == CCR)
315     outfn (stream, "ccr");
316
317   else if ((x & MODE) == EXR)
318     outfn (stream, "exr");
319
320   else if ((x & MODE) == MACREG)
321     outfn (stream, "mac%c", cst ? 'l' : 'h');
322
323   else
324     /* xgettext:c-format */
325     outfn (stream, _("Hmmmm 0x%x"), x);
326 }
327
328 static unsigned int
329 bfd_h8_disassemble (bfd_vma addr, disassemble_info *info, int mach)
330 {
331   /* Find the first entry in the table for this opcode.  */
332   int regno[3] = { 0, 0, 0 };
333   int dispregno[3] = { 0, 0, 0 };
334   int cst[3] = { 0, 0, 0 };
335   int cstlen[3] = { 0, 0, 0 };
336   static bfd_boolean init = 0;
337   const struct h8_instruction *qi;
338   char const **pregnames = mach != 0 ? lregnames : wregnames;
339   int status;
340   unsigned int l;
341   unsigned char data[MAX_CODE_NIBBLES];
342   void *stream = info->stream;
343   fprintf_ftype outfn = info->fprintf_func;
344
345   if (!init)
346     {
347       bfd_h8_disassemble_init ();
348       init = 1;
349     }
350
351   status = info->read_memory_func (addr, data, 2, info);
352   if (status != 0)
353     {
354       info->memory_error_func (status, addr, info);
355       return -1;
356     }
357
358   for (l = 2; status == 0 && l < sizeof (data) / 2; l += 2)
359     status = info->read_memory_func (addr + l, data + l, 2, info);
360
361   /* Find the exact opcode/arg combo.  */
362   for (qi = h8_instructions; qi->opcode->name; qi++)
363     {
364       const struct h8_opcode *q = qi->opcode;
365       op_type *nib = q->data.nib;
366       unsigned int len = 0;
367
368       while (1)
369         {
370           op_type looking_for = *nib;
371           int thisnib = data[len / 2];
372           int opnr;
373
374           thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf);
375           opnr = ((looking_for & OP3) == OP3 ? 2
376                   : (looking_for & DST) == DST ? 1 : 0);
377
378           if (looking_for < 16 && looking_for >= 0)
379             {
380               if (looking_for != thisnib)
381                 goto fail;
382             }
383           else
384             {
385               if ((int) looking_for & (int) B31)
386                 {
387                   if (!((thisnib & 0x8) != 0))
388                     goto fail;
389
390                   looking_for = (op_type) ((int) looking_for & ~(int) B31);
391                   thisnib &= 0x7;
392                 }
393               else if ((int) looking_for & (int) B30)
394                 {
395                   if (!((thisnib & 0x8) == 0))
396                     goto fail;
397
398                   looking_for = (op_type) ((int) looking_for & ~(int) B30);
399                 }
400
401               if ((int) looking_for & (int) B21)
402                 {
403                   if (!((thisnib & 0x4) != 0))
404                     goto fail;
405
406                   looking_for = (op_type) ((int) looking_for & ~(int) B21);
407                   thisnib &= 0xb;
408                 }
409               else if ((int) looking_for & (int) B20)
410                 {
411                   if (!((thisnib & 0x4) == 0))
412                     goto fail;
413
414                   looking_for = (op_type) ((int) looking_for & ~(int) B20);
415                 }
416               if ((int) looking_for & (int) B11)
417                 {
418                   if (!((thisnib & 0x2) != 0))
419                     goto fail;
420
421                   looking_for = (op_type) ((int) looking_for & ~(int) B11);
422                   thisnib &= 0xd;
423                 }
424               else if ((int) looking_for & (int) B10)
425                 {
426                   if (!((thisnib & 0x2) == 0))
427                     goto fail;
428
429                   looking_for = (op_type) ((int) looking_for & ~(int) B10);
430                 }
431
432               if ((int) looking_for & (int) B01)
433                 {
434                   if (!((thisnib & 0x1) != 0))
435                     goto fail;
436
437                   looking_for = (op_type) ((int) looking_for & ~(int) B01);
438                   thisnib &= 0xe;
439                 }
440               else if ((int) looking_for & (int) B00)
441                 {
442                   if (!((thisnib & 0x1) == 0))
443                     goto fail;
444
445                   looking_for = (op_type) ((int) looking_for & ~(int) B00);
446                 }
447
448               if (looking_for & IGNORE)
449                 {
450                   /* Hitachi has declared that IGNORE must be zero.  */
451                   if (thisnib != 0)
452                     goto fail;
453                 }
454               else if ((looking_for & MODE) == DATA)
455                 {
456                   ;                     /* Skip embedded data.  */
457                 }
458               else if ((looking_for & MODE) == DBIT)
459                 {
460                   /* Exclude adds/subs by looking at bit 0 and 2, and
461                      make sure the operand size, either w or l,
462                      matches by looking at bit 1.  */
463                   if ((looking_for & 7) != (thisnib & 7))
464                     goto fail;
465
466                   cst[opnr] = (thisnib & 0x8) ? 2 : 1;
467                 }
468               else if ((looking_for & MODE) == DISP
469                        || (looking_for & MODE) == ABS
470                        || (looking_for & MODE) == PCREL
471                        || (looking_for & MODE) == INDEXB
472                        || (looking_for & MODE) == INDEXW
473                        || (looking_for & MODE) == INDEXL)
474                 {
475                   extract_immediate (stream, looking_for, thisnib, 
476                                      data + len / 2, cst + opnr, 
477                                      cstlen + opnr, q);
478                   /* Even address == bra, odd == bra/s.  */
479                   if (q->how == O (O_BRAS, SB))
480                     cst[opnr] -= 1;
481                 }
482               else if ((looking_for & MODE) == REG
483                        || (looking_for & MODE) == LOWREG
484                        || (looking_for & MODE) == IND
485                        || (looking_for & MODE) == PREINC
486                        || (looking_for & MODE) == POSTINC
487                        || (looking_for & MODE) == PREDEC
488                        || (looking_for & MODE) == POSTDEC)
489                 {
490                   regno[opnr] = thisnib;
491                 }
492               else if (looking_for & CTRL)      /* Control Register.  */
493                 {
494                   thisnib &= 7;
495                   if (((looking_for & MODE) == CCR  && (thisnib != C_CCR))
496                       || ((looking_for & MODE) == EXR  && (thisnib != C_EXR))
497                       || ((looking_for & MODE) == MACH && (thisnib != C_MACH))
498                       || ((looking_for & MODE) == MACL && (thisnib != C_MACL))
499                       || ((looking_for & MODE) == VBR  && (thisnib != C_VBR))
500                       || ((looking_for & MODE) == SBR  && (thisnib != C_SBR)))
501                     goto fail;
502                   if (((looking_for & MODE) == CCR_EXR
503                        && (thisnib != C_CCR && thisnib != C_EXR))
504                       || ((looking_for & MODE) == VBR_SBR
505                           && (thisnib != C_VBR && thisnib != C_SBR))
506                       || ((looking_for & MODE) == MACREG
507                           && (thisnib != C_MACH && thisnib != C_MACL)))
508                     goto fail;
509                   if (((looking_for & MODE) == CC_EX_VB_SB
510                        && (thisnib != C_CCR && thisnib != C_EXR
511                            && thisnib != C_VBR && thisnib != C_SBR)))
512                     goto fail;
513
514                   regno[opnr] = thisnib;
515                 }
516               else if ((looking_for & SIZE) == L_5)
517                 {
518                   cst[opnr] = data[len / 2] & 31;
519                   cstlen[opnr] = 5;
520                 }
521               else if ((looking_for & SIZE) == L_4)
522                 {
523                   cst[opnr] = thisnib;
524                   cstlen[opnr] = 4;
525                 }
526               else if ((looking_for & SIZE) == L_16
527                        || (looking_for & SIZE) == L_16U)
528                 {
529                   cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2];
530                   cstlen[opnr] = 16;
531                 }
532               else if ((looking_for & MODE) == MEMIND)
533                 {
534                   cst[opnr] = data[1];
535                 }
536               else if ((looking_for & MODE) == VECIND)
537                 {
538                   cst[opnr] = data[1] & 0x7f;
539                 }
540               else if ((looking_for & SIZE) == L_32)
541                 {
542                   int i = len / 2;
543
544                   cst[opnr] = ((data[i] << 24) 
545                                | (data[i + 1] << 16) 
546                                | (data[i + 2] << 8)
547                                | (data[i + 3]));
548
549                   cstlen[opnr] = 32;
550                 }
551               else if ((looking_for & SIZE) == L_24)
552                 {
553                   int i = len / 2;
554
555                   cst[opnr] = 
556                     (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
557                   cstlen[opnr] = 24;
558                 }
559               else if (looking_for & IGNORE)
560                 {
561                   ;
562                 }
563               else if (looking_for & DISPREG)
564                 {
565                   dispregno[opnr] = thisnib & 7;
566                 }
567               else if ((looking_for & MODE) == KBIT)
568                 {
569                   switch (thisnib)
570                     {
571                     case 9:
572                       cst[opnr] = 4;
573                       break;
574                     case 8:
575                       cst[opnr] = 2;
576                       break;
577                     case 0:
578                       cst[opnr] = 1;
579                       break;
580                     default:
581                       goto fail;
582                     }
583                 }
584               else if ((looking_for & SIZE) == L_8)
585                 {
586                   cstlen[opnr] = 8;
587                   cst[opnr] = data[len / 2];
588                 }
589               else if ((looking_for & SIZE) == L_3
590                        || (looking_for & SIZE) == L_3NZ)
591                 {
592                   cst[opnr] = thisnib & 0x7;
593                   if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ)
594                     goto fail;
595                 }
596               else if ((looking_for & SIZE) == L_2)
597                 {
598                   cstlen[opnr] = 2;
599                   cst[opnr] = thisnib & 0x3;
600                 }
601               else if ((looking_for & MODE) == MACREG)
602                 {
603                   cst[opnr] = (thisnib == 3);
604                 }
605               else if (looking_for == (op_type) E)
606                 {
607                   outfn (stream, "%s\t", q->name);
608
609                   /* Gross.  Disgusting.  */
610                   if (strcmp (q->name, "ldm.l") == 0)
611                     {
612                       int count, high;
613
614                       count = (data[1] / 16) & 0x3;
615                       high = regno[1];
616
617                       outfn (stream, "@sp+,er%d-er%d", high - count, high);
618                       return qi->length;
619                     }
620
621                   if (strcmp (q->name, "stm.l") == 0)
622                     {
623                       int count, low;
624
625                       count = (data[1] / 16) & 0x3;
626                       low = regno[0];
627
628                       outfn (stream, "er%d-er%d,@-sp", low, low + count);
629                       return qi->length;
630                     }
631                   if (strcmp (q->name, "rte/l") == 0
632                       || strcmp (q->name, "rts/l") == 0)
633                     {
634                       if (regno[0] == 0)
635                         outfn (stream, "er%d", regno[1]);
636                       else
637                         outfn (stream, "er%d-er%d", regno[1] - regno[0],
638                                regno[1]);
639                       return qi->length;
640                     }
641                   if (strncmp (q->name, "mova", 4) == 0)
642                     {
643                       op_type *args = q->args.nib;
644
645                       if (args[1] == (op_type) E)
646                         {
647                           /* Short form.  */
648                           print_one_arg (info, addr, args[0], cst[0], 
649                                          cstlen[0], dispregno[0], regno[0], 
650                                          pregnames, qi->length);
651                           outfn (stream, ",er%d", dispregno[0]);
652                         }
653                       else
654                         {
655                           outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]);
656                           print_one_arg (info, addr, args[1], cst[1], 
657                                          cstlen[1], dispregno[1], regno[1], 
658                                          pregnames, qi->length);
659                           outfn (stream, ".%c),",
660                                  (args[0] & MODE) == INDEXB ? 'b' : 'w');
661                           print_one_arg (info, addr, args[2], cst[2], 
662                                          cstlen[2], dispregno[2], regno[2], 
663                                          pregnames, qi->length);
664                         }
665                       return qi->length;
666                     }
667                   /* Fill in the args.  */
668                   {
669                     op_type *args = q->args.nib;
670                     int hadone = 0;
671                     int nargs;
672
673                     /* Special case handling for the adds and subs instructions
674                        since in H8 mode thay can only take the r0-r7 registers
675                        but in other (higher) modes they can take the er0-er7
676                        registers as well.  */
677                     if (strcmp (qi->opcode->name, "adds") == 0
678                         || strcmp (qi->opcode->name, "subs") == 0)
679                       {
680                         outfn (stream, "#%d,%s", cst[0], pregnames[regno[1] & 0x7]);
681                         return qi->length;
682                       }
683
684                     for (nargs = 0; 
685                          nargs < 3 && args[nargs] != (op_type) E;
686                          nargs++)
687                       {
688                         int x = args[nargs];
689
690                         if (hadone)
691                           outfn (stream, ",");
692
693                         print_one_arg (info, addr, x,
694                                        cst[nargs], cstlen[nargs],
695                                        dispregno[nargs], regno[nargs],
696                                        pregnames, qi->length);
697
698                         hadone = 1;
699                       }
700                   }
701
702                   return qi->length;
703                 }
704               else
705                 /* xgettext:c-format */
706                 outfn (stream, _("Don't understand 0x%x \n"), looking_for);
707             }
708
709           len++;
710           nib++;
711         }
712
713     fail:
714       ;
715     }
716
717   /* Fell off the end.  */
718   outfn (stream, ".word\tH'%x,H'%x", data[0], data[1]);
719   return 2;
720 }
721
722 int
723 print_insn_h8300 (bfd_vma addr, disassemble_info *info)
724 {
725   return bfd_h8_disassemble (addr, info, 0);
726 }
727
728 int
729 print_insn_h8300h (bfd_vma addr, disassemble_info *info)
730 {
731   return bfd_h8_disassemble (addr, info, 1);
732 }
733
734 int
735 print_insn_h8300s (bfd_vma addr, disassemble_info *info)
736 {
737   return bfd_h8_disassemble (addr, info, 2);
738 }