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