Add GNU Free Documentation License
[binutils.git] / opcodes / sh-dis.c
blobe4675157189998e2602f5fec2143a337b57df904
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. */
19 #include <stdio.h>
20 #include "sysdep.h"
21 #define STATIC_TABLE
22 #define DEFINE_TABLE
24 #include "sh-opc.h"
25 #include "dis-asm.h"
27 #define LITTLE_BIT 2
29 static void
30 print_movxy (op, rn, rm, fprintf_fn, stream)
31 sh_opcode_info *op;
32 int rn, rm;
33 fprintf_ftype fprintf_fn;
34 void *stream;
36 int n;
38 fprintf_fn (stream, "%s\t", op->name);
39 for (n = 0; n < 2; n++)
41 switch (op->arg[n])
43 case A_IND_N:
44 fprintf_fn (stream, "@r%d", rn);
45 break;
46 case A_INC_N:
47 fprintf_fn (stream, "@r%d+", rn);
48 break;
49 case A_PMOD_N:
50 fprintf_fn (stream, "@r%d+r8", rn);
51 break;
52 case A_PMODY_N:
53 fprintf_fn (stream, "@r%d+r9", rn);
54 break;
55 case DSP_REG_M:
56 fprintf_fn (stream, "a%c", '0' + rm);
57 break;
58 case DSP_REG_X:
59 fprintf_fn (stream, "x%c", '0' + rm);
60 break;
61 case DSP_REG_Y:
62 fprintf_fn (stream, "y%c", '0' + rm);
63 break;
64 default:
65 abort ();
67 if (n == 0)
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. */
77 static void
78 print_insn_ddt (insn, info)
79 int insn;
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. */
86 if (insn == 0x000)
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);
98 else
100 static sh_opcode_info *first_movx, *first_movy;
101 sh_opcode_info *opx, *opy;
102 int insn_x, insn_y;
104 if (! first_movx)
106 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
107 first_movx++;
108 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
109 first_movy++;
111 insn_x = (insn >> 2) & 0xb;
112 if (insn_x)
114 for (opx = first_movx; opx->nibbles[2] != insn_x;)
115 opx++;
116 print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
117 fprintf_fn, stream);
119 insn_y = (insn & 3) | ((insn >> 1) & 8);
120 if (insn_y)
122 if (insn_x)
123 fprintf_fn (stream, "\t");
124 for (opy = first_movy; opy->nibbles[2] != insn_y;)
125 opy++;
126 print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
127 fprintf_fn, stream);
132 static void
133 print_dsp_reg (rm, fprintf_fn, stream)
134 int rm;
135 fprintf_ftype fprintf_fn;
136 void *stream;
138 switch (rm)
140 case A_A1_NUM:
141 fprintf_fn (stream, "a1");
142 break;
143 case A_A0_NUM:
144 fprintf_fn (stream, "a0");
145 break;
146 case A_X0_NUM:
147 fprintf_fn (stream, "x0");
148 break;
149 case A_X1_NUM:
150 fprintf_fn (stream, "x1");
151 break;
152 case A_Y0_NUM:
153 fprintf_fn (stream, "y0");
154 break;
155 case A_Y1_NUM:
156 fprintf_fn (stream, "y1");
157 break;
158 case A_M0_NUM:
159 fprintf_fn (stream, "m0");
160 break;
161 case A_A1G_NUM:
162 fprintf_fn (stream, "a1g");
163 break;
164 case A_M1_NUM:
165 fprintf_fn (stream, "m1");
166 break;
167 case A_A0G_NUM:
168 fprintf_fn (stream, "a0g");
169 break;
170 default:
171 fprintf_fn (stream, "0x%x", rm);
172 break;
176 static void
177 print_insn_ppi (field_b, info)
178 int field_b;
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 int nib1, nib2, nib3;
186 char *dc;
187 sh_opcode_info *op;
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);
195 return;
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]);
217 return;
220 nib1 = PPIC;
221 nib2 = field_b >> 12 & 0xf;
222 nib3 = field_b >> 8 & 0xf;
223 switch (nib3 & 0x3)
225 case 0:
226 dc = "";
227 nib1 = PPI3;
228 break;
229 case 1:
230 dc = "";
231 break;
232 case 2:
233 dc = "dct ";
234 nib3 -= 1;
235 break;
236 case 3:
237 dc = "dcf ";
238 nib3 -= 2;
239 break;
241 for (op = sh_table; op->name; op++)
243 if (op->nibbles[1] == nib1
244 && op->nibbles[2] == nib2
245 && op->nibbles[3] == nib3)
247 int n;
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, ",");
254 switch (op->arg[n])
256 case DSP_REG_N:
257 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
258 break;
259 case DSP_REG_X:
260 fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
261 break;
262 case DSP_REG_Y:
263 fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
264 break;
265 case A_MACH:
266 fprintf_fn (stream, "mach");
267 break;
268 case A_MACL:
269 fprintf_fn (stream, "macl");
270 break;
271 default:
272 abort ();
275 return;
278 /* Not found. */
279 fprintf_fn (stream, ".word 0x%x", field_b);
282 static int
283 print_insn_shx (memaddr, info)
284 bfd_vma memaddr;
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];
291 int status;
292 bfd_vma relmask = ~(bfd_vma) 0;
293 sh_opcode_info *op;
294 int target_arch;
296 switch (info->mach)
298 case bfd_mach_sh:
299 target_arch = arch_sh1;
300 break;
301 case bfd_mach_sh2:
302 target_arch = arch_sh2;
303 break;
304 case bfd_mach_sh_dsp:
305 target_arch = arch_sh_dsp;
306 break;
307 case bfd_mach_sh3:
308 target_arch = arch_sh3;
309 break;
310 case bfd_mach_sh3_dsp:
311 target_arch = arch_sh3_dsp;
312 break;
313 case bfd_mach_sh3e:
314 target_arch = arch_sh3e;
315 break;
316 case bfd_mach_sh4:
317 target_arch = arch_sh4;
318 break;
319 default:
320 abort ();
323 status = info->read_memory_func (memaddr, insn, 2, info);
325 if (status != 0)
327 info->memory_error_func (status, memaddr, info);
328 return -1;
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;
339 else
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)
350 if (nibs[1] & 8)
352 int field_b;
354 status = info->read_memory_func (memaddr + 2, insn, 2, info);
356 if (status != 0)
358 info->memory_error_func (status, memaddr + 2, info);
359 return -1;
362 if (info->flags & LITTLE_BIT)
363 field_b = insn[1] << 8 | insn[0];
364 else
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);
369 return 4;
371 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
372 return 2;
374 for (op = sh_table; op->name; op++)
376 int n;
377 int imm = 0;
378 int rn = 0;
379 int rm = 0;
380 int rb = 0;
381 int disp_pc;
382 bfd_vma disp_pc_addr = 0;
384 if ((op->arch & target_arch) == 0)
385 goto fail;
386 for (n = 0; n < 4; n++)
388 int i = op->nibbles[n];
390 if (i < 16)
392 if (nibs[n] == i)
393 continue;
394 goto fail;
396 switch (i)
398 case BRANCH_8:
399 imm = (nibs[2] << 4) | (nibs[3]);
400 if (imm & 0x80)
401 imm |= ~0xff;
402 imm = ((char) imm) * 2 + 4;
403 goto ok;
404 case BRANCH_12:
405 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
406 if (imm & 0x800)
407 imm |= ~0xfff;
408 imm = imm * 2 + 4;
409 goto ok;
410 case IMM0_4:
411 case IMM1_4:
412 imm = nibs[3];
413 goto ok;
414 case IMM0_4BY2:
415 case IMM1_4BY2:
416 imm = nibs[3] << 1;
417 goto ok;
418 case IMM0_4BY4:
419 case IMM1_4BY4:
420 imm = nibs[3] << 2;
421 goto ok;
422 case IMM0_8:
423 case IMM1_8:
424 imm = (nibs[2] << 4) | nibs[3];
425 goto ok;
426 case PCRELIMM_8BY2:
427 imm = ((nibs[2] << 4) | nibs[3]) << 1;
428 relmask = ~(bfd_vma) 1;
429 goto ok;
430 case PCRELIMM_8BY4:
431 imm = ((nibs[2] << 4) | nibs[3]) << 2;
432 relmask = ~(bfd_vma) 3;
433 goto ok;
434 case IMM0_8BY2:
435 case IMM1_8BY2:
436 imm = ((nibs[2] << 4) | nibs[3]) << 1;
437 goto ok;
438 case IMM0_8BY4:
439 case IMM1_8BY4:
440 imm = ((nibs[2] << 4) | nibs[3]) << 2;
441 goto ok;
442 case REG_N:
443 rn = nibs[n];
444 break;
445 case REG_M:
446 rm = nibs[n];
447 break;
448 case REG_NM:
449 rn = (nibs[n] & 0xc) >> 2;
450 rm = (nibs[n] & 0x3);
451 break;
452 case REG_B:
453 rb = nibs[n] & 0x07;
454 break;
455 case SDT_REG_N:
456 /* sh-dsp: single data transfer. */
457 rn = nibs[n];
458 if ((rn & 0xc) != 4)
459 goto fail;
460 rn = rn & 0x3;
461 rn |= (rn & 2) << 1;
462 break;
463 case PPI:
464 case REPEAT:
465 goto fail;
466 default:
467 abort ();
472 fprintf_fn (stream, "%s\t", op->name);
473 disp_pc = 0;
474 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
476 if (n && op->arg[1] != A_END)
477 fprintf_fn (stream, ",");
478 switch (op->arg[n])
480 case A_IMM:
481 fprintf_fn (stream, "#%d", (char) (imm));
482 break;
483 case A_R0:
484 fprintf_fn (stream, "r0");
485 break;
486 case A_REG_N:
487 fprintf_fn (stream, "r%d", rn);
488 break;
489 case A_INC_N:
490 fprintf_fn (stream, "@r%d+", rn);
491 break;
492 case A_DEC_N:
493 fprintf_fn (stream, "@-r%d", rn);
494 break;
495 case A_IND_N:
496 fprintf_fn (stream, "@r%d", rn);
497 break;
498 case A_DISP_REG_N:
499 fprintf_fn (stream, "@(%d,r%d)", imm, rn);
500 break;
501 case A_PMOD_N:
502 fprintf_fn (stream, "@r%d+r8", rn);
503 break;
504 case A_REG_M:
505 fprintf_fn (stream, "r%d", rm);
506 break;
507 case A_INC_M:
508 fprintf_fn (stream, "@r%d+", rm);
509 break;
510 case A_DEC_M:
511 fprintf_fn (stream, "@-r%d", rm);
512 break;
513 case A_IND_M:
514 fprintf_fn (stream, "@r%d", rm);
515 break;
516 case A_DISP_REG_M:
517 fprintf_fn (stream, "@(%d,r%d)", imm, rm);
518 break;
519 case A_REG_B:
520 fprintf_fn (stream, "r%d_bank", rb);
521 break;
522 case A_DISP_PC:
523 disp_pc = 1;
524 disp_pc_addr = imm + 4 + (memaddr & relmask);
525 (*info->print_address_func) (disp_pc_addr, info);
526 break;
527 case A_IND_R0_REG_N:
528 fprintf_fn (stream, "@(r0,r%d)", rn);
529 break;
530 case A_IND_R0_REG_M:
531 fprintf_fn (stream, "@(r0,r%d)", rm);
532 break;
533 case A_DISP_GBR:
534 fprintf_fn (stream, "@(%d,gbr)", imm);
535 break;
536 case A_R0_GBR:
537 fprintf_fn (stream, "@(r0,gbr)");
538 break;
539 case A_BDISP12:
540 case A_BDISP8:
541 (*info->print_address_func) (imm + memaddr, info);
542 break;
543 case A_SR:
544 fprintf_fn (stream, "sr");
545 break;
546 case A_GBR:
547 fprintf_fn (stream, "gbr");
548 break;
549 case A_VBR:
550 fprintf_fn (stream, "vbr");
551 break;
552 case A_DSR:
553 fprintf_fn (stream, "dsr");
554 break;
555 case A_MOD:
556 fprintf_fn (stream, "mod");
557 break;
558 case A_RE:
559 fprintf_fn (stream, "re");
560 break;
561 case A_RS:
562 fprintf_fn (stream, "rs");
563 break;
564 case A_A0:
565 fprintf_fn (stream, "a0");
566 break;
567 case A_X0:
568 fprintf_fn (stream, "x0");
569 break;
570 case A_X1:
571 fprintf_fn (stream, "x1");
572 break;
573 case A_Y0:
574 fprintf_fn (stream, "y0");
575 break;
576 case A_Y1:
577 fprintf_fn (stream, "y1");
578 break;
579 case DSP_REG_M:
580 print_dsp_reg (rm, fprintf_fn, stream);
581 break;
582 case A_SSR:
583 fprintf_fn (stream, "ssr");
584 break;
585 case A_SPC:
586 fprintf_fn (stream, "spc");
587 break;
588 case A_MACH:
589 fprintf_fn (stream, "mach");
590 break;
591 case A_MACL:
592 fprintf_fn (stream, "macl");
593 break;
594 case A_PR:
595 fprintf_fn (stream, "pr");
596 break;
597 case A_SGR:
598 fprintf_fn (stream, "sgr");
599 break;
600 case A_DBR:
601 fprintf_fn (stream, "dbr");
602 break;
603 case F_REG_N:
604 fprintf_fn (stream, "fr%d", rn);
605 break;
606 case F_REG_M:
607 fprintf_fn (stream, "fr%d", rm);
608 break;
609 case DX_REG_N:
610 if (rn & 1)
612 fprintf_fn (stream, "xd%d", rn & ~1);
613 break;
615 d_reg_n:
616 case D_REG_N:
617 fprintf_fn (stream, "dr%d", rn);
618 break;
619 case DX_REG_M:
620 if (rm & 1)
622 fprintf_fn (stream, "xd%d", rm & ~1);
623 break;
625 case D_REG_M:
626 fprintf_fn (stream, "dr%d", rm);
627 break;
628 case FPSCR_M:
629 case FPSCR_N:
630 fprintf_fn (stream, "fpscr");
631 break;
632 case FPUL_M:
633 case FPUL_N:
634 fprintf_fn (stream, "fpul");
635 break;
636 case F_FR0:
637 fprintf_fn (stream, "fr0");
638 break;
639 case V_REG_N:
640 fprintf_fn (stream, "fv%d", rn * 4);
641 break;
642 case V_REG_M:
643 fprintf_fn (stream, "fv%d", rm * 4);
644 break;
645 case XMTRX_M4:
646 fprintf_fn (stream, "xmtrx");
647 break;
648 default:
649 abort ();
653 #if 0
654 /* This code prints instructions in delay slots on the same line
655 as the instruction which needs the delay slots. This can be
656 confusing, since other disassembler don't work this way, and
657 it means that the instructions are not all in a line. So I
658 disabled it. Ian. */
659 if (!(info->flags & 1)
660 && (op->name[0] == 'j'
661 || (op->name[0] == 'b'
662 && (op->name[1] == 'r'
663 || op->name[1] == 's'))
664 || (op->name[0] == 'r' && op->name[1] == 't')
665 || (op->name[0] == 'b' && op->name[2] == '.')))
667 info->flags |= 1;
668 fprintf_fn (stream, "\t(slot ");
669 print_insn_shx (memaddr + 2, info);
670 info->flags &= ~1;
671 fprintf_fn (stream, ")");
672 return 4;
674 #endif
676 if (disp_pc && strcmp (op->name, "mova") != 0)
678 int size;
679 bfd_byte bytes[4];
681 if (relmask == ~(bfd_vma) 1)
682 size = 2;
683 else
684 size = 4;
685 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
686 if (status == 0)
688 unsigned int val;
690 if (size == 2)
692 if ((info->flags & LITTLE_BIT) != 0)
693 val = bfd_getl16 (bytes);
694 else
695 val = bfd_getb16 (bytes);
697 else
699 if ((info->flags & LITTLE_BIT) != 0)
700 val = bfd_getl32 (bytes);
701 else
702 val = bfd_getb32 (bytes);
704 fprintf_fn (stream, "\t! 0x%x", val);
708 return 2;
709 fail:
713 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
714 return 2;
718 print_insn_shl (memaddr, info)
719 bfd_vma memaddr;
720 struct disassemble_info *info;
722 int r;
724 info->flags = LITTLE_BIT;
725 r = print_insn_shx (memaddr, info);
726 return r;
730 print_insn_sh (memaddr, info)
731 bfd_vma memaddr;
732 struct disassemble_info *info;
734 int r;
736 info->flags = 0;
737 r = print_insn_shx (memaddr, info);
738 return r;