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