1 /* Disassemble SH instructions.
2 Copyright (C) 1993, 94, 95, 96, 97, 1998, 2000
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. */
30 print_movxy (op
, rn
, rm
, fprintf_fn
, stream
)
33 fprintf_ftype fprintf_fn
;
38 fprintf_fn (stream
, "%s\t", op
->name
);
39 for (n
= 0; n
< 2; n
++)
44 fprintf_fn (stream
, "@r%d", rn
);
47 fprintf_fn (stream
, "@r%d+", rn
);
50 fprintf_fn (stream
, "@r%d+r8", rn
);
53 fprintf_fn (stream
, "@r%d+r9", rn
);
56 fprintf_fn (stream
, "a%c", '0' + rm
);
59 fprintf_fn (stream
, "x%c", '0' + rm
);
62 fprintf_fn (stream
, "y%c", '0' + rm
);
68 fprintf_fn (stream
, ",");
72 /* Print a double data transfer insn. INSN is just the lower three
73 nibbles of the insn, i.e. field a and the bit that indicates if
74 a parallel processing insn follows.
75 Return nonzero if a field b of a parallel processing insns follows. */
78 print_insn_ddt (insn
, info
)
80 struct disassemble_info
*info
;
82 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
83 void *stream
= info
->stream
;
85 /* If this is just a nop, make sure to emit something. */
87 fprintf_fn (stream
, "nopx\tnopy");
89 /* If a parallel processing insn was printed before,
90 and we got a non-nop, emit a tab. */
91 if ((insn
& 0x800) && (insn
& 0x3ff))
92 fprintf_fn (stream
, "\t");
94 /* Check if either the x or y part is invalid. */
95 if (((insn
& 0xc) == 0 && (insn
& 0x2a0))
96 || ((insn
& 3) == 0 && (insn
& 0x150)))
97 fprintf_fn (stream
, ".word 0x%x", insn
);
100 static sh_opcode_info
*first_movx
, *first_movy
;
101 sh_opcode_info
*opx
, *opy
;
102 unsigned int insn_x
, insn_y
;
106 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX
;)
108 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY
;)
111 insn_x
= (insn
>> 2) & 0xb;
114 for (opx
= first_movx
; opx
->nibbles
[2] != insn_x
;)
116 print_movxy (opx
, ((insn
>> 9) & 1) + 4, (insn
>> 7) & 1,
119 insn_y
= (insn
& 3) | ((insn
>> 1) & 8);
123 fprintf_fn (stream
, "\t");
124 for (opy
= first_movy
; opy
->nibbles
[2] != insn_y
;)
126 print_movxy (opy
, ((insn
>> 8) & 1) + 6, (insn
>> 6) & 1,
133 print_dsp_reg (rm
, fprintf_fn
, stream
)
135 fprintf_ftype fprintf_fn
;
141 fprintf_fn (stream
, "a1");
144 fprintf_fn (stream
, "a0");
147 fprintf_fn (stream
, "x0");
150 fprintf_fn (stream
, "x1");
153 fprintf_fn (stream
, "y0");
156 fprintf_fn (stream
, "y1");
159 fprintf_fn (stream
, "m0");
162 fprintf_fn (stream
, "a1g");
165 fprintf_fn (stream
, "m1");
168 fprintf_fn (stream
, "a0g");
171 fprintf_fn (stream
, "0x%x", rm
);
177 print_insn_ppi (field_b
, info
)
179 struct disassemble_info
*info
;
181 static char *sx_tab
[] = { "x0", "x1", "a0", "a1" };
182 static char *sy_tab
[] = { "y0", "y1", "m0", "m1" };
183 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
184 void *stream
= info
->stream
;
185 unsigned int nib1
, nib2
, nib3
;
189 if ((field_b
& 0xe800) == 0)
191 fprintf_fn (stream
, "psh%c\t#%d,",
192 field_b
& 0x1000 ? 'a' : 'l',
193 (field_b
>> 4) & 127);
194 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
197 if ((field_b
& 0xc000) == 0x4000 && (field_b
& 0x3000) != 0x1000)
199 static char *du_tab
[] = { "x0", "y0", "a0", "a1" };
200 static char *se_tab
[] = { "x0", "x1", "y0", "a1" };
201 static char *sf_tab
[] = { "y0", "y1", "x0", "a1" };
202 static char *sg_tab
[] = { "m0", "m1", "a0", "a1" };
204 if (field_b
& 0x2000)
206 fprintf_fn (stream
, "p%s %s,%s,%s\t",
207 (field_b
& 0x1000) ? "add" : "sub",
208 sx_tab
[(field_b
>> 6) & 3],
209 sy_tab
[(field_b
>> 4) & 3],
210 du_tab
[(field_b
>> 0) & 3]);
212 fprintf_fn (stream
, "pmuls%c%s,%s,%s",
213 field_b
& 0x2000 ? ' ' : '\t',
214 se_tab
[(field_b
>> 10) & 3],
215 sf_tab
[(field_b
>> 8) & 3],
216 sg_tab
[(field_b
>> 2) & 3]);
221 nib2
= field_b
>> 12 & 0xf;
222 nib3
= field_b
>> 8 & 0xf;
241 for (op
= sh_table
; op
->name
; op
++)
243 if (op
->nibbles
[1] == nib1
244 && op
->nibbles
[2] == nib2
245 && op
->nibbles
[3] == nib3
)
249 fprintf_fn (stream
, "%s%s\t", dc
, op
->name
);
250 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
252 if (n
&& op
->arg
[1] != A_END
)
253 fprintf_fn (stream
, ",");
257 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
260 fprintf_fn (stream
, sx_tab
[(field_b
>> 6) & 3]);
263 fprintf_fn (stream
, sy_tab
[(field_b
>> 4) & 3]);
266 fprintf_fn (stream
, "mach");
269 fprintf_fn (stream
, "macl");
279 fprintf_fn (stream
, ".word 0x%x", field_b
);
283 print_insn_shx (memaddr
, info
)
285 struct disassemble_info
*info
;
287 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
288 void *stream
= info
->stream
;
289 unsigned char insn
[2];
290 unsigned char nibs
[4];
292 bfd_vma relmask
= ~(bfd_vma
) 0;
299 target_arch
= arch_sh1
;
302 target_arch
= arch_sh2
;
304 case bfd_mach_sh_dsp
:
305 target_arch
= arch_sh_dsp
;
308 target_arch
= arch_sh3
;
310 case bfd_mach_sh3_dsp
:
311 target_arch
= arch_sh3_dsp
;
314 target_arch
= arch_sh3e
;
317 target_arch
= arch_sh4
;
323 status
= info
->read_memory_func (memaddr
, insn
, 2, info
);
327 info
->memory_error_func (status
, memaddr
, info
);
331 if (info
->flags
& LITTLE_BIT
)
333 nibs
[0] = (insn
[1] >> 4) & 0xf;
334 nibs
[1] = insn
[1] & 0xf;
336 nibs
[2] = (insn
[0] >> 4) & 0xf;
337 nibs
[3] = insn
[0] & 0xf;
341 nibs
[0] = (insn
[0] >> 4) & 0xf;
342 nibs
[1] = insn
[0] & 0xf;
344 nibs
[2] = (insn
[1] >> 4) & 0xf;
345 nibs
[3] = insn
[1] & 0xf;
348 if (nibs
[0] == 0xf && (nibs
[1] & 4) == 0 && target_arch
& arch_sh_dsp_up
)
354 status
= info
->read_memory_func (memaddr
+ 2, insn
, 2, info
);
358 info
->memory_error_func (status
, memaddr
+ 2, info
);
362 if (info
->flags
& LITTLE_BIT
)
363 field_b
= insn
[1] << 8 | insn
[0];
365 field_b
= insn
[0] << 8 | insn
[1];
367 print_insn_ppi (field_b
, info
);
368 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
371 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
374 for (op
= sh_table
; op
->name
; op
++)
382 bfd_vma disp_pc_addr
= 0;
384 if ((op
->arch
& target_arch
) == 0)
386 for (n
= 0; n
< 4; n
++)
388 int i
= op
->nibbles
[n
];
399 imm
= (nibs
[2] << 4) | (nibs
[3]);
402 imm
= ((char) imm
) * 2 + 4;
405 imm
= ((nibs
[1]) << 8) | (nibs
[2] << 4) | (nibs
[3]);
424 imm
= (nibs
[2] << 4) | nibs
[3];
427 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
428 relmask
= ~(bfd_vma
) 1;
431 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
432 relmask
= ~(bfd_vma
) 3;
436 imm
= ((nibs
[2] << 4) | nibs
[3]) << 1;
440 imm
= ((nibs
[2] << 4) | nibs
[3]) << 2;
449 rn
= (nibs
[n
] & 0xc) >> 2;
450 rm
= (nibs
[n
] & 0x3);
456 /* sh-dsp: single data transfer. */
472 fprintf_fn (stream
, "%s\t", op
->name
);
474 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
476 if (n
&& op
->arg
[1] != A_END
)
477 fprintf_fn (stream
, ",");
481 fprintf_fn (stream
, "#%d", (char) (imm
));
484 fprintf_fn (stream
, "r0");
487 fprintf_fn (stream
, "r%d", rn
);
490 fprintf_fn (stream
, "@r%d+", rn
);
493 fprintf_fn (stream
, "@-r%d", rn
);
496 fprintf_fn (stream
, "@r%d", rn
);
499 fprintf_fn (stream
, "@(%d,r%d)", imm
, rn
);
502 fprintf_fn (stream
, "@r%d+r8", rn
);
505 fprintf_fn (stream
, "r%d", rm
);
508 fprintf_fn (stream
, "@r%d+", rm
);
511 fprintf_fn (stream
, "@-r%d", rm
);
514 fprintf_fn (stream
, "@r%d", rm
);
517 fprintf_fn (stream
, "@(%d,r%d)", imm
, rm
);
520 fprintf_fn (stream
, "r%d_bank", rb
);
524 disp_pc_addr
= imm
+ 4 + (memaddr
& relmask
);
525 (*info
->print_address_func
) (disp_pc_addr
, info
);
528 fprintf_fn (stream
, "@(r0,r%d)", rn
);
531 fprintf_fn (stream
, "@(r0,r%d)", rm
);
534 fprintf_fn (stream
, "@(%d,gbr)", imm
);
537 fprintf_fn (stream
, "@(r0,gbr)");
541 (*info
->print_address_func
) (imm
+ memaddr
, info
);
544 fprintf_fn (stream
, "sr");
547 fprintf_fn (stream
, "gbr");
550 fprintf_fn (stream
, "vbr");
553 fprintf_fn (stream
, "dsr");
556 fprintf_fn (stream
, "mod");
559 fprintf_fn (stream
, "re");
562 fprintf_fn (stream
, "rs");
565 fprintf_fn (stream
, "a0");
568 fprintf_fn (stream
, "x0");
571 fprintf_fn (stream
, "x1");
574 fprintf_fn (stream
, "y0");
577 fprintf_fn (stream
, "y1");
580 print_dsp_reg (rm
, fprintf_fn
, stream
);
583 fprintf_fn (stream
, "ssr");
586 fprintf_fn (stream
, "spc");
589 fprintf_fn (stream
, "mach");
592 fprintf_fn (stream
, "macl");
595 fprintf_fn (stream
, "pr");
598 fprintf_fn (stream
, "sgr");
601 fprintf_fn (stream
, "dbr");
604 fprintf_fn (stream
, "fr%d", rn
);
607 fprintf_fn (stream
, "fr%d", rm
);
612 fprintf_fn (stream
, "xd%d", rn
& ~1);
616 fprintf_fn (stream
, "dr%d", rn
);
621 fprintf_fn (stream
, "xd%d", rm
& ~1);
625 fprintf_fn (stream
, "dr%d", rm
);
629 fprintf_fn (stream
, "fpscr");
633 fprintf_fn (stream
, "fpul");
636 fprintf_fn (stream
, "fr0");
639 fprintf_fn (stream
, "fv%d", rn
* 4);
642 fprintf_fn (stream
, "fv%d", rm
* 4);
645 fprintf_fn (stream
, "xmtrx");
653 /* This code prints instructions in delay slots on the same line
654 as the instruction which needs the delay slots. This can be
655 confusing, since other disassembler don't work this way, and
656 it means that the instructions are not all in a line. So I
658 if (!(info
->flags
& 1)
659 && (op
->name
[0] == 'j'
660 || (op
->name
[0] == 'b'
661 && (op
->name
[1] == 'r'
662 || op
->name
[1] == 's'))
663 || (op
->name
[0] == 'r' && op
->name
[1] == 't')
664 || (op
->name
[0] == 'b' && op
->name
[2] == '.')))
667 fprintf_fn (stream
, "\t(slot ");
668 print_insn_shx (memaddr
+ 2, info
);
670 fprintf_fn (stream
, ")");
675 if (disp_pc
&& strcmp (op
->name
, "mova") != 0)
680 if (relmask
== ~(bfd_vma
) 1)
684 status
= info
->read_memory_func (disp_pc_addr
, bytes
, size
, info
);
691 if ((info
->flags
& LITTLE_BIT
) != 0)
692 val
= bfd_getl16 (bytes
);
694 val
= bfd_getb16 (bytes
);
698 if ((info
->flags
& LITTLE_BIT
) != 0)
699 val
= bfd_getl32 (bytes
);
701 val
= bfd_getb32 (bytes
);
703 fprintf_fn (stream
, "\t! 0x%x", val
);
712 fprintf_fn (stream
, ".word 0x%x%x%x%x", nibs
[0], nibs
[1], nibs
[2], nibs
[3]);
717 print_insn_shl (memaddr
, info
)
719 struct disassemble_info
*info
;
723 info
->flags
= LITTLE_BIT
;
724 r
= print_insn_shx (memaddr
, info
);
729 print_insn_sh (memaddr
, info
)
731 struct disassemble_info
*info
;
736 r
= print_insn_shx (memaddr
, info
);
This page took 0.043621 seconds and 4 git commands to generate.