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