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. */
28 print_movxy (op, rn, rm, fprintf_fn, stream)
31 fprintf_ftype fprintf_fn;
36 fprintf_fn (stream,"%s\t", op->name);
37 for (n = 0; n < 2; n++)
42 fprintf_fn (stream, "@r%d", rn);
45 fprintf_fn (stream, "@r%d+", rn);
48 fprintf_fn (stream, "@r%d+r8", rn);
51 fprintf_fn (stream, "@r%d+r9", rn);
54 fprintf_fn (stream, "a%c", '0' + rm);
57 fprintf_fn (stream, "x%c", '0' + rm);
60 fprintf_fn (stream, "y%c", '0' + rm);
66 fprintf_fn (stream, ",");
70 /* Print a double data transfer insn. INSN is just the lower three
71 nibbles of the insn, i.e. field a and the bit that indicates if
72 a parallel processing insn follows.
73 Return nonzero if a field b of a parallel processing insns follows. */
75 print_insn_ddt (insn, info)
77 struct disassemble_info *info;
79 fprintf_ftype fprintf_fn = info->fprintf_func;
80 void *stream = info->stream;
82 /* If this is just a nop, make sure to emit something. */
84 fprintf_fn (stream, "nopx\tnopy");
86 /* If a parallel processing insn was printed before,
87 and we got a non-nop, emit a tab. */
88 if ((insn & 0x800) && (insn & 0x3ff))
89 fprintf_fn (stream, "\t");
91 /* Check if either the x or y part is invalid. */
92 if (((insn & 0xc) == 0 && (insn & 0x2a0))
93 || ((insn & 3) == 0 && (insn & 0x150)))
94 fprintf_fn (stream, ".word 0x%x", insn);
97 static sh_opcode_info *first_movx, *first_movy;
98 sh_opcode_info *opx, *opy;
103 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX; )
105 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY; )
108 insn_x = (insn >> 2) & 0xb;
111 for (opx = first_movx; opx->nibbles[2] != insn_x; ) opx++;
112 print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
115 insn_y = (insn & 3) | ((insn >> 1) & 8);
119 fprintf_fn (stream, "\t");
120 for (opy = first_movy; opy->nibbles[2] != insn_y; ) opy++;
121 print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
128 print_dsp_reg (rm, fprintf_fn, stream)
130 fprintf_ftype fprintf_fn;
136 fprintf_fn (stream, "a1");
139 fprintf_fn (stream, "a0");
142 fprintf_fn (stream, "x0");
145 fprintf_fn (stream, "x1");
148 fprintf_fn (stream, "y0");
151 fprintf_fn (stream, "y1");
154 fprintf_fn (stream, "m0");
157 fprintf_fn (stream, "a1g");
160 fprintf_fn (stream, "m1");
163 fprintf_fn (stream, "a0g");
166 fprintf_fn (stream, "0x%x", rm);
172 print_insn_ppi (field_b, info)
174 struct disassemble_info *info;
176 static char *sx_tab[] = {"x0","x1","a0","a1"};
177 static char *sy_tab[] = {"y0","y1","m0","m1"};
178 fprintf_ftype fprintf_fn = info->fprintf_func;
179 void *stream = info->stream;
180 int nib1, nib2, nib3;
184 if ((field_b & 0xe800) == 0)
186 fprintf_fn (stream, "psh%c\t#%d,",
187 field_b & 0x1000 ? 'a' : 'l',
188 (field_b >> 4) & 127);
189 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
192 if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
194 static char *du_tab[] = {"x0","y0","a0","a1"};
195 static char *se_tab[] = {"x0","x1","y0","a1"};
196 static char *sf_tab[] = {"y0","y1","x0","a1"};
197 static char *sg_tab[] = {"m0","m1","a0","a1"};
199 if (field_b & 0x2000)
201 fprintf_fn (stream, "p%s %s,%s,%s\t",
202 (field_b & 0x1000) ? "add" : "sub",
203 sx_tab[(field_b >> 6) & 3],
204 sy_tab[(field_b >> 4) & 3],
205 du_tab[(field_b >> 0) & 3]);
207 fprintf_fn (stream, "pmuls%c%s,%s,%s",
208 field_b & 0x2000 ? ' ' : '\t',
209 se_tab[(field_b >> 10) & 3],
210 sf_tab[(field_b >> 8) & 3],
211 sg_tab[(field_b >> 2) & 3]);
216 nib2 = field_b >> 12 & 0xf;
217 nib3 = field_b >> 8 & 0xf;
236 for (op = sh_table; op->name; op++)
238 if (op->nibbles[1] == nib1
239 && op->nibbles[2] == nib2
240 && op->nibbles[3] == nib3)
244 fprintf_fn (stream, "%s%s\t", dc, op->name);
245 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
247 if (n && op->arg[1] != A_END)
248 fprintf_fn (stream, ",");
252 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
255 fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
258 fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
261 fprintf_fn (stream, "mach");
264 fprintf_fn (stream ,"macl");
274 fprintf_fn (stream, ".word 0x%x", field_b);
278 print_insn_shx (memaddr, info)
280 struct disassemble_info *info;
282 fprintf_ftype fprintf_fn = info->fprintf_func;
283 void *stream = info->stream;
284 unsigned char insn[2];
285 unsigned char nibs[4];
287 bfd_vma relmask = ~ (bfd_vma) 0;
294 target_arch = arch_sh1;
297 target_arch = arch_sh2;
299 case bfd_mach_sh_dsp:
300 target_arch = arch_sh_dsp;
303 target_arch = arch_sh3;
305 case bfd_mach_sh3_dsp:
306 target_arch = arch_sh3_dsp;
309 target_arch = arch_sh3e;
312 target_arch = arch_sh4;
318 status = info->read_memory_func (memaddr, insn, 2, info);
322 info->memory_error_func (status, memaddr, info);
326 if (info->flags & LITTLE_BIT)
328 nibs[0] = (insn[1] >> 4) & 0xf;
329 nibs[1] = insn[1] & 0xf;
331 nibs[2] = (insn[0] >> 4) & 0xf;
332 nibs[3] = insn[0] & 0xf;
336 nibs[0] = (insn[0] >> 4) & 0xf;
337 nibs[1] = insn[0] & 0xf;
339 nibs[2] = (insn[1] >> 4) & 0xf;
340 nibs[3] = insn[1] & 0xf;
343 if (nibs[0] == 0xf && (nibs[1] & 4) == 0 && target_arch & arch_sh_dsp_up)
349 status = info->read_memory_func (memaddr + 2, insn, 2, info);
353 info->memory_error_func (status, memaddr + 2, info);
357 if (info->flags & LITTLE_BIT)
358 field_b = insn[1] << 8 | insn[0];
360 field_b = insn[0] << 8 | insn[1];
362 print_insn_ppi (field_b, info);
363 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
366 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
369 for (op = sh_table; op->name; op++)
377 bfd_vma disp_pc_addr = 0;
379 if ((op->arch & target_arch) == 0)
381 for (n = 0; n < 4; n++)
383 int i = op->nibbles[n];
394 imm = (nibs[2] << 4) | (nibs[3]);
397 imm = ((char)imm) * 2 + 4 ;
400 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
419 imm = (nibs[2] << 4) | nibs[3];
422 imm = ((nibs[2] << 4) | nibs[3]) <<1;
423 relmask = ~ (bfd_vma) 1;
426 imm = ((nibs[2] << 4) | nibs[3]) <<2;
427 relmask = ~ (bfd_vma) 3;
431 imm = ((nibs[2] << 4) | nibs[3]) <<1;
435 imm = ((nibs[2] << 4) | nibs[3]) <<2;
444 rn = (nibs[n] & 0xc) >> 2;
445 rm = (nibs[n] & 0x3);
451 /* sh-dsp: single data transfer. */
467 fprintf_fn (stream,"%s\t", op->name);
469 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
471 if (n && op->arg[1] != A_END)
472 fprintf_fn (stream, ",");
476 fprintf_fn (stream, "#%d", (char)(imm));
479 fprintf_fn (stream, "r0");
482 fprintf_fn (stream, "r%d", rn);
485 fprintf_fn (stream, "@r%d+", rn);
488 fprintf_fn (stream, "@-r%d", rn);
491 fprintf_fn (stream, "@r%d", rn);
494 fprintf_fn (stream, "@(%d,r%d)", imm, rn);
497 fprintf_fn (stream, "@r%d+r8", rn);
500 fprintf_fn (stream, "r%d", rm);
503 fprintf_fn (stream, "@r%d+", rm);
506 fprintf_fn (stream, "@-r%d", rm);
509 fprintf_fn (stream, "@r%d", rm);
512 fprintf_fn (stream, "@(%d,r%d)", imm, rm);
515 fprintf_fn (stream, "r%d_bank", rb);
519 disp_pc_addr = imm + 4 + (memaddr & relmask);
520 (*info->print_address_func) (disp_pc_addr, info);
523 fprintf_fn (stream, "@(r0,r%d)", rn);
526 fprintf_fn (stream, "@(r0,r%d)", rm);
529 fprintf_fn (stream, "@(%d,gbr)",imm);
532 fprintf_fn (stream, "@(r0,gbr)");
536 (*info->print_address_func) (imm + memaddr, info);
539 fprintf_fn (stream, "sr");
542 fprintf_fn (stream, "gbr");
545 fprintf_fn (stream, "vbr");
548 fprintf_fn (stream, "dsr");
551 fprintf_fn (stream, "mod");
554 fprintf_fn (stream, "re");
557 fprintf_fn (stream, "rs");
560 fprintf_fn (stream, "a0");
563 fprintf_fn (stream, "x0");
566 fprintf_fn (stream, "x1");
569 fprintf_fn (stream, "y0");
572 fprintf_fn (stream, "y1");
575 print_dsp_reg (rm, fprintf_fn, stream);
578 fprintf_fn (stream, "ssr");
581 fprintf_fn (stream, "spc");
584 fprintf_fn (stream, "mach");
587 fprintf_fn (stream ,"macl");
590 fprintf_fn (stream, "pr");
593 fprintf_fn (stream, "sgr");
596 fprintf_fn (stream, "dbr");
599 fprintf_fn (stream, "fr%d", rn);
602 fprintf_fn (stream, "fr%d", rm);
607 fprintf_fn (stream, "xd%d", rn & ~1);
612 fprintf_fn (stream, "dr%d", rn);
617 fprintf_fn (stream, "xd%d", rm & ~1);
621 fprintf_fn (stream, "dr%d", rm);
625 fprintf_fn (stream, "fpscr");
629 fprintf_fn (stream, "fpul");
632 fprintf_fn (stream, "fr0");
635 fprintf_fn (stream, "fv%d", rn*4);
638 fprintf_fn (stream, "fv%d", rm*4);
641 fprintf_fn (stream, "xmtrx");
649 /* This code prints instructions in delay slots on the same line
650 as the instruction which needs the delay slots. This can be
651 confusing, since other disassembler don't work this way, and
652 it means that the instructions are not all in a line. So I
654 if (!(info->flags & 1)
655 && (op->name[0] == 'j'
656 || (op->name[0] == 'b'
657 && (op->name[1] == 'r'
658 || op->name[1] == 's'))
659 || (op->name[0] == 'r' && op->name[1] == 't')
660 || (op->name[0] == 'b' && op->name[2] == '.')))
663 fprintf_fn (stream, "\t(slot ");
664 print_insn_shx (memaddr + 2, info);
666 fprintf_fn (stream, ")");
671 if (disp_pc && strcmp (op->name, "mova") != 0)
676 if (relmask == ~ (bfd_vma) 1)
680 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
687 if ((info->flags & LITTLE_BIT) != 0)
688 val = bfd_getl16 (bytes);
690 val = bfd_getb16 (bytes);
694 if ((info->flags & LITTLE_BIT) != 0)
695 val = bfd_getl32 (bytes);
697 val = bfd_getb32 (bytes);
699 fprintf_fn (stream, "\t! 0x%x", val);
708 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
713 print_insn_shl (memaddr, info)
715 struct disassemble_info *info;
719 info->flags = LITTLE_BIT;
720 r = print_insn_shx (memaddr, info);
725 print_insn_sh (memaddr, info)
727 struct disassemble_info *info;
732 r = print_insn_shx (memaddr, info);