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
print_movxy(op,rn,rm,fprintf_fn,stream)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
print_insn_ddt(insn,info)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
print_dsp_reg(rm,fprintf_fn,stream)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
print_insn_ppi(field_b,info)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
print_insn_sh(memaddr,info)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 }
865