bfd/doc/
[external/binutils.git] / opcodes / sh-dis.c
1 /* Disassemble SH instructions.
2    Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005
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., 51 Franklin Street - Fifth Floor, Boston,
18    MA 02110-1301, USA.  */
19
20 #include <stdio.h>
21 #include "sysdep.h"
22 #define STATIC_TABLE
23 #define DEFINE_TABLE
24
25 #include "sh-opc.h"
26 #include "dis-asm.h"
27
28 #ifdef ARCH_all
29 #define INCLUDE_SHMEDIA
30 #endif
31
32 static void
33 print_movxy (const sh_opcode_info *op,
34              int rn,
35              int rm,
36              fprintf_ftype fprintf_fn,
37              void *stream)
38 {
39   int n;
40
41   fprintf_fn (stream, "%s\t", op->name);
42   for (n = 0; n < 2; n++)
43     {
44       switch (op->arg[n])
45         {
46         case A_IND_N:
47         case AX_IND_N:
48         case AXY_IND_N:
49         case AY_IND_N:
50         case AYX_IND_N:
51           fprintf_fn (stream, "@r%d", rn);
52           break;
53         case A_INC_N:
54         case AX_INC_N:
55         case AXY_INC_N:
56         case AY_INC_N:
57         case AYX_INC_N:
58           fprintf_fn (stream, "@r%d+", rn);
59           break;
60         case AX_PMOD_N:
61         case AXY_PMOD_N:
62           fprintf_fn (stream, "@r%d+r8", rn);
63           break;
64         case AY_PMOD_N:
65         case AYX_PMOD_N:
66           fprintf_fn (stream, "@r%d+r9", rn);
67           break;
68         case DSP_REG_A_M:
69           fprintf_fn (stream, "a%c", '0' + rm);
70           break;
71         case DSP_REG_X:
72           fprintf_fn (stream, "x%c", '0' + rm);
73           break;
74         case DSP_REG_Y:
75           fprintf_fn (stream, "y%c", '0' + rm);
76           break;
77         case DSP_REG_AX:
78           fprintf_fn (stream, "%c%c",
79                       (rm & 1) ? 'x' : 'a',
80                       (rm & 2) ? '1' : '0');
81           break;
82         case DSP_REG_XY:
83           fprintf_fn (stream, "%c%c",
84                       (rm & 1) ? 'y' : 'x',
85                       (rm & 2) ? '1' : '0');
86           break;
87         case DSP_REG_AY:
88           fprintf_fn (stream, "%c%c",
89                       (rm & 2) ? 'y' : 'a',
90                       (rm & 1) ? '1' : '0');
91           break;
92         case DSP_REG_YX:
93           fprintf_fn (stream, "%c%c",
94                       (rm & 2) ? 'x' : 'y',
95                       (rm & 1) ? '1' : '0');
96           break;
97         default:
98           abort ();
99         }
100       if (n == 0)
101         fprintf_fn (stream, ",");
102     }
103 }
104
105 /* Print a double data transfer insn.  INSN is just the lower three
106    nibbles of the insn, i.e. field a and the bit that indicates if
107    a parallel processing insn follows.
108    Return nonzero if a field b of a parallel processing insns follows.  */
109
110 static void
111 print_insn_ddt (int insn, struct disassemble_info *info)
112 {
113   fprintf_ftype fprintf_fn = info->fprintf_func;
114   void *stream = info->stream;
115
116   /* If this is just a nop, make sure to emit something.  */
117   if (insn == 0x000)
118     fprintf_fn (stream, "nopx\tnopy");
119
120   /* If a parallel processing insn was printed before,
121      and we got a non-nop, emit a tab.  */
122   if ((insn & 0x800) && (insn & 0x3ff))
123     fprintf_fn (stream, "\t");
124
125   /* Check if either the x or y part is invalid.  */
126   if (((insn & 0xc) == 0 && (insn & 0x2a0))
127       || ((insn & 3) == 0 && (insn & 0x150)))
128     if (info->mach != bfd_mach_sh_dsp
129         && info->mach != bfd_mach_sh3_dsp)
130       {
131         static const sh_opcode_info *first_movx, *first_movy;
132         const sh_opcode_info *op;
133         int is_movy;
134
135         if (! first_movx)
136           {
137             for (first_movx = sh_table; first_movx->nibbles[1] != MOVX_NOPY;)
138               first_movx++;
139             for (first_movy = first_movx; first_movy->nibbles[1] != MOVY_NOPX;)
140               first_movy++;
141           }
142
143         is_movy = ((insn & 3) != 0);
144
145         if (is_movy)
146           op = first_movy;
147         else
148           op = first_movx;
149
150         while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
151                || op->nibbles[3] != (unsigned) (insn & 0xf))
152           op++;
153         
154         print_movxy (op,
155                      (4 * ((insn & (is_movy ? 0x200 : 0x100)) == 0)
156                       + 2 * is_movy
157                       + 1 * ((insn & (is_movy ? 0x100 : 0x200)) != 0)),
158                      (insn >> 6) & 3,
159                      fprintf_fn, stream);
160       }
161     else
162       fprintf_fn (stream, ".word 0x%x", insn);
163   else
164     {
165       static const sh_opcode_info *first_movx, *first_movy;
166       const sh_opcode_info *opx, *opy;
167       unsigned int insn_x, insn_y;
168
169       if (! first_movx)
170         {
171           for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
172             first_movx++;
173           for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
174             first_movy++;
175         }
176       insn_x = (insn >> 2) & 0xb;
177       if (insn_x)
178         {
179           for (opx = first_movx; opx->nibbles[2] != insn_x;)
180             opx++;
181           print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
182                        fprintf_fn, stream);
183         }
184       insn_y = (insn & 3) | ((insn >> 1) & 8);
185       if (insn_y)
186         {
187           if (insn_x)
188             fprintf_fn (stream, "\t");
189           for (opy = first_movy; opy->nibbles[2] != insn_y;)
190             opy++;
191           print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
192                        fprintf_fn, stream);
193         }
194     }
195 }
196
197 static void
198 print_dsp_reg (int rm, fprintf_ftype fprintf_fn, void *stream)
199 {
200   switch (rm)
201     {
202     case A_A1_NUM:
203       fprintf_fn (stream, "a1");
204       break;
205     case A_A0_NUM:
206       fprintf_fn (stream, "a0");
207       break;
208     case A_X0_NUM:
209       fprintf_fn (stream, "x0");
210       break;
211     case A_X1_NUM:
212       fprintf_fn (stream, "x1");
213       break;
214     case A_Y0_NUM:
215       fprintf_fn (stream, "y0");
216       break;
217     case A_Y1_NUM:
218       fprintf_fn (stream, "y1");
219       break;
220     case A_M0_NUM:
221       fprintf_fn (stream, "m0");
222       break;
223     case A_A1G_NUM:
224       fprintf_fn (stream, "a1g");
225       break;
226     case A_M1_NUM:
227       fprintf_fn (stream, "m1");
228       break;
229     case A_A0G_NUM:
230       fprintf_fn (stream, "a0g");
231       break;
232     default:
233       fprintf_fn (stream, "0x%x", rm);
234       break;
235     }
236 }
237
238 static void
239 print_insn_ppi (int field_b, struct disassemble_info *info)
240 {
241   static char *sx_tab[] = { "x0", "x1", "a0", "a1" };
242   static char *sy_tab[] = { "y0", "y1", "m0", "m1" };
243   fprintf_ftype fprintf_fn = info->fprintf_func;
244   void *stream = info->stream;
245   unsigned int nib1, nib2, nib3;
246   unsigned int altnib1, nib4;
247   char *dc = NULL;
248   const sh_opcode_info *op;
249
250   if ((field_b & 0xe800) == 0)
251     {
252       fprintf_fn (stream, "psh%c\t#%d,",
253                   field_b & 0x1000 ? 'a' : 'l',
254                   (field_b >> 4) & 127);
255       print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
256       return;
257     }
258   if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
259     {
260       static char *du_tab[] = { "x0", "y0", "a0", "a1" };
261       static char *se_tab[] = { "x0", "x1", "y0", "a1" };
262       static char *sf_tab[] = { "y0", "y1", "x0", "a1" };
263       static char *sg_tab[] = { "m0", "m1", "a0", "a1" };
264
265       if (field_b & 0x2000)
266         fprintf_fn (stream, "p%s %s,%s,%s\t",
267                     (field_b & 0x1000) ? "add" : "sub",
268                     sx_tab[(field_b >> 6) & 3],
269                     sy_tab[(field_b >> 4) & 3],
270                     du_tab[(field_b >> 0) & 3]);
271
272       else if ((field_b & 0xf0) == 0x10
273                && info->mach != bfd_mach_sh_dsp
274                && info->mach != bfd_mach_sh3_dsp)
275         fprintf_fn (stream, "pclr %s \t", du_tab[(field_b >> 0) & 3]);
276
277       else if ((field_b & 0xf3) != 0)
278         fprintf_fn (stream, ".word 0x%x\t", field_b);
279
280       fprintf_fn (stream, "pmuls%c%s,%s,%s",
281                   field_b & 0x2000 ? ' ' : '\t',
282                   se_tab[(field_b >> 10) & 3],
283                   sf_tab[(field_b >>  8) & 3],
284                   sg_tab[(field_b >>  2) & 3]);
285       return;
286     }
287
288   nib1 = PPIC;
289   nib2 = field_b >> 12 & 0xf;
290   nib3 = field_b >> 8 & 0xf;
291   nib4 = field_b >> 4 & 0xf;
292   switch (nib3 & 0x3)
293     {
294     case 0:
295       dc = "";
296       nib1 = PPI3;
297       break;
298     case 1:
299       dc = "";
300       break;
301     case 2:
302       dc = "dct ";
303       nib3 -= 1;
304       break;
305     case 3:
306       dc = "dcf ";
307       nib3 -= 2;
308       break;
309     }
310   if (nib1 == PPI3)
311     altnib1 = PPI3NC;
312   else
313     altnib1 = nib1;
314   for (op = sh_table; op->name; op++)
315     {
316       if ((op->nibbles[1] == nib1 || op->nibbles[1] == altnib1)
317           && op->nibbles[2] == nib2
318           && op->nibbles[3] == nib3)
319         {
320           int n;
321
322           switch (op->nibbles[4])
323             {
324             case HEX_0:
325               break;
326             case HEX_XX00:
327               if ((nib4 & 3) != 0)
328                 continue;
329               break;
330             case HEX_1:
331               if ((nib4 & 3) != 1)
332                 continue;
333               break;
334             case HEX_00YY:
335               if ((nib4 & 0xc) != 0)
336                 continue;
337               break;
338             case HEX_4:
339               if ((nib4 & 0xc) != 4)
340                 continue;
341               break;
342             default:
343               abort ();
344             }
345           fprintf_fn (stream, "%s%s\t", dc, op->name);
346           for (n = 0; n < 3 && op->arg[n] != A_END; n++)
347             {
348               if (n && op->arg[1] != A_END)
349                 fprintf_fn (stream, ",");
350               switch (op->arg[n])
351                 {
352                 case DSP_REG_N:
353                   print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
354                   break;
355                 case DSP_REG_X:
356                   fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
357                   break;
358                 case DSP_REG_Y:
359                   fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
360                   break;
361                 case A_MACH:
362                   fprintf_fn (stream, "mach");
363                   break;
364                 case A_MACL:
365                   fprintf_fn (stream, "macl");
366                   break;
367                 default:
368                   abort ();
369                 }
370             }
371           return;
372         }
373     }
374   /* Not found.  */
375   fprintf_fn (stream, ".word 0x%x", field_b);
376 }
377
378 /* FIXME mvs: movx insns print as ".word 0x%03x", insn & 0xfff
379    (ie. the upper nibble is missing).  */
380
381 int
382 print_insn_sh (bfd_vma memaddr, struct disassemble_info *info)
383 {
384   fprintf_ftype fprintf_fn = info->fprintf_func;
385   void *stream = info->stream;
386   unsigned char insn[4];
387   unsigned char nibs[8];
388   int status;
389   bfd_vma relmask = ~(bfd_vma) 0;
390   const sh_opcode_info *op;
391   unsigned int target_arch;
392   int allow_op32;
393
394   switch (info->mach)
395     {
396     case bfd_mach_sh:
397       target_arch = arch_sh1;
398       /* SH coff object files lack information about the machine type, so
399          we end up with bfd_mach_sh unless it was set explicitly (which
400          could have happended if this is a call from gdb or the simulator.)  */
401       if (info->symbols
402           && bfd_asymbol_flavour(*info->symbols) == bfd_target_coff_flavour)
403         target_arch = arch_sh4;
404       break;
405     case bfd_mach_sh5:
406 #ifdef INCLUDE_SHMEDIA
407       status = print_insn_sh64 (memaddr, info);
408       if (status != -2)
409         return status;
410 #endif
411       /* When we get here for sh64, it's because we want to disassemble
412          SHcompact, i.e. arch_sh4.  */
413       target_arch = arch_sh4;
414       break;
415     default:
416       target_arch = sh_get_arch_from_bfd_mach (info->mach);
417     }
418
419   status = info->read_memory_func (memaddr, insn, 2, info);
420
421   if (status != 0)
422     {
423       info->memory_error_func (status, memaddr, info);
424       return -1;
425     }
426
427   if (info->endian == BFD_ENDIAN_LITTLE)
428     {
429       nibs[0] = (insn[1] >> 4) & 0xf;
430       nibs[1] = insn[1] & 0xf;
431
432       nibs[2] = (insn[0] >> 4) & 0xf;
433       nibs[3] = insn[0] & 0xf;
434     }
435   else
436     {
437       nibs[0] = (insn[0] >> 4) & 0xf;
438       nibs[1] = insn[0] & 0xf;
439
440       nibs[2] = (insn[1] >> 4) & 0xf;
441       nibs[3] = insn[1] & 0xf;
442     }
443   status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
444   if (status != 0)
445     allow_op32 = 0;
446   else
447     {
448       allow_op32 = 1;
449
450       if (info->endian == BFD_ENDIAN_LITTLE)
451         {
452           nibs[4] = (insn[3] >> 4) & 0xf;
453           nibs[5] = insn[3] & 0xf;
454
455           nibs[6] = (insn[2] >> 4) & 0xf;
456           nibs[7] = insn[2] & 0xf;
457         }
458       else
459         {
460           nibs[4] = (insn[2] >> 4) & 0xf;
461           nibs[5] = insn[2] & 0xf;
462
463           nibs[6] = (insn[3] >> 4) & 0xf;
464           nibs[7] = insn[3] & 0xf;
465         }
466     }
467
468   if (nibs[0] == 0xf && (nibs[1] & 4) == 0
469       && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
470     {
471       if (nibs[1] & 8)
472         {
473           int field_b;
474
475           status = info->read_memory_func (memaddr + 2, insn, 2, info);
476
477           if (status != 0)
478             {
479               info->memory_error_func (status, memaddr + 2, info);
480               return -1;
481             }
482
483           if (info->endian == BFD_ENDIAN_LITTLE)
484             field_b = insn[1] << 8 | insn[0];
485           else
486             field_b = insn[0] << 8 | insn[1];
487
488           print_insn_ppi (field_b, info);
489           print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
490           return 4;
491         }
492       print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
493       return 2;
494     }
495   for (op = sh_table; op->name; op++)
496     {
497       int n;
498       int imm = 0;
499       int rn = 0;
500       int rm = 0;
501       int rb = 0;
502       int disp_pc;
503       bfd_vma disp_pc_addr = 0;
504       int disp = 0;
505       int has_disp = 0;
506       int max_n = SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 8 : 4;
507
508       if (!allow_op32
509           && SH_MERGE_ARCH_SET (op->arch, arch_op32))
510         goto fail;
511
512       if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
513         goto fail;
514       for (n = 0; n < max_n; n++)
515         {
516           int i = op->nibbles[n];
517
518           if (i < 16)
519             {
520               if (nibs[n] == i)
521                 continue;
522               goto fail;
523             }
524           switch (i)
525             {
526             case BRANCH_8:
527               imm = (nibs[2] << 4) | (nibs[3]);
528               if (imm & 0x80)
529                 imm |= ~0xff;
530               imm = ((char) imm) * 2 + 4;
531               goto ok;
532             case BRANCH_12:
533               imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
534               if (imm & 0x800)
535                 imm |= ~0xfff;
536               imm = imm * 2 + 4;
537               goto ok;
538             case IMM0_3c:
539               if (nibs[3] & 0x8)
540                 goto fail;
541               imm = nibs[3] & 0x7;
542               break;
543             case IMM0_3s:
544               if (!(nibs[3] & 0x8))
545                 goto fail;
546               imm = nibs[3] & 0x7;
547               break;
548             case IMM0_3Uc:
549               if (nibs[2] & 0x8)
550                 goto fail;
551               imm = nibs[2] & 0x7;
552               break;
553             case IMM0_3Us:
554               if (!(nibs[2] & 0x8))
555                 goto fail;
556               imm = nibs[2] & 0x7;
557               break;
558             case DISP0_12:
559             case DISP1_12:
560               disp = (nibs[5] << 8) | (nibs[6] << 4) | nibs[7];
561               has_disp = 1;
562               goto ok;
563             case DISP0_12BY2:
564             case DISP1_12BY2:
565               disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 1;
566               relmask = ~(bfd_vma) 1;
567               has_disp = 1;
568               goto ok;
569             case DISP0_12BY4:
570             case DISP1_12BY4:
571               disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 2;
572               relmask = ~(bfd_vma) 3;
573               has_disp = 1;
574               goto ok;
575             case DISP0_12BY8:
576             case DISP1_12BY8:
577               disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 3;
578               relmask = ~(bfd_vma) 7;
579               has_disp = 1;
580               goto ok;
581             case IMM0_20_4:
582               break;
583             case IMM0_20:
584               imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
585                      | (nibs[6] << 4) | nibs[7]);
586               if (imm & 0x80000)
587                 imm -= 0x100000;
588               goto ok;
589             case IMM0_20BY8:
590               imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
591                      | (nibs[6] << 4) | nibs[7]);
592               imm <<= 8;
593               if (imm & 0x8000000)
594                 imm -= 0x10000000;
595               goto ok;
596             case IMM0_4:
597             case IMM1_4:
598               imm = nibs[3];
599               goto ok;
600             case IMM0_4BY2:
601             case IMM1_4BY2:
602               imm = nibs[3] << 1;
603               goto ok;
604             case IMM0_4BY4:
605             case IMM1_4BY4:
606               imm = nibs[3] << 2;
607               goto ok;
608             case IMM0_8:
609             case IMM1_8:
610               imm = (nibs[2] << 4) | nibs[3];
611               disp = imm;
612               has_disp = 1;
613               if (imm & 0x80)
614                 imm -= 0x100;
615               goto ok;
616             case PCRELIMM_8BY2:
617               imm = ((nibs[2] << 4) | nibs[3]) << 1;
618               relmask = ~(bfd_vma) 1;
619               goto ok;
620             case PCRELIMM_8BY4:
621               imm = ((nibs[2] << 4) | nibs[3]) << 2;
622               relmask = ~(bfd_vma) 3;
623               goto ok;
624             case IMM0_8BY2:
625             case IMM1_8BY2:
626               imm = ((nibs[2] << 4) | nibs[3]) << 1;
627               goto ok;
628             case IMM0_8BY4:
629             case IMM1_8BY4:
630               imm = ((nibs[2] << 4) | nibs[3]) << 2;
631               goto ok;
632             case REG_N_D:
633               if ((nibs[n] & 1) != 0)
634                 goto fail;
635               /* Fall through.  */
636             case REG_N:
637               rn = nibs[n];
638               break;
639             case REG_M:
640               rm = nibs[n];
641               break;
642             case REG_N_B01:
643               if ((nibs[n] & 0x3) != 1 /* binary 01 */)
644                 goto fail;
645               rn = (nibs[n] & 0xc) >> 2;
646               break;
647             case REG_NM:
648               rn = (nibs[n] & 0xc) >> 2;
649               rm = (nibs[n] & 0x3);
650               break;
651             case REG_B:
652               rb = nibs[n] & 0x07;
653               break;
654             case SDT_REG_N:
655               /* sh-dsp: single data transfer.  */
656               rn = nibs[n];
657               if ((rn & 0xc) != 4)
658                 goto fail;
659               rn = rn & 0x3;
660               rn |= (!(rn & 2)) << 2;
661               break;
662             case PPI:
663             case REPEAT:
664               goto fail;
665             default:
666               abort ();
667             }
668         }
669
670     ok:
671       /* sh2a has D_REG but not X_REG.  We don't know the pattern
672          doesn't match unless we check the output args to see if they
673          make sense.  */
674       if (target_arch == arch_sh2a
675           && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
676               || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
677         goto fail;
678
679       fprintf_fn (stream, "%s\t", op->name);
680       disp_pc = 0;
681       for (n = 0; n < 3 && op->arg[n] != A_END; n++)
682         {
683           if (n && op->arg[1] != A_END)
684             fprintf_fn (stream, ",");
685           switch (op->arg[n])
686             {
687             case A_IMM:
688               fprintf_fn (stream, "#%d", imm);
689               break;
690             case A_R0:
691               fprintf_fn (stream, "r0");
692               break;
693             case A_REG_N:
694               fprintf_fn (stream, "r%d", rn);
695               break;
696             case A_INC_N:
697             case AS_INC_N:
698               fprintf_fn (stream, "@r%d+", rn);
699               break;
700             case A_DEC_N:
701             case AS_DEC_N:
702               fprintf_fn (stream, "@-r%d", rn);
703               break;
704             case A_IND_N:
705             case AS_IND_N:
706               fprintf_fn (stream, "@r%d", rn);
707               break;
708             case A_DISP_REG_N:
709               fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
710               break;
711             case AS_PMOD_N:
712               fprintf_fn (stream, "@r%d+r8", rn);
713               break;
714             case A_REG_M:
715               fprintf_fn (stream, "r%d", rm);
716               break;
717             case A_INC_M:
718               fprintf_fn (stream, "@r%d+", rm);
719               break;
720             case A_DEC_M:
721               fprintf_fn (stream, "@-r%d", rm);
722               break;
723             case A_IND_M:
724               fprintf_fn (stream, "@r%d", rm);
725               break;
726             case A_DISP_REG_M:
727               fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
728               break;
729             case A_REG_B:
730               fprintf_fn (stream, "r%d_bank", rb);
731               break;
732             case A_DISP_PC:
733               disp_pc = 1;
734               disp_pc_addr = imm + 4 + (memaddr & relmask);
735               (*info->print_address_func) (disp_pc_addr, info);
736               break;
737             case A_IND_R0_REG_N:
738               fprintf_fn (stream, "@(r0,r%d)", rn);
739               break;
740             case A_IND_R0_REG_M:
741               fprintf_fn (stream, "@(r0,r%d)", rm);
742               break;
743             case A_DISP_GBR:
744               fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
745               break;
746             case A_TBR:
747               fprintf_fn (stream, "tbr");
748               break;
749             case A_DISP2_TBR:
750               fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
751               break;
752             case A_INC_R15:
753               fprintf_fn (stream, "@r15+");
754               break;
755             case A_DEC_R15:
756               fprintf_fn (stream, "@-r15");
757               break;
758             case A_R0_GBR:
759               fprintf_fn (stream, "@(r0,gbr)");
760               break;
761             case A_BDISP12:
762             case A_BDISP8:
763               (*info->print_address_func) (imm + memaddr, info);
764               break;
765             case A_SR:
766               fprintf_fn (stream, "sr");
767               break;
768             case A_GBR:
769               fprintf_fn (stream, "gbr");
770               break;
771             case A_VBR:
772               fprintf_fn (stream, "vbr");
773               break;
774             case A_DSR:
775               fprintf_fn (stream, "dsr");
776               break;
777             case A_MOD:
778               fprintf_fn (stream, "mod");
779               break;
780             case A_RE:
781               fprintf_fn (stream, "re");
782               break;
783             case A_RS:
784               fprintf_fn (stream, "rs");
785               break;
786             case A_A0:
787               fprintf_fn (stream, "a0");
788               break;
789             case A_X0:
790               fprintf_fn (stream, "x0");
791               break;
792             case A_X1:
793               fprintf_fn (stream, "x1");
794               break;
795             case A_Y0:
796               fprintf_fn (stream, "y0");
797               break;
798             case A_Y1:
799               fprintf_fn (stream, "y1");
800               break;
801             case DSP_REG_M:
802               print_dsp_reg (rm, fprintf_fn, stream);
803               break;
804             case A_SSR:
805               fprintf_fn (stream, "ssr");
806               break;
807             case A_SPC:
808               fprintf_fn (stream, "spc");
809               break;
810             case A_MACH:
811               fprintf_fn (stream, "mach");
812               break;
813             case A_MACL:
814               fprintf_fn (stream, "macl");
815               break;
816             case A_PR:
817               fprintf_fn (stream, "pr");
818               break;
819             case A_SGR:
820               fprintf_fn (stream, "sgr");
821               break;
822             case A_DBR:
823               fprintf_fn (stream, "dbr");
824               break;
825             case F_REG_N:
826               fprintf_fn (stream, "fr%d", rn);
827               break;
828             case F_REG_M:
829               fprintf_fn (stream, "fr%d", rm);
830               break;
831             case DX_REG_N:
832               if (rn & 1)
833                 {
834                   fprintf_fn (stream, "xd%d", rn & ~1);
835                   break;
836                 }
837             case D_REG_N:
838               fprintf_fn (stream, "dr%d", rn);
839               break;
840             case DX_REG_M:
841               if (rm & 1)
842                 {
843                   fprintf_fn (stream, "xd%d", rm & ~1);
844                   break;
845                 }
846             case D_REG_M:
847               fprintf_fn (stream, "dr%d", rm);
848               break;
849             case FPSCR_M:
850             case FPSCR_N:
851               fprintf_fn (stream, "fpscr");
852               break;
853             case FPUL_M:
854             case FPUL_N:
855               fprintf_fn (stream, "fpul");
856               break;
857             case F_FR0:
858               fprintf_fn (stream, "fr0");
859               break;
860             case V_REG_N:
861               fprintf_fn (stream, "fv%d", rn * 4);
862               break;
863             case V_REG_M:
864               fprintf_fn (stream, "fv%d", rm * 4);
865               break;
866             case XMTRX_M4:
867               fprintf_fn (stream, "xmtrx");
868               break;
869             default:
870               abort ();
871             }
872         }
873
874 #if 0
875       /* This code prints instructions in delay slots on the same line
876          as the instruction which needs the delay slots.  This can be
877          confusing, since other disassembler don't work this way, and
878          it means that the instructions are not all in a line.  So I
879          disabled it.  Ian.  */
880       if (!(info->flags & 1)
881           && (op->name[0] == 'j'
882               || (op->name[0] == 'b'
883                   && (op->name[1] == 'r'
884                       || op->name[1] == 's'))
885               || (op->name[0] == 'r' && op->name[1] == 't')
886               || (op->name[0] == 'b' && op->name[2] == '.')))
887         {
888           info->flags |= 1;
889           fprintf_fn (stream, "\t(slot ");
890           print_insn_sh (memaddr + 2, info);
891           info->flags &= ~1;
892           fprintf_fn (stream, ")");
893           return 4;
894         }
895 #endif
896
897       if (disp_pc && strcmp (op->name, "mova") != 0)
898         {
899           int size;
900           bfd_byte bytes[4];
901
902           if (relmask == ~(bfd_vma) 1)
903             size = 2;
904           else
905             size = 4;
906           status = info->read_memory_func (disp_pc_addr, bytes, size, info);
907           if (status == 0)
908             {
909               unsigned int val;
910
911               if (size == 2)
912                 {
913                   if (info->endian == BFD_ENDIAN_LITTLE)
914                     val = bfd_getl16 (bytes);
915                   else
916                     val = bfd_getb16 (bytes);
917                 }
918               else
919                 {
920                   if (info->endian == BFD_ENDIAN_LITTLE)
921                     val = bfd_getl32 (bytes);
922                   else
923                     val = bfd_getb32 (bytes);
924                 }
925               if ((*info->symbol_at_address_func) (val, info))
926                 {
927                   fprintf_fn (stream, "\t! 0x");
928                   (*info->print_address_func) (val, info);
929                 }
930               else
931                 fprintf_fn (stream, "\t! 0x%x", val);
932             }
933         }
934
935       return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
936     fail:
937       ;
938
939     }
940   fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
941   return 2;
942 }