]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/sh-dis.c
-Wimplicit-fallthrough warning fixes
[thirdparty/binutils-gdb.git] / opcodes / sh-dis.c
1 /* Disassemble SH instructions.
2 Copyright (C) 1993-2016 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 "dis-asm.h"
29
30 #ifdef ARCH_all
31 #define INCLUDE_SHMEDIA
32 #endif
33
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)
40 {
41 int n;
42
43 fprintf_fn (stream, "%s\t", op->name);
44 for (n = 0; n < 2; n++)
45 {
46 switch (op->arg[n])
47 {
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 ();
101 }
102 if (n == 0)
103 fprintf_fn (stream, ",");
104 }
105 }
106
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. */
111
112 static void
113 print_insn_ddt (int insn, struct disassemble_info *info)
114 {
115 fprintf_ftype fprintf_fn = info->fprintf_func;
116 void *stream = info->stream;
117
118 /* If this is just a nop, make sure to emit something. */
119 if (insn == 0x000)
120 fprintf_fn (stream, "nopx\tnopy");
121
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");
126
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)
132 {
133 static const sh_opcode_info *first_movx, *first_movy;
134 const sh_opcode_info *op;
135 int is_movy;
136
137 if (! first_movx)
138 {
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++;
143 }
144
145 is_movy = ((insn & 3) != 0);
146
147 if (is_movy)
148 op = first_movy;
149 else
150 op = first_movx;
151
152 while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
153 || op->nibbles[3] != (unsigned) (insn & 0xf))
154 op++;
155
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);
162 }
163 else
164 fprintf_fn (stream, ".word 0x%x", insn);
165 else
166 {
167 static const sh_opcode_info *first_movx, *first_movy;
168 const sh_opcode_info *opx, *opy;
169 unsigned int insn_x, insn_y;
170
171 if (! first_movx)
172 {
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++;
177 }
178 insn_x = (insn >> 2) & 0xb;
179 if (insn_x)
180 {
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);
185 }
186 insn_y = (insn & 3) | ((insn >> 1) & 8);
187 if (insn_y)
188 {
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);
195 }
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 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);
419 }
420
421 status = info->read_memory_func (memaddr, insn, 2, info);
422
423 if (status != 0)
424 {
425 info->memory_error_func (status, memaddr, info);
426 return -1;
427 }
428
429 if (info->endian == BFD_ENDIAN_LITTLE)
430 {
431 nibs[0] = (insn[1] >> 4) & 0xf;
432 nibs[1] = insn[1] & 0xf;
433
434 nibs[2] = (insn[0] >> 4) & 0xf;
435 nibs[3] = insn[0] & 0xf;
436 }
437 else
438 {
439 nibs[0] = (insn[0] >> 4) & 0xf;
440 nibs[1] = insn[0] & 0xf;
441
442 nibs[2] = (insn[1] >> 4) & 0xf;
443 nibs[3] = insn[1] & 0xf;
444 }
445 status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
446 if (status != 0)
447 allow_op32 = 0;
448 else
449 {
450 allow_op32 = 1;
451
452 if (info->endian == BFD_ENDIAN_LITTLE)
453 {
454 nibs[4] = (insn[3] >> 4) & 0xf;
455 nibs[5] = insn[3] & 0xf;
456
457 nibs[6] = (insn[2] >> 4) & 0xf;
458 nibs[7] = insn[2] & 0xf;
459 }
460 else
461 {
462 nibs[4] = (insn[2] >> 4) & 0xf;
463 nibs[5] = insn[2] & 0xf;
464
465 nibs[6] = (insn[3] >> 4) & 0xf;
466 nibs[7] = insn[3] & 0xf;
467 }
468 }
469
470 if (nibs[0] == 0xf && (nibs[1] & 4) == 0
471 && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
472 {
473 if (nibs[1] & 8)
474 {
475 int field_b;
476
477 status = info->read_memory_func (memaddr + 2, insn, 2, info);
478
479 if (status != 0)
480 {
481 info->memory_error_func (status, memaddr + 2, info);
482 return -1;
483 }
484
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];
489
490 print_insn_ppi (field_b, info);
491 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
492 return 4;
493 }
494 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
495 return 2;
496 }
497 for (op = sh_table; op->name; op++)
498 {
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;
509
510 if (!allow_op32
511 && SH_MERGE_ARCH_SET (op->arch, arch_op32))
512 goto fail;
513
514 if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
515 goto fail;
516 for (n = 0; n < max_n; n++)
517 {
518 int i = op->nibbles[n];
519
520 if (i < 16)
521 {
522 if (nibs[n] == i)
523 continue;
524 goto fail;
525 }
526 switch (i)
527 {
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 ();
669 }
670 }
671
672 ok:
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;
680
681 fprintf_fn (stream, "%s\t", op->name);
682 disp_pc = 0;
683 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
684 {
685 if (n && op->arg[1] != A_END)
686 fprintf_fn (stream, ",");
687 switch (op->arg[n])
688 {
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)
835 {
836 fprintf_fn (stream, "xd%d", rn & ~1);
837 break;
838 }
839 /* Fall through. */
840 case D_REG_N:
841 fprintf_fn (stream, "dr%d", rn);
842 break;
843 case DX_REG_M:
844 if (rm & 1)
845 {
846 fprintf_fn (stream, "xd%d", rm & ~1);
847 break;
848 }
849 /* Fall through. */
850 case D_REG_M:
851 fprintf_fn (stream, "dr%d", rm);
852 break;
853 case FPSCR_M:
854 case FPSCR_N:
855 fprintf_fn (stream, "fpscr");
856 break;
857 case FPUL_M:
858 case FPUL_N:
859 fprintf_fn (stream, "fpul");
860 break;
861 case F_FR0:
862 fprintf_fn (stream, "fr0");
863 break;
864 case V_REG_N:
865 fprintf_fn (stream, "fv%d", rn * 4);
866 break;
867 case V_REG_M:
868 fprintf_fn (stream, "fv%d", rm * 4);
869 break;
870 case XMTRX_M4:
871 fprintf_fn (stream, "xmtrx");
872 break;
873 default:
874 abort ();
875 }
876 }
877
878 #if 0
879 /* This code prints instructions in delay slots on the same line
880 as the instruction which needs the delay slots. This can be
881 confusing, since other disassembler don't work this way, and
882 it means that the instructions are not all in a line. So I
883 disabled it. Ian. */
884 if (!(info->flags & 1)
885 && (op->name[0] == 'j'
886 || (op->name[0] == 'b'
887 && (op->name[1] == 'r'
888 || op->name[1] == 's'))
889 || (op->name[0] == 'r' && op->name[1] == 't')
890 || (op->name[0] == 'b' && op->name[2] == '.')))
891 {
892 info->flags |= 1;
893 fprintf_fn (stream, "\t(slot ");
894 print_insn_sh (memaddr + 2, info);
895 info->flags &= ~1;
896 fprintf_fn (stream, ")");
897 return 4;
898 }
899 #endif
900
901 if (disp_pc && strcmp (op->name, "mova") != 0)
902 {
903 int size;
904 bfd_byte bytes[4];
905
906 if (relmask == ~(bfd_vma) 1)
907 size = 2;
908 else
909 size = 4;
910 /* Not reading an instruction - disable stop_vma. */
911 info->stop_vma = 0;
912 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
913 if (status == 0)
914 {
915 unsigned int val;
916
917 if (size == 2)
918 {
919 if (info->endian == BFD_ENDIAN_LITTLE)
920 val = bfd_getl16 (bytes);
921 else
922 val = bfd_getb16 (bytes);
923 }
924 else
925 {
926 if (info->endian == BFD_ENDIAN_LITTLE)
927 val = bfd_getl32 (bytes);
928 else
929 val = bfd_getb32 (bytes);
930 }
931 if ((*info->symbol_at_address_func) (val, info))
932 {
933 fprintf_fn (stream, "\t! ");
934 (*info->print_address_func) (val, info);
935 }
936 else
937 fprintf_fn (stream, "\t! %x", val);
938 }
939 }
940
941 return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
942 fail:
943 ;
944
945 }
946 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
947 return 2;
948 }