xref: /netbsd-src/external/gpl3/gdb/dist/opcodes/sh-dis.c (revision 692ee2d9fc01d56bdf42d81adfeff0517a12149c)
1 /* Disassemble SH instructions.
2    Copyright (C) 1993-2024 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 
107 static void
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
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
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
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 	      if (!(nibs[n] & 0x08)) /* Must always be 1.  */
649 		goto fail;
650 	      rb = nibs[n] & 0x07;
651 	      break;
652 	    case SDT_REG_N:
653 	      /* sh-dsp: single data transfer.  */
654 	      rn = nibs[n];
655 	      if ((rn & 0xc) != 4)
656 		goto fail;
657 	      rn = rn & 0x3;
658 	      rn |= (!(rn & 2)) << 2;
659 	      break;
660 	    case PPI:
661 	    case REPEAT:
662 	      goto fail;
663 	    default:
664 	      abort ();
665 	    }
666 	}
667 
668     ok:
669       /* sh2a has D_REG but not X_REG.  We don't know the pattern
670 	 doesn't match unless we check the output args to see if they
671 	 make sense.  */
672       if (target_arch == arch_sh2a
673 	  && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
674 	      || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
675 	goto fail;
676 
677       fprintf_fn (stream, "%s\t", op->name);
678       disp_pc = 0;
679       for (n = 0; n < 3 && op->arg[n] != A_END; n++)
680 	{
681 	  if (n && op->arg[1] != A_END)
682 	    fprintf_fn (stream, ",");
683 	  switch (op->arg[n])
684 	    {
685 	    case A_IMM:
686 	      fprintf_fn (stream, "#%d", imm);
687 	      break;
688 	    case A_R0:
689 	      fprintf_fn (stream, "r0");
690 	      break;
691 	    case A_REG_N:
692 	      fprintf_fn (stream, "r%d", rn);
693 	      break;
694 	    case A_INC_N:
695 	    case AS_INC_N:
696 	      fprintf_fn (stream, "@r%d+", rn);
697 	      break;
698 	    case A_DEC_N:
699 	    case AS_DEC_N:
700 	      fprintf_fn (stream, "@-r%d", rn);
701 	      break;
702 	    case A_IND_N:
703 	    case AS_IND_N:
704 	      fprintf_fn (stream, "@r%d", rn);
705 	      break;
706 	    case A_DISP_REG_N:
707 	      fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
708 	      break;
709 	    case AS_PMOD_N:
710 	      fprintf_fn (stream, "@r%d+r8", rn);
711 	      break;
712 	    case A_REG_M:
713 	      fprintf_fn (stream, "r%d", rm);
714 	      break;
715 	    case A_INC_M:
716 	      fprintf_fn (stream, "@r%d+", rm);
717 	      break;
718 	    case A_DEC_M:
719 	      fprintf_fn (stream, "@-r%d", rm);
720 	      break;
721 	    case A_IND_M:
722 	      fprintf_fn (stream, "@r%d", rm);
723 	      break;
724 	    case A_DISP_REG_M:
725 	      fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
726 	      break;
727 	    case A_REG_B:
728 	      fprintf_fn (stream, "r%d_bank", rb);
729 	      break;
730 	    case A_DISP_PC:
731 	      disp_pc = 1;
732 	      disp_pc_addr = imm + 4 + (memaddr & relmask);
733 	      (*info->print_address_func) (disp_pc_addr, info);
734 	      break;
735 	    case A_IND_R0_REG_N:
736 	      fprintf_fn (stream, "@(r0,r%d)", rn);
737 	      break;
738 	    case A_IND_R0_REG_M:
739 	      fprintf_fn (stream, "@(r0,r%d)", rm);
740 	      break;
741 	    case A_DISP_GBR:
742 	      fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
743 	      break;
744 	    case A_TBR:
745 	      fprintf_fn (stream, "tbr");
746 	      break;
747 	    case A_DISP2_TBR:
748 	      fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
749 	      break;
750 	    case A_INC_R15:
751 	      fprintf_fn (stream, "@r15+");
752 	      break;
753 	    case A_DEC_R15:
754 	      fprintf_fn (stream, "@-r15");
755 	      break;
756 	    case A_R0_GBR:
757 	      fprintf_fn (stream, "@(r0,gbr)");
758 	      break;
759 	    case A_BDISP12:
760 	    case A_BDISP8:
761 	      (*info->print_address_func) (imm + memaddr, info);
762 	      break;
763 	    case A_SR:
764 	      fprintf_fn (stream, "sr");
765 	      break;
766 	    case A_GBR:
767 	      fprintf_fn (stream, "gbr");
768 	      break;
769 	    case A_VBR:
770 	      fprintf_fn (stream, "vbr");
771 	      break;
772 	    case A_DSR:
773 	      fprintf_fn (stream, "dsr");
774 	      break;
775 	    case A_MOD:
776 	      fprintf_fn (stream, "mod");
777 	      break;
778 	    case A_RE:
779 	      fprintf_fn (stream, "re");
780 	      break;
781 	    case A_RS:
782 	      fprintf_fn (stream, "rs");
783 	      break;
784 	    case A_A0:
785 	      fprintf_fn (stream, "a0");
786 	      break;
787 	    case A_X0:
788 	      fprintf_fn (stream, "x0");
789 	      break;
790 	    case A_X1:
791 	      fprintf_fn (stream, "x1");
792 	      break;
793 	    case A_Y0:
794 	      fprintf_fn (stream, "y0");
795 	      break;
796 	    case A_Y1:
797 	      fprintf_fn (stream, "y1");
798 	      break;
799 	    case DSP_REG_M:
800 	      print_dsp_reg (rm, fprintf_fn, stream);
801 	      break;
802 	    case A_SSR:
803 	      fprintf_fn (stream, "ssr");
804 	      break;
805 	    case A_SPC:
806 	      fprintf_fn (stream, "spc");
807 	      break;
808 	    case A_MACH:
809 	      fprintf_fn (stream, "mach");
810 	      break;
811 	    case A_MACL:
812 	      fprintf_fn (stream, "macl");
813 	      break;
814 	    case A_PR:
815 	      fprintf_fn (stream, "pr");
816 	      break;
817 	    case A_SGR:
818 	      fprintf_fn (stream, "sgr");
819 	      break;
820 	    case A_DBR:
821 	      fprintf_fn (stream, "dbr");
822 	      break;
823 	    case F_REG_N:
824 	      fprintf_fn (stream, "fr%d", rn);
825 	      break;
826 	    case F_REG_M:
827 	      fprintf_fn (stream, "fr%d", rm);
828 	      break;
829 	    case DX_REG_N:
830 	      if (rn & 1)
831 		{
832 		  fprintf_fn (stream, "xd%d", rn & ~1);
833 		  break;
834 		}
835 	      /* Fall through.  */
836 	    case D_REG_N:
837 	      fprintf_fn (stream, "dr%d", rn);
838 	      break;
839 	    case DX_REG_M:
840 	      if (rm & 1)
841 		{
842 		  fprintf_fn (stream, "xd%d", rm & ~1);
843 		  break;
844 		}
845 	      /* Fall through.  */
846 	    case D_REG_M:
847 	      fprintf_fn (stream, "dr%d", rm);
848 	      break;
849 	    case FPSCR_M:
850 	    case FPSCR_N:
851 	      fprintf_fn (stream, "fpscr");
852 	      break;
853 	    case FPUL_M:
854 	    case FPUL_N:
855 	      fprintf_fn (stream, "fpul");
856 	      break;
857 	    case F_FR0:
858 	      fprintf_fn (stream, "fr0");
859 	      break;
860 	    case V_REG_N:
861 	      fprintf_fn (stream, "fv%d", rn * 4);
862 	      break;
863 	    case V_REG_M:
864 	      fprintf_fn (stream, "fv%d", rm * 4);
865 	      break;
866 	    case XMTRX_M4:
867 	      fprintf_fn (stream, "xmtrx");
868 	      break;
869 	    default:
870 	      abort ();
871 	    }
872 	}
873 
874 #if 0
875       /* This code prints instructions in delay slots on the same line
876          as the instruction which needs the delay slots.  This can be
877          confusing, since other disassembler don't work this way, and
878          it means that the instructions are not all in a line.  So I
879          disabled it.  Ian.  */
880       if (!(info->flags & 1)
881 	  && (op->name[0] == 'j'
882 	      || (op->name[0] == 'b'
883 		  && (op->name[1] == 'r'
884 		      || op->name[1] == 's'))
885 	      || (op->name[0] == 'r' && op->name[1] == 't')
886 	      || (op->name[0] == 'b' && op->name[2] == '.')))
887 	{
888 	  info->flags |= 1;
889 	  fprintf_fn (stream, "\t(slot ");
890 	  print_insn_sh (memaddr + 2, info);
891 	  info->flags &= ~1;
892 	  fprintf_fn (stream, ")");
893 	  return 4;
894 	}
895 #endif
896 
897       if (disp_pc && strcmp (op->name, "mova") != 0)
898 	{
899 	  int size;
900 	  bfd_byte bytes[4];
901 
902 	  if (relmask == ~(bfd_vma) 1)
903 	    size = 2;
904 	  else
905 	    size = 4;
906 	  /* Not reading an instruction - disable stop_vma.  */
907 	  info->stop_vma = 0;
908 	  status = info->read_memory_func (disp_pc_addr, bytes, size, info);
909 	  if (status == 0)
910 	    {
911 	      unsigned int val;
912 
913 	      if (size == 2)
914 		{
915 		  if (info->endian == BFD_ENDIAN_LITTLE)
916 		    val = bfd_getl16 (bytes);
917 		  else
918 		    val = bfd_getb16 (bytes);
919 		}
920 	      else
921 		{
922 		  if (info->endian == BFD_ENDIAN_LITTLE)
923 		    val = bfd_getl32 (bytes);
924 		  else
925 		    val = bfd_getb32 (bytes);
926 		}
927 	      if ((*info->symbol_at_address_func) (val, info))
928 		{
929 		  fprintf_fn (stream, "\t! ");
930 		  (*info->print_address_func) (val, info);
931 		}
932 	      else
933 		fprintf_fn (stream, "\t! %x", val);
934 	    }
935 	}
936 
937       return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
938     fail:
939       ;
940 
941     }
942   fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
943   return 2;
944 }
945