1 /* Disassemble SH instructions.
2 Copyright (C) 1993, 94, 95, 96, 97, 1998, 2000 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 print_movxy (op
, rn
, rm
, fprintf_fn
, stream
)
32 fprintf_ftype fprintf_fn
;
37 fprintf_fn (stream
,"%s\t", op
->name
);
38 for (n
= 0; n
< 2; n
++)
43 fprintf_fn (stream
, "@r%d", rn
);
46 fprintf_fn (stream
, "@r%d+", rn
);
49 fprintf_fn (stream
, "@r%d+r8", rn
);
52 fprintf_fn (stream
, "@r%d+r9", rn
);
55 fprintf_fn (stream
, "a%c", '0' + rm
);
58 fprintf_fn (stream
, "x%c", '0' + rm
);
61 fprintf_fn (stream
, "y%c", '0' + rm
);
67 fprintf_fn (stream
, ",");
71 /* Print a double data transfer insn. INSN is just the lower three
72 nibbles of the insn, i.e. field a and the bit that indicates if
73 a parallel processing insn follows.
74 Return nonzero if a field b of a parallel processing insns follows. */
76 print_insn_ddt (insn
, info
)
78 struct disassemble_info
*info
;
80 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
81 void *stream
= info
->stream
;
83 /* If this is just a nop, make sure to emit something. */
85 fprintf_fn (stream
, "nopx\tnopy");
87 /* If a parallel processing insn was printed before,
88 and we got a non-nop, emit a tab. */
89 if ((insn
& 0x800) && (insn
& 0x3ff))
90 fprintf_fn (stream
, "\t");
92 /* Check if either the x or y part is invalid. */
93 if (((insn
& 0xc) == 0 && (insn
& 0x2a0))
94 || ((insn
& 3) == 0 && (insn
& 0x150)))
95 fprintf_fn (stream
, ".word 0x%x", insn
);
98 static sh_opcode_info
*first_movx
, *first_movy
;
99 sh_opcode_info
*opx
, *opy
;
104 for (first_movx
= sh_table
; first_movx
->nibbles
[1] != MOVX
; )
106 for (first_movy
= first_movx
; first_movy
->nibbles
[1] != MOVY
; )
109 insn_x
= (insn
>> 2) & 0xb;
112 for (opx
= first_movx
; opx
->nibbles
[2] != insn_x
; ) opx
++;
113 print_movxy (opx
, ((insn
>> 9) & 1) + 4, (insn
>> 7) & 1,
116 insn_y
= (insn
& 3) | ((insn
>> 1) & 8);
120 fprintf_fn (stream
, "\t");
121 for (opy
= first_movy
; opy
->nibbles
[2] != insn_y
; ) opy
++;
122 print_movxy (opy
, ((insn
>> 8) & 1) + 6, (insn
>> 6) & 1,
129 print_dsp_reg (rm
, fprintf_fn
, stream
)
131 fprintf_ftype fprintf_fn
;
137 fprintf_fn (stream
, "a1");
140 fprintf_fn (stream
, "a0");
143 fprintf_fn (stream
, "x0");
146 fprintf_fn (stream
, "x1");
149 fprintf_fn (stream
, "y0");
152 fprintf_fn (stream
, "y1");
155 fprintf_fn (stream
, "m0");
158 fprintf_fn (stream
, "a1g");
161 fprintf_fn (stream
, "m1");
164 fprintf_fn (stream
, "a0g");
167 fprintf_fn (stream
, "0x%x", rm
);
173 print_insn_ppi (field_b
, info
)
175 struct disassemble_info
*info
;
177 static char *sx_tab
[] = {"x0","x1","a0","a1"};
178 static char *sy_tab
[] = {"y0","y1","m0","m1"};
179 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
180 void *stream
= info
->stream
;
181 int nib1
, nib2
, nib3
;
185 if ((field_b
& 0xe800) == 0)
187 fprintf_fn (stream
, "psh%c\t#%d,",
188 field_b
& 0x1000 ? 'a' : 'l',
189 (field_b
>> 4) & 127);
190 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
193 if ((field_b
& 0xc000) == 0x4000 && (field_b
& 0x3000) != 0x1000)
195 static char *du_tab
[] = {"x0","y0","a0","a1"};
196 static char *se_tab
[] = {"x0","x1","y0","a1"};
197 static char *sf_tab
[] = {"y0","y1","x0","a1"};
198 static char *sg_tab
[] = {"m0","m1","a0","a1"};
200 if (field_b
& 0x2000)
202 fprintf_fn (stream
, "p%s %s,%s,%s\t",
203 (field_b
& 0x1000) ? "add" : "sub",
204 sx_tab
[(field_b
>> 6) & 3],
205 sy_tab
[(field_b
>> 4) & 3],
206 du_tab
[(field_b
>> 0) & 3]);
208 fprintf_fn (stream
, "pmuls%c%s,%s,%s",
209 field_b
& 0x2000 ? ' ' : '\t',
210 se_tab
[(field_b
>> 10) & 3],
211 sf_tab
[(field_b
>> 8) & 3],
212 sg_tab
[(field_b
>> 2) & 3]);
217 nib2
= field_b
>> 12 & 0xf;
218 nib3
= field_b
>> 8 & 0xf;
237 for (op
= sh_table
; op
->name
; op
++)
239 if (op
->nibbles
[1] == nib1
240 && op
->nibbles
[2] == nib2
241 && op
->nibbles
[3] == nib3
)
245 fprintf_fn (stream
, "%s%s\t", dc
, op
->name
);
246 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
248 if (n
&& op
->arg
[1] != A_END
)
249 fprintf_fn (stream
, ",");
253 print_dsp_reg (field_b
& 0xf, fprintf_fn
, stream
);
256 fprintf_fn (stream
, sx_tab
[(field_b
>> 6) & 3]);
259 fprintf_fn (stream
, sy_tab
[(field_b
>> 4) & 3]);
262 fprintf_fn (stream
, "mach");
265 fprintf_fn (stream
,"macl");
275 fprintf_fn (stream
, ".word 0x%x", field_b
);
279 print_insn_shx (memaddr
, info
)
281 struct disassemble_info
*info
;
283 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
284 void *stream
= info
->stream
;
285 unsigned char insn
[2];
286 unsigned char nibs
[4];
288 bfd_vma relmask
= ~ (bfd_vma
) 0;
295 target_arch
= arch_sh1
;
298 target_arch
= arch_sh2
;
300 case bfd_mach_sh_dsp
:
301 target_arch
= arch_sh_dsp
;
304 target_arch
= arch_sh3
;
306 case bfd_mach_sh3_dsp
:
307 target_arch
= arch_sh3_dsp
;
310 target_arch
= arch_sh3e
;
313 target_arch
= arch_sh4
;
319 status
= info
->read_memory_func (memaddr
, insn
, 2, info
);
323 info
->memory_error_func (status
, memaddr
, info
);
327 if (info
->flags
& LITTLE_BIT
)
329 nibs
[0] = (insn
[1] >> 4) & 0xf;
330 nibs
[1] = insn
[1] & 0xf;
332 nibs
[2] = (insn
[0] >> 4) & 0xf;
333 nibs
[3] = insn
[0] & 0xf;
337 nibs
[0] = (insn
[0] >> 4) & 0xf;
338 nibs
[1] = insn
[0] & 0xf;
340 nibs
[2] = (insn
[1] >> 4) & 0xf;
341 nibs
[3] = insn
[1] & 0xf;
344 if (nibs
[0] == 0xf && (nibs
[1] & 4) == 0 && target_arch
& arch_sh_dsp_up
)
350 status
= info
->read_memory_func (memaddr
+ 2, insn
, 2, info
);
354 info
->memory_error_func (status
, memaddr
+ 2, info
);
358 if (info
->flags
& LITTLE_BIT
)
359 field_b
= insn
[1] << 8 | insn
[0];
361 field_b
= insn
[0] << 8 | insn
[1];
363 print_insn_ppi (field_b
, info
);
364 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
367 print_insn_ddt ((nibs
[1] << 8) | (nibs
[2] << 4) | nibs
[3], info
);
370 for (op
= sh_table
; op
->name
; op
++)
378 bfd_vma disp_pc_addr
= 0;
380 if ((op
->arch
& target_arch
) == 0)
382 for (n
= 0; n
< 4; n
++)
384 int i
= op
->nibbles
[n
];
395 imm
= (nibs
[2] << 4) | (nibs
[3]);
398 imm
= ((char)imm
) * 2 + 4 ;
401 imm
= ((nibs
[1]) << 8) | (nibs
[2] << 4) | (nibs
[3]);
420 imm
= (nibs
[2] << 4) | nibs
[3];
423 imm
= ((nibs
[2] << 4) | nibs
[3]) <<1;
424 relmask
= ~ (bfd_vma
) 1;
427 imm
= ((nibs
[2] << 4) | nibs
[3]) <<2;
428 relmask
= ~ (bfd_vma
) 3;
432 imm
= ((nibs
[2] << 4) | nibs
[3]) <<1;
436 imm
= ((nibs
[2] << 4) | nibs
[3]) <<2;
445 rn
= (nibs
[n
] & 0xc) >> 2;
446 rm
= (nibs
[n
] & 0x3);
452 /* sh-dsp: single data transfer. */
468 fprintf_fn (stream
,"%s\t", op
->name
);
470 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
472 if (n
&& op
->arg
[1] != A_END
)
473 fprintf_fn (stream
, ",");
477 fprintf_fn (stream
, "#%d", (char)(imm
));
480 fprintf_fn (stream
, "r0");
483 fprintf_fn (stream
, "r%d", rn
);
486 fprintf_fn (stream
, "@r%d+", rn
);
489 fprintf_fn (stream
, "@-r%d", rn
);
492 fprintf_fn (stream
, "@r%d", rn
);
495 fprintf_fn (stream
, "@(%d,r%d)", imm
, rn
);
498 fprintf_fn (stream
, "@r%d+r8", rn
);
501 fprintf_fn (stream
, "r%d", rm
);
504 fprintf_fn (stream
, "@r%d+", rm
);
507 fprintf_fn (stream
, "@-r%d", rm
);
510 fprintf_fn (stream
, "@r%d", rm
);
513 fprintf_fn (stream
, "@(%d,r%d)", imm
, rm
);
516 fprintf_fn (stream
, "r%d_bank", rb
);
520 disp_pc_addr
= imm
+ 4 + (memaddr
& relmask
);
521 (*info
->print_address_func
) (disp_pc_addr
, info
);
524 fprintf_fn (stream
, "@(r0,r%d)", rn
);
527 fprintf_fn (stream
, "@(r0,r%d)", rm
);
530 fprintf_fn (stream
, "@(%d,gbr)",imm
);
533 fprintf_fn (stream
, "@(r0,gbr)");
537 (*info
->print_address_func
) (imm
+ memaddr
, info
);
540 fprintf_fn (stream
, "sr");
543 fprintf_fn (stream
, "gbr");
546 fprintf_fn (stream
, "vbr");
549 fprintf_fn (stream
, "dsr");
552 fprintf_fn (stream
, "mod");
555 fprintf_fn (stream
, "re");
558 fprintf_fn (stream
, "rs");
561 fprintf_fn (stream
, "a0");
564 fprintf_fn (stream
, "x0");
567 fprintf_fn (stream
, "x1");
570 fprintf_fn (stream
, "y0");
573 fprintf_fn (stream
, "y1");
576 print_dsp_reg (rm
, fprintf_fn
, stream
);
579 fprintf_fn (stream
, "ssr");
582 fprintf_fn (stream
, "spc");
585 fprintf_fn (stream
, "mach");
588 fprintf_fn (stream
,"macl");
591 fprintf_fn (stream
, "pr");
594 fprintf_fn (stream
, "sgr");
597 fprintf_fn (stream
, "dbr");
600 fprintf_fn (stream
, "fr%d", rn
);
603 fprintf_fn (stream
, "fr%d", rm
);
608 fprintf_fn (stream
, "xd%d", rn
& ~1);
613 fprintf_fn (stream
, "dr%d", rn
);
618 fprintf_fn (stream
, "xd%d", rm
& ~1);
622 fprintf_fn (stream
, "dr%d", rm
);
626 fprintf_fn (stream
, "fpscr");
630 fprintf_fn (stream
, "fpul");
633 fprintf_fn (stream
, "fr0");
636 fprintf_fn (stream
, "fv%d", rn
*4);
639 fprintf_fn (stream
, "fv%d", rm
*4);
642 fprintf_fn (stream
, "xmtrx");
650 /* This code prints instructions in delay slots on the same line
651 as the instruction which needs the delay slots. This can be
652 confusing, since other disassembler don't work this way, and
653 it means that the instructions are not all in a line. So I
655 if (!(info
->flags
& 1)
656 && (op
->name
[0] == 'j'
657 || (op
->name
[0] == 'b'
658 && (op
->name
[1] == 'r'
659 || op
->name
[1] == 's'))
660 || (op
->name
[0] == 'r' && op
->name
[1] == 't')
661 || (op
->name
[0] == 'b' && op
->name
[2] == '.')))
664 fprintf_fn (stream
, "\t(slot ");
665 print_insn_shx (memaddr
+ 2, info
);
667 fprintf_fn (stream
, ")");
672 if (disp_pc
&& strcmp (op
->name
, "mova") != 0)
677 if (relmask
== ~ (bfd_vma
) 1)
681 status
= info
->read_memory_func (disp_pc_addr
, bytes
, size
, info
);
688 if ((info
->flags
& LITTLE_BIT
) != 0)
689 val
= bfd_getl16 (bytes
);
691 val
= bfd_getb16 (bytes
);
695 if ((info
->flags
& LITTLE_BIT
) != 0)
696 val
= bfd_getl32 (bytes
);
698 val
= bfd_getb32 (bytes
);
700 fprintf_fn (stream
, "\t! 0x%x", val
);
709 fprintf_fn (stream
, ".word 0x%x%x%x%x", nibs
[0], nibs
[1], nibs
[2], nibs
[3]);
714 print_insn_shl (memaddr
, info
)
716 struct disassemble_info
*info
;
720 info
->flags
= LITTLE_BIT
;
721 r
= print_insn_shx (memaddr
, info
);
726 print_insn_sh (memaddr
, info
)
728 struct disassemble_info
*info
;
733 r
= print_insn_shx (memaddr
, info
);
This page took 0.043817 seconds and 4 git commands to generate.