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