1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002
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
++)
52 fprintf_fn (stream
, "@r%d", rn
);
55 fprintf_fn (stream
, "@r%d+", rn
);
58 fprintf_fn (stream
, "@r%d+r8", rn
);
61 fprintf_fn (stream
, "@r%d+r9", rn
);
64 fprintf_fn (stream
, "a%c", '0' + rm
);
67 fprintf_fn (stream
, "x%c", '0' + rm
);
70 fprintf_fn (stream
, "y%c", '0' + rm
);
76 fprintf_fn (stream
, ",");
80 /* Print a double data transfer insn. INSN is just the lower three
81 nibbles of the insn, i.e. field a and the bit that indicates if
82 a parallel processing insn follows.
83 Return nonzero if a field b of a parallel processing insns follows. */
86 print_insn_ddt (insn
, info
)
88 struct disassemble_info
*info
;
90 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
91 void *stream
= info
->stream
;
93 /* If this is just a nop, make sure to emit something. */
95 fprintf_fn (stream
, "nopx\tnopy");
97 /* If a parallel processing insn was printed before,
98 and we got a non-nop, emit a tab. */
99 if ((insn
& 0x800) && (insn
& 0x3ff))
100 fprintf_fn (stream
, "\t");
102 /* Check if either the x or y part is invalid. */
103 if (((insn
& 0xc) == 0 && (insn
& 0x2a0))
104 || ((insn
& 3) == 0 && (insn
& 0x150)))
105 fprintf_fn (stream
, ".word 0x%x", insn
);
108 static const sh_opcode_info
*first_movx
, *first_movy
;
109 const sh_opcode_info
*opx
, *opy
;
110 unsigned int insn_x
, insn_y
;
114 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX
;)
116 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY
;)
119 insn_x
= (insn
>> 2) & 0xb;
122 for (opx
= first_movx
; opx
->nibbles
[2] != insn_x
;)
124 print_movxy (opx
, ((insn
>> 9) & 1) + 4, (insn
>> 7) & 1,
127 insn_y
= (insn
& 3) | ((insn
>> 1) & 8);
131 fprintf_fn (stream
, "\t");
132 for (opy
= first_movy
; opy
->nibbles
[2] != insn_y
;)
134 print_movxy (opy
, ((insn
>> 8) & 1) + 6, (insn
>> 6) & 1,
141 print_dsp_reg (rm
, fprintf_fn
, stream
)
143 fprintf_ftype fprintf_fn
;
149 fprintf_fn (stream
, "a1");
152 fprintf_fn (stream
, "a0");
155 fprintf_fn (stream
, "x0");
158 fprintf_fn (stream
, "x1");
161 fprintf_fn (stream
, "y0");
164 fprintf_fn (stream
, "y1");
167 fprintf_fn (stream
, "m0");
170 fprintf_fn (stream
, "a1g");
173 fprintf_fn (stream
, "m1");
176 fprintf_fn (stream
, "a0g");
179 fprintf_fn (stream
, "0x%x", rm
);
185 print_insn_ppi (field_b
, info
)
187 struct disassemble_info
*info
;
189 static char *sx_tab
[] = { "x0", "x1", "a0", "a1" };
190 static char *sy_tab
[] = { "y0", "y1", "m0", "m1" };
191 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
192 void *stream
= info
->stream
;
193 unsigned int nib1
, nib2
, nib3
;
195 const sh_opcode_info
*op
;
197 if ((field_b
& 0xe800) == 0)
199 fprintf_fn (stream
, "psh%c\t#%d,",
200 field_b
& 0x1000 ? 'a' : 'l',
201 (field_b
>> 4) & 127);
202 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
205 if ((field_b
& 0xc000) == 0x4000 && (field_b
& 0x3000) != 0x1000)
207 static char *du_tab
[] = { "x0", "y0", "a0", "a1" };
208 static char *se_tab
[] = { "x0", "x1", "y0", "a1" };
209 static char *sf_tab
[] = { "y0", "y1", "x0", "a1" };
210 static char *sg_tab
[] = { "m0", "m1", "a0", "a1" };
212 if (field_b
& 0x2000)
214 fprintf_fn (stream
, "p%s %s,%s,%s\t",
215 (field_b
& 0x1000) ? "add" : "sub",
216 sx_tab
[(field_b
>> 6) & 3],
217 sy_tab
[(field_b
>> 4) & 3],
218 du_tab
[(field_b
>> 0) & 3]);
220 fprintf_fn (stream
, "pmuls%c%s,%s,%s",
221 field_b
& 0x2000 ? ' ' : '\t',
222 se_tab
[(field_b
>> 10) & 3],
223 sf_tab
[(field_b
>> 8) & 3],
224 sg_tab
[(field_b
>> 2) & 3]);
229 nib2
= field_b
>> 12 & 0xf;
230 nib3
= field_b
>> 8 & 0xf;
249 for (op
= sh_table
; op
->name
; op
++)
251 if (op
->nibbles
[1] == nib1
252 && op
->nibbles
[2] == nib2
253 && op
->nibbles
[3] == nib3
)
257 fprintf_fn (stream
, "%s%s\t", dc
, op
->name
);
258 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
260 if (n
&& op
->arg
[1] != A_END
)
261 fprintf_fn (stream
, ",");
265 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
268 fprintf_fn (stream
, sx_tab
[(field_b
>> 6) & 3]);
271 fprintf_fn (stream
, sy_tab
[(field_b
>> 4) & 3]);
274 fprintf_fn (stream
, "mach");
277 fprintf_fn (stream
, "macl");
287 fprintf_fn (stream
, ".word 0x%x", field_b
);
291 print_insn_sh (memaddr
, info
)
293 struct disassemble_info
*info
;
295 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
296 void *stream
= info
->stream
;
297 unsigned char insn
[2];
298 unsigned char nibs
[4];
300 bfd_vma relmask
= ~(bfd_vma
) 0;
301 const sh_opcode_info
*op
;
307 target_arch
= arch_sh1
;
308 /* SH coff object files lack information about the machine type, so
309 we end up with bfd_mach_sh unless it was set explicitly (which
310 could have happended if this is a call from gdb or the simulator.) */
312 && bfd_asymbol_flavour(*info
->symbols
) == bfd_target_coff_flavour
)
313 target_arch
= arch_sh4
;
316 target_arch
= arch_sh2
;
318 case bfd_mach_sh_dsp
:
319 target_arch
= arch_sh_dsp
;
322 target_arch
= arch_sh3
;
324 case bfd_mach_sh3_dsp
:
325 target_arch
= arch_sh3_dsp
;
328 target_arch
= arch_sh3e
;
331 target_arch
= arch_sh4
;
334 #ifdef INCLUDE_SHMEDIA
335 status
= print_insn_sh64 (memaddr
, info
);
339 /* When we get here for sh64, it's because we want to disassemble
340 SHcompact, i.e. arch_sh4. */
341 target_arch
= arch_sh4
;
347 status
= info
->read_memory_func (memaddr
, insn
, 2, info
);
351 info
->memory_error_func (status
, memaddr
, info
);
355 if (info
->endian
== BFD_ENDIAN_LITTLE
)
357 nibs
[0] = (insn
[1] >> 4) & 0xf;
358 nibs
[1] = insn
[1] & 0xf;
360 nibs
[2] = (insn
[0] >> 4) & 0xf;
361 nibs
[3] = insn
[0] & 0xf;
365 nibs
[0] = (insn
[0] >> 4) & 0xf;
366 nibs
[1] = insn
[0] & 0xf;
368 nibs
[2] = (insn
[1] >> 4) & 0xf;
369 nibs
[3] = insn
[1] & 0xf;
372 if (nibs
[0] == 0xf && (nibs
[1] & 4) == 0 && target_arch
& arch_sh_dsp_up
)
378 status
= info
->read_memory_func (memaddr
+ 2, insn
, 2, info
);
382 info
->memory_error_func (status
, memaddr
+ 2, info
);
386 if (info
->endian
== BFD_ENDIAN_LITTLE
)
387 field_b
= insn
[1] << 8 | insn
[0];
389 field_b
= insn
[0] << 8 | insn
[1];
391 print_insn_ppi (field_b
, info
);
392 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
395 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
398 for (op
= sh_table
; op
->name
; op
++)
406 bfd_vma disp_pc_addr
= 0;
408 if ((op
->arch
& target_arch
) == 0)
410 for (n
= 0; n
< 4; n
++)
412 int i
= op
->nibbles
[n
];
423 imm
= (nibs
[2] << 4) | (nibs
[3]);
426 imm
= ((char) imm
) * 2 + 4;
429 imm
= ((nibs
[1]) << 8) | (nibs
[2] << 4) | (nibs
[3]);
448 imm
= (nibs
[2] << 4) | nibs
[3];
451 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
452 relmask
= ~(bfd_vma
) 1;
455 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
456 relmask
= ~(bfd_vma
) 3;
460 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
464 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
473 rn
= (nibs
[n
] & 0xc) >> 2;
474 rm
= (nibs
[n
] & 0x3);
480 /* sh-dsp: single data transfer. */
485 rn
|= (!(rn
& 2)) << 2;
496 fprintf_fn (stream
, "%s\t", op
->name
);
498 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
500 if (n
&& op
->arg
[1] != A_END
)
501 fprintf_fn (stream
, ",");
505 fprintf_fn (stream
, "#%d", (char) (imm
));
508 fprintf_fn (stream
, "r0");
511 fprintf_fn (stream
, "r%d", rn
);
514 fprintf_fn (stream
, "@r%d+", rn
);
517 fprintf_fn (stream
, "@-r%d", rn
);
520 fprintf_fn (stream
, "@r%d", rn
);
523 fprintf_fn (stream
, "@(%d,r%d)", imm
, rn
);
526 fprintf_fn (stream
, "@r%d+r8", rn
);
529 fprintf_fn (stream
, "r%d", rm
);
532 fprintf_fn (stream
, "@r%d+", rm
);
535 fprintf_fn (stream
, "@-r%d", rm
);
538 fprintf_fn (stream
, "@r%d", rm
);
541 fprintf_fn (stream
, "@(%d,r%d)", imm
, rm
);
544 fprintf_fn (stream
, "r%d_bank", rb
);
548 disp_pc_addr
= imm
+ 4 + (memaddr
& relmask
);
549 (*info
->print_address_func
) (disp_pc_addr
, info
);
552 fprintf_fn (stream
, "@(r0,r%d)", rn
);
555 fprintf_fn (stream
, "@(r0,r%d)", rm
);
558 fprintf_fn (stream
, "@(%d,gbr)", imm
);
561 fprintf_fn (stream
, "@(r0,gbr)");
565 (*info
->print_address_func
) (imm
+ memaddr
, info
);
568 fprintf_fn (stream
, "sr");
571 fprintf_fn (stream
, "gbr");
574 fprintf_fn (stream
, "vbr");
577 fprintf_fn (stream
, "dsr");
580 fprintf_fn (stream
, "mod");
583 fprintf_fn (stream
, "re");
586 fprintf_fn (stream
, "rs");
589 fprintf_fn (stream
, "a0");
592 fprintf_fn (stream
, "x0");
595 fprintf_fn (stream
, "x1");
598 fprintf_fn (stream
, "y0");
601 fprintf_fn (stream
, "y1");
604 print_dsp_reg (rm
, fprintf_fn
, stream
);
607 fprintf_fn (stream
, "ssr");
610 fprintf_fn (stream
, "spc");
613 fprintf_fn (stream
, "mach");
616 fprintf_fn (stream
, "macl");
619 fprintf_fn (stream
, "pr");
622 fprintf_fn (stream
, "sgr");
625 fprintf_fn (stream
, "dbr");
628 fprintf_fn (stream
, "fr%d", rn
);
631 fprintf_fn (stream
, "fr%d", rm
);
636 fprintf_fn (stream
, "xd%d", rn
& ~1);
640 fprintf_fn (stream
, "dr%d", rn
);
645 fprintf_fn (stream
, "xd%d", rm
& ~1);
649 fprintf_fn (stream
, "dr%d", rm
);
653 fprintf_fn (stream
, "fpscr");
657 fprintf_fn (stream
, "fpul");
660 fprintf_fn (stream
, "fr0");
663 fprintf_fn (stream
, "fv%d", rn
* 4);
666 fprintf_fn (stream
, "fv%d", rm
* 4);
669 fprintf_fn (stream
, "xmtrx");
677 /* This code prints instructions in delay slots on the same line
678 as the instruction which needs the delay slots. This can be
679 confusing, since other disassembler don't work this way, and
680 it means that the instructions are not all in a line. So I
682 if (!(info
->flags
& 1)
683 && (op
->name
[0] == 'j'
684 || (op
->name
[0] == 'b'
685 && (op
->name
[1] == 'r'
686 || op
->name
[1] == 's'))
687 || (op
->name
[0] == 'r' && op
->name
[1] == 't')
688 || (op
->name
[0] == 'b' && op
->name
[2] == '.')))
691 fprintf_fn (stream
, "\t(slot ");
692 print_insn_sh (memaddr
+ 2, info
);
694 fprintf_fn (stream
, ")");
699 if (disp_pc
&& strcmp (op
->name
, "mova") != 0)
704 if (relmask
== ~(bfd_vma
) 1)
708 status
= info
->read_memory_func (disp_pc_addr
, bytes
, size
, info
);
715 if (info
->endian
== BFD_ENDIAN_LITTLE
)
716 val
= bfd_getl16 (bytes
);
718 val
= bfd_getb16 (bytes
);
722 if (info
->endian
== BFD_ENDIAN_LITTLE
)
723 val
= bfd_getl32 (bytes
);
725 val
= bfd_getb32 (bytes
);
727 fprintf_fn (stream
, "\t! 0x%x", val
);
736 fprintf_fn (stream
, ".word 0x%x%x%x%x", nibs
[0], nibs
[1], nibs
[2], nibs
[3]);