readelf/objdump: Handle DWARF info with mixed types of range section.
[binutils-gdb.git] / opcodes / sh-dis.c
blob6fd59a6ffb7313b9118ab882ad4bf8e6e9455f8b
1 /* Disassemble SH instructions.
2 Copyright (C) 1993-2023 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
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.
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.
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. */
21 #include "sysdep.h"
22 #include <stdio.h>
24 #define STATIC_TABLE
25 #define DEFINE_TABLE
27 #include "sh-opc.h"
28 #include "disassemble.h"
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)
37 int n;
39 fprintf_fn (stream, "%s\t", op->name);
40 for (n = 0; n < 2; n++)
42 switch (op->arg[n])
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 ();
98 if (n == 0)
99 fprintf_fn (stream, ",");
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. */
107 static void
108 print_insn_ddt (int insn, struct disassemble_info *info)
110 fprintf_ftype fprintf_fn = info->fprintf_func;
111 void *stream = info->stream;
113 /* If this is just a nop, make sure to emit something. */
114 if (insn == 0x000)
116 fprintf_fn (stream, "nopx\tnopy");
117 return;
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");
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)
131 static const sh_opcode_info *first_movx, *first_movy;
132 const sh_opcode_info *op;
133 int is_movy;
135 if (! first_movx)
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++;
143 is_movy = ((insn & 3) != 0);
145 if (is_movy)
146 op = first_movy;
147 else
148 op = first_movx;
150 while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
151 || op->nibbles[3] != (unsigned) (insn & 0xf))
152 op++;
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);
161 else
162 fprintf_fn (stream, ".word 0x%x", insn | 0xf000);
163 else
165 static const sh_opcode_info *first_movx, *first_movy;
166 const sh_opcode_info *opx, *opy;
167 unsigned int insn_x, insn_y;
169 if (! first_movx)
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++;
176 insn_x = (insn >> 2) & 0xb;
177 if (insn_x)
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);
184 insn_y = (insn & 3) | ((insn >> 1) & 8);
185 if (insn_y)
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);
194 if (!insn_x && !insn_y && ((insn & 0x3ff) != 0 || (insn & 0x800) == 0))
195 fprintf_fn (stream, ".word 0x%x", insn | 0xf000);
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, "%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 ();
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 default:
408 target_arch = sh_get_arch_from_bfd_mach (info->mach);
411 status = info->read_memory_func (memaddr, insn, 2, info);
413 if (status != 0)
415 info->memory_error_func (status, memaddr, info);
416 return -1;
419 if (info->endian == BFD_ENDIAN_LITTLE)
421 nibs[0] = (insn[1] >> 4) & 0xf;
422 nibs[1] = insn[1] & 0xf;
424 nibs[2] = (insn[0] >> 4) & 0xf;
425 nibs[3] = insn[0] & 0xf;
427 else
429 nibs[0] = (insn[0] >> 4) & 0xf;
430 nibs[1] = insn[0] & 0xf;
432 nibs[2] = (insn[1] >> 4) & 0xf;
433 nibs[3] = insn[1] & 0xf;
435 status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
436 if (status != 0)
437 allow_op32 = 0;
438 else
440 allow_op32 = 1;
442 if (info->endian == BFD_ENDIAN_LITTLE)
444 nibs[4] = (insn[3] >> 4) & 0xf;
445 nibs[5] = insn[3] & 0xf;
447 nibs[6] = (insn[2] >> 4) & 0xf;
448 nibs[7] = insn[2] & 0xf;
450 else
452 nibs[4] = (insn[2] >> 4) & 0xf;
453 nibs[5] = insn[2] & 0xf;
455 nibs[6] = (insn[3] >> 4) & 0xf;
456 nibs[7] = insn[3] & 0xf;
460 if (nibs[0] == 0xf && (nibs[1] & 4) == 0
461 && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
463 if (nibs[1] & 8)
465 int field_b;
467 status = info->read_memory_func (memaddr + 2, insn, 2, info);
469 if (status != 0)
471 info->memory_error_func (status, memaddr + 2, info);
472 return -1;
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];
480 print_insn_ppi (field_b, info);
481 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
482 return 4;
484 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
485 return 2;
487 for (op = sh_table; op->name; op++)
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;
500 if (!allow_op32
501 && SH_MERGE_ARCH_SET (op->arch, arch_op32))
502 goto fail;
504 if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
505 goto fail;
506 for (n = 0; n < max_n; n++)
508 int i = op->nibbles[n];
510 if (i < 16)
512 if (nibs[n] == i)
513 continue;
514 goto fail;
516 switch (i)
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 ();
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;
677 fprintf_fn (stream, "%s\t", op->name);
678 disp_pc = 0;
679 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
681 if (n && op->arg[1] != A_END)
682 fprintf_fn (stream, ",");
683 switch (op->arg[n])
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)
832 fprintf_fn (stream, "xd%d", rn & ~1);
833 break;
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)
842 fprintf_fn (stream, "xd%d", rm & ~1);
843 break;
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 ();
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] == '.')))
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;
895 #endif
897 if (disp_pc && strcmp (op->name, "mova") != 0)
899 int size;
900 bfd_byte bytes[4];
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)
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;