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