* sh-dis.c (print_insn_sh): If coff and bfd_mach_sh, use arch_sh4
[platform/upstream/binutils.git] / opcodes / sh-dis.c
1 /* Disassemble SH instructions.
2    Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18
19 #include <stdio.h>
20 #include "sysdep.h"
21 #define STATIC_TABLE
22 #define DEFINE_TABLE
23
24 #include "sh-opc.h"
25 #include "dis-asm.h"
26
27 static void print_movxy
28   PARAMS ((sh_opcode_info *, int, int, fprintf_ftype, void *));
29 static void print_insn_ddt PARAMS ((int, struct disassemble_info *));
30 static void print_dsp_reg PARAMS ((int, fprintf_ftype, void *));
31 static void print_insn_ppi PARAMS ((int, struct disassemble_info *));
32
33 static void
34 print_movxy (op, rn, rm, fprintf_fn, stream)
35      sh_opcode_info *op;
36      int rn, rm;
37      fprintf_ftype fprintf_fn;
38      void *stream;
39 {
40   int n;
41
42   fprintf_fn (stream, "%s\t", op->name);
43   for (n = 0; n < 2; n++)
44     {
45       switch (op->arg[n])
46         {
47         case A_IND_N:
48           fprintf_fn (stream, "@r%d", rn);
49           break;
50         case A_INC_N:
51           fprintf_fn (stream, "@r%d+", rn);
52           break;
53         case A_PMOD_N:
54           fprintf_fn (stream, "@r%d+r8", rn);
55           break;
56         case A_PMODY_N:
57           fprintf_fn (stream, "@r%d+r9", rn);
58           break;
59         case DSP_REG_M:
60           fprintf_fn (stream, "a%c", '0' + rm);
61           break;
62         case DSP_REG_X:
63           fprintf_fn (stream, "x%c", '0' + rm);
64           break;
65         case DSP_REG_Y:
66           fprintf_fn (stream, "y%c", '0' + rm);
67           break;
68         default:
69           abort ();
70         }
71       if (n == 0)
72         fprintf_fn (stream, ",");
73     }
74 }
75
76 /* Print a double data transfer insn.  INSN is just the lower three
77    nibbles of the insn, i.e. field a and the bit that indicates if
78    a parallel processing insn follows.
79    Return nonzero if a field b of a parallel processing insns follows.  */
80
81 static void
82 print_insn_ddt (insn, info)
83      int insn;
84      struct disassemble_info *info;
85 {
86   fprintf_ftype fprintf_fn = info->fprintf_func;
87   void *stream = info->stream;
88
89   /* If this is just a nop, make sure to emit something.  */
90   if (insn == 0x000)
91     fprintf_fn (stream, "nopx\tnopy");
92
93   /* If a parallel processing insn was printed before,
94      and we got a non-nop, emit a tab.  */
95   if ((insn & 0x800) && (insn & 0x3ff))
96     fprintf_fn (stream, "\t");
97
98   /* Check if either the x or y part is invalid.  */
99   if (((insn & 0xc) == 0 && (insn & 0x2a0))
100       || ((insn & 3) == 0 && (insn & 0x150)))
101     fprintf_fn (stream, ".word 0x%x", insn);
102   else
103     {
104       static sh_opcode_info *first_movx, *first_movy;
105       sh_opcode_info *opx, *opy;
106       unsigned int insn_x, insn_y;
107
108       if (! first_movx)
109         {
110           for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
111             first_movx++;
112           for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
113             first_movy++;
114         }
115       insn_x = (insn >> 2) & 0xb;
116       if (insn_x)
117         {
118           for (opx = first_movx; opx->nibbles[2] != insn_x;)
119             opx++;
120           print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
121                        fprintf_fn, stream);
122         }
123       insn_y = (insn & 3) | ((insn >> 1) & 8);
124       if (insn_y)
125         {
126           if (insn_x)
127             fprintf_fn (stream, "\t");
128           for (opy = first_movy; opy->nibbles[2] != insn_y;)
129             opy++;
130           print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
131                        fprintf_fn, stream);
132         }
133     }
134 }
135
136 static void
137 print_dsp_reg (rm, fprintf_fn, stream)
138      int rm;
139      fprintf_ftype fprintf_fn;
140      void *stream;
141 {
142   switch (rm)
143     {
144     case A_A1_NUM:
145       fprintf_fn (stream, "a1");
146       break;
147     case A_A0_NUM:
148       fprintf_fn (stream, "a0");
149       break;
150     case A_X0_NUM:
151       fprintf_fn (stream, "x0");
152       break;
153     case A_X1_NUM:
154       fprintf_fn (stream, "x1");
155       break;
156     case A_Y0_NUM:
157       fprintf_fn (stream, "y0");
158       break;
159     case A_Y1_NUM:
160       fprintf_fn (stream, "y1");
161       break;
162     case A_M0_NUM:
163       fprintf_fn (stream, "m0");
164       break;
165     case A_A1G_NUM:
166       fprintf_fn (stream, "a1g");
167       break;
168     case A_M1_NUM:
169       fprintf_fn (stream, "m1");
170       break;
171     case A_A0G_NUM:
172       fprintf_fn (stream, "a0g");
173       break;
174     default:
175       fprintf_fn (stream, "0x%x", rm);
176       break;
177     }
178 }
179
180 static void
181 print_insn_ppi (field_b, info)
182      int field_b;
183      struct disassemble_info *info;
184 {
185   static char *sx_tab[] = { "x0", "x1", "a0", "a1" };
186   static char *sy_tab[] = { "y0", "y1", "m0", "m1" };
187   fprintf_ftype fprintf_fn = info->fprintf_func;
188   void *stream = info->stream;
189   unsigned int nib1, nib2, nib3;
190   char *dc = NULL;
191   sh_opcode_info *op;
192
193   if ((field_b & 0xe800) == 0)
194     {
195       fprintf_fn (stream, "psh%c\t#%d,",
196                   field_b & 0x1000 ? 'a' : 'l',
197                   (field_b >> 4) & 127);
198       print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
199       return;
200     }
201   if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
202     {
203       static char *du_tab[] = { "x0", "y0", "a0", "a1" };
204       static char *se_tab[] = { "x0", "x1", "y0", "a1" };
205       static char *sf_tab[] = { "y0", "y1", "x0", "a1" };
206       static char *sg_tab[] = { "m0", "m1", "a0", "a1" };
207
208       if (field_b & 0x2000)
209         {
210           fprintf_fn (stream, "p%s %s,%s,%s\t",
211                       (field_b & 0x1000) ? "add" : "sub",
212                       sx_tab[(field_b >> 6) & 3],
213                       sy_tab[(field_b >> 4) & 3],
214                       du_tab[(field_b >> 0) & 3]);
215         }
216       fprintf_fn (stream, "pmuls%c%s,%s,%s",
217                   field_b & 0x2000 ? ' ' : '\t',
218                   se_tab[(field_b >> 10) & 3],
219                   sf_tab[(field_b >>  8) & 3],
220                   sg_tab[(field_b >>  2) & 3]);
221       return;
222     }
223
224   nib1 = PPIC;
225   nib2 = field_b >> 12 & 0xf;
226   nib3 = field_b >> 8 & 0xf;
227   switch (nib3 & 0x3)
228     {
229     case 0:
230       dc = "";
231       nib1 = PPI3;
232       break;
233     case 1:
234       dc = "";
235       break;
236     case 2:
237       dc = "dct ";
238       nib3 -= 1;
239       break;
240     case 3:
241       dc = "dcf ";
242       nib3 -= 2;
243       break;
244     }
245   for (op = sh_table; op->name; op++)
246     {
247       if (op->nibbles[1] == nib1
248           && op->nibbles[2] == nib2
249           && op->nibbles[3] == nib3)
250         {
251           int n;
252
253           fprintf_fn (stream, "%s%s\t", dc, op->name);
254           for (n = 0; n < 3 && op->arg[n] != A_END; n++)
255             {
256               if (n && op->arg[1] != A_END)
257                 fprintf_fn (stream, ",");
258               switch (op->arg[n])
259                 {
260                 case DSP_REG_N:
261                   print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
262                   break;
263                 case DSP_REG_X:
264                   fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
265                   break;
266                 case DSP_REG_Y:
267                   fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
268                   break;
269                 case A_MACH:
270                   fprintf_fn (stream, "mach");
271                   break;
272                 case A_MACL:
273                   fprintf_fn (stream, "macl");
274                   break;
275                 default:
276                   abort ();
277                 }
278             }
279           return;
280         }
281     }
282   /* Not found.  */
283   fprintf_fn (stream, ".word 0x%x", field_b);
284 }
285
286 int
287 print_insn_sh (memaddr, info)
288      bfd_vma memaddr;
289      struct disassemble_info *info;
290 {
291   fprintf_ftype fprintf_fn = info->fprintf_func;
292   void *stream = info->stream;
293   unsigned char insn[2];
294   unsigned char nibs[4];
295   int status;
296   bfd_vma relmask = ~(bfd_vma) 0;
297   sh_opcode_info *op;
298   int target_arch;
299
300   switch (info->mach)
301     {
302     case bfd_mach_sh:
303       target_arch = arch_sh1;
304       /* SH coff object files lack information about the machine type, so
305          we end up with bfd_mach_sh unless it was set explicitly (which
306          could have happended if this is a call from gdb or the simulator.)  */
307       if (bfd_asymbol_flavour(*info->symbols) == bfd_target_coff_flavour)
308         target_arch = arch_sh4;
309       break;
310     case bfd_mach_sh2:
311       target_arch = arch_sh2;
312       break;
313     case bfd_mach_sh_dsp:
314       target_arch = arch_sh_dsp;
315       break;
316     case bfd_mach_sh3:
317       target_arch = arch_sh3;
318       break;
319     case bfd_mach_sh3_dsp:
320       target_arch = arch_sh3_dsp;
321       break;
322     case bfd_mach_sh3e:
323       target_arch = arch_sh3e;
324       break;
325     case bfd_mach_sh4:
326       target_arch = arch_sh4;
327       break;
328     case bfd_mach_sh5:
329 #ifdef INCLUDE_SHMEDIA
330       status = print_insn_sh64 (memaddr, info);
331       if (status != -2)
332         return status;
333 #endif
334       /* When we get here for sh64, it's because we want to disassemble
335          SHcompact, i.e. arch_sh4.  */
336       target_arch = arch_sh4;
337       break;
338     default:
339       abort ();
340     }
341
342   status = info->read_memory_func (memaddr, insn, 2, info);
343
344   if (status != 0)
345     {
346       info->memory_error_func (status, memaddr, info);
347       return -1;
348     }
349
350   if (info->endian == BFD_ENDIAN_LITTLE)
351     {
352       nibs[0] = (insn[1] >> 4) & 0xf;
353       nibs[1] = insn[1] & 0xf;
354
355       nibs[2] = (insn[0] >> 4) & 0xf;
356       nibs[3] = insn[0] & 0xf;
357     }
358   else
359     {
360       nibs[0] = (insn[0] >> 4) & 0xf;
361       nibs[1] = insn[0] & 0xf;
362
363       nibs[2] = (insn[1] >> 4) & 0xf;
364       nibs[3] = insn[1] & 0xf;
365     }
366
367   if (nibs[0] == 0xf && (nibs[1] & 4) == 0 && target_arch & arch_sh_dsp_up)
368     {
369       if (nibs[1] & 8)
370         {
371           int field_b;
372
373           status = info->read_memory_func (memaddr + 2, insn, 2, info);
374
375           if (status != 0)
376             {
377               info->memory_error_func (status, memaddr + 2, info);
378               return -1;
379             }
380
381           if (info->endian == BFD_ENDIAN_LITTLE)
382             field_b = insn[1] << 8 | insn[0];
383           else
384             field_b = insn[0] << 8 | insn[1];
385
386           print_insn_ppi (field_b, info);
387           print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
388           return 4;
389         }
390       print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
391       return 2;
392     }
393   for (op = sh_table; op->name; op++)
394     {
395       int n;
396       int imm = 0;
397       int rn = 0;
398       int rm = 0;
399       int rb = 0;
400       int disp_pc;
401       bfd_vma disp_pc_addr = 0;
402
403       if ((op->arch & target_arch) == 0)
404         goto fail;
405       for (n = 0; n < 4; n++)
406         {
407           int i = op->nibbles[n];
408
409           if (i < 16)
410             {
411               if (nibs[n] == i)
412                 continue;
413               goto fail;
414             }
415           switch (i)
416             {
417             case BRANCH_8:
418               imm = (nibs[2] << 4) | (nibs[3]);
419               if (imm & 0x80)
420                 imm |= ~0xff;
421               imm = ((char) imm) * 2 + 4;
422               goto ok;
423             case BRANCH_12:
424               imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
425               if (imm & 0x800)
426                 imm |= ~0xfff;
427               imm = imm * 2 + 4;
428               goto ok;
429             case IMM0_4:
430             case IMM1_4:
431               imm = nibs[3];
432               goto ok;
433             case IMM0_4BY2:
434             case IMM1_4BY2:
435               imm = nibs[3] << 1;
436               goto ok;
437             case IMM0_4BY4:
438             case IMM1_4BY4:
439               imm = nibs[3] << 2;
440               goto ok;
441             case IMM0_8:
442             case IMM1_8:
443               imm = (nibs[2] << 4) | nibs[3];
444               goto ok;
445             case PCRELIMM_8BY2:
446               imm = ((nibs[2] << 4) | nibs[3]) << 1;
447               relmask = ~(bfd_vma) 1;
448               goto ok;
449             case PCRELIMM_8BY4:
450               imm = ((nibs[2] << 4) | nibs[3]) << 2;
451               relmask = ~(bfd_vma) 3;
452               goto ok;
453             case IMM0_8BY2:
454             case IMM1_8BY2:
455               imm = ((nibs[2] << 4) | nibs[3]) << 1;
456               goto ok;
457             case IMM0_8BY4:
458             case IMM1_8BY4:
459               imm = ((nibs[2] << 4) | nibs[3]) << 2;
460               goto ok;
461             case REG_N:
462               rn = nibs[n];
463               break;
464             case REG_M:
465               rm = nibs[n];
466               break;
467             case REG_NM:
468               rn = (nibs[n] & 0xc) >> 2;
469               rm = (nibs[n] & 0x3);
470               break;
471             case REG_B:
472               rb = nibs[n] & 0x07;
473               break;
474             case SDT_REG_N:
475               /* sh-dsp: single data transfer.  */
476               rn = nibs[n];
477               if ((rn & 0xc) != 4)
478                 goto fail;
479               rn = rn & 0x3;
480               rn |= (!(rn & 2)) << 2;
481               break;
482             case PPI:
483             case REPEAT:
484               goto fail;
485             default:
486               abort ();
487             }
488         }
489
490     ok:
491       fprintf_fn (stream, "%s\t", op->name);
492       disp_pc = 0;
493       for (n = 0; n < 3 && op->arg[n] != A_END; n++)
494         {
495           if (n && op->arg[1] != A_END)
496             fprintf_fn (stream, ",");
497           switch (op->arg[n])
498             {
499             case A_IMM:
500               fprintf_fn (stream, "#%d", (char) (imm));
501               break;
502             case A_R0:
503               fprintf_fn (stream, "r0");
504               break;
505             case A_REG_N:
506               fprintf_fn (stream, "r%d", rn);
507               break;
508             case A_INC_N:
509               fprintf_fn (stream, "@r%d+", rn);
510               break;
511             case A_DEC_N:
512               fprintf_fn (stream, "@-r%d", rn);
513               break;
514             case A_IND_N:
515               fprintf_fn (stream, "@r%d", rn);
516               break;
517             case A_DISP_REG_N:
518               fprintf_fn (stream, "@(%d,r%d)", imm, rn);
519               break;
520             case A_PMOD_N:
521               fprintf_fn (stream, "@r%d+r8", rn);
522               break;
523             case A_REG_M:
524               fprintf_fn (stream, "r%d", rm);
525               break;
526             case A_INC_M:
527               fprintf_fn (stream, "@r%d+", rm);
528               break;
529             case A_DEC_M:
530               fprintf_fn (stream, "@-r%d", rm);
531               break;
532             case A_IND_M:
533               fprintf_fn (stream, "@r%d", rm);
534               break;
535             case A_DISP_REG_M:
536               fprintf_fn (stream, "@(%d,r%d)", imm, rm);
537               break;
538             case A_REG_B:
539               fprintf_fn (stream, "r%d_bank", rb);
540               break;
541             case A_DISP_PC:
542               disp_pc = 1;
543               disp_pc_addr = imm + 4 + (memaddr & relmask);
544               (*info->print_address_func) (disp_pc_addr, info);
545               break;
546             case A_IND_R0_REG_N:
547               fprintf_fn (stream, "@(r0,r%d)", rn);
548               break;
549             case A_IND_R0_REG_M:
550               fprintf_fn (stream, "@(r0,r%d)", rm);
551               break;
552             case A_DISP_GBR:
553               fprintf_fn (stream, "@(%d,gbr)", imm);
554               break;
555             case A_R0_GBR:
556               fprintf_fn (stream, "@(r0,gbr)");
557               break;
558             case A_BDISP12:
559             case A_BDISP8:
560               (*info->print_address_func) (imm + memaddr, info);
561               break;
562             case A_SR:
563               fprintf_fn (stream, "sr");
564               break;
565             case A_GBR:
566               fprintf_fn (stream, "gbr");
567               break;
568             case A_VBR:
569               fprintf_fn (stream, "vbr");
570               break;
571             case A_DSR:
572               fprintf_fn (stream, "dsr");
573               break;
574             case A_MOD:
575               fprintf_fn (stream, "mod");
576               break;
577             case A_RE:
578               fprintf_fn (stream, "re");
579               break;
580             case A_RS:
581               fprintf_fn (stream, "rs");
582               break;
583             case A_A0:
584               fprintf_fn (stream, "a0");
585               break;
586             case A_X0:
587               fprintf_fn (stream, "x0");
588               break;
589             case A_X1:
590               fprintf_fn (stream, "x1");
591               break;
592             case A_Y0:
593               fprintf_fn (stream, "y0");
594               break;
595             case A_Y1:
596               fprintf_fn (stream, "y1");
597               break;
598             case DSP_REG_M:
599               print_dsp_reg (rm, fprintf_fn, stream);
600               break;
601             case A_SSR:
602               fprintf_fn (stream, "ssr");
603               break;
604             case A_SPC:
605               fprintf_fn (stream, "spc");
606               break;
607             case A_MACH:
608               fprintf_fn (stream, "mach");
609               break;
610             case A_MACL:
611               fprintf_fn (stream, "macl");
612               break;
613             case A_PR:
614               fprintf_fn (stream, "pr");
615               break;
616             case A_SGR:
617               fprintf_fn (stream, "sgr");
618               break;
619             case A_DBR:
620               fprintf_fn (stream, "dbr");
621               break;
622             case F_REG_N:
623               fprintf_fn (stream, "fr%d", rn);
624               break;
625             case F_REG_M:
626               fprintf_fn (stream, "fr%d", rm);
627               break;
628             case DX_REG_N:
629               if (rn & 1)
630                 {
631                   fprintf_fn (stream, "xd%d", rn & ~1);
632                   break;
633                 }
634             case D_REG_N:
635               fprintf_fn (stream, "dr%d", rn);
636               break;
637             case DX_REG_M:
638               if (rm & 1)
639                 {
640                   fprintf_fn (stream, "xd%d", rm & ~1);
641                   break;
642                 }
643             case D_REG_M:
644               fprintf_fn (stream, "dr%d", rm);
645               break;
646             case FPSCR_M:
647             case FPSCR_N:
648               fprintf_fn (stream, "fpscr");
649               break;
650             case FPUL_M:
651             case FPUL_N:
652               fprintf_fn (stream, "fpul");
653               break;
654             case F_FR0:
655               fprintf_fn (stream, "fr0");
656               break;
657             case V_REG_N:
658               fprintf_fn (stream, "fv%d", rn * 4);
659               break;
660             case V_REG_M:
661               fprintf_fn (stream, "fv%d", rm * 4);
662               break;
663             case XMTRX_M4:
664               fprintf_fn (stream, "xmtrx");
665               break;
666             default:
667               abort ();
668             }
669         }
670
671 #if 0
672       /* This code prints instructions in delay slots on the same line
673          as the instruction which needs the delay slots.  This can be
674          confusing, since other disassembler don't work this way, and
675          it means that the instructions are not all in a line.  So I
676          disabled it.  Ian.  */
677       if (!(info->flags & 1)
678           && (op->name[0] == 'j'
679               || (op->name[0] == 'b'
680                   && (op->name[1] == 'r'
681                       || op->name[1] == 's'))
682               || (op->name[0] == 'r' && op->name[1] == 't')
683               || (op->name[0] == 'b' && op->name[2] == '.')))
684         {
685           info->flags |= 1;
686           fprintf_fn (stream, "\t(slot ");
687           print_insn_sh (memaddr + 2, info);
688           info->flags &= ~1;
689           fprintf_fn (stream, ")");
690           return 4;
691         }
692 #endif
693
694       if (disp_pc && strcmp (op->name, "mova") != 0)
695         {
696           int size;
697           bfd_byte bytes[4];
698
699           if (relmask == ~(bfd_vma) 1)
700             size = 2;
701           else
702             size = 4;
703           status = info->read_memory_func (disp_pc_addr, bytes, size, info);
704           if (status == 0)
705             {
706               unsigned int val;
707
708               if (size == 2)
709                 {
710                   if (info->endian == BFD_ENDIAN_LITTLE)
711                     val = bfd_getl16 (bytes);
712                   else
713                     val = bfd_getb16 (bytes);
714                 }
715               else
716                 {
717                   if (info->endian == BFD_ENDIAN_LITTLE)
718                     val = bfd_getl32 (bytes);
719                   else
720                     val = bfd_getb32 (bytes);
721                 }
722               fprintf_fn (stream, "\t! 0x%x", val);
723             }
724         }
725
726       return 2;
727     fail:
728       ;
729
730     }
731   fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
732   return 2;
733 }