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