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