* README: Remove claim that MEMORY is not supported.
[binutils.git] / opcodes / sh-dis.c
blob76d123334200a7cb350bb5ad272ae25638b2e8c8
1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007 Free Software Foundation, Inc.
5 This file is part of the GNU opcodes library.
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.
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.
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. */
22 #include <stdio.h>
23 #include "sysdep.h"
24 #define STATIC_TABLE
25 #define DEFINE_TABLE
27 #include "sh-opc.h"
28 #include "dis-asm.h"
30 #ifdef ARCH_all
31 #define INCLUDE_SHMEDIA
32 #endif
34 static void
35 print_movxy (const sh_opcode_info *op,
36 int rn,
37 int rm,
38 fprintf_ftype fprintf_fn,
39 void *stream)
41 int n;
43 fprintf_fn (stream, "%s\t", op->name);
44 for (n = 0; n < 2; n++)
46 switch (op->arg[n])
48 case A_IND_N:
49 case AX_IND_N:
50 case AXY_IND_N:
51 case AY_IND_N:
52 case AYX_IND_N:
53 fprintf_fn (stream, "@r%d", rn);
54 break;
55 case A_INC_N:
56 case AX_INC_N:
57 case AXY_INC_N:
58 case AY_INC_N:
59 case AYX_INC_N:
60 fprintf_fn (stream, "@r%d+", rn);
61 break;
62 case AX_PMOD_N:
63 case AXY_PMOD_N:
64 fprintf_fn (stream, "@r%d+r8", rn);
65 break;
66 case AY_PMOD_N:
67 case AYX_PMOD_N:
68 fprintf_fn (stream, "@r%d+r9", rn);
69 break;
70 case DSP_REG_A_M:
71 fprintf_fn (stream, "a%c", '0' + rm);
72 break;
73 case DSP_REG_X:
74 fprintf_fn (stream, "x%c", '0' + rm);
75 break;
76 case DSP_REG_Y:
77 fprintf_fn (stream, "y%c", '0' + rm);
78 break;
79 case DSP_REG_AX:
80 fprintf_fn (stream, "%c%c",
81 (rm & 1) ? 'x' : 'a',
82 (rm & 2) ? '1' : '0');
83 break;
84 case DSP_REG_XY:
85 fprintf_fn (stream, "%c%c",
86 (rm & 1) ? 'y' : 'x',
87 (rm & 2) ? '1' : '0');
88 break;
89 case DSP_REG_AY:
90 fprintf_fn (stream, "%c%c",
91 (rm & 2) ? 'y' : 'a',
92 (rm & 1) ? '1' : '0');
93 break;
94 case DSP_REG_YX:
95 fprintf_fn (stream, "%c%c",
96 (rm & 2) ? 'x' : 'y',
97 (rm & 1) ? '1' : '0');
98 break;
99 default:
100 abort ();
102 if (n == 0)
103 fprintf_fn (stream, ",");
107 /* Print a double data transfer insn. INSN is just the lower three
108 nibbles of the insn, i.e. field a and the bit that indicates if
109 a parallel processing insn follows.
110 Return nonzero if a field b of a parallel processing insns follows. */
112 static void
113 print_insn_ddt (int insn, struct disassemble_info *info)
115 fprintf_ftype fprintf_fn = info->fprintf_func;
116 void *stream = info->stream;
118 /* If this is just a nop, make sure to emit something. */
119 if (insn == 0x000)
120 fprintf_fn (stream, "nopx\tnopy");
122 /* If a parallel processing insn was printed before,
123 and we got a non-nop, emit a tab. */
124 if ((insn & 0x800) && (insn & 0x3ff))
125 fprintf_fn (stream, "\t");
127 /* Check if either the x or y part is invalid. */
128 if (((insn & 0xc) == 0 && (insn & 0x2a0))
129 || ((insn & 3) == 0 && (insn & 0x150)))
130 if (info->mach != bfd_mach_sh_dsp
131 && info->mach != bfd_mach_sh3_dsp)
133 static const sh_opcode_info *first_movx, *first_movy;
134 const sh_opcode_info *op;
135 int is_movy;
137 if (! first_movx)
139 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX_NOPY;)
140 first_movx++;
141 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY_NOPX;)
142 first_movy++;
145 is_movy = ((insn & 3) != 0);
147 if (is_movy)
148 op = first_movy;
149 else
150 op = first_movx;
152 while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
153 || op->nibbles[3] != (unsigned) (insn & 0xf))
154 op++;
156 print_movxy (op,
157 (4 * ((insn & (is_movy ? 0x200 : 0x100)) == 0)
158 + 2 * is_movy
159 + 1 * ((insn & (is_movy ? 0x100 : 0x200)) != 0)),
160 (insn >> 6) & 3,
161 fprintf_fn, stream);
163 else
164 fprintf_fn (stream, ".word 0x%x", insn);
165 else
167 static const sh_opcode_info *first_movx, *first_movy;
168 const sh_opcode_info *opx, *opy;
169 unsigned int insn_x, insn_y;
171 if (! first_movx)
173 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
174 first_movx++;
175 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
176 first_movy++;
178 insn_x = (insn >> 2) & 0xb;
179 if (insn_x)
181 for (opx = first_movx; opx->nibbles[2] != insn_x;)
182 opx++;
183 print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
184 fprintf_fn, stream);
186 insn_y = (insn & 3) | ((insn >> 1) & 8);
187 if (insn_y)
189 if (insn_x)
190 fprintf_fn (stream, "\t");
191 for (opy = first_movy; opy->nibbles[2] != insn_y;)
192 opy++;
193 print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
194 fprintf_fn, stream);
199 static void
200 print_dsp_reg (int rm, fprintf_ftype fprintf_fn, void *stream)
202 switch (rm)
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;
240 static void
241 print_insn_ppi (int field_b, struct disassemble_info *info)
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;
252 if ((field_b & 0xe800) == 0)
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;
260 if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
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" };
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]);
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]);
279 else if ((field_b & 0xf3) != 0)
280 fprintf_fn (stream, ".word 0x%x\t", field_b);
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;
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)
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;
312 if (nib1 == PPI3)
313 altnib1 = PPI3NC;
314 else
315 altnib1 = nib1;
316 for (op = sh_table; op->name; op++)
318 if ((op->nibbles[1] == nib1 || op->nibbles[1] == altnib1)
319 && op->nibbles[2] == nib2
320 && op->nibbles[3] == nib3)
322 int n;
324 switch (op->nibbles[4])
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 ();
347 fprintf_fn (stream, "%s%s\t", dc, op->name);
348 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
350 if (n && op->arg[1] != A_END)
351 fprintf_fn (stream, ",");
352 switch (op->arg[n])
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, sx_tab[(field_b >> 6) & 3]);
359 break;
360 case DSP_REG_Y:
361 fprintf_fn (stream, 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 ();
373 return;
376 /* Not found. */
377 fprintf_fn (stream, ".word 0x%x", field_b);
380 /* FIXME mvs: movx insns print as ".word 0x%03x", insn & 0xfff
381 (ie. the upper nibble is missing). */
384 print_insn_sh (bfd_vma memaddr, struct disassemble_info *info)
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;
396 switch (info->mach)
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 case bfd_mach_sh5:
408 #ifdef INCLUDE_SHMEDIA
409 status = print_insn_sh64 (memaddr, info);
410 if (status != -2)
411 return status;
412 #endif
413 /* When we get here for sh64, it's because we want to disassemble
414 SHcompact, i.e. arch_sh4. */
415 target_arch = arch_sh4;
416 break;
417 default:
418 target_arch = sh_get_arch_from_bfd_mach (info->mach);
421 status = info->read_memory_func (memaddr, insn, 2, info);
423 if (status != 0)
425 info->memory_error_func (status, memaddr, info);
426 return -1;
429 if (info->endian == BFD_ENDIAN_LITTLE)
431 nibs[0] = (insn[1] >> 4) & 0xf;
432 nibs[1] = insn[1] & 0xf;
434 nibs[2] = (insn[0] >> 4) & 0xf;
435 nibs[3] = insn[0] & 0xf;
437 else
439 nibs[0] = (insn[0] >> 4) & 0xf;
440 nibs[1] = insn[0] & 0xf;
442 nibs[2] = (insn[1] >> 4) & 0xf;
443 nibs[3] = insn[1] & 0xf;
445 status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
446 if (status != 0)
447 allow_op32 = 0;
448 else
450 allow_op32 = 1;
452 if (info->endian == BFD_ENDIAN_LITTLE)
454 nibs[4] = (insn[3] >> 4) & 0xf;
455 nibs[5] = insn[3] & 0xf;
457 nibs[6] = (insn[2] >> 4) & 0xf;
458 nibs[7] = insn[2] & 0xf;
460 else
462 nibs[4] = (insn[2] >> 4) & 0xf;
463 nibs[5] = insn[2] & 0xf;
465 nibs[6] = (insn[3] >> 4) & 0xf;
466 nibs[7] = insn[3] & 0xf;
470 if (nibs[0] == 0xf && (nibs[1] & 4) == 0
471 && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
473 if (nibs[1] & 8)
475 int field_b;
477 status = info->read_memory_func (memaddr + 2, insn, 2, info);
479 if (status != 0)
481 info->memory_error_func (status, memaddr + 2, info);
482 return -1;
485 if (info->endian == BFD_ENDIAN_LITTLE)
486 field_b = insn[1] << 8 | insn[0];
487 else
488 field_b = insn[0] << 8 | insn[1];
490 print_insn_ppi (field_b, info);
491 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
492 return 4;
494 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
495 return 2;
497 for (op = sh_table; op->name; op++)
499 int n;
500 int imm = 0;
501 int rn = 0;
502 int rm = 0;
503 int rb = 0;
504 int disp_pc;
505 bfd_vma disp_pc_addr = 0;
506 int disp = 0;
507 int has_disp = 0;
508 int max_n = SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 8 : 4;
510 if (!allow_op32
511 && SH_MERGE_ARCH_SET (op->arch, arch_op32))
512 goto fail;
514 if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
515 goto fail;
516 for (n = 0; n < max_n; n++)
518 int i = op->nibbles[n];
520 if (i < 16)
522 if (nibs[n] == i)
523 continue;
524 goto fail;
526 switch (i)
528 case BRANCH_8:
529 imm = (nibs[2] << 4) | (nibs[3]);
530 if (imm & 0x80)
531 imm |= ~0xff;
532 imm = ((char) imm) * 2 + 4;
533 goto ok;
534 case BRANCH_12:
535 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
536 if (imm & 0x800)
537 imm |= ~0xfff;
538 imm = imm * 2 + 4;
539 goto ok;
540 case IMM0_3c:
541 if (nibs[3] & 0x8)
542 goto fail;
543 imm = nibs[3] & 0x7;
544 break;
545 case IMM0_3s:
546 if (!(nibs[3] & 0x8))
547 goto fail;
548 imm = nibs[3] & 0x7;
549 break;
550 case IMM0_3Uc:
551 if (nibs[2] & 0x8)
552 goto fail;
553 imm = nibs[2] & 0x7;
554 break;
555 case IMM0_3Us:
556 if (!(nibs[2] & 0x8))
557 goto fail;
558 imm = nibs[2] & 0x7;
559 break;
560 case DISP0_12:
561 case DISP1_12:
562 disp = (nibs[5] << 8) | (nibs[6] << 4) | nibs[7];
563 has_disp = 1;
564 goto ok;
565 case DISP0_12BY2:
566 case DISP1_12BY2:
567 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 1;
568 relmask = ~(bfd_vma) 1;
569 has_disp = 1;
570 goto ok;
571 case DISP0_12BY4:
572 case DISP1_12BY4:
573 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 2;
574 relmask = ~(bfd_vma) 3;
575 has_disp = 1;
576 goto ok;
577 case DISP0_12BY8:
578 case DISP1_12BY8:
579 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 3;
580 relmask = ~(bfd_vma) 7;
581 has_disp = 1;
582 goto ok;
583 case IMM0_20_4:
584 break;
585 case IMM0_20:
586 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
587 | (nibs[6] << 4) | nibs[7]);
588 if (imm & 0x80000)
589 imm -= 0x100000;
590 goto ok;
591 case IMM0_20BY8:
592 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
593 | (nibs[6] << 4) | nibs[7]);
594 imm <<= 8;
595 if (imm & 0x8000000)
596 imm -= 0x10000000;
597 goto ok;
598 case IMM0_4:
599 case IMM1_4:
600 imm = nibs[3];
601 goto ok;
602 case IMM0_4BY2:
603 case IMM1_4BY2:
604 imm = nibs[3] << 1;
605 goto ok;
606 case IMM0_4BY4:
607 case IMM1_4BY4:
608 imm = nibs[3] << 2;
609 goto ok;
610 case IMM0_8:
611 case IMM1_8:
612 imm = (nibs[2] << 4) | nibs[3];
613 disp = imm;
614 has_disp = 1;
615 if (imm & 0x80)
616 imm -= 0x100;
617 goto ok;
618 case PCRELIMM_8BY2:
619 imm = ((nibs[2] << 4) | nibs[3]) << 1;
620 relmask = ~(bfd_vma) 1;
621 goto ok;
622 case PCRELIMM_8BY4:
623 imm = ((nibs[2] << 4) | nibs[3]) << 2;
624 relmask = ~(bfd_vma) 3;
625 goto ok;
626 case IMM0_8BY2:
627 case IMM1_8BY2:
628 imm = ((nibs[2] << 4) | nibs[3]) << 1;
629 goto ok;
630 case IMM0_8BY4:
631 case IMM1_8BY4:
632 imm = ((nibs[2] << 4) | nibs[3]) << 2;
633 goto ok;
634 case REG_N_D:
635 if ((nibs[n] & 1) != 0)
636 goto fail;
637 /* Fall through. */
638 case REG_N:
639 rn = nibs[n];
640 break;
641 case REG_M:
642 rm = nibs[n];
643 break;
644 case REG_N_B01:
645 if ((nibs[n] & 0x3) != 1 /* binary 01 */)
646 goto fail;
647 rn = (nibs[n] & 0xc) >> 2;
648 break;
649 case REG_NM:
650 rn = (nibs[n] & 0xc) >> 2;
651 rm = (nibs[n] & 0x3);
652 break;
653 case REG_B:
654 rb = nibs[n] & 0x07;
655 break;
656 case SDT_REG_N:
657 /* sh-dsp: single data transfer. */
658 rn = nibs[n];
659 if ((rn & 0xc) != 4)
660 goto fail;
661 rn = rn & 0x3;
662 rn |= (!(rn & 2)) << 2;
663 break;
664 case PPI:
665 case REPEAT:
666 goto fail;
667 default:
668 abort ();
673 /* sh2a has D_REG but not X_REG. We don't know the pattern
674 doesn't match unless we check the output args to see if they
675 make sense. */
676 if (target_arch == arch_sh2a
677 && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
678 || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
679 goto fail;
681 fprintf_fn (stream, "%s\t", op->name);
682 disp_pc = 0;
683 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
685 if (n && op->arg[1] != A_END)
686 fprintf_fn (stream, ",");
687 switch (op->arg[n])
689 case A_IMM:
690 fprintf_fn (stream, "#%d", imm);
691 break;
692 case A_R0:
693 fprintf_fn (stream, "r0");
694 break;
695 case A_REG_N:
696 fprintf_fn (stream, "r%d", rn);
697 break;
698 case A_INC_N:
699 case AS_INC_N:
700 fprintf_fn (stream, "@r%d+", rn);
701 break;
702 case A_DEC_N:
703 case AS_DEC_N:
704 fprintf_fn (stream, "@-r%d", rn);
705 break;
706 case A_IND_N:
707 case AS_IND_N:
708 fprintf_fn (stream, "@r%d", rn);
709 break;
710 case A_DISP_REG_N:
711 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
712 break;
713 case AS_PMOD_N:
714 fprintf_fn (stream, "@r%d+r8", rn);
715 break;
716 case A_REG_M:
717 fprintf_fn (stream, "r%d", rm);
718 break;
719 case A_INC_M:
720 fprintf_fn (stream, "@r%d+", rm);
721 break;
722 case A_DEC_M:
723 fprintf_fn (stream, "@-r%d", rm);
724 break;
725 case A_IND_M:
726 fprintf_fn (stream, "@r%d", rm);
727 break;
728 case A_DISP_REG_M:
729 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
730 break;
731 case A_REG_B:
732 fprintf_fn (stream, "r%d_bank", rb);
733 break;
734 case A_DISP_PC:
735 disp_pc = 1;
736 disp_pc_addr = imm + 4 + (memaddr & relmask);
737 (*info->print_address_func) (disp_pc_addr, info);
738 break;
739 case A_IND_R0_REG_N:
740 fprintf_fn (stream, "@(r0,r%d)", rn);
741 break;
742 case A_IND_R0_REG_M:
743 fprintf_fn (stream, "@(r0,r%d)", rm);
744 break;
745 case A_DISP_GBR:
746 fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
747 break;
748 case A_TBR:
749 fprintf_fn (stream, "tbr");
750 break;
751 case A_DISP2_TBR:
752 fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
753 break;
754 case A_INC_R15:
755 fprintf_fn (stream, "@r15+");
756 break;
757 case A_DEC_R15:
758 fprintf_fn (stream, "@-r15");
759 break;
760 case A_R0_GBR:
761 fprintf_fn (stream, "@(r0,gbr)");
762 break;
763 case A_BDISP12:
764 case A_BDISP8:
765 (*info->print_address_func) (imm + memaddr, info);
766 break;
767 case A_SR:
768 fprintf_fn (stream, "sr");
769 break;
770 case A_GBR:
771 fprintf_fn (stream, "gbr");
772 break;
773 case A_VBR:
774 fprintf_fn (stream, "vbr");
775 break;
776 case A_DSR:
777 fprintf_fn (stream, "dsr");
778 break;
779 case A_MOD:
780 fprintf_fn (stream, "mod");
781 break;
782 case A_RE:
783 fprintf_fn (stream, "re");
784 break;
785 case A_RS:
786 fprintf_fn (stream, "rs");
787 break;
788 case A_A0:
789 fprintf_fn (stream, "a0");
790 break;
791 case A_X0:
792 fprintf_fn (stream, "x0");
793 break;
794 case A_X1:
795 fprintf_fn (stream, "x1");
796 break;
797 case A_Y0:
798 fprintf_fn (stream, "y0");
799 break;
800 case A_Y1:
801 fprintf_fn (stream, "y1");
802 break;
803 case DSP_REG_M:
804 print_dsp_reg (rm, fprintf_fn, stream);
805 break;
806 case A_SSR:
807 fprintf_fn (stream, "ssr");
808 break;
809 case A_SPC:
810 fprintf_fn (stream, "spc");
811 break;
812 case A_MACH:
813 fprintf_fn (stream, "mach");
814 break;
815 case A_MACL:
816 fprintf_fn (stream, "macl");
817 break;
818 case A_PR:
819 fprintf_fn (stream, "pr");
820 break;
821 case A_SGR:
822 fprintf_fn (stream, "sgr");
823 break;
824 case A_DBR:
825 fprintf_fn (stream, "dbr");
826 break;
827 case F_REG_N:
828 fprintf_fn (stream, "fr%d", rn);
829 break;
830 case F_REG_M:
831 fprintf_fn (stream, "fr%d", rm);
832 break;
833 case DX_REG_N:
834 if (rn & 1)
836 fprintf_fn (stream, "xd%d", rn & ~1);
837 break;
839 case D_REG_N:
840 fprintf_fn (stream, "dr%d", rn);
841 break;
842 case DX_REG_M:
843 if (rm & 1)
845 fprintf_fn (stream, "xd%d", rm & ~1);
846 break;
848 case D_REG_M:
849 fprintf_fn (stream, "dr%d", rm);
850 break;
851 case FPSCR_M:
852 case FPSCR_N:
853 fprintf_fn (stream, "fpscr");
854 break;
855 case FPUL_M:
856 case FPUL_N:
857 fprintf_fn (stream, "fpul");
858 break;
859 case F_FR0:
860 fprintf_fn (stream, "fr0");
861 break;
862 case V_REG_N:
863 fprintf_fn (stream, "fv%d", rn * 4);
864 break;
865 case V_REG_M:
866 fprintf_fn (stream, "fv%d", rm * 4);
867 break;
868 case XMTRX_M4:
869 fprintf_fn (stream, "xmtrx");
870 break;
871 default:
872 abort ();
876 #if 0
877 /* This code prints instructions in delay slots on the same line
878 as the instruction which needs the delay slots. This can be
879 confusing, since other disassembler don't work this way, and
880 it means that the instructions are not all in a line. So I
881 disabled it. Ian. */
882 if (!(info->flags & 1)
883 && (op->name[0] == 'j'
884 || (op->name[0] == 'b'
885 && (op->name[1] == 'r'
886 || op->name[1] == 's'))
887 || (op->name[0] == 'r' && op->name[1] == 't')
888 || (op->name[0] == 'b' && op->name[2] == '.')))
890 info->flags |= 1;
891 fprintf_fn (stream, "\t(slot ");
892 print_insn_sh (memaddr + 2, info);
893 info->flags &= ~1;
894 fprintf_fn (stream, ")");
895 return 4;
897 #endif
899 if (disp_pc && strcmp (op->name, "mova") != 0)
901 int size;
902 bfd_byte bytes[4];
904 if (relmask == ~(bfd_vma) 1)
905 size = 2;
906 else
907 size = 4;
908 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
909 if (status == 0)
911 unsigned int val;
913 if (size == 2)
915 if (info->endian == BFD_ENDIAN_LITTLE)
916 val = bfd_getl16 (bytes);
917 else
918 val = bfd_getb16 (bytes);
920 else
922 if (info->endian == BFD_ENDIAN_LITTLE)
923 val = bfd_getl32 (bytes);
924 else
925 val = bfd_getb32 (bytes);
927 if ((*info->symbol_at_address_func) (val, info))
929 fprintf_fn (stream, "\t! ");
930 (*info->print_address_func) (val, info);
932 else
933 fprintf_fn (stream, "\t! %x", val);
937 return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
938 fail:
942 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
943 return 2;