* sh-dis.c (print_insn_sh): If coff and bfd_mach_sh, use arch_sh4
[deliverable/binutils-gdb.git] / opcodes / sh-dis.c
1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001
3 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #include <stdio.h>
20 #include "sysdep.h"
21 #define STATIC_TABLE
22 #define DEFINE_TABLE
23
24 #include "sh-opc.h"
25 #include "dis-asm.h"
26
27 static void print_movxy
28 PARAMS ((sh_opcode_info *, int, int, fprintf_ftype, void *));
29 static void print_insn_ddt PARAMS ((int, struct disassemble_info *));
30 static void print_dsp_reg PARAMS ((int, fprintf_ftype, void *));
31 static void print_insn_ppi PARAMS ((int, struct disassemble_info *));
32
33 static void
34 print_movxy (op, rn, rm, fprintf_fn, stream)
35 sh_opcode_info *op;
36 int rn, rm;
37 fprintf_ftype fprintf_fn;
38 void *stream;
39 {
40 int n;
41
42 fprintf_fn (stream, "%s\t", op->name);
43 for (n = 0; n < 2; n++)
44 {
45 switch (op->arg[n])
46 {
47 case A_IND_N:
48 fprintf_fn (stream, "@r%d", rn);
49 break;
50 case A_INC_N:
51 fprintf_fn (stream, "@r%d+", rn);
52 break;
53 case A_PMOD_N:
54 fprintf_fn (stream, "@r%d+r8", rn);
55 break;
56 case A_PMODY_N:
57 fprintf_fn (stream, "@r%d+r9", rn);
58 break;
59 case DSP_REG_M:
60 fprintf_fn (stream, "a%c", '0' + rm);
61 break;
62 case DSP_REG_X:
63 fprintf_fn (stream, "x%c", '0' + rm);
64 break;
65 case DSP_REG_Y:
66 fprintf_fn (stream, "y%c", '0' + rm);
67 break;
68 default:
69 abort ();
70 }
71 if (n == 0)
72 fprintf_fn (stream, ",");
73 }
74 }
75
76 /* Print a double data transfer insn. INSN is just the lower three
77 nibbles of the insn, i.e. field a and the bit that indicates if
78 a parallel processing insn follows.
79 Return nonzero if a field b of a parallel processing insns follows. */
80
81 static void
82 print_insn_ddt (insn, info)
83 int insn;
84 struct disassemble_info *info;
85 {
86 fprintf_ftype fprintf_fn = info->fprintf_func;
87 void *stream = info->stream;
88
89 /* If this is just a nop, make sure to emit something. */
90 if (insn == 0x000)
91 fprintf_fn (stream, "nopx\tnopy");
92
93 /* If a parallel processing insn was printed before,
94 and we got a non-nop, emit a tab. */
95 if ((insn & 0x800) && (insn & 0x3ff))
96 fprintf_fn (stream, "\t");
97
98 /* Check if either the x or y part is invalid. */
99 if (((insn & 0xc) == 0 && (insn & 0x2a0))
100 || ((insn & 3) == 0 && (insn & 0x150)))
101 fprintf_fn (stream, ".word 0x%x", insn);
102 else
103 {
104 static sh_opcode_info *first_movx, *first_movy;
105 sh_opcode_info *opx, *opy;
106 unsigned int insn_x, insn_y;
107
108 if (! first_movx)
109 {
110 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
111 first_movx++;
112 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
113 first_movy++;
114 }
115 insn_x = (insn >> 2) & 0xb;
116 if (insn_x)
117 {
118 for (opx = first_movx; opx->nibbles[2] != insn_x;)
119 opx++;
120 print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
121 fprintf_fn, stream);
122 }
123 insn_y = (insn & 3) | ((insn >> 1) & 8);
124 if (insn_y)
125 {
126 if (insn_x)
127 fprintf_fn (stream, "\t");
128 for (opy = first_movy; opy->nibbles[2] != insn_y;)
129 opy++;
130 print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
131 fprintf_fn, stream);
132 }
133 }
134 }
135
136 static void
137 print_dsp_reg (rm, fprintf_fn, stream)
138 int rm;
139 fprintf_ftype fprintf_fn;
140 void *stream;
141 {
142 switch (rm)
143 {
144 case A_A1_NUM:
145 fprintf_fn (stream, "a1");
146 break;
147 case A_A0_NUM:
148 fprintf_fn (stream, "a0");
149 break;
150 case A_X0_NUM:
151 fprintf_fn (stream, "x0");
152 break;
153 case A_X1_NUM:
154 fprintf_fn (stream, "x1");
155 break;
156 case A_Y0_NUM:
157 fprintf_fn (stream, "y0");
158 break;
159 case A_Y1_NUM:
160 fprintf_fn (stream, "y1");
161 break;
162 case A_M0_NUM:
163 fprintf_fn (stream, "m0");
164 break;
165 case A_A1G_NUM:
166 fprintf_fn (stream, "a1g");
167 break;
168 case A_M1_NUM:
169 fprintf_fn (stream, "m1");
170 break;
171 case A_A0G_NUM:
172 fprintf_fn (stream, "a0g");
173 break;
174 default:
175 fprintf_fn (stream, "0x%x", rm);
176 break;
177 }
178 }
179
180 static void
181 print_insn_ppi (field_b, info)
182 int field_b;
183 struct disassemble_info *info;
184 {
185 static char *sx_tab[] = { "x0", "x1", "a0", "a1" };
186 static char *sy_tab[] = { "y0", "y1", "m0", "m1" };
187 fprintf_ftype fprintf_fn = info->fprintf_func;
188 void *stream = info->stream;
189 unsigned int nib1, nib2, nib3;
190 char *dc = NULL;
191 sh_opcode_info *op;
192
193 if ((field_b & 0xe800) == 0)
194 {
195 fprintf_fn (stream, "psh%c\t#%d,",
196 field_b & 0x1000 ? 'a' : 'l',
197 (field_b >> 4) & 127);
198 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
199 return;
200 }
201 if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
202 {
203 static char *du_tab[] = { "x0", "y0", "a0", "a1" };
204 static char *se_tab[] = { "x0", "x1", "y0", "a1" };
205 static char *sf_tab[] = { "y0", "y1", "x0", "a1" };
206 static char *sg_tab[] = { "m0", "m1", "a0", "a1" };
207
208 if (field_b & 0x2000)
209 {
210 fprintf_fn (stream, "p%s %s,%s,%s\t",
211 (field_b & 0x1000) ? "add" : "sub",
212 sx_tab[(field_b >> 6) & 3],
213 sy_tab[(field_b >> 4) & 3],
214 du_tab[(field_b >> 0) & 3]);
215 }
216 fprintf_fn (stream, "pmuls%c%s,%s,%s",
217 field_b & 0x2000 ? ' ' : '\t',
218 se_tab[(field_b >> 10) & 3],
219 sf_tab[(field_b >> 8) & 3],
220 sg_tab[(field_b >> 2) & 3]);
221 return;
222 }
223
224 nib1 = PPIC;
225 nib2 = field_b >> 12 & 0xf;
226 nib3 = field_b >> 8 & 0xf;
227 switch (nib3 & 0x3)
228 {
229 case 0:
230 dc = "";
231 nib1 = PPI3;
232 break;
233 case 1:
234 dc = "";
235 break;
236 case 2:
237 dc = "dct ";
238 nib3 -= 1;
239 break;
240 case 3:
241 dc = "dcf ";
242 nib3 -= 2;
243 break;
244 }
245 for (op = sh_table; op->name; op++)
246 {
247 if (op->nibbles[1] == nib1
248 && op->nibbles[2] == nib2
249 && op->nibbles[3] == nib3)
250 {
251 int n;
252
253 fprintf_fn (stream, "%s%s\t", dc, op->name);
254 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
255 {
256 if (n && op->arg[1] != A_END)
257 fprintf_fn (stream, ",");
258 switch (op->arg[n])
259 {
260 case DSP_REG_N:
261 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
262 break;
263 case DSP_REG_X:
264 fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
265 break;
266 case DSP_REG_Y:
267 fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
268 break;
269 case A_MACH:
270 fprintf_fn (stream, "mach");
271 break;
272 case A_MACL:
273 fprintf_fn (stream, "macl");
274 break;
275 default:
276 abort ();
277 }
278 }
279 return;
280 }
281 }
282 /* Not found. */
283 fprintf_fn (stream, ".word 0x%x", field_b);
284 }
285
286 int
287 print_insn_sh (memaddr, info)
288 bfd_vma memaddr;
289 struct disassemble_info *info;
290 {
291 fprintf_ftype fprintf_fn = info->fprintf_func;
292 void *stream = info->stream;
293 unsigned char insn[2];
294 unsigned char nibs[4];
295 int status;
296 bfd_vma relmask = ~(bfd_vma) 0;
297 sh_opcode_info *op;
298 int target_arch;
299
300 switch (info->mach)
301 {
302 case bfd_mach_sh:
303 target_arch = arch_sh1;
304 /* SH coff object files lack information about the machine type, so
305 we end up with bfd_mach_sh unless it was set explicitly (which
306 could have happended if this is a call from gdb or the simulator.) */
307 if (bfd_asymbol_flavour(*info->symbols) == bfd_target_coff_flavour)
308 target_arch = arch_sh4;
309 break;
310 case bfd_mach_sh2:
311 target_arch = arch_sh2;
312 break;
313 case bfd_mach_sh_dsp:
314 target_arch = arch_sh_dsp;
315 break;
316 case bfd_mach_sh3:
317 target_arch = arch_sh3;
318 break;
319 case bfd_mach_sh3_dsp:
320 target_arch = arch_sh3_dsp;
321 break;
322 case bfd_mach_sh3e:
323 target_arch = arch_sh3e;
324 break;
325 case bfd_mach_sh4:
326 target_arch = arch_sh4;
327 break;
328 case bfd_mach_sh5:
329 #ifdef INCLUDE_SHMEDIA
330 status = print_insn_sh64 (memaddr, info);
331 if (status != -2)
332 return status;
333 #endif
334 /* When we get here for sh64, it's because we want to disassemble
335 SHcompact, i.e. arch_sh4. */
336 target_arch = arch_sh4;
337 break;
338 default:
339 abort ();
340 }
341
342 status = info->read_memory_func (memaddr, insn, 2, info);
343
344 if (status != 0)
345 {
346 info->memory_error_func (status, memaddr, info);
347 return -1;
348 }
349
350 if (info->endian == BFD_ENDIAN_LITTLE)
351 {
352 nibs[0] = (insn[1] >> 4) & 0xf;
353 nibs[1] = insn[1] & 0xf;
354
355 nibs[2] = (insn[0] >> 4) & 0xf;
356 nibs[3] = insn[0] & 0xf;
357 }
358 else
359 {
360 nibs[0] = (insn[0] >> 4) & 0xf;
361 nibs[1] = insn[0] & 0xf;
362
363 nibs[2] = (insn[1] >> 4) & 0xf;
364 nibs[3] = insn[1] & 0xf;
365 }
366
367 if (nibs[0] == 0xf && (nibs[1] & 4) == 0 && target_arch & arch_sh_dsp_up)
368 {
369 if (nibs[1] & 8)
370 {
371 int field_b;
372
373 status = info->read_memory_func (memaddr + 2, insn, 2, info);
374
375 if (status != 0)
376 {
377 info->memory_error_func (status, memaddr + 2, info);
378 return -1;
379 }
380
381 if (info->endian == BFD_ENDIAN_LITTLE)
382 field_b = insn[1] << 8 | insn[0];
383 else
384 field_b = insn[0] << 8 | insn[1];
385
386 print_insn_ppi (field_b, info);
387 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
388 return 4;
389 }
390 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
391 return 2;
392 }
393 for (op = sh_table; op->name; op++)
394 {
395 int n;
396 int imm = 0;
397 int rn = 0;
398 int rm = 0;
399 int rb = 0;
400 int disp_pc;
401 bfd_vma disp_pc_addr = 0;
402
403 if ((op->arch & target_arch) == 0)
404 goto fail;
405 for (n = 0; n < 4; n++)
406 {
407 int i = op->nibbles[n];
408
409 if (i < 16)
410 {
411 if (nibs[n] == i)
412 continue;
413 goto fail;
414 }
415 switch (i)
416 {
417 case BRANCH_8:
418 imm = (nibs[2] << 4) | (nibs[3]);
419 if (imm & 0x80)
420 imm |= ~0xff;
421 imm = ((char) imm) * 2 + 4;
422 goto ok;
423 case BRANCH_12:
424 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
425 if (imm & 0x800)
426 imm |= ~0xfff;
427 imm = imm * 2 + 4;
428 goto ok;
429 case IMM0_4:
430 case IMM1_4:
431 imm = nibs[3];
432 goto ok;
433 case IMM0_4BY2:
434 case IMM1_4BY2:
435 imm = nibs[3] << 1;
436 goto ok;
437 case IMM0_4BY4:
438 case IMM1_4BY4:
439 imm = nibs[3] << 2;
440 goto ok;
441 case IMM0_8:
442 case IMM1_8:
443 imm = (nibs[2] << 4) | nibs[3];
444 goto ok;
445 case PCRELIMM_8BY2:
446 imm = ((nibs[2] << 4) | nibs[3]) << 1;
447 relmask = ~(bfd_vma) 1;
448 goto ok;
449 case PCRELIMM_8BY4:
450 imm = ((nibs[2] << 4) | nibs[3]) << 2;
451 relmask = ~(bfd_vma) 3;
452 goto ok;
453 case IMM0_8BY2:
454 case IMM1_8BY2:
455 imm = ((nibs[2] << 4) | nibs[3]) << 1;
456 goto ok;
457 case IMM0_8BY4:
458 case IMM1_8BY4:
459 imm = ((nibs[2] << 4) | nibs[3]) << 2;
460 goto ok;
461 case REG_N:
462 rn = nibs[n];
463 break;
464 case REG_M:
465 rm = nibs[n];
466 break;
467 case REG_NM:
468 rn = (nibs[n] & 0xc) >> 2;
469 rm = (nibs[n] & 0x3);
470 break;
471 case REG_B:
472 rb = nibs[n] & 0x07;
473 break;
474 case SDT_REG_N:
475 /* sh-dsp: single data transfer. */
476 rn = nibs[n];
477 if ((rn & 0xc) != 4)
478 goto fail;
479 rn = rn & 0x3;
480 rn |= (!(rn & 2)) << 2;
481 break;
482 case PPI:
483 case REPEAT:
484 goto fail;
485 default:
486 abort ();
487 }
488 }
489
490 ok:
491 fprintf_fn (stream, "%s\t", op->name);
492 disp_pc = 0;
493 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
494 {
495 if (n && op->arg[1] != A_END)
496 fprintf_fn (stream, ",");
497 switch (op->arg[n])
498 {
499 case A_IMM:
500 fprintf_fn (stream, "#%d", (char) (imm));
501 break;
502 case A_R0:
503 fprintf_fn (stream, "r0");
504 break;
505 case A_REG_N:
506 fprintf_fn (stream, "r%d", rn);
507 break;
508 case A_INC_N:
509 fprintf_fn (stream, "@r%d+", rn);
510 break;
511 case A_DEC_N:
512 fprintf_fn (stream, "@-r%d", rn);
513 break;
514 case A_IND_N:
515 fprintf_fn (stream, "@r%d", rn);
516 break;
517 case A_DISP_REG_N:
518 fprintf_fn (stream, "@(%d,r%d)", imm, rn);
519 break;
520 case A_PMOD_N:
521 fprintf_fn (stream, "@r%d+r8", rn);
522 break;
523 case A_REG_M:
524 fprintf_fn (stream, "r%d", rm);
525 break;
526 case A_INC_M:
527 fprintf_fn (stream, "@r%d+", rm);
528 break;
529 case A_DEC_M:
530 fprintf_fn (stream, "@-r%d", rm);
531 break;
532 case A_IND_M:
533 fprintf_fn (stream, "@r%d", rm);
534 break;
535 case A_DISP_REG_M:
536 fprintf_fn (stream, "@(%d,r%d)", imm, rm);
537 break;
538 case A_REG_B:
539 fprintf_fn (stream, "r%d_bank", rb);
540 break;
541 case A_DISP_PC:
542 disp_pc = 1;
543 disp_pc_addr = imm + 4 + (memaddr & relmask);
544 (*info->print_address_func) (disp_pc_addr, info);
545 break;
546 case A_IND_R0_REG_N:
547 fprintf_fn (stream, "@(r0,r%d)", rn);
548 break;
549 case A_IND_R0_REG_M:
550 fprintf_fn (stream, "@(r0,r%d)", rm);
551 break;
552 case A_DISP_GBR:
553 fprintf_fn (stream, "@(%d,gbr)", imm);
554 break;
555 case A_R0_GBR:
556 fprintf_fn (stream, "@(r0,gbr)");
557 break;
558 case A_BDISP12:
559 case A_BDISP8:
560 (*info->print_address_func) (imm + memaddr, info);
561 break;
562 case A_SR:
563 fprintf_fn (stream, "sr");
564 break;
565 case A_GBR:
566 fprintf_fn (stream, "gbr");
567 break;
568 case A_VBR:
569 fprintf_fn (stream, "vbr");
570 break;
571 case A_DSR:
572 fprintf_fn (stream, "dsr");
573 break;
574 case A_MOD:
575 fprintf_fn (stream, "mod");
576 break;
577 case A_RE:
578 fprintf_fn (stream, "re");
579 break;
580 case A_RS:
581 fprintf_fn (stream, "rs");
582 break;
583 case A_A0:
584 fprintf_fn (stream, "a0");
585 break;
586 case A_X0:
587 fprintf_fn (stream, "x0");
588 break;
589 case A_X1:
590 fprintf_fn (stream, "x1");
591 break;
592 case A_Y0:
593 fprintf_fn (stream, "y0");
594 break;
595 case A_Y1:
596 fprintf_fn (stream, "y1");
597 break;
598 case DSP_REG_M:
599 print_dsp_reg (rm, fprintf_fn, stream);
600 break;
601 case A_SSR:
602 fprintf_fn (stream, "ssr");
603 break;
604 case A_SPC:
605 fprintf_fn (stream, "spc");
606 break;
607 case A_MACH:
608 fprintf_fn (stream, "mach");
609 break;
610 case A_MACL:
611 fprintf_fn (stream, "macl");
612 break;
613 case A_PR:
614 fprintf_fn (stream, "pr");
615 break;
616 case A_SGR:
617 fprintf_fn (stream, "sgr");
618 break;
619 case A_DBR:
620 fprintf_fn (stream, "dbr");
621 break;
622 case F_REG_N:
623 fprintf_fn (stream, "fr%d", rn);
624 break;
625 case F_REG_M:
626 fprintf_fn (stream, "fr%d", rm);
627 break;
628 case DX_REG_N:
629 if (rn & 1)
630 {
631 fprintf_fn (stream, "xd%d", rn & ~1);
632 break;
633 }
634 case D_REG_N:
635 fprintf_fn (stream, "dr%d", rn);
636 break;
637 case DX_REG_M:
638 if (rm & 1)
639 {
640 fprintf_fn (stream, "xd%d", rm & ~1);
641 break;
642 }
643 case D_REG_M:
644 fprintf_fn (stream, "dr%d", rm);
645 break;
646 case FPSCR_M:
647 case FPSCR_N:
648 fprintf_fn (stream, "fpscr");
649 break;
650 case FPUL_M:
651 case FPUL_N:
652 fprintf_fn (stream, "fpul");
653 break;
654 case F_FR0:
655 fprintf_fn (stream, "fr0");
656 break;
657 case V_REG_N:
658 fprintf_fn (stream, "fv%d", rn * 4);
659 break;
660 case V_REG_M:
661 fprintf_fn (stream, "fv%d", rm * 4);
662 break;
663 case XMTRX_M4:
664 fprintf_fn (stream, "xmtrx");
665 break;
666 default:
667 abort ();
668 }
669 }
670
671 #if 0
672 /* This code prints instructions in delay slots on the same line
673 as the instruction which needs the delay slots. This can be
674 confusing, since other disassembler don't work this way, and
675 it means that the instructions are not all in a line. So I
676 disabled it. Ian. */
677 if (!(info->flags & 1)
678 && (op->name[0] == 'j'
679 || (op->name[0] == 'b'
680 && (op->name[1] == 'r'
681 || op->name[1] == 's'))
682 || (op->name[0] == 'r' && op->name[1] == 't')
683 || (op->name[0] == 'b' && op->name[2] == '.')))
684 {
685 info->flags |= 1;
686 fprintf_fn (stream, "\t(slot ");
687 print_insn_sh (memaddr + 2, info);
688 info->flags &= ~1;
689 fprintf_fn (stream, ")");
690 return 4;
691 }
692 #endif
693
694 if (disp_pc && strcmp (op->name, "mova") != 0)
695 {
696 int size;
697 bfd_byte bytes[4];
698
699 if (relmask == ~(bfd_vma) 1)
700 size = 2;
701 else
702 size = 4;
703 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
704 if (status == 0)
705 {
706 unsigned int val;
707
708 if (size == 2)
709 {
710 if (info->endian == BFD_ENDIAN_LITTLE)
711 val = bfd_getl16 (bytes);
712 else
713 val = bfd_getb16 (bytes);
714 }
715 else
716 {
717 if (info->endian == BFD_ENDIAN_LITTLE)
718 val = bfd_getl32 (bytes);
719 else
720 val = bfd_getb32 (bytes);
721 }
722 fprintf_fn (stream, "\t! 0x%x", val);
723 }
724 }
725
726 return 2;
727 fail:
728 ;
729
730 }
731 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
732 return 2;
733 }
This page took 0.045425 seconds and 5 git commands to generate.