1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2012 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)
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. */
32 #define INCLUDE_SHMEDIA
36 print_movxy (const sh_opcode_info
*op
,
39 fprintf_ftype fprintf_fn
,
44 fprintf_fn (stream
, "%s\t", op
->name
);
45 for (n
= 0; n
< 2; n
++)
54 fprintf_fn (stream
, "@r%d", rn
);
61 fprintf_fn (stream
, "@r%d+", rn
);
65 fprintf_fn (stream
, "@r%d+r8", rn
);
69 fprintf_fn (stream
, "@r%d+r9", rn
);
72 fprintf_fn (stream
, "a%c", '0' + rm
);
75 fprintf_fn (stream
, "x%c", '0' + rm
);
78 fprintf_fn (stream
, "y%c", '0' + rm
);
81 fprintf_fn (stream
, "%c%c",
83 (rm
& 2) ? '1' : '0');
86 fprintf_fn (stream
, "%c%c",
88 (rm
& 2) ? '1' : '0');
91 fprintf_fn (stream
, "%c%c",
93 (rm
& 1) ? '1' : '0');
96 fprintf_fn (stream
, "%c%c",
98 (rm
& 1) ? '1' : '0');
104 fprintf_fn (stream
, ",");
108 /* Print a double data transfer insn. INSN is just the lower three
109 nibbles of the insn, i.e. field a and the bit that indicates if
110 a parallel processing insn follows.
111 Return nonzero if a field b of a parallel processing insns follows. */
114 print_insn_ddt (int insn
, struct disassemble_info
*info
)
116 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
117 void *stream
= info
->stream
;
119 /* If this is just a nop, make sure to emit something. */
121 fprintf_fn (stream
, "nopx\tnopy");
123 /* If a parallel processing insn was printed before,
124 and we got a non-nop, emit a tab. */
125 if ((insn
& 0x800) && (insn
& 0x3ff))
126 fprintf_fn (stream
, "\t");
128 /* Check if either the x or y part is invalid. */
129 if (((insn
& 0xc) == 0 && (insn
& 0x2a0))
130 || ((insn
& 3) == 0 && (insn
& 0x150)))
131 if (info
->mach
!= bfd_mach_sh_dsp
132 && info
->mach
!= bfd_mach_sh3_dsp
)
134 static const sh_opcode_info
*first_movx
, *first_movy
;
135 const sh_opcode_info
*op
;
140 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX_NOPY
;)
142 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY_NOPX
;)
146 is_movy
= ((insn
& 3) != 0);
153 while (op
->nibbles
[2] != (unsigned) ((insn
>> 4) & 3)
154 || op
->nibbles
[3] != (unsigned) (insn
& 0xf))
158 (4 * ((insn
& (is_movy
? 0x200 : 0x100)) == 0)
160 + 1 * ((insn
& (is_movy
? 0x100 : 0x200)) != 0)),
165 fprintf_fn (stream
, ".word 0x%x", insn
);
168 static const sh_opcode_info
*first_movx
, *first_movy
;
169 const sh_opcode_info
*opx
, *opy
;
170 unsigned int insn_x
, insn_y
;
174 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX
;)
176 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY
;)
179 insn_x
= (insn
>> 2) & 0xb;
182 for (opx
= first_movx
; opx
->nibbles
[2] != insn_x
;)
184 print_movxy (opx
, ((insn
>> 9) & 1) + 4, (insn
>> 7) & 1,
187 insn_y
= (insn
& 3) | ((insn
>> 1) & 8);
191 fprintf_fn (stream
, "\t");
192 for (opy
= first_movy
; opy
->nibbles
[2] != insn_y
;)
194 print_movxy (opy
, ((insn
>> 8) & 1) + 6, (insn
>> 6) & 1,
201 print_dsp_reg (int rm
, fprintf_ftype fprintf_fn
, void *stream
)
206 fprintf_fn (stream
, "a1");
209 fprintf_fn (stream
, "a0");
212 fprintf_fn (stream
, "x0");
215 fprintf_fn (stream
, "x1");
218 fprintf_fn (stream
, "y0");
221 fprintf_fn (stream
, "y1");
224 fprintf_fn (stream
, "m0");
227 fprintf_fn (stream
, "a1g");
230 fprintf_fn (stream
, "m1");
233 fprintf_fn (stream
, "a0g");
236 fprintf_fn (stream
, "0x%x", rm
);
242 print_insn_ppi (int field_b
, struct disassemble_info
*info
)
244 static char *sx_tab
[] = { "x0", "x1", "a0", "a1" };
245 static char *sy_tab
[] = { "y0", "y1", "m0", "m1" };
246 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
247 void *stream
= info
->stream
;
248 unsigned int nib1
, nib2
, nib3
;
249 unsigned int altnib1
, nib4
;
251 const sh_opcode_info
*op
;
253 if ((field_b
& 0xe800) == 0)
255 fprintf_fn (stream
, "psh%c\t#%d,",
256 field_b
& 0x1000 ? 'a' : 'l',
257 (field_b
>> 4) & 127);
258 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
261 if ((field_b
& 0xc000) == 0x4000 && (field_b
& 0x3000) != 0x1000)
263 static char *du_tab
[] = { "x0", "y0", "a0", "a1" };
264 static char *se_tab
[] = { "x0", "x1", "y0", "a1" };
265 static char *sf_tab
[] = { "y0", "y1", "x0", "a1" };
266 static char *sg_tab
[] = { "m0", "m1", "a0", "a1" };
268 if (field_b
& 0x2000)
269 fprintf_fn (stream
, "p%s %s,%s,%s\t",
270 (field_b
& 0x1000) ? "add" : "sub",
271 sx_tab
[(field_b
>> 6) & 3],
272 sy_tab
[(field_b
>> 4) & 3],
273 du_tab
[(field_b
>> 0) & 3]);
275 else if ((field_b
& 0xf0) == 0x10
276 && info
->mach
!= bfd_mach_sh_dsp
277 && info
->mach
!= bfd_mach_sh3_dsp
)
278 fprintf_fn (stream
, "pclr %s \t", du_tab
[(field_b
>> 0) & 3]);
280 else if ((field_b
& 0xf3) != 0)
281 fprintf_fn (stream
, ".word 0x%x\t", field_b
);
283 fprintf_fn (stream
, "pmuls%c%s,%s,%s",
284 field_b
& 0x2000 ? ' ' : '\t',
285 se_tab
[(field_b
>> 10) & 3],
286 sf_tab
[(field_b
>> 8) & 3],
287 sg_tab
[(field_b
>> 2) & 3]);
292 nib2
= field_b
>> 12 & 0xf;
293 nib3
= field_b
>> 8 & 0xf;
294 nib4
= field_b
>> 4 & 0xf;
317 for (op
= sh_table
; op
->name
; op
++)
319 if ((op
->nibbles
[1] == nib1
|| op
->nibbles
[1] == altnib1
)
320 && op
->nibbles
[2] == nib2
321 && op
->nibbles
[3] == nib3
)
325 switch (op
->nibbles
[4])
338 if ((nib4
& 0xc) != 0)
342 if ((nib4
& 0xc) != 4)
348 fprintf_fn (stream
, "%s%s\t", dc
, op
->name
);
349 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
351 if (n
&& op
->arg
[1] != A_END
)
352 fprintf_fn (stream
, ",");
356 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
359 fprintf_fn (stream
, "%s", sx_tab
[(field_b
>> 6) & 3]);
362 fprintf_fn (stream
, "%s", sy_tab
[(field_b
>> 4) & 3]);
365 fprintf_fn (stream
, "mach");
368 fprintf_fn (stream
, "macl");
378 fprintf_fn (stream
, ".word 0x%x", field_b
);
381 /* FIXME mvs: movx insns print as ".word 0x%03x", insn & 0xfff
382 (ie. the upper nibble is missing). */
385 print_insn_sh (bfd_vma memaddr
, struct disassemble_info
*info
)
387 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
388 void *stream
= info
->stream
;
389 unsigned char insn
[4];
390 unsigned char nibs
[8];
392 bfd_vma relmask
= ~(bfd_vma
) 0;
393 const sh_opcode_info
*op
;
394 unsigned int target_arch
;
400 target_arch
= arch_sh1
;
401 /* SH coff object files lack information about the machine type, so
402 we end up with bfd_mach_sh unless it was set explicitly (which
403 could have happended if this is a call from gdb or the simulator.) */
405 && bfd_asymbol_flavour(*info
->symbols
) == bfd_target_coff_flavour
)
406 target_arch
= arch_sh4
;
409 #ifdef INCLUDE_SHMEDIA
410 status
= print_insn_sh64 (memaddr
, info
);
414 /* When we get here for sh64, it's because we want to disassemble
415 SHcompact, i.e. arch_sh4. */
416 target_arch
= arch_sh4
;
419 target_arch
= sh_get_arch_from_bfd_mach (info
->mach
);
422 status
= info
->read_memory_func (memaddr
, insn
, 2, info
);
426 info
->memory_error_func (status
, memaddr
, info
);
430 if (info
->endian
== BFD_ENDIAN_LITTLE
)
432 nibs
[0] = (insn
[1] >> 4) & 0xf;
433 nibs
[1] = insn
[1] & 0xf;
435 nibs
[2] = (insn
[0] >> 4) & 0xf;
436 nibs
[3] = insn
[0] & 0xf;
440 nibs
[0] = (insn
[0] >> 4) & 0xf;
441 nibs
[1] = insn
[0] & 0xf;
443 nibs
[2] = (insn
[1] >> 4) & 0xf;
444 nibs
[3] = insn
[1] & 0xf;
446 status
= info
->read_memory_func (memaddr
+ 2, insn
+ 2, 2, info
);
453 if (info
->endian
== BFD_ENDIAN_LITTLE
)
455 nibs
[4] = (insn
[3] >> 4) & 0xf;
456 nibs
[5] = insn
[3] & 0xf;
458 nibs
[6] = (insn
[2] >> 4) & 0xf;
459 nibs
[7] = insn
[2] & 0xf;
463 nibs
[4] = (insn
[2] >> 4) & 0xf;
464 nibs
[5] = insn
[2] & 0xf;
466 nibs
[6] = (insn
[3] >> 4) & 0xf;
467 nibs
[7] = insn
[3] & 0xf;
471 if (nibs
[0] == 0xf && (nibs
[1] & 4) == 0
472 && SH_MERGE_ARCH_SET_VALID (target_arch
, arch_sh_dsp_up
))
478 status
= info
->read_memory_func (memaddr
+ 2, insn
, 2, info
);
482 info
->memory_error_func (status
, memaddr
+ 2, info
);
486 if (info
->endian
== BFD_ENDIAN_LITTLE
)
487 field_b
= insn
[1] << 8 | insn
[0];
489 field_b
= insn
[0] << 8 | insn
[1];
491 print_insn_ppi (field_b
, info
);
492 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
495 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
498 for (op
= sh_table
; op
->name
; op
++)
506 bfd_vma disp_pc_addr
= 0;
509 int max_n
= SH_MERGE_ARCH_SET (op
->arch
, arch_op32
) ? 8 : 4;
512 && SH_MERGE_ARCH_SET (op
->arch
, arch_op32
))
515 if (!SH_MERGE_ARCH_SET_VALID (op
->arch
, target_arch
))
517 for (n
= 0; n
< max_n
; n
++)
519 int i
= op
->nibbles
[n
];
530 imm
= (nibs
[2] << 4) | (nibs
[3]);
533 imm
= ((char) imm
) * 2 + 4;
536 imm
= ((nibs
[1]) << 8) | (nibs
[2] << 4) | (nibs
[3]);
547 if (!(nibs
[3] & 0x8))
557 if (!(nibs
[2] & 0x8))
563 disp
= (nibs
[5] << 8) | (nibs
[6] << 4) | nibs
[7];
568 disp
= ((nibs
[5] << 8) | (nibs
[6] << 4) | nibs
[7]) << 1;
569 relmask
= ~(bfd_vma
) 1;
574 disp
= ((nibs
[5] << 8) | (nibs
[6] << 4) | nibs
[7]) << 2;
575 relmask
= ~(bfd_vma
) 3;
580 disp
= ((nibs
[5] << 8) | (nibs
[6] << 4) | nibs
[7]) << 3;
581 relmask
= ~(bfd_vma
) 7;
587 imm
= ((nibs
[2] << 16) | (nibs
[4] << 12) | (nibs
[5] << 8)
588 | (nibs
[6] << 4) | nibs
[7]);
593 imm
= ((nibs
[2] << 16) | (nibs
[4] << 12) | (nibs
[5] << 8)
594 | (nibs
[6] << 4) | nibs
[7]);
613 imm
= (nibs
[2] << 4) | nibs
[3];
620 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
621 relmask
= ~(bfd_vma
) 1;
624 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
625 relmask
= ~(bfd_vma
) 3;
629 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
633 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
636 if ((nibs
[n
] & 1) != 0)
646 if ((nibs
[n
] & 0x3) != 1 /* binary 01 */)
648 rn
= (nibs
[n
] & 0xc) >> 2;
651 rn
= (nibs
[n
] & 0xc) >> 2;
652 rm
= (nibs
[n
] & 0x3);
658 /* sh-dsp: single data transfer. */
663 rn
|= (!(rn
& 2)) << 2;
674 /* sh2a has D_REG but not X_REG. We don't know the pattern
675 doesn't match unless we check the output args to see if they
677 if (target_arch
== arch_sh2a
678 && ((op
->arg
[0] == DX_REG_M
&& (rm
& 1) != 0)
679 || (op
->arg
[1] == DX_REG_N
&& (rn
& 1) != 0)))
682 fprintf_fn (stream
, "%s\t", op
->name
);
684 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
686 if (n
&& op
->arg
[1] != A_END
)
687 fprintf_fn (stream
, ",");
691 fprintf_fn (stream
, "#%d", imm
);
694 fprintf_fn (stream
, "r0");
697 fprintf_fn (stream
, "r%d", rn
);
701 fprintf_fn (stream
, "@r%d+", rn
);
705 fprintf_fn (stream
, "@-r%d", rn
);
709 fprintf_fn (stream
, "@r%d", rn
);
712 fprintf_fn (stream
, "@(%d,r%d)", has_disp
?disp
:imm
, rn
);
715 fprintf_fn (stream
, "@r%d+r8", rn
);
718 fprintf_fn (stream
, "r%d", rm
);
721 fprintf_fn (stream
, "@r%d+", rm
);
724 fprintf_fn (stream
, "@-r%d", rm
);
727 fprintf_fn (stream
, "@r%d", rm
);
730 fprintf_fn (stream
, "@(%d,r%d)", has_disp
?disp
:imm
, rm
);
733 fprintf_fn (stream
, "r%d_bank", rb
);
737 disp_pc_addr
= imm
+ 4 + (memaddr
& relmask
);
738 (*info
->print_address_func
) (disp_pc_addr
, info
);
741 fprintf_fn (stream
, "@(r0,r%d)", rn
);
744 fprintf_fn (stream
, "@(r0,r%d)", rm
);
747 fprintf_fn (stream
, "@(%d,gbr)", has_disp
?disp
:imm
);
750 fprintf_fn (stream
, "tbr");
753 fprintf_fn (stream
, "@@(%d,tbr)", has_disp
?disp
:imm
);
756 fprintf_fn (stream
, "@r15+");
759 fprintf_fn (stream
, "@-r15");
762 fprintf_fn (stream
, "@(r0,gbr)");
766 (*info
->print_address_func
) (imm
+ memaddr
, info
);
769 fprintf_fn (stream
, "sr");
772 fprintf_fn (stream
, "gbr");
775 fprintf_fn (stream
, "vbr");
778 fprintf_fn (stream
, "dsr");
781 fprintf_fn (stream
, "mod");
784 fprintf_fn (stream
, "re");
787 fprintf_fn (stream
, "rs");
790 fprintf_fn (stream
, "a0");
793 fprintf_fn (stream
, "x0");
796 fprintf_fn (stream
, "x1");
799 fprintf_fn (stream
, "y0");
802 fprintf_fn (stream
, "y1");
805 print_dsp_reg (rm
, fprintf_fn
, stream
);
808 fprintf_fn (stream
, "ssr");
811 fprintf_fn (stream
, "spc");
814 fprintf_fn (stream
, "mach");
817 fprintf_fn (stream
, "macl");
820 fprintf_fn (stream
, "pr");
823 fprintf_fn (stream
, "sgr");
826 fprintf_fn (stream
, "dbr");
829 fprintf_fn (stream
, "fr%d", rn
);
832 fprintf_fn (stream
, "fr%d", rm
);
837 fprintf_fn (stream
, "xd%d", rn
& ~1);
841 fprintf_fn (stream
, "dr%d", rn
);
846 fprintf_fn (stream
, "xd%d", rm
& ~1);
850 fprintf_fn (stream
, "dr%d", rm
);
854 fprintf_fn (stream
, "fpscr");
858 fprintf_fn (stream
, "fpul");
861 fprintf_fn (stream
, "fr0");
864 fprintf_fn (stream
, "fv%d", rn
* 4);
867 fprintf_fn (stream
, "fv%d", rm
* 4);
870 fprintf_fn (stream
, "xmtrx");
878 /* This code prints instructions in delay slots on the same line
879 as the instruction which needs the delay slots. This can be
880 confusing, since other disassembler don't work this way, and
881 it means that the instructions are not all in a line. So I
883 if (!(info
->flags
& 1)
884 && (op
->name
[0] == 'j'
885 || (op
->name
[0] == 'b'
886 && (op
->name
[1] == 'r'
887 || op
->name
[1] == 's'))
888 || (op
->name
[0] == 'r' && op
->name
[1] == 't')
889 || (op
->name
[0] == 'b' && op
->name
[2] == '.')))
892 fprintf_fn (stream
, "\t(slot ");
893 print_insn_sh (memaddr
+ 2, info
);
895 fprintf_fn (stream
, ")");
900 if (disp_pc
&& strcmp (op
->name
, "mova") != 0)
905 if (relmask
== ~(bfd_vma
) 1)
909 status
= info
->read_memory_func (disp_pc_addr
, bytes
, size
, info
);
916 if (info
->endian
== BFD_ENDIAN_LITTLE
)
917 val
= bfd_getl16 (bytes
);
919 val
= bfd_getb16 (bytes
);
923 if (info
->endian
== BFD_ENDIAN_LITTLE
)
924 val
= bfd_getl32 (bytes
);
926 val
= bfd_getb32 (bytes
);
928 if ((*info
->symbol_at_address_func
) (val
, info
))
930 fprintf_fn (stream
, "\t! ");
931 (*info
->print_address_func
) (val
, info
);
934 fprintf_fn (stream
, "\t! %x", val
);
938 return SH_MERGE_ARCH_SET (op
->arch
, arch_op32
) ? 4 : 2;
943 fprintf_fn (stream
, ".word 0x%x%x%x%x", nibs
[0], nibs
[1], nibs
[2], nibs
[3]);
This page took 0.051688 seconds and 4 git commands to generate.