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