1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001
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. */
29 static void print_movxy
30 PARAMS ((sh_opcode_info
*, int, int, fprintf_ftype
, void *));
31 static void print_insn_ddt
PARAMS ((int, struct disassemble_info
*));
32 static void print_dsp_reg
PARAMS ((int, fprintf_ftype
, void *));
33 static void print_insn_ppi
PARAMS ((int, struct disassemble_info
*));
34 static int print_insn_shx
PARAMS ((bfd_vma
, struct disassemble_info
*));
37 print_movxy (op
, rn
, rm
, fprintf_fn
, stream
)
40 fprintf_ftype fprintf_fn
;
45 fprintf_fn (stream
, "%s\t", op
->name
);
46 for (n
= 0; n
< 2; n
++)
51 fprintf_fn (stream
, "@r%d", rn
);
54 fprintf_fn (stream
, "@r%d+", rn
);
57 fprintf_fn (stream
, "@r%d+r8", rn
);
60 fprintf_fn (stream
, "@r%d+r9", rn
);
63 fprintf_fn (stream
, "a%c", '0' + rm
);
66 fprintf_fn (stream
, "x%c", '0' + rm
);
69 fprintf_fn (stream
, "y%c", '0' + rm
);
75 fprintf_fn (stream
, ",");
79 /* Print a double data transfer insn. INSN is just the lower three
80 nibbles of the insn, i.e. field a and the bit that indicates if
81 a parallel processing insn follows.
82 Return nonzero if a field b of a parallel processing insns follows. */
85 print_insn_ddt (insn
, info
)
87 struct disassemble_info
*info
;
89 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
90 void *stream
= info
->stream
;
92 /* If this is just a nop, make sure to emit something. */
94 fprintf_fn (stream
, "nopx\tnopy");
96 /* If a parallel processing insn was printed before,
97 and we got a non-nop, emit a tab. */
98 if ((insn
& 0x800) && (insn
& 0x3ff))
99 fprintf_fn (stream
, "\t");
101 /* Check if either the x or y part is invalid. */
102 if (((insn
& 0xc) == 0 && (insn
& 0x2a0))
103 || ((insn
& 3) == 0 && (insn
& 0x150)))
104 fprintf_fn (stream
, ".word 0x%x", insn
);
107 static sh_opcode_info
*first_movx
, *first_movy
;
108 sh_opcode_info
*opx
, *opy
;
109 unsigned int insn_x
, insn_y
;
113 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX
;)
115 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY
;)
118 insn_x
= (insn
>> 2) & 0xb;
121 for (opx
= first_movx
; opx
->nibbles
[2] != insn_x
;)
123 print_movxy (opx
, ((insn
>> 9) & 1) + 4, (insn
>> 7) & 1,
126 insn_y
= (insn
& 3) | ((insn
>> 1) & 8);
130 fprintf_fn (stream
, "\t");
131 for (opy
= first_movy
; opy
->nibbles
[2] != insn_y
;)
133 print_movxy (opy
, ((insn
>> 8) & 1) + 6, (insn
>> 6) & 1,
140 print_dsp_reg (rm
, fprintf_fn
, stream
)
142 fprintf_ftype fprintf_fn
;
148 fprintf_fn (stream
, "a1");
151 fprintf_fn (stream
, "a0");
154 fprintf_fn (stream
, "x0");
157 fprintf_fn (stream
, "x1");
160 fprintf_fn (stream
, "y0");
163 fprintf_fn (stream
, "y1");
166 fprintf_fn (stream
, "m0");
169 fprintf_fn (stream
, "a1g");
172 fprintf_fn (stream
, "m1");
175 fprintf_fn (stream
, "a0g");
178 fprintf_fn (stream
, "0x%x", rm
);
184 print_insn_ppi (field_b
, info
)
186 struct disassemble_info
*info
;
188 static char *sx_tab
[] = { "x0", "x1", "a0", "a1" };
189 static char *sy_tab
[] = { "y0", "y1", "m0", "m1" };
190 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
191 void *stream
= info
->stream
;
192 unsigned int nib1
, nib2
, nib3
;
196 if ((field_b
& 0xe800) == 0)
198 fprintf_fn (stream
, "psh%c\t#%d,",
199 field_b
& 0x1000 ? 'a' : 'l',
200 (field_b
>> 4) & 127);
201 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
204 if ((field_b
& 0xc000) == 0x4000 && (field_b
& 0x3000) != 0x1000)
206 static char *du_tab
[] = { "x0", "y0", "a0", "a1" };
207 static char *se_tab
[] = { "x0", "x1", "y0", "a1" };
208 static char *sf_tab
[] = { "y0", "y1", "x0", "a1" };
209 static char *sg_tab
[] = { "m0", "m1", "a0", "a1" };
211 if (field_b
& 0x2000)
213 fprintf_fn (stream
, "p%s %s,%s,%s\t",
214 (field_b
& 0x1000) ? "add" : "sub",
215 sx_tab
[(field_b
>> 6) & 3],
216 sy_tab
[(field_b
>> 4) & 3],
217 du_tab
[(field_b
>> 0) & 3]);
219 fprintf_fn (stream
, "pmuls%c%s,%s,%s",
220 field_b
& 0x2000 ? ' ' : '\t',
221 se_tab
[(field_b
>> 10) & 3],
222 sf_tab
[(field_b
>> 8) & 3],
223 sg_tab
[(field_b
>> 2) & 3]);
228 nib2
= field_b
>> 12 & 0xf;
229 nib3
= field_b
>> 8 & 0xf;
248 for (op
= sh_table
; op
->name
; op
++)
250 if (op
->nibbles
[1] == nib1
251 && op
->nibbles
[2] == nib2
252 && op
->nibbles
[3] == nib3
)
256 fprintf_fn (stream
, "%s%s\t", dc
, op
->name
);
257 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
259 if (n
&& op
->arg
[1] != A_END
)
260 fprintf_fn (stream
, ",");
264 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
267 fprintf_fn (stream
, sx_tab
[(field_b
>> 6) & 3]);
270 fprintf_fn (stream
, sy_tab
[(field_b
>> 4) & 3]);
273 fprintf_fn (stream
, "mach");
276 fprintf_fn (stream
, "macl");
286 fprintf_fn (stream
, ".word 0x%x", field_b
);
290 print_insn_shx (memaddr
, info
)
292 struct disassemble_info
*info
;
294 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
295 void *stream
= info
->stream
;
296 unsigned char insn
[2];
297 unsigned char nibs
[4];
299 bfd_vma relmask
= ~(bfd_vma
) 0;
306 target_arch
= arch_sh1
;
309 target_arch
= arch_sh2
;
311 case bfd_mach_sh_dsp
:
312 target_arch
= arch_sh_dsp
;
315 target_arch
= arch_sh3
;
317 case bfd_mach_sh3_dsp
:
318 target_arch
= arch_sh3_dsp
;
321 target_arch
= arch_sh3e
;
324 target_arch
= arch_sh4
;
330 status
= info
->read_memory_func (memaddr
, insn
, 2, info
);
334 info
->memory_error_func (status
, memaddr
, info
);
338 if (info
->flags
& LITTLE_BIT
)
340 nibs
[0] = (insn
[1] >> 4) & 0xf;
341 nibs
[1] = insn
[1] & 0xf;
343 nibs
[2] = (insn
[0] >> 4) & 0xf;
344 nibs
[3] = insn
[0] & 0xf;
348 nibs
[0] = (insn
[0] >> 4) & 0xf;
349 nibs
[1] = insn
[0] & 0xf;
351 nibs
[2] = (insn
[1] >> 4) & 0xf;
352 nibs
[3] = insn
[1] & 0xf;
355 if (nibs
[0] == 0xf && (nibs
[1] & 4) == 0 && target_arch
& arch_sh_dsp_up
)
361 status
= info
->read_memory_func (memaddr
+ 2, insn
, 2, info
);
365 info
->memory_error_func (status
, memaddr
+ 2, info
);
369 if (info
->flags
& LITTLE_BIT
)
370 field_b
= insn
[1] << 8 | insn
[0];
372 field_b
= insn
[0] << 8 | insn
[1];
374 print_insn_ppi (field_b
, info
);
375 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
378 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
381 for (op
= sh_table
; op
->name
; op
++)
389 bfd_vma disp_pc_addr
= 0;
391 if ((op
->arch
& target_arch
) == 0)
393 for (n
= 0; n
< 4; n
++)
395 int i
= op
->nibbles
[n
];
406 imm
= (nibs
[2] << 4) | (nibs
[3]);
409 imm
= ((char) imm
) * 2 + 4;
412 imm
= ((nibs
[1]) << 8) | (nibs
[2] << 4) | (nibs
[3]);
431 imm
= (nibs
[2] << 4) | nibs
[3];
434 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
435 relmask
= ~(bfd_vma
) 1;
438 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
439 relmask
= ~(bfd_vma
) 3;
443 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
447 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
456 rn
= (nibs
[n
] & 0xc) >> 2;
457 rm
= (nibs
[n
] & 0x3);
463 /* sh-dsp: single data transfer. */
468 rn
|= (!(rn
& 2)) << 2;
479 fprintf_fn (stream
, "%s\t", op
->name
);
481 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
483 if (n
&& op
->arg
[1] != A_END
)
484 fprintf_fn (stream
, ",");
488 fprintf_fn (stream
, "#%d", (char) (imm
));
491 fprintf_fn (stream
, "r0");
494 fprintf_fn (stream
, "r%d", rn
);
497 fprintf_fn (stream
, "@r%d+", rn
);
500 fprintf_fn (stream
, "@-r%d", rn
);
503 fprintf_fn (stream
, "@r%d", rn
);
506 fprintf_fn (stream
, "@(%d,r%d)", imm
, rn
);
509 fprintf_fn (stream
, "@r%d+r8", rn
);
512 fprintf_fn (stream
, "r%d", rm
);
515 fprintf_fn (stream
, "@r%d+", rm
);
518 fprintf_fn (stream
, "@-r%d", rm
);
521 fprintf_fn (stream
, "@r%d", rm
);
524 fprintf_fn (stream
, "@(%d,r%d)", imm
, rm
);
527 fprintf_fn (stream
, "r%d_bank", rb
);
531 disp_pc_addr
= imm
+ 4 + (memaddr
& relmask
);
532 (*info
->print_address_func
) (disp_pc_addr
, info
);
535 fprintf_fn (stream
, "@(r0,r%d)", rn
);
538 fprintf_fn (stream
, "@(r0,r%d)", rm
);
541 fprintf_fn (stream
, "@(%d,gbr)", imm
);
544 fprintf_fn (stream
, "@(r0,gbr)");
548 (*info
->print_address_func
) (imm
+ memaddr
, info
);
551 fprintf_fn (stream
, "sr");
554 fprintf_fn (stream
, "gbr");
557 fprintf_fn (stream
, "vbr");
560 fprintf_fn (stream
, "dsr");
563 fprintf_fn (stream
, "mod");
566 fprintf_fn (stream
, "re");
569 fprintf_fn (stream
, "rs");
572 fprintf_fn (stream
, "a0");
575 fprintf_fn (stream
, "x0");
578 fprintf_fn (stream
, "x1");
581 fprintf_fn (stream
, "y0");
584 fprintf_fn (stream
, "y1");
587 print_dsp_reg (rm
, fprintf_fn
, stream
);
590 fprintf_fn (stream
, "ssr");
593 fprintf_fn (stream
, "spc");
596 fprintf_fn (stream
, "mach");
599 fprintf_fn (stream
, "macl");
602 fprintf_fn (stream
, "pr");
605 fprintf_fn (stream
, "sgr");
608 fprintf_fn (stream
, "dbr");
611 fprintf_fn (stream
, "fr%d", rn
);
614 fprintf_fn (stream
, "fr%d", rm
);
619 fprintf_fn (stream
, "xd%d", rn
& ~1);
623 fprintf_fn (stream
, "dr%d", rn
);
628 fprintf_fn (stream
, "xd%d", rm
& ~1);
632 fprintf_fn (stream
, "dr%d", rm
);
636 fprintf_fn (stream
, "fpscr");
640 fprintf_fn (stream
, "fpul");
643 fprintf_fn (stream
, "fr0");
646 fprintf_fn (stream
, "fv%d", rn
* 4);
649 fprintf_fn (stream
, "fv%d", rm
* 4);
652 fprintf_fn (stream
, "xmtrx");
660 /* This code prints instructions in delay slots on the same line
661 as the instruction which needs the delay slots. This can be
662 confusing, since other disassembler don't work this way, and
663 it means that the instructions are not all in a line. So I
665 if (!(info
->flags
& 1)
666 && (op
->name
[0] == 'j'
667 || (op
->name
[0] == 'b'
668 && (op
->name
[1] == 'r'
669 || op
->name
[1] == 's'))
670 || (op
->name
[0] == 'r' && op
->name
[1] == 't')
671 || (op
->name
[0] == 'b' && op
->name
[2] == '.')))
674 fprintf_fn (stream
, "\t(slot ");
675 print_insn_shx (memaddr
+ 2, info
);
677 fprintf_fn (stream
, ")");
682 if (disp_pc
&& strcmp (op
->name
, "mova") != 0)
687 if (relmask
== ~(bfd_vma
) 1)
691 status
= info
->read_memory_func (disp_pc_addr
, bytes
, size
, info
);
698 if ((info
->flags
& LITTLE_BIT
) != 0)
699 val
= bfd_getl16 (bytes
);
701 val
= bfd_getb16 (bytes
);
705 if ((info
->flags
& LITTLE_BIT
) != 0)
706 val
= bfd_getl32 (bytes
);
708 val
= bfd_getb32 (bytes
);
710 fprintf_fn (stream
, "\t! 0x%x", val
);
719 fprintf_fn (stream
, ".word 0x%x%x%x%x", nibs
[0], nibs
[1], nibs
[2], nibs
[3]);
724 print_insn_shl (memaddr
, info
)
726 struct disassemble_info
*info
;
730 info
->flags
= LITTLE_BIT
;
731 r
= print_insn_shx (memaddr
, info
);
736 print_insn_sh (memaddr
, info
)
738 struct disassemble_info
*info
;
743 r
= print_insn_shx (memaddr
, info
);