1 /* Disassemble SH instructions.
2 Copyright (C) 1993-2019 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)
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. */
28 #include "disassemble.h"
31 print_movxy (const sh_opcode_info
*op
,
34 fprintf_ftype fprintf_fn
,
39 fprintf_fn (stream
, "%s\t", op
->name
);
40 for (n
= 0; n
< 2; n
++)
49 fprintf_fn (stream
, "@r%d", rn
);
56 fprintf_fn (stream
, "@r%d+", rn
);
60 fprintf_fn (stream
, "@r%d+r8", rn
);
64 fprintf_fn (stream
, "@r%d+r9", rn
);
67 fprintf_fn (stream
, "a%c", '0' + rm
);
70 fprintf_fn (stream
, "x%c", '0' + rm
);
73 fprintf_fn (stream
, "y%c", '0' + rm
);
76 fprintf_fn (stream
, "%c%c",
78 (rm
& 2) ? '1' : '0');
81 fprintf_fn (stream
, "%c%c",
83 (rm
& 2) ? '1' : '0');
86 fprintf_fn (stream
, "%c%c",
88 (rm
& 1) ? '1' : '0');
91 fprintf_fn (stream
, "%c%c",
93 (rm
& 1) ? '1' : '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.
106 Return nonzero if a field b of a parallel processing insns follows. */
109 print_insn_ddt (int insn
, struct disassemble_info
*info
)
111 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
112 void *stream
= info
->stream
;
114 /* If this is just a nop, make sure to emit something. */
116 fprintf_fn (stream
, "nopx\tnopy");
118 /* If a parallel processing insn was printed before,
119 and we got a non-nop, emit a tab. */
120 if ((insn
& 0x800) && (insn
& 0x3ff))
121 fprintf_fn (stream
, "\t");
123 /* Check if either the x or y part is invalid. */
124 if (((insn
& 0xc) == 0 && (insn
& 0x2a0))
125 || ((insn
& 3) == 0 && (insn
& 0x150)))
126 if (info
->mach
!= bfd_mach_sh_dsp
127 && info
->mach
!= bfd_mach_sh3_dsp
)
129 static const sh_opcode_info
*first_movx
, *first_movy
;
130 const sh_opcode_info
*op
;
135 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX_NOPY
;)
137 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY_NOPX
;)
141 is_movy
= ((insn
& 3) != 0);
148 while (op
->nibbles
[2] != (unsigned) ((insn
>> 4) & 3)
149 || op
->nibbles
[3] != (unsigned) (insn
& 0xf))
153 (4 * ((insn
& (is_movy
? 0x200 : 0x100)) == 0)
155 + 1 * ((insn
& (is_movy
? 0x100 : 0x200)) != 0)),
160 fprintf_fn (stream
, ".word 0x%x", insn
);
163 static const sh_opcode_info
*first_movx
, *first_movy
;
164 const sh_opcode_info
*opx
, *opy
;
165 unsigned int insn_x
, insn_y
;
169 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX
;)
171 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY
;)
174 insn_x
= (insn
>> 2) & 0xb;
177 for (opx
= first_movx
; opx
->nibbles
[2] != insn_x
;)
179 print_movxy (opx
, ((insn
>> 9) & 1) + 4, (insn
>> 7) & 1,
182 insn_y
= (insn
& 3) | ((insn
>> 1) & 8);
186 fprintf_fn (stream
, "\t");
187 for (opy
= first_movy
; opy
->nibbles
[2] != insn_y
;)
189 print_movxy (opy
, ((insn
>> 8) & 1) + 6, (insn
>> 6) & 1,
196 print_dsp_reg (int rm
, fprintf_ftype fprintf_fn
, void *stream
)
201 fprintf_fn (stream
, "a1");
204 fprintf_fn (stream
, "a0");
207 fprintf_fn (stream
, "x0");
210 fprintf_fn (stream
, "x1");
213 fprintf_fn (stream
, "y0");
216 fprintf_fn (stream
, "y1");
219 fprintf_fn (stream
, "m0");
222 fprintf_fn (stream
, "a1g");
225 fprintf_fn (stream
, "m1");
228 fprintf_fn (stream
, "a0g");
231 fprintf_fn (stream
, "0x%x", rm
);
237 print_insn_ppi (int field_b
, struct disassemble_info
*info
)
239 static char *sx_tab
[] = { "x0", "x1", "a0", "a1" };
240 static char *sy_tab
[] = { "y0", "y1", "m0", "m1" };
241 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
242 void *stream
= info
->stream
;
243 unsigned int nib1
, nib2
, nib3
;
244 unsigned int altnib1
, nib4
;
246 const sh_opcode_info
*op
;
248 if ((field_b
& 0xe800) == 0)
250 fprintf_fn (stream
, "psh%c\t#%d,",
251 field_b
& 0x1000 ? 'a' : 'l',
252 (field_b
>> 4) & 127);
253 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
256 if ((field_b
& 0xc000) == 0x4000 && (field_b
& 0x3000) != 0x1000)
258 static char *du_tab
[] = { "x0", "y0", "a0", "a1" };
259 static char *se_tab
[] = { "x0", "x1", "y0", "a1" };
260 static char *sf_tab
[] = { "y0", "y1", "x0", "a1" };
261 static char *sg_tab
[] = { "m0", "m1", "a0", "a1" };
263 if (field_b
& 0x2000)
264 fprintf_fn (stream
, "p%s %s,%s,%s\t",
265 (field_b
& 0x1000) ? "add" : "sub",
266 sx_tab
[(field_b
>> 6) & 3],
267 sy_tab
[(field_b
>> 4) & 3],
268 du_tab
[(field_b
>> 0) & 3]);
270 else if ((field_b
& 0xf0) == 0x10
271 && info
->mach
!= bfd_mach_sh_dsp
272 && info
->mach
!= bfd_mach_sh3_dsp
)
273 fprintf_fn (stream
, "pclr %s \t", du_tab
[(field_b
>> 0) & 3]);
275 else if ((field_b
& 0xf3) != 0)
276 fprintf_fn (stream
, ".word 0x%x\t", field_b
);
278 fprintf_fn (stream
, "pmuls%c%s,%s,%s",
279 field_b
& 0x2000 ? ' ' : '\t',
280 se_tab
[(field_b
>> 10) & 3],
281 sf_tab
[(field_b
>> 8) & 3],
282 sg_tab
[(field_b
>> 2) & 3]);
287 nib2
= field_b
>> 12 & 0xf;
288 nib3
= field_b
>> 8 & 0xf;
289 nib4
= field_b
>> 4 & 0xf;
312 for (op
= sh_table
; op
->name
; op
++)
314 if ((op
->nibbles
[1] == nib1
|| op
->nibbles
[1] == altnib1
)
315 && op
->nibbles
[2] == nib2
316 && op
->nibbles
[3] == nib3
)
320 switch (op
->nibbles
[4])
333 if ((nib4
& 0xc) != 0)
337 if ((nib4
& 0xc) != 4)
343 fprintf_fn (stream
, "%s%s\t", dc
, op
->name
);
344 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
346 if (n
&& op
->arg
[1] != A_END
)
347 fprintf_fn (stream
, ",");
351 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
354 fprintf_fn (stream
, "%s", sx_tab
[(field_b
>> 6) & 3]);
357 fprintf_fn (stream
, "%s", sy_tab
[(field_b
>> 4) & 3]);
360 fprintf_fn (stream
, "mach");
363 fprintf_fn (stream
, "macl");
373 fprintf_fn (stream
, ".word 0x%x", field_b
);
376 /* FIXME mvs: movx insns print as ".word 0x%03x", insn & 0xfff
377 (ie. the upper nibble is missing). */
380 print_insn_sh (bfd_vma memaddr
, struct disassemble_info
*info
)
382 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
383 void *stream
= info
->stream
;
384 unsigned char insn
[4];
385 unsigned char nibs
[8];
387 bfd_vma relmask
= ~(bfd_vma
) 0;
388 const sh_opcode_info
*op
;
389 unsigned int target_arch
;
395 target_arch
= arch_sh1
;
396 /* SH coff object files lack information about the machine type, so
397 we end up with bfd_mach_sh unless it was set explicitly (which
398 could have happended if this is a call from gdb or the simulator.) */
400 && bfd_asymbol_flavour(*info
->symbols
) == bfd_target_coff_flavour
)
401 target_arch
= arch_sh4
;
404 target_arch
= sh_get_arch_from_bfd_mach (info
->mach
);
407 status
= info
->read_memory_func (memaddr
, insn
, 2, info
);
411 info
->memory_error_func (status
, memaddr
, info
);
415 if (info
->endian
== BFD_ENDIAN_LITTLE
)
417 nibs
[0] = (insn
[1] >> 4) & 0xf;
418 nibs
[1] = insn
[1] & 0xf;
420 nibs
[2] = (insn
[0] >> 4) & 0xf;
421 nibs
[3] = insn
[0] & 0xf;
425 nibs
[0] = (insn
[0] >> 4) & 0xf;
426 nibs
[1] = insn
[0] & 0xf;
428 nibs
[2] = (insn
[1] >> 4) & 0xf;
429 nibs
[3] = insn
[1] & 0xf;
431 status
= info
->read_memory_func (memaddr
+ 2, insn
+ 2, 2, info
);
438 if (info
->endian
== BFD_ENDIAN_LITTLE
)
440 nibs
[4] = (insn
[3] >> 4) & 0xf;
441 nibs
[5] = insn
[3] & 0xf;
443 nibs
[6] = (insn
[2] >> 4) & 0xf;
444 nibs
[7] = insn
[2] & 0xf;
448 nibs
[4] = (insn
[2] >> 4) & 0xf;
449 nibs
[5] = insn
[2] & 0xf;
451 nibs
[6] = (insn
[3] >> 4) & 0xf;
452 nibs
[7] = insn
[3] & 0xf;
456 if (nibs
[0] == 0xf && (nibs
[1] & 4) == 0
457 && SH_MERGE_ARCH_SET_VALID (target_arch
, arch_sh_dsp_up
))
463 status
= info
->read_memory_func (memaddr
+ 2, insn
, 2, info
);
467 info
->memory_error_func (status
, memaddr
+ 2, info
);
471 if (info
->endian
== BFD_ENDIAN_LITTLE
)
472 field_b
= insn
[1] << 8 | insn
[0];
474 field_b
= insn
[0] << 8 | insn
[1];
476 print_insn_ppi (field_b
, info
);
477 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
480 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
483 for (op
= sh_table
; op
->name
; op
++)
491 bfd_vma disp_pc_addr
= 0;
494 int max_n
= SH_MERGE_ARCH_SET (op
->arch
, arch_op32
) ? 8 : 4;
497 && SH_MERGE_ARCH_SET (op
->arch
, arch_op32
))
500 if (!SH_MERGE_ARCH_SET_VALID (op
->arch
, target_arch
))
502 for (n
= 0; n
< max_n
; n
++)
504 int i
= op
->nibbles
[n
];
515 imm
= (nibs
[2] << 4) | (nibs
[3]);
518 imm
= ((char) imm
) * 2 + 4;
521 imm
= ((nibs
[1]) << 8) | (nibs
[2] << 4) | (nibs
[3]);
532 if (!(nibs
[3] & 0x8))
542 if (!(nibs
[2] & 0x8))
548 disp
= (nibs
[5] << 8) | (nibs
[6] << 4) | nibs
[7];
553 disp
= ((nibs
[5] << 8) | (nibs
[6] << 4) | nibs
[7]) << 1;
554 relmask
= ~(bfd_vma
) 1;
559 disp
= ((nibs
[5] << 8) | (nibs
[6] << 4) | nibs
[7]) << 2;
560 relmask
= ~(bfd_vma
) 3;
565 disp
= ((nibs
[5] << 8) | (nibs
[6] << 4) | nibs
[7]) << 3;
566 relmask
= ~(bfd_vma
) 7;
572 imm
= ((nibs
[2] << 16) | (nibs
[4] << 12) | (nibs
[5] << 8)
573 | (nibs
[6] << 4) | nibs
[7]);
578 imm
= ((nibs
[2] << 16) | (nibs
[4] << 12) | (nibs
[5] << 8)
579 | (nibs
[6] << 4) | nibs
[7]);
598 imm
= (nibs
[2] << 4) | nibs
[3];
605 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
606 relmask
= ~(bfd_vma
) 1;
609 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
610 relmask
= ~(bfd_vma
) 3;
614 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
618 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
621 if ((nibs
[n
] & 1) != 0)
631 if ((nibs
[n
] & 0x3) != 1 /* binary 01 */)
633 rn
= (nibs
[n
] & 0xc) >> 2;
636 rn
= (nibs
[n
] & 0xc) >> 2;
637 rm
= (nibs
[n
] & 0x3);
643 /* sh-dsp: single data transfer. */
648 rn
|= (!(rn
& 2)) << 2;
659 /* sh2a has D_REG but not X_REG. We don't know the pattern
660 doesn't match unless we check the output args to see if they
662 if (target_arch
== arch_sh2a
663 && ((op
->arg
[0] == DX_REG_M
&& (rm
& 1) != 0)
664 || (op
->arg
[1] == DX_REG_N
&& (rn
& 1) != 0)))
667 fprintf_fn (stream
, "%s\t", op
->name
);
669 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
671 if (n
&& op
->arg
[1] != A_END
)
672 fprintf_fn (stream
, ",");
676 fprintf_fn (stream
, "#%d", imm
);
679 fprintf_fn (stream
, "r0");
682 fprintf_fn (stream
, "r%d", rn
);
686 fprintf_fn (stream
, "@r%d+", rn
);
690 fprintf_fn (stream
, "@-r%d", rn
);
694 fprintf_fn (stream
, "@r%d", rn
);
697 fprintf_fn (stream
, "@(%d,r%d)", has_disp
?disp
:imm
, rn
);
700 fprintf_fn (stream
, "@r%d+r8", rn
);
703 fprintf_fn (stream
, "r%d", rm
);
706 fprintf_fn (stream
, "@r%d+", rm
);
709 fprintf_fn (stream
, "@-r%d", rm
);
712 fprintf_fn (stream
, "@r%d", rm
);
715 fprintf_fn (stream
, "@(%d,r%d)", has_disp
?disp
:imm
, rm
);
718 fprintf_fn (stream
, "r%d_bank", rb
);
722 disp_pc_addr
= imm
+ 4 + (memaddr
& relmask
);
723 (*info
->print_address_func
) (disp_pc_addr
, info
);
726 fprintf_fn (stream
, "@(r0,r%d)", rn
);
729 fprintf_fn (stream
, "@(r0,r%d)", rm
);
732 fprintf_fn (stream
, "@(%d,gbr)", has_disp
?disp
:imm
);
735 fprintf_fn (stream
, "tbr");
738 fprintf_fn (stream
, "@@(%d,tbr)", has_disp
?disp
:imm
);
741 fprintf_fn (stream
, "@r15+");
744 fprintf_fn (stream
, "@-r15");
747 fprintf_fn (stream
, "@(r0,gbr)");
751 (*info
->print_address_func
) (imm
+ memaddr
, info
);
754 fprintf_fn (stream
, "sr");
757 fprintf_fn (stream
, "gbr");
760 fprintf_fn (stream
, "vbr");
763 fprintf_fn (stream
, "dsr");
766 fprintf_fn (stream
, "mod");
769 fprintf_fn (stream
, "re");
772 fprintf_fn (stream
, "rs");
775 fprintf_fn (stream
, "a0");
778 fprintf_fn (stream
, "x0");
781 fprintf_fn (stream
, "x1");
784 fprintf_fn (stream
, "y0");
787 fprintf_fn (stream
, "y1");
790 print_dsp_reg (rm
, fprintf_fn
, stream
);
793 fprintf_fn (stream
, "ssr");
796 fprintf_fn (stream
, "spc");
799 fprintf_fn (stream
, "mach");
802 fprintf_fn (stream
, "macl");
805 fprintf_fn (stream
, "pr");
808 fprintf_fn (stream
, "sgr");
811 fprintf_fn (stream
, "dbr");
814 fprintf_fn (stream
, "fr%d", rn
);
817 fprintf_fn (stream
, "fr%d", rm
);
822 fprintf_fn (stream
, "xd%d", rn
& ~1);
827 fprintf_fn (stream
, "dr%d", rn
);
832 fprintf_fn (stream
, "xd%d", rm
& ~1);
837 fprintf_fn (stream
, "dr%d", rm
);
841 fprintf_fn (stream
, "fpscr");
845 fprintf_fn (stream
, "fpul");
848 fprintf_fn (stream
, "fr0");
851 fprintf_fn (stream
, "fv%d", rn
* 4);
854 fprintf_fn (stream
, "fv%d", rm
* 4);
857 fprintf_fn (stream
, "xmtrx");
865 /* This code prints instructions in delay slots on the same line
866 as the instruction which needs the delay slots. This can be
867 confusing, since other disassembler don't work this way, and
868 it means that the instructions are not all in a line. So I
870 if (!(info
->flags
& 1)
871 && (op
->name
[0] == 'j'
872 || (op
->name
[0] == 'b'
873 && (op
->name
[1] == 'r'
874 || op
->name
[1] == 's'))
875 || (op
->name
[0] == 'r' && op
->name
[1] == 't')
876 || (op
->name
[0] == 'b' && op
->name
[2] == '.')))
879 fprintf_fn (stream
, "\t(slot ");
880 print_insn_sh (memaddr
+ 2, info
);
882 fprintf_fn (stream
, ")");
887 if (disp_pc
&& strcmp (op
->name
, "mova") != 0)
892 if (relmask
== ~(bfd_vma
) 1)
896 /* Not reading an instruction - disable stop_vma. */
898 status
= info
->read_memory_func (disp_pc_addr
, bytes
, size
, info
);
905 if (info
->endian
== BFD_ENDIAN_LITTLE
)
906 val
= bfd_getl16 (bytes
);
908 val
= bfd_getb16 (bytes
);
912 if (info
->endian
== BFD_ENDIAN_LITTLE
)
913 val
= bfd_getl32 (bytes
);
915 val
= bfd_getb32 (bytes
);
917 if ((*info
->symbol_at_address_func
) (val
, info
))
919 fprintf_fn (stream
, "\t! ");
920 (*info
->print_address_func
) (val
, info
);
923 fprintf_fn (stream
, "\t! %x", val
);
927 return SH_MERGE_ARCH_SET (op
->arch
, arch_op32
) ? 4 : 2;
932 fprintf_fn (stream
, ".word 0x%x%x%x%x", nibs
[0], nibs
[1], nibs
[2], nibs
[3]);
This page took 0.052425 seconds and 4 git commands to generate.