1 /* Disassemble SH instructions.
2 Copyright (C) 1993, 94, 95, 96, 97, 1998 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. */
28 print_insn_shx (memaddr
, info
)
30 struct disassemble_info
*info
;
32 fprintf_ftype fprintf_fn
= info
->fprintf_func
;
33 void *stream
= info
->stream
;
34 unsigned char insn
[2];
35 unsigned char nibs
[4];
37 bfd_vma relmask
= ~ (bfd_vma
) 0;
40 status
= info
->read_memory_func (memaddr
, insn
, 2, info
);
44 info
->memory_error_func (status
, memaddr
, info
);
48 if (info
->flags
& LITTLE_BIT
)
50 nibs
[0] = (insn
[1] >> 4) & 0xf;
51 nibs
[1] = insn
[1] & 0xf;
53 nibs
[2] = (insn
[0] >> 4) & 0xf;
54 nibs
[3] = insn
[0] & 0xf;
58 nibs
[0] = (insn
[0] >> 4) & 0xf;
59 nibs
[1] = insn
[0] & 0xf;
61 nibs
[2] = (insn
[1] >> 4) & 0xf;
62 nibs
[3] = insn
[1] & 0xf;
65 for (op
= sh_table
; op
->name
; op
++)
73 bfd_vma disp_pc_addr
= 0;
75 for (n
= 0; n
< 4; n
++)
77 int i
= op
->nibbles
[n
];
88 imm
= (nibs
[2] << 4) | (nibs
[3]);
91 imm
= ((char)imm
) * 2 + 4 ;
94 imm
= ((nibs
[1]) << 8) | (nibs
[2] << 4) | (nibs
[3]);
109 imm
= (nibs
[2] << 4) | nibs
[3];
112 imm
= ((nibs
[2] << 4) | nibs
[3]) <<1;
113 relmask
= ~ (bfd_vma
) 1;
116 imm
= ((nibs
[2] << 4) | nibs
[3]) <<2;
117 relmask
= ~ (bfd_vma
) 3;
120 imm
= ((nibs
[2] << 4) | nibs
[3]) <<1;
123 imm
= ((nibs
[2] << 4) | nibs
[3]) <<2;
126 imm
= (nibs
[2] << 4) | (nibs
[3]);
138 rn
= (nibs
[n
] & 0xc) >> 2;
139 rm
= (nibs
[n
] & 0x3);
150 fprintf_fn (stream
,"%s\t", op
->name
);
152 for (n
= 0; n
< 3 && op
->arg
[n
] != A_END
; n
++)
154 if (n
&& op
->arg
[1] != A_END
)
155 fprintf_fn (stream
, ",");
159 fprintf_fn (stream
, "#%d", (char)(imm
));
162 fprintf_fn (stream
, "r0");
165 fprintf_fn (stream
, "r%d", rn
);
168 fprintf_fn (stream
, "@r%d+", rn
);
171 fprintf_fn (stream
, "@-r%d", rn
);
174 fprintf_fn (stream
, "@r%d", rn
);
177 fprintf_fn (stream
, "@(%d,r%d)", imm
, rn
);
180 fprintf_fn (stream
, "r%d", rm
);
183 fprintf_fn (stream
, "@r%d+", rm
);
186 fprintf_fn (stream
, "@-r%d", rm
);
189 fprintf_fn (stream
, "@r%d", rm
);
192 fprintf_fn (stream
, "@(%d,r%d)", imm
, rm
);
195 fprintf_fn (stream
, "r%d_bank", rb
);
199 disp_pc_addr
= imm
+ 4 + (memaddr
& relmask
);
200 (*info
->print_address_func
) (disp_pc_addr
, info
);
203 fprintf_fn (stream
, "@(r0,r%d)", rn
);
206 fprintf_fn (stream
, "@(r0,r%d)", rm
);
209 fprintf_fn (stream
, "@(%d,gbr)",imm
);
212 fprintf_fn (stream
, "@(r0,gbr)");
216 (*info
->print_address_func
) (imm
+ memaddr
, info
);
219 fprintf_fn (stream
, "sr");
222 fprintf_fn (stream
, "gbr");
225 fprintf_fn (stream
, "vbr");
228 fprintf_fn (stream
, "ssr");
231 fprintf_fn (stream
, "spc");
234 fprintf_fn (stream
, "mach");
237 fprintf_fn (stream
,"macl");
240 fprintf_fn (stream
, "pr");
243 fprintf_fn (stream
, "sgr");
246 fprintf_fn (stream
, "dbr");
252 fprintf_fn (stream
, "fr%d", rn
);
255 fprintf_fn (stream
, "fr%d", rm
);
260 fprintf_fn (stream
, "xd%d", rn
& ~1);
265 fprintf_fn (stream
, "dr%d", rn
);
270 fprintf_fn (stream
, "xd%d", rm
& ~1);
274 fprintf_fn (stream
, "dr%d", rm
);
278 fprintf_fn (stream
, "fpscr");
282 fprintf_fn (stream
, "fpul");
285 fprintf_fn (stream
, "fr0");
288 fprintf_fn (stream
, "fv%d", rn
*4);
291 fprintf_fn (stream
, "fv%d", rm
*4);
294 fprintf_fn (stream
, "xmtrx");
302 /* This code prints instructions in delay slots on the same line
303 as the instruction which needs the delay slots. This can be
304 confusing, since other disassembler don't work this way, and
305 it means that the instructions are not all in a line. So I
307 if (!(info
->flags
& 1)
308 && (op
->name
[0] == 'j'
309 || (op
->name
[0] == 'b'
310 && (op
->name
[1] == 'r'
311 || op
->name
[1] == 's'))
312 || (op
->name
[0] == 'r' && op
->name
[1] == 't')
313 || (op
->name
[0] == 'b' && op
->name
[2] == '.')))
316 fprintf_fn (stream
, "\t(slot ");
317 print_insn_shx (memaddr
+ 2, info
);
319 fprintf_fn (stream
, ")");
324 if (disp_pc
&& strcmp (op
->name
, "mova") != 0)
329 if (relmask
== ~ (bfd_vma
) 1)
333 status
= info
->read_memory_func (disp_pc_addr
, bytes
, size
, info
);
340 if ((info
->flags
& LITTLE_BIT
) != 0)
341 val
= bfd_getl16 (bytes
);
343 val
= bfd_getb16 (bytes
);
347 if ((info
->flags
& LITTLE_BIT
) != 0)
348 val
= bfd_getl32 (bytes
);
350 val
= bfd_getb32 (bytes
);
352 fprintf_fn (stream
, "\t! 0x%x", val
);
361 fprintf_fn (stream
, ".word 0x%x%x%x%x", nibs
[0], nibs
[1], nibs
[2], nibs
[3]);
366 print_insn_shl (memaddr
, info
)
368 struct disassemble_info
*info
;
372 info
->flags
= LITTLE_BIT
;
373 r
= print_insn_shx (memaddr
, info
);
378 print_insn_sh (memaddr
, info
)
380 struct disassemble_info
*info
;
385 r
= print_insn_shx (memaddr
, info
);