1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
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.
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.
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. */
28 #define INCLUDE_SHMEDIA
31 static void print_movxy
32 PARAMS ((const sh_opcode_info
*, int, int, fprintf_ftype
, void *));
33 static void print_insn_ddt
PARAMS ((int, struct disassemble_info
*));
34 static void print_dsp_reg
PARAMS ((int, fprintf_ftype
, void *));
35 static void print_insn_ppi
PARAMS ((int, struct disassemble_info
*));
38 print_movxy (op
, rn
, rm
, fprintf_fn
, stream
)
39 const sh_opcode_info
*op
;
41 fprintf_ftype fprintf_fn
;
46 fprintf_fn (stream
, "%s\t", op
->name
);
47 for (n
= 0; n
< 2; n
++)
56 fprintf_fn (stream
, "@r%d", rn
);
63 fprintf_fn (stream
, "@r%d+", rn
);
67 fprintf_fn (stream
, "@r%d+r8", rn
);
71 fprintf_fn (stream
, "@r%d+r9", rn
);
74 fprintf_fn (stream
, "a%c", '0' + rm
);
77 fprintf_fn (stream
, "x%c", '0' + rm
);
80 fprintf_fn (stream
, "y%c", '0' + rm
);
83 fprintf_fn (stream
, "%c%c",
85 (rm
& 2) ? '1' : '0');
88 fprintf_fn (stream
, "%c%c",
90 (rm
& 2) ? '1' : '0');
93 fprintf_fn (stream
, "%c%c",
95 (rm
& 1) ? '1' : '0');
98 fprintf_fn (stream
, "%c%c",
100 (rm
& 1) ? '1' : '0');
106 fprintf_fn (stream
, ",");
110 /* Print a double data transfer insn. INSN is just the lower three
111 nibbles of the insn, i.e. field a and the bit that indicates if
112 a parallel processing insn follows.
113 Return nonzero if a field b of a parallel processing insns follows. */
116 print_insn_ddt (insn
, info
)
118 struct disassemble_info
*info
;
120 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
121 void *stream
= info
->stream
;
123 /* If this is just a nop, make sure to emit something. */
125 fprintf_fn (stream
, "nopx\tnopy");
127 /* If a parallel processing insn was printed before,
128 and we got a non-nop, emit a tab. */
129 if ((insn
& 0x800) && (insn
& 0x3ff))
130 fprintf_fn (stream
, "\t");
132 /* Check if either the x or y part is invalid. */
133 if (((insn
& 0xc) == 0 && (insn
& 0x2a0))
134 || ((insn
& 3) == 0 && (insn
& 0x150)))
135 if (info
->mach
!= bfd_mach_sh_dsp
136 && info
->mach
!= bfd_mach_sh3_dsp
)
138 static const sh_opcode_info
*first_movx
, *first_movy
;
139 const sh_opcode_info
*op
;
144 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX_NOPY
;)
146 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY_NOPX
;)
150 is_movy
= ((insn
& 3) != 0);
157 while (op
->nibbles
[2] != (unsigned) ((insn
>> 4) & 3)
158 || op
->nibbles
[3] != (unsigned) (insn
& 0xf))
162 (4 * ((insn
& (is_movy
? 0x200 : 0x100)) == 0)
164 + 1 * ((insn
& (is_movy
? 0x100 : 0x200)) != 0)),
169 fprintf_fn (stream
, ".word 0x%x", insn
);
172 static const sh_opcode_info
*first_movx
, *first_movy
;
173 const sh_opcode_info
*opx
, *opy
;
174 unsigned int insn_x
, insn_y
;
178 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX
;)
180 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY
;)
183 insn_x
= (insn
>> 2) & 0xb;
186 for (opx
= first_movx
; opx
->nibbles
[2] != insn_x
;)
188 print_movxy (opx
, ((insn
>> 9) & 1) + 4, (insn
>> 7) & 1,
191 insn_y
= (insn
& 3) | ((insn
>> 1) & 8);
195 fprintf_fn (stream
, "\t");
196 for (opy
= first_movy
; opy
->nibbles
[2] != insn_y
;)
198 print_movxy (opy
, ((insn
>> 8) & 1) + 6, (insn
>> 6) & 1,
205 print_dsp_reg (rm
, fprintf_fn
, stream
)
207 fprintf_ftype fprintf_fn
;
213 fprintf_fn (stream
, "a1");
216 fprintf_fn (stream
, "a0");
219 fprintf_fn (stream
, "x0");
222 fprintf_fn (stream
, "x1");
225 fprintf_fn (stream
, "y0");
228 fprintf_fn (stream
, "y1");
231 fprintf_fn (stream
, "m0");
234 fprintf_fn (stream
, "a1g");
237 fprintf_fn (stream
, "m1");
240 fprintf_fn (stream
, "a0g");
243 fprintf_fn (stream
, "0x%x", rm
);
249 print_insn_ppi (field_b
, info
)
251 struct disassemble_info
*info
;
253 static char *sx_tab
[] = { "x0", "x1", "a0", "a1" };
254 static char *sy_tab
[] = { "y0", "y1", "m0", "m1" };
255 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
256 void *stream
= info
->stream
;
257 unsigned int nib1
, nib2
, nib3
;
258 unsigned int altnib1
, nib4
;
260 const sh_opcode_info
*op
;
262 if ((field_b
& 0xe800) == 0)
264 fprintf_fn (stream
, "psh%c\t#%d,",
265 field_b
& 0x1000 ? 'a' : 'l',
266 (field_b
>> 4) & 127);
267 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
270 if ((field_b
& 0xc000) == 0x4000 && (field_b
& 0x3000) != 0x1000)
272 static char *du_tab
[] = { "x0", "y0", "a0", "a1" };
273 static char *se_tab
[] = { "x0", "x1", "y0", "a1" };
274 static char *sf_tab
[] = { "y0", "y1", "x0", "a1" };
275 static char *sg_tab
[] = { "m0", "m1", "a0", "a1" };
277 if (field_b
& 0x2000)
279 fprintf_fn (stream
, "p%s %s,%s,%s\t",
280 (field_b
& 0x1000) ? "add" : "sub",
281 sx_tab
[(field_b
>> 6) & 3],
282 sy_tab
[(field_b
>> 4) & 3],
283 du_tab
[(field_b
>> 0) & 3]);
285 else if ((field_b
& 0xf0) == 0x10
286 && info
->mach
!= bfd_mach_sh_dsp
287 && info
->mach
!= bfd_mach_sh3_dsp
)
289 fprintf_fn (stream
, "pclr %s \t", du_tab
[(field_b
>> 0) & 3]);
291 else if ((field_b
& 0xf3) != 0)
293 fprintf_fn (stream
, ".word 0x%x\t", field_b
);
295 fprintf_fn (stream
, "pmuls%c%s,%s,%s",
296 field_b
& 0x2000 ? ' ' : '\t',
297 se_tab
[(field_b
>> 10) & 3],
298 sf_tab
[(field_b
>> 8) & 3],
299 sg_tab
[(field_b
>> 2) & 3]);
304 nib2
= field_b
>> 12 & 0xf;
305 nib3
= field_b
>> 8 & 0xf;
306 nib4
= field_b
>> 4 & 0xf;
329 for (op
= sh_table
; op
->name
; op
++)
331 if ((op
->nibbles
[1] == nib1
|| op
->nibbles
[1] == altnib1
)
332 && op
->nibbles
[2] == nib2
333 && op
->nibbles
[3] == nib3
)
337 switch (op
->nibbles
[4])
350 if ((nib4
& 0xc) != 0)
354 if ((nib4
& 0xc) != 4)
360 fprintf_fn (stream
, "%s%s\t", dc
, op
->name
);
361 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
363 if (n
&& op
->arg
[1] != A_END
)
364 fprintf_fn (stream
, ",");
368 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
371 fprintf_fn (stream
, sx_tab
[(field_b
>> 6) & 3]);
374 fprintf_fn (stream
, sy_tab
[(field_b
>> 4) & 3]);
377 fprintf_fn (stream
, "mach");
380 fprintf_fn (stream
, "macl");
390 fprintf_fn (stream
, ".word 0x%x", field_b
);
394 print_insn_sh (memaddr
, info
)
396 struct disassemble_info
*info
;
398 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
399 void *stream
= info
->stream
;
400 unsigned char insn
[4];
401 unsigned char nibs
[4];
403 bfd_vma relmask
= ~(bfd_vma
) 0;
404 const sh_opcode_info
*op
;
410 target_arch
= arch_sh1
;
411 /* SH coff object files lack information about the machine type, so
412 we end up with bfd_mach_sh unless it was set explicitly (which
413 could have happended if this is a call from gdb or the simulator.) */
415 && bfd_asymbol_flavour(*info
->symbols
) == bfd_target_coff_flavour
)
416 target_arch
= arch_sh4
;
419 target_arch
= arch_sh2
;
422 target_arch
= arch_sh2e
;
424 case bfd_mach_sh_dsp
:
425 target_arch
= arch_sh_dsp
;
428 target_arch
= arch_sh3
;
430 case bfd_mach_sh3_dsp
:
431 target_arch
= arch_sh3_dsp
;
434 target_arch
= arch_sh3e
;
436 case bfd_mach_sh4_nofpu
:
437 target_arch
= arch_sh4_nofpu
;
440 target_arch
= arch_sh4
;
443 case bfd_mach_sh4a_nofpu
:
444 target_arch
= arch_sh4a
;
446 case bfd_mach_sh4al_dsp
:
447 target_arch
= arch_sh4al_dsp
;
449 case bfd_mach_sh4_nommu_nofpu
:
450 target_arch
= arch_sh4_nommu_nofpu
;
453 #ifdef INCLUDE_SHMEDIA
454 status
= print_insn_sh64 (memaddr
, info
);
458 /* When we get here for sh64, it's because we want to disassemble
459 SHcompact, i.e. arch_sh4. */
460 target_arch
= arch_sh4
;
466 status
= info
->read_memory_func (memaddr
, insn
, 2, info
);
470 info
->memory_error_func (status
, memaddr
, info
);
474 if (info
->endian
== BFD_ENDIAN_LITTLE
)
476 nibs
[0] = (insn
[1] >> 4) & 0xf;
477 nibs
[1] = insn
[1] & 0xf;
479 nibs
[2] = (insn
[0] >> 4) & 0xf;
480 nibs
[3] = insn
[0] & 0xf;
484 nibs
[0] = (insn
[0] >> 4) & 0xf;
485 nibs
[1] = insn
[0] & 0xf;
487 nibs
[2] = (insn
[1] >> 4) & 0xf;
488 nibs
[3] = insn
[1] & 0xf;
491 if (nibs
[0] == 0xf && (nibs
[1] & 4) == 0 && target_arch
& arch_sh_dsp_up
)
497 status
= info
->read_memory_func (memaddr
+ 2, insn
, 2, info
);
501 info
->memory_error_func (status
, memaddr
+ 2, info
);
505 if (info
->endian
== BFD_ENDIAN_LITTLE
)
506 field_b
= insn
[1] << 8 | insn
[0];
508 field_b
= insn
[0] << 8 | insn
[1];
510 print_insn_ppi (field_b
, info
);
511 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
514 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
517 for (op
= sh_table
; op
->name
; op
++)
525 bfd_vma disp_pc_addr
= 0;
527 if ((op
->arch
& target_arch
) == 0)
529 for (n
= 0; n
< 4; n
++)
531 int i
= op
->nibbles
[n
];
542 imm
= (nibs
[2] << 4) | (nibs
[3]);
545 imm
= ((char) imm
) * 2 + 4;
548 imm
= ((nibs
[1]) << 8) | (nibs
[2] << 4) | (nibs
[3]);
567 imm
= (nibs
[2] << 4) | nibs
[3];
570 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
571 relmask
= ~(bfd_vma
) 1;
574 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
575 relmask
= ~(bfd_vma
) 3;
579 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
583 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
586 if ((nibs
[n
] & 1) != 0)
596 if ((nibs
[n
] & 0x3) != 1 /* binary 01 */)
598 rn
= (nibs
[n
] & 0xc) >> 2;
601 rn
= (nibs
[n
] & 0xc) >> 2;
602 rm
= (nibs
[n
] & 0x3);
608 /* sh-dsp: single data transfer. */
613 rn
|= (!(rn
& 2)) << 2;
624 fprintf_fn (stream
, "%s\t", op
->name
);
626 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
628 if (n
&& op
->arg
[1] != A_END
)
629 fprintf_fn (stream
, ",");
633 fprintf_fn (stream
, "#%d", (char) (imm
));
636 fprintf_fn (stream
, "r0");
639 fprintf_fn (stream
, "r%d", rn
);
643 fprintf_fn (stream
, "@r%d+", rn
);
647 fprintf_fn (stream
, "@-r%d", rn
);
651 fprintf_fn (stream
, "@r%d", rn
);
654 fprintf_fn (stream
, "@(%d,r%d)", imm
, rn
);
657 fprintf_fn (stream
, "@r%d+r8", rn
);
660 fprintf_fn (stream
, "r%d", rm
);
663 fprintf_fn (stream
, "@r%d+", rm
);
666 fprintf_fn (stream
, "@-r%d", rm
);
669 fprintf_fn (stream
, "@r%d", rm
);
672 fprintf_fn (stream
, "@(%d,r%d)", imm
, rm
);
675 fprintf_fn (stream
, "r%d_bank", rb
);
679 disp_pc_addr
= imm
+ 4 + (memaddr
& relmask
);
680 (*info
->print_address_func
) (disp_pc_addr
, info
);
683 fprintf_fn (stream
, "@(r0,r%d)", rn
);
686 fprintf_fn (stream
, "@(r0,r%d)", rm
);
689 fprintf_fn (stream
, "@(%d,gbr)", imm
);
692 fprintf_fn (stream
, "@(r0,gbr)");
696 (*info
->print_address_func
) (imm
+ memaddr
, info
);
699 fprintf_fn (stream
, "sr");
702 fprintf_fn (stream
, "gbr");
705 fprintf_fn (stream
, "vbr");
708 fprintf_fn (stream
, "dsr");
711 fprintf_fn (stream
, "mod");
714 fprintf_fn (stream
, "re");
717 fprintf_fn (stream
, "rs");
720 fprintf_fn (stream
, "a0");
723 fprintf_fn (stream
, "x0");
726 fprintf_fn (stream
, "x1");
729 fprintf_fn (stream
, "y0");
732 fprintf_fn (stream
, "y1");
735 print_dsp_reg (rm
, fprintf_fn
, stream
);
738 fprintf_fn (stream
, "ssr");
741 fprintf_fn (stream
, "spc");
744 fprintf_fn (stream
, "mach");
747 fprintf_fn (stream
, "macl");
750 fprintf_fn (stream
, "pr");
753 fprintf_fn (stream
, "sgr");
756 fprintf_fn (stream
, "dbr");
759 fprintf_fn (stream
, "fr%d", rn
);
762 fprintf_fn (stream
, "fr%d", rm
);
767 fprintf_fn (stream
, "xd%d", rn
& ~1);
771 fprintf_fn (stream
, "dr%d", rn
);
776 fprintf_fn (stream
, "xd%d", rm
& ~1);
780 fprintf_fn (stream
, "dr%d", rm
);
784 fprintf_fn (stream
, "fpscr");
788 fprintf_fn (stream
, "fpul");
791 fprintf_fn (stream
, "fr0");
794 fprintf_fn (stream
, "fv%d", rn
* 4);
797 fprintf_fn (stream
, "fv%d", rm
* 4);
800 fprintf_fn (stream
, "xmtrx");
808 /* This code prints instructions in delay slots on the same line
809 as the instruction which needs the delay slots. This can be
810 confusing, since other disassembler don't work this way, and
811 it means that the instructions are not all in a line. So I
813 if (!(info
->flags
& 1)
814 && (op
->name
[0] == 'j'
815 || (op
->name
[0] == 'b'
816 && (op
->name
[1] == 'r'
817 || op
->name
[1] == 's'))
818 || (op
->name
[0] == 'r' && op
->name
[1] == 't')
819 || (op
->name
[0] == 'b' && op
->name
[2] == '.')))
822 fprintf_fn (stream
, "\t(slot ");
823 print_insn_sh (memaddr
+ 2, info
);
825 fprintf_fn (stream
, ")");
830 if (disp_pc
&& strcmp (op
->name
, "mova") != 0)
835 if (relmask
== ~(bfd_vma
) 1)
839 status
= info
->read_memory_func (disp_pc_addr
, bytes
, size
, info
);
846 if (info
->endian
== BFD_ENDIAN_LITTLE
)
847 val
= bfd_getl16 (bytes
);
849 val
= bfd_getb16 (bytes
);
853 if (info
->endian
== BFD_ENDIAN_LITTLE
)
854 val
= bfd_getl32 (bytes
);
856 val
= bfd_getb32 (bytes
);
858 fprintf_fn (stream
, "\t! 0x%x", val
);
867 fprintf_fn (stream
, ".word 0x%x%x%x%x", nibs
[0], nibs
[1], nibs
[2], nibs
[3]);