OSDN Git Service

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