fix encoding & decoding of DSP single data transfer instructions
[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 #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     default:
327       abort ();
328     }
329
330   status = info->read_memory_func (memaddr, insn, 2, info);
331
332   if (status != 0)
333     {
334       info->memory_error_func (status, memaddr, info);
335       return -1;
336     }
337
338   if (info->flags & LITTLE_BIT)
339     {
340       nibs[0] = (insn[1] >> 4) & 0xf;
341       nibs[1] = insn[1] & 0xf;
342
343       nibs[2] = (insn[0] >> 4) & 0xf;
344       nibs[3] = insn[0] & 0xf;
345     }
346   else
347     {
348       nibs[0] = (insn[0] >> 4) & 0xf;
349       nibs[1] = insn[0] & 0xf;
350
351       nibs[2] = (insn[1] >> 4) & 0xf;
352       nibs[3] = insn[1] & 0xf;
353     }
354
355   if (nibs[0] == 0xf && (nibs[1] & 4) == 0 && target_arch & arch_sh_dsp_up)
356     {
357       if (nibs[1] & 8)
358         {
359           int field_b;
360
361           status = info->read_memory_func (memaddr + 2, insn, 2, info);
362
363           if (status != 0)
364             {
365               info->memory_error_func (status, memaddr + 2, info);
366               return -1;
367             }
368
369           if (info->flags & LITTLE_BIT)
370             field_b = insn[1] << 8 | insn[0];
371           else
372             field_b = insn[0] << 8 | insn[1];
373
374           print_insn_ppi (field_b, info);
375           print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
376           return 4;
377         }
378       print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
379       return 2;
380     }
381   for (op = sh_table; op->name; op++)
382     {
383       int n;
384       int imm = 0;
385       int rn = 0;
386       int rm = 0;
387       int rb = 0;
388       int disp_pc;
389       bfd_vma disp_pc_addr = 0;
390
391       if ((op->arch & target_arch) == 0)
392         goto fail;
393       for (n = 0; n < 4; n++)
394         {
395           int i = op->nibbles[n];
396
397           if (i < 16)
398             {
399               if (nibs[n] == i)
400                 continue;
401               goto fail;
402             }
403           switch (i)
404             {
405             case BRANCH_8:
406               imm = (nibs[2] << 4) | (nibs[3]);
407               if (imm & 0x80)
408                 imm |= ~0xff;
409               imm = ((char) imm) * 2 + 4;
410               goto ok;
411             case BRANCH_12:
412               imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
413               if (imm & 0x800)
414                 imm |= ~0xfff;
415               imm = imm * 2 + 4;
416               goto ok;
417             case IMM0_4:
418             case IMM1_4:
419               imm = nibs[3];
420               goto ok;
421             case IMM0_4BY2:
422             case IMM1_4BY2:
423               imm = nibs[3] << 1;
424               goto ok;
425             case IMM0_4BY4:
426             case IMM1_4BY4:
427               imm = nibs[3] << 2;
428               goto ok;
429             case IMM0_8:
430             case IMM1_8:
431               imm = (nibs[2] << 4) | nibs[3];
432               goto ok;
433             case PCRELIMM_8BY2:
434               imm = ((nibs[2] << 4) | nibs[3]) << 1;
435               relmask = ~(bfd_vma) 1;
436               goto ok;
437             case PCRELIMM_8BY4:
438               imm = ((nibs[2] << 4) | nibs[3]) << 2;
439               relmask = ~(bfd_vma) 3;
440               goto ok;
441             case IMM0_8BY2:
442             case IMM1_8BY2:
443               imm = ((nibs[2] << 4) | nibs[3]) << 1;
444               goto ok;
445             case IMM0_8BY4:
446             case IMM1_8BY4:
447               imm = ((nibs[2] << 4) | nibs[3]) << 2;
448               goto ok;
449             case REG_N:
450               rn = nibs[n];
451               break;
452             case REG_M:
453               rm = nibs[n];
454               break;
455             case REG_NM:
456               rn = (nibs[n] & 0xc) >> 2;
457               rm = (nibs[n] & 0x3);
458               break;
459             case REG_B:
460               rb = nibs[n] & 0x07;
461               break;
462             case SDT_REG_N:
463               /* sh-dsp: single data transfer.  */
464               rn = nibs[n];
465               if ((rn & 0xc) != 4)
466                 goto fail;
467               rn = rn & 0x3;
468               rn |= (!(rn & 2)) << 2;
469               break;
470             case PPI:
471             case REPEAT:
472               goto fail;
473             default:
474               abort ();
475             }
476         }
477
478     ok:
479       fprintf_fn (stream, "%s\t", op->name);
480       disp_pc = 0;
481       for (n = 0; n < 3 && op->arg[n] != A_END; n++)
482         {
483           if (n && op->arg[1] != A_END)
484             fprintf_fn (stream, ",");
485           switch (op->arg[n])
486             {
487             case A_IMM:
488               fprintf_fn (stream, "#%d", (char) (imm));
489               break;
490             case A_R0:
491               fprintf_fn (stream, "r0");
492               break;
493             case A_REG_N:
494               fprintf_fn (stream, "r%d", rn);
495               break;
496             case A_INC_N:
497               fprintf_fn (stream, "@r%d+", rn);
498               break;
499             case A_DEC_N:
500               fprintf_fn (stream, "@-r%d", rn);
501               break;
502             case A_IND_N:
503               fprintf_fn (stream, "@r%d", rn);
504               break;
505             case A_DISP_REG_N:
506               fprintf_fn (stream, "@(%d,r%d)", imm, rn);
507               break;
508             case A_PMOD_N:
509               fprintf_fn (stream, "@r%d+r8", rn);
510               break;
511             case A_REG_M:
512               fprintf_fn (stream, "r%d", rm);
513               break;
514             case A_INC_M:
515               fprintf_fn (stream, "@r%d+", rm);
516               break;
517             case A_DEC_M:
518               fprintf_fn (stream, "@-r%d", rm);
519               break;
520             case A_IND_M:
521               fprintf_fn (stream, "@r%d", rm);
522               break;
523             case A_DISP_REG_M:
524               fprintf_fn (stream, "@(%d,r%d)", imm, rm);
525               break;
526             case A_REG_B:
527               fprintf_fn (stream, "r%d_bank", rb);
528               break;
529             case A_DISP_PC:
530               disp_pc = 1;
531               disp_pc_addr = imm + 4 + (memaddr & relmask);
532               (*info->print_address_func) (disp_pc_addr, info);
533               break;
534             case A_IND_R0_REG_N:
535               fprintf_fn (stream, "@(r0,r%d)", rn);
536               break;
537             case A_IND_R0_REG_M:
538               fprintf_fn (stream, "@(r0,r%d)", rm);
539               break;
540             case A_DISP_GBR:
541               fprintf_fn (stream, "@(%d,gbr)", imm);
542               break;
543             case A_R0_GBR:
544               fprintf_fn (stream, "@(r0,gbr)");
545               break;
546             case A_BDISP12:
547             case A_BDISP8:
548               (*info->print_address_func) (imm + memaddr, info);
549               break;
550             case A_SR:
551               fprintf_fn (stream, "sr");
552               break;
553             case A_GBR:
554               fprintf_fn (stream, "gbr");
555               break;
556             case A_VBR:
557               fprintf_fn (stream, "vbr");
558               break;
559             case A_DSR:
560               fprintf_fn (stream, "dsr");
561               break;
562             case A_MOD:
563               fprintf_fn (stream, "mod");
564               break;
565             case A_RE:
566               fprintf_fn (stream, "re");
567               break;
568             case A_RS:
569               fprintf_fn (stream, "rs");
570               break;
571             case A_A0:
572               fprintf_fn (stream, "a0");
573               break;
574             case A_X0:
575               fprintf_fn (stream, "x0");
576               break;
577             case A_X1:
578               fprintf_fn (stream, "x1");
579               break;
580             case A_Y0:
581               fprintf_fn (stream, "y0");
582               break;
583             case A_Y1:
584               fprintf_fn (stream, "y1");
585               break;
586             case DSP_REG_M:
587               print_dsp_reg (rm, fprintf_fn, stream);
588               break;
589             case A_SSR:
590               fprintf_fn (stream, "ssr");
591               break;
592             case A_SPC:
593               fprintf_fn (stream, "spc");
594               break;
595             case A_MACH:
596               fprintf_fn (stream, "mach");
597               break;
598             case A_MACL:
599               fprintf_fn (stream, "macl");
600               break;
601             case A_PR:
602               fprintf_fn (stream, "pr");
603               break;
604             case A_SGR:
605               fprintf_fn (stream, "sgr");
606               break;
607             case A_DBR:
608               fprintf_fn (stream, "dbr");
609               break;
610             case F_REG_N:
611               fprintf_fn (stream, "fr%d", rn);
612               break;
613             case F_REG_M:
614               fprintf_fn (stream, "fr%d", rm);
615               break;
616             case DX_REG_N:
617               if (rn & 1)
618                 {
619                   fprintf_fn (stream, "xd%d", rn & ~1);
620                   break;
621                 }
622             case D_REG_N:
623               fprintf_fn (stream, "dr%d", rn);
624               break;
625             case DX_REG_M:
626               if (rm & 1)
627                 {
628                   fprintf_fn (stream, "xd%d", rm & ~1);
629                   break;
630                 }
631             case D_REG_M:
632               fprintf_fn (stream, "dr%d", rm);
633               break;
634             case FPSCR_M:
635             case FPSCR_N:
636               fprintf_fn (stream, "fpscr");
637               break;
638             case FPUL_M:
639             case FPUL_N:
640               fprintf_fn (stream, "fpul");
641               break;
642             case F_FR0:
643               fprintf_fn (stream, "fr0");
644               break;
645             case V_REG_N:
646               fprintf_fn (stream, "fv%d", rn * 4);
647               break;
648             case V_REG_M:
649               fprintf_fn (stream, "fv%d", rm * 4);
650               break;
651             case XMTRX_M4:
652               fprintf_fn (stream, "xmtrx");
653               break;
654             default:
655               abort ();
656             }
657         }
658
659 #if 0
660       /* This code prints instructions in delay slots on the same line
661          as the instruction which needs the delay slots.  This can be
662          confusing, since other disassembler don't work this way, and
663          it means that the instructions are not all in a line.  So I
664          disabled it.  Ian.  */
665       if (!(info->flags & 1)
666           && (op->name[0] == 'j'
667               || (op->name[0] == 'b'
668                   && (op->name[1] == 'r'
669                       || op->name[1] == 's'))
670               || (op->name[0] == 'r' && op->name[1] == 't')
671               || (op->name[0] == 'b' && op->name[2] == '.')))
672         {
673           info->flags |= 1;
674           fprintf_fn (stream, "\t(slot ");
675           print_insn_shx (memaddr + 2, info);
676           info->flags &= ~1;
677           fprintf_fn (stream, ")");
678           return 4;
679         }
680 #endif
681
682       if (disp_pc && strcmp (op->name, "mova") != 0)
683         {
684           int size;
685           bfd_byte bytes[4];
686
687           if (relmask == ~(bfd_vma) 1)
688             size = 2;
689           else
690             size = 4;
691           status = info->read_memory_func (disp_pc_addr, bytes, size, info);
692           if (status == 0)
693             {
694               unsigned int val;
695
696               if (size == 2)
697                 {
698                   if ((info->flags & LITTLE_BIT) != 0)
699                     val = bfd_getl16 (bytes);
700                   else
701                     val = bfd_getb16 (bytes);
702                 }
703               else
704                 {
705                   if ((info->flags & LITTLE_BIT) != 0)
706                     val = bfd_getl32 (bytes);
707                   else
708                     val = bfd_getb32 (bytes);
709                 }
710               fprintf_fn (stream, "\t! 0x%x", val);
711             }
712         }
713
714       return 2;
715     fail:
716       ;
717
718     }
719   fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
720   return 2;
721 }
722
723 int
724 print_insn_shl (memaddr, info)
725      bfd_vma memaddr;
726      struct disassemble_info *info;
727 {
728   int r;
729
730   info->flags = LITTLE_BIT;
731   r = print_insn_shx (memaddr, info);
732   return r;
733 }
734
735 int
736 print_insn_sh (memaddr, info)
737      bfd_vma memaddr;
738      struct disassemble_info *info;
739 {
740   int r;
741
742   info->flags = 0;
743   r = print_insn_shx (memaddr, info);
744   return r;
745 }