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