2004-05-28 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   unsigned 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_sh5:
419 #ifdef INCLUDE_SHMEDIA
420       status = print_insn_sh64 (memaddr, info);
421       if (status != -2)
422         return status;
423 #endif
424       /* When we get here for sh64, it's because we want to disassemble
425          SHcompact, i.e. arch_sh4.  */
426       target_arch = arch_sh4;
427       break;
428     default:
429       target_arch = sh_get_arch_from_bfd_mach (info->mach);
430     }
431
432   status = info->read_memory_func (memaddr, insn, 2, info);
433
434   if (status != 0)
435     {
436       info->memory_error_func (status, memaddr, info);
437       return -1;
438     }
439
440   if (info->endian == BFD_ENDIAN_LITTLE)
441     {
442       nibs[0] = (insn[1] >> 4) & 0xf;
443       nibs[1] = insn[1] & 0xf;
444
445       nibs[2] = (insn[0] >> 4) & 0xf;
446       nibs[3] = insn[0] & 0xf;
447     }
448   else
449     {
450       nibs[0] = (insn[0] >> 4) & 0xf;
451       nibs[1] = insn[0] & 0xf;
452
453       nibs[2] = (insn[1] >> 4) & 0xf;
454       nibs[3] = insn[1] & 0xf;
455     }
456
457   if (nibs[0] == 0xf && (nibs[1] & 4) == 0
458       && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
459     {
460       if (nibs[1] & 8)
461         {
462           int field_b;
463
464           status = info->read_memory_func (memaddr + 2, insn, 2, info);
465
466           if (status != 0)
467             {
468               info->memory_error_func (status, memaddr + 2, info);
469               return -1;
470             }
471
472           if (info->endian == BFD_ENDIAN_LITTLE)
473             field_b = insn[1] << 8 | insn[0];
474           else
475             field_b = insn[0] << 8 | insn[1];
476
477           print_insn_ppi (field_b, info);
478           print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
479           return 4;
480         }
481       print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
482       return 2;
483     }
484   for (op = sh_table; op->name; op++)
485     {
486       int n;
487       int imm = 0;
488       int rn = 0;
489       int rm = 0;
490       int rb = 0;
491       int disp_pc;
492       bfd_vma disp_pc_addr = 0;
493
494       if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
495         goto fail;
496       for (n = 0; n < 4; n++)
497         {
498           int i = op->nibbles[n];
499
500           if (i < 16)
501             {
502               if (nibs[n] == i)
503                 continue;
504               goto fail;
505             }
506           switch (i)
507             {
508             case BRANCH_8:
509               imm = (nibs[2] << 4) | (nibs[3]);
510               if (imm & 0x80)
511                 imm |= ~0xff;
512               imm = ((char) imm) * 2 + 4;
513               goto ok;
514             case BRANCH_12:
515               imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
516               if (imm & 0x800)
517                 imm |= ~0xfff;
518               imm = imm * 2 + 4;
519               goto ok;
520             case IMM0_4:
521             case IMM1_4:
522               imm = nibs[3];
523               goto ok;
524             case IMM0_4BY2:
525             case IMM1_4BY2:
526               imm = nibs[3] << 1;
527               goto ok;
528             case IMM0_4BY4:
529             case IMM1_4BY4:
530               imm = nibs[3] << 2;
531               goto ok;
532             case IMM0_8:
533             case IMM1_8:
534               imm = (nibs[2] << 4) | nibs[3];
535               goto ok;
536             case PCRELIMM_8BY2:
537               imm = ((nibs[2] << 4) | nibs[3]) << 1;
538               relmask = ~(bfd_vma) 1;
539               goto ok;
540             case PCRELIMM_8BY4:
541               imm = ((nibs[2] << 4) | nibs[3]) << 2;
542               relmask = ~(bfd_vma) 3;
543               goto ok;
544             case IMM0_8BY2:
545             case IMM1_8BY2:
546               imm = ((nibs[2] << 4) | nibs[3]) << 1;
547               goto ok;
548             case IMM0_8BY4:
549             case IMM1_8BY4:
550               imm = ((nibs[2] << 4) | nibs[3]) << 2;
551               goto ok;
552             case REG_N_D:
553               if ((nibs[n] & 1) != 0)
554                 goto fail;
555               /* fall through */
556             case REG_N:
557               rn = nibs[n];
558               break;
559             case REG_M:
560               rm = nibs[n];
561               break;
562             case REG_N_B01:
563               if ((nibs[n] & 0x3) != 1 /* binary 01 */)
564                 goto fail;
565               rn = (nibs[n] & 0xc) >> 2;
566               break;
567             case REG_NM:
568               rn = (nibs[n] & 0xc) >> 2;
569               rm = (nibs[n] & 0x3);
570               break;
571             case REG_B:
572               rb = nibs[n] & 0x07;
573               break;
574             case SDT_REG_N:
575               /* sh-dsp: single data transfer.  */
576               rn = nibs[n];
577               if ((rn & 0xc) != 4)
578                 goto fail;
579               rn = rn & 0x3;
580               rn |= (!(rn & 2)) << 2;
581               break;
582             case PPI:
583             case REPEAT:
584               goto fail;
585             default:
586               abort ();
587             }
588         }
589
590     ok:
591       fprintf_fn (stream, "%s\t", op->name);
592       disp_pc = 0;
593       for (n = 0; n < 3 && op->arg[n] != A_END; n++)
594         {
595           if (n && op->arg[1] != A_END)
596             fprintf_fn (stream, ",");
597           switch (op->arg[n])
598             {
599             case A_IMM:
600               fprintf_fn (stream, "#%d", (char) (imm));
601               break;
602             case A_R0:
603               fprintf_fn (stream, "r0");
604               break;
605             case A_REG_N:
606               fprintf_fn (stream, "r%d", rn);
607               break;
608             case A_INC_N:
609             case AS_INC_N:
610               fprintf_fn (stream, "@r%d+", rn);
611               break;
612             case A_DEC_N:
613             case AS_DEC_N:
614               fprintf_fn (stream, "@-r%d", rn);
615               break;
616             case A_IND_N:
617             case AS_IND_N:
618               fprintf_fn (stream, "@r%d", rn);
619               break;
620             case A_DISP_REG_N:
621               fprintf_fn (stream, "@(%d,r%d)", imm, rn);
622               break;
623             case AS_PMOD_N:
624               fprintf_fn (stream, "@r%d+r8", rn);
625               break;
626             case A_REG_M:
627               fprintf_fn (stream, "r%d", rm);
628               break;
629             case A_INC_M:
630               fprintf_fn (stream, "@r%d+", rm);
631               break;
632             case A_DEC_M:
633               fprintf_fn (stream, "@-r%d", rm);
634               break;
635             case A_IND_M:
636               fprintf_fn (stream, "@r%d", rm);
637               break;
638             case A_DISP_REG_M:
639               fprintf_fn (stream, "@(%d,r%d)", imm, rm);
640               break;
641             case A_REG_B:
642               fprintf_fn (stream, "r%d_bank", rb);
643               break;
644             case A_DISP_PC:
645               disp_pc = 1;
646               disp_pc_addr = imm + 4 + (memaddr & relmask);
647               (*info->print_address_func) (disp_pc_addr, info);
648               break;
649             case A_IND_R0_REG_N:
650               fprintf_fn (stream, "@(r0,r%d)", rn);
651               break;
652             case A_IND_R0_REG_M:
653               fprintf_fn (stream, "@(r0,r%d)", rm);
654               break;
655             case A_DISP_GBR:
656               fprintf_fn (stream, "@(%d,gbr)", imm);
657               break;
658             case A_R0_GBR:
659               fprintf_fn (stream, "@(r0,gbr)");
660               break;
661             case A_BDISP12:
662             case A_BDISP8:
663               (*info->print_address_func) (imm + memaddr, info);
664               break;
665             case A_SR:
666               fprintf_fn (stream, "sr");
667               break;
668             case A_GBR:
669               fprintf_fn (stream, "gbr");
670               break;
671             case A_VBR:
672               fprintf_fn (stream, "vbr");
673               break;
674             case A_DSR:
675               fprintf_fn (stream, "dsr");
676               break;
677             case A_MOD:
678               fprintf_fn (stream, "mod");
679               break;
680             case A_RE:
681               fprintf_fn (stream, "re");
682               break;
683             case A_RS:
684               fprintf_fn (stream, "rs");
685               break;
686             case A_A0:
687               fprintf_fn (stream, "a0");
688               break;
689             case A_X0:
690               fprintf_fn (stream, "x0");
691               break;
692             case A_X1:
693               fprintf_fn (stream, "x1");
694               break;
695             case A_Y0:
696               fprintf_fn (stream, "y0");
697               break;
698             case A_Y1:
699               fprintf_fn (stream, "y1");
700               break;
701             case DSP_REG_M:
702               print_dsp_reg (rm, fprintf_fn, stream);
703               break;
704             case A_SSR:
705               fprintf_fn (stream, "ssr");
706               break;
707             case A_SPC:
708               fprintf_fn (stream, "spc");
709               break;
710             case A_MACH:
711               fprintf_fn (stream, "mach");
712               break;
713             case A_MACL:
714               fprintf_fn (stream, "macl");
715               break;
716             case A_PR:
717               fprintf_fn (stream, "pr");
718               break;
719             case A_SGR:
720               fprintf_fn (stream, "sgr");
721               break;
722             case A_DBR:
723               fprintf_fn (stream, "dbr");
724               break;
725             case F_REG_N:
726               fprintf_fn (stream, "fr%d", rn);
727               break;
728             case F_REG_M:
729               fprintf_fn (stream, "fr%d", rm);
730               break;
731             case DX_REG_N:
732               if (rn & 1)
733                 {
734                   fprintf_fn (stream, "xd%d", rn & ~1);
735                   break;
736                 }
737             case D_REG_N:
738               fprintf_fn (stream, "dr%d", rn);
739               break;
740             case DX_REG_M:
741               if (rm & 1)
742                 {
743                   fprintf_fn (stream, "xd%d", rm & ~1);
744                   break;
745                 }
746             case D_REG_M:
747               fprintf_fn (stream, "dr%d", rm);
748               break;
749             case FPSCR_M:
750             case FPSCR_N:
751               fprintf_fn (stream, "fpscr");
752               break;
753             case FPUL_M:
754             case FPUL_N:
755               fprintf_fn (stream, "fpul");
756               break;
757             case F_FR0:
758               fprintf_fn (stream, "fr0");
759               break;
760             case V_REG_N:
761               fprintf_fn (stream, "fv%d", rn * 4);
762               break;
763             case V_REG_M:
764               fprintf_fn (stream, "fv%d", rm * 4);
765               break;
766             case XMTRX_M4:
767               fprintf_fn (stream, "xmtrx");
768               break;
769             default:
770               abort ();
771             }
772         }
773
774 #if 0
775       /* This code prints instructions in delay slots on the same line
776          as the instruction which needs the delay slots.  This can be
777          confusing, since other disassembler don't work this way, and
778          it means that the instructions are not all in a line.  So I
779          disabled it.  Ian.  */
780       if (!(info->flags & 1)
781           && (op->name[0] == 'j'
782               || (op->name[0] == 'b'
783                   && (op->name[1] == 'r'
784                       || op->name[1] == 's'))
785               || (op->name[0] == 'r' && op->name[1] == 't')
786               || (op->name[0] == 'b' && op->name[2] == '.')))
787         {
788           info->flags |= 1;
789           fprintf_fn (stream, "\t(slot ");
790           print_insn_sh (memaddr + 2, info);
791           info->flags &= ~1;
792           fprintf_fn (stream, ")");
793           return 4;
794         }
795 #endif
796
797       if (disp_pc && strcmp (op->name, "mova") != 0)
798         {
799           int size;
800           bfd_byte bytes[4];
801
802           if (relmask == ~(bfd_vma) 1)
803             size = 2;
804           else
805             size = 4;
806           status = info->read_memory_func (disp_pc_addr, bytes, size, info);
807           if (status == 0)
808             {
809               unsigned int val;
810
811               if (size == 2)
812                 {
813                   if (info->endian == BFD_ENDIAN_LITTLE)
814                     val = bfd_getl16 (bytes);
815                   else
816                     val = bfd_getb16 (bytes);
817                 }
818               else
819                 {
820                   if (info->endian == BFD_ENDIAN_LITTLE)
821                     val = bfd_getl32 (bytes);
822                   else
823                     val = bfd_getb32 (bytes);
824                 }
825               if ((*info->symbol_at_address_func) (val, info))
826                 {
827                   fprintf_fn (stream, "\t! 0x");
828                   (*info->print_address_func) (val, info);
829                 }
830               else
831                 fprintf_fn (stream, "\t! 0x%x", val);
832             }
833         }
834
835       return 2;
836     fail:
837       ;
838
839     }
840   fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
841   return 2;
842 }