]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/sh-dis.c
Contribute sh64-elf.
[thirdparty/binutils-gdb.git] / opcodes / sh-dis.c
1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001
3 Free Software Foundation, Inc.
4
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.
9
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.
14
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. */
18
19 #include <stdio.h>
20 #include "sysdep.h"
21 #define STATIC_TABLE
22 #define DEFINE_TABLE
23
24 #include "sh-opc.h"
25 #include "dis-asm.h"
26
27 #define LITTLE_BIT 2
28
29 static void print_movxy
30 PARAMS ((sh_opcode_info *, int, int, fprintf_ftype, void *));
31 static void print_insn_ddt PARAMS ((int, struct disassemble_info *));
32 static void print_dsp_reg PARAMS ((int, fprintf_ftype, void *));
33 static void print_insn_ppi PARAMS ((int, struct disassemble_info *));
34 static int print_insn_shx PARAMS ((bfd_vma, struct disassemble_info *));
35
36 static void
37 print_movxy (op, rn, rm, fprintf_fn, stream)
38 sh_opcode_info *op;
39 int rn, rm;
40 fprintf_ftype fprintf_fn;
41 void *stream;
42 {
43 int n;
44
45 fprintf_fn (stream, "%s\t", op->name);
46 for (n = 0; n < 2; n++)
47 {
48 switch (op->arg[n])
49 {
50 case A_IND_N:
51 fprintf_fn (stream, "@r%d", rn);
52 break;
53 case A_INC_N:
54 fprintf_fn (stream, "@r%d+", rn);
55 break;
56 case A_PMOD_N:
57 fprintf_fn (stream, "@r%d+r8", rn);
58 break;
59 case A_PMODY_N:
60 fprintf_fn (stream, "@r%d+r9", rn);
61 break;
62 case DSP_REG_M:
63 fprintf_fn (stream, "a%c", '0' + rm);
64 break;
65 case DSP_REG_X:
66 fprintf_fn (stream, "x%c", '0' + rm);
67 break;
68 case DSP_REG_Y:
69 fprintf_fn (stream, "y%c", '0' + rm);
70 break;
71 default:
72 abort ();
73 }
74 if (n == 0)
75 fprintf_fn (stream, ",");
76 }
77 }
78
79 /* Print a double data transfer insn. INSN is just the lower three
80 nibbles of the insn, i.e. field a and the bit that indicates if
81 a parallel processing insn follows.
82 Return nonzero if a field b of a parallel processing insns follows. */
83
84 static void
85 print_insn_ddt (insn, info)
86 int insn;
87 struct disassemble_info *info;
88 {
89 fprintf_ftype fprintf_fn = info->fprintf_func;
90 void *stream = info->stream;
91
92 /* If this is just a nop, make sure to emit something. */
93 if (insn == 0x000)
94 fprintf_fn (stream, "nopx\tnopy");
95
96 /* If a parallel processing insn was printed before,
97 and we got a non-nop, emit a tab. */
98 if ((insn & 0x800) && (insn & 0x3ff))
99 fprintf_fn (stream, "\t");
100
101 /* Check if either the x or y part is invalid. */
102 if (((insn & 0xc) == 0 && (insn & 0x2a0))
103 || ((insn & 3) == 0 && (insn & 0x150)))
104 fprintf_fn (stream, ".word 0x%x", insn);
105 else
106 {
107 static sh_opcode_info *first_movx, *first_movy;
108 sh_opcode_info *opx, *opy;
109 unsigned int insn_x, insn_y;
110
111 if (! first_movx)
112 {
113 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
114 first_movx++;
115 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
116 first_movy++;
117 }
118 insn_x = (insn >> 2) & 0xb;
119 if (insn_x)
120 {
121 for (opx = first_movx; opx->nibbles[2] != insn_x;)
122 opx++;
123 print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
124 fprintf_fn, stream);
125 }
126 insn_y = (insn & 3) | ((insn >> 1) & 8);
127 if (insn_y)
128 {
129 if (insn_x)
130 fprintf_fn (stream, "\t");
131 for (opy = first_movy; opy->nibbles[2] != insn_y;)
132 opy++;
133 print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
134 fprintf_fn, stream);
135 }
136 }
137 }
138
139 static void
140 print_dsp_reg (rm, fprintf_fn, stream)
141 int rm;
142 fprintf_ftype fprintf_fn;
143 void *stream;
144 {
145 switch (rm)
146 {
147 case A_A1_NUM:
148 fprintf_fn (stream, "a1");
149 break;
150 case A_A0_NUM:
151 fprintf_fn (stream, "a0");
152 break;
153 case A_X0_NUM:
154 fprintf_fn (stream, "x0");
155 break;
156 case A_X1_NUM:
157 fprintf_fn (stream, "x1");
158 break;
159 case A_Y0_NUM:
160 fprintf_fn (stream, "y0");
161 break;
162 case A_Y1_NUM:
163 fprintf_fn (stream, "y1");
164 break;
165 case A_M0_NUM:
166 fprintf_fn (stream, "m0");
167 break;
168 case A_A1G_NUM:
169 fprintf_fn (stream, "a1g");
170 break;
171 case A_M1_NUM:
172 fprintf_fn (stream, "m1");
173 break;
174 case A_A0G_NUM:
175 fprintf_fn (stream, "a0g");
176 break;
177 default:
178 fprintf_fn (stream, "0x%x", rm);
179 break;
180 }
181 }
182
183 static void
184 print_insn_ppi (field_b, info)
185 int field_b;
186 struct disassemble_info *info;
187 {
188 static char *sx_tab[] = { "x0", "x1", "a0", "a1" };
189 static char *sy_tab[] = { "y0", "y1", "m0", "m1" };
190 fprintf_ftype fprintf_fn = info->fprintf_func;
191 void *stream = info->stream;
192 unsigned int nib1, nib2, nib3;
193 char *dc = NULL;
194 sh_opcode_info *op;
195
196 if ((field_b & 0xe800) == 0)
197 {
198 fprintf_fn (stream, "psh%c\t#%d,",
199 field_b & 0x1000 ? 'a' : 'l',
200 (field_b >> 4) & 127);
201 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
202 return;
203 }
204 if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
205 {
206 static char *du_tab[] = { "x0", "y0", "a0", "a1" };
207 static char *se_tab[] = { "x0", "x1", "y0", "a1" };
208 static char *sf_tab[] = { "y0", "y1", "x0", "a1" };
209 static char *sg_tab[] = { "m0", "m1", "a0", "a1" };
210
211 if (field_b & 0x2000)
212 {
213 fprintf_fn (stream, "p%s %s,%s,%s\t",
214 (field_b & 0x1000) ? "add" : "sub",
215 sx_tab[(field_b >> 6) & 3],
216 sy_tab[(field_b >> 4) & 3],
217 du_tab[(field_b >> 0) & 3]);
218 }
219 fprintf_fn (stream, "pmuls%c%s,%s,%s",
220 field_b & 0x2000 ? ' ' : '\t',
221 se_tab[(field_b >> 10) & 3],
222 sf_tab[(field_b >> 8) & 3],
223 sg_tab[(field_b >> 2) & 3]);
224 return;
225 }
226
227 nib1 = PPIC;
228 nib2 = field_b >> 12 & 0xf;
229 nib3 = field_b >> 8 & 0xf;
230 switch (nib3 & 0x3)
231 {
232 case 0:
233 dc = "";
234 nib1 = PPI3;
235 break;
236 case 1:
237 dc = "";
238 break;
239 case 2:
240 dc = "dct ";
241 nib3 -= 1;
242 break;
243 case 3:
244 dc = "dcf ";
245 nib3 -= 2;
246 break;
247 }
248 for (op = sh_table; op->name; op++)
249 {
250 if (op->nibbles[1] == nib1
251 && op->nibbles[2] == nib2
252 && op->nibbles[3] == nib3)
253 {
254 int n;
255
256 fprintf_fn (stream, "%s%s\t", dc, op->name);
257 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
258 {
259 if (n && op->arg[1] != A_END)
260 fprintf_fn (stream, ",");
261 switch (op->arg[n])
262 {
263 case DSP_REG_N:
264 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
265 break;
266 case DSP_REG_X:
267 fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
268 break;
269 case DSP_REG_Y:
270 fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
271 break;
272 case A_MACH:
273 fprintf_fn (stream, "mach");
274 break;
275 case A_MACL:
276 fprintf_fn (stream, "macl");
277 break;
278 default:
279 abort ();
280 }
281 }
282 return;
283 }
284 }
285 /* Not found. */
286 fprintf_fn (stream, ".word 0x%x", field_b);
287 }
288
289 static int
290 print_insn_shx (memaddr, info)
291 bfd_vma memaddr;
292 struct disassemble_info *info;
293 {
294 fprintf_ftype fprintf_fn = info->fprintf_func;
295 void *stream = info->stream;
296 unsigned char insn[2];
297 unsigned char nibs[4];
298 int status;
299 bfd_vma relmask = ~(bfd_vma) 0;
300 sh_opcode_info *op;
301 int target_arch;
302
303 switch (info->mach)
304 {
305 case bfd_mach_sh:
306 target_arch = arch_sh1;
307 break;
308 case bfd_mach_sh2:
309 target_arch = arch_sh2;
310 break;
311 case bfd_mach_sh_dsp:
312 target_arch = arch_sh_dsp;
313 break;
314 case bfd_mach_sh3:
315 target_arch = arch_sh3;
316 break;
317 case bfd_mach_sh3_dsp:
318 target_arch = arch_sh3_dsp;
319 break;
320 case bfd_mach_sh3e:
321 target_arch = arch_sh3e;
322 break;
323 case bfd_mach_sh4:
324 target_arch = arch_sh4;
325 break;
326 case bfd_mach_sh5:
327 /* When we get here for sh64, it's because we want to disassemble
328 SHcompact, i.e. arch_sh4. */
329 target_arch = arch_sh4;
330 break;
331 default:
332 abort ();
333 }
334
335 status = info->read_memory_func (memaddr, insn, 2, info);
336
337 if (status != 0)
338 {
339 info->memory_error_func (status, memaddr, info);
340 return -1;
341 }
342
343 if (info->flags & LITTLE_BIT)
344 {
345 nibs[0] = (insn[1] >> 4) & 0xf;
346 nibs[1] = insn[1] & 0xf;
347
348 nibs[2] = (insn[0] >> 4) & 0xf;
349 nibs[3] = insn[0] & 0xf;
350 }
351 else
352 {
353 nibs[0] = (insn[0] >> 4) & 0xf;
354 nibs[1] = insn[0] & 0xf;
355
356 nibs[2] = (insn[1] >> 4) & 0xf;
357 nibs[3] = insn[1] & 0xf;
358 }
359
360 if (nibs[0] == 0xf && (nibs[1] & 4) == 0 && target_arch & arch_sh_dsp_up)
361 {
362 if (nibs[1] & 8)
363 {
364 int field_b;
365
366 status = info->read_memory_func (memaddr + 2, insn, 2, info);
367
368 if (status != 0)
369 {
370 info->memory_error_func (status, memaddr + 2, info);
371 return -1;
372 }
373
374 if (info->flags & LITTLE_BIT)
375 field_b = insn[1] << 8 | insn[0];
376 else
377 field_b = insn[0] << 8 | insn[1];
378
379 print_insn_ppi (field_b, info);
380 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
381 return 4;
382 }
383 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
384 return 2;
385 }
386 for (op = sh_table; op->name; op++)
387 {
388 int n;
389 int imm = 0;
390 int rn = 0;
391 int rm = 0;
392 int rb = 0;
393 int disp_pc;
394 bfd_vma disp_pc_addr = 0;
395
396 if ((op->arch & target_arch) == 0)
397 goto fail;
398 for (n = 0; n < 4; n++)
399 {
400 int i = op->nibbles[n];
401
402 if (i < 16)
403 {
404 if (nibs[n] == i)
405 continue;
406 goto fail;
407 }
408 switch (i)
409 {
410 case BRANCH_8:
411 imm = (nibs[2] << 4) | (nibs[3]);
412 if (imm & 0x80)
413 imm |= ~0xff;
414 imm = ((char) imm) * 2 + 4;
415 goto ok;
416 case BRANCH_12:
417 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
418 if (imm & 0x800)
419 imm |= ~0xfff;
420 imm = imm * 2 + 4;
421 goto ok;
422 case IMM0_4:
423 case IMM1_4:
424 imm = nibs[3];
425 goto ok;
426 case IMM0_4BY2:
427 case IMM1_4BY2:
428 imm = nibs[3] << 1;
429 goto ok;
430 case IMM0_4BY4:
431 case IMM1_4BY4:
432 imm = nibs[3] << 2;
433 goto ok;
434 case IMM0_8:
435 case IMM1_8:
436 imm = (nibs[2] << 4) | nibs[3];
437 goto ok;
438 case PCRELIMM_8BY2:
439 imm = ((nibs[2] << 4) | nibs[3]) << 1;
440 relmask = ~(bfd_vma) 1;
441 goto ok;
442 case PCRELIMM_8BY4:
443 imm = ((nibs[2] << 4) | nibs[3]) << 2;
444 relmask = ~(bfd_vma) 3;
445 goto ok;
446 case IMM0_8BY2:
447 case IMM1_8BY2:
448 imm = ((nibs[2] << 4) | nibs[3]) << 1;
449 goto ok;
450 case IMM0_8BY4:
451 case IMM1_8BY4:
452 imm = ((nibs[2] << 4) | nibs[3]) << 2;
453 goto ok;
454 case REG_N:
455 rn = nibs[n];
456 break;
457 case REG_M:
458 rm = nibs[n];
459 break;
460 case REG_NM:
461 rn = (nibs[n] & 0xc) >> 2;
462 rm = (nibs[n] & 0x3);
463 break;
464 case REG_B:
465 rb = nibs[n] & 0x07;
466 break;
467 case SDT_REG_N:
468 /* sh-dsp: single data transfer. */
469 rn = nibs[n];
470 if ((rn & 0xc) != 4)
471 goto fail;
472 rn = rn & 0x3;
473 rn |= (!(rn & 2)) << 2;
474 break;
475 case PPI:
476 case REPEAT:
477 goto fail;
478 default:
479 abort ();
480 }
481 }
482
483 ok:
484 fprintf_fn (stream, "%s\t", op->name);
485 disp_pc = 0;
486 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
487 {
488 if (n && op->arg[1] != A_END)
489 fprintf_fn (stream, ",");
490 switch (op->arg[n])
491 {
492 case A_IMM:
493 fprintf_fn (stream, "#%d", (char) (imm));
494 break;
495 case A_R0:
496 fprintf_fn (stream, "r0");
497 break;
498 case A_REG_N:
499 fprintf_fn (stream, "r%d", rn);
500 break;
501 case A_INC_N:
502 fprintf_fn (stream, "@r%d+", rn);
503 break;
504 case A_DEC_N:
505 fprintf_fn (stream, "@-r%d", rn);
506 break;
507 case A_IND_N:
508 fprintf_fn (stream, "@r%d", rn);
509 break;
510 case A_DISP_REG_N:
511 fprintf_fn (stream, "@(%d,r%d)", imm, rn);
512 break;
513 case A_PMOD_N:
514 fprintf_fn (stream, "@r%d+r8", rn);
515 break;
516 case A_REG_M:
517 fprintf_fn (stream, "r%d", rm);
518 break;
519 case A_INC_M:
520 fprintf_fn (stream, "@r%d+", rm);
521 break;
522 case A_DEC_M:
523 fprintf_fn (stream, "@-r%d", rm);
524 break;
525 case A_IND_M:
526 fprintf_fn (stream, "@r%d", rm);
527 break;
528 case A_DISP_REG_M:
529 fprintf_fn (stream, "@(%d,r%d)", imm, rm);
530 break;
531 case A_REG_B:
532 fprintf_fn (stream, "r%d_bank", rb);
533 break;
534 case A_DISP_PC:
535 disp_pc = 1;
536 disp_pc_addr = imm + 4 + (memaddr & relmask);
537 (*info->print_address_func) (disp_pc_addr, info);
538 break;
539 case A_IND_R0_REG_N:
540 fprintf_fn (stream, "@(r0,r%d)", rn);
541 break;
542 case A_IND_R0_REG_M:
543 fprintf_fn (stream, "@(r0,r%d)", rm);
544 break;
545 case A_DISP_GBR:
546 fprintf_fn (stream, "@(%d,gbr)", imm);
547 break;
548 case A_R0_GBR:
549 fprintf_fn (stream, "@(r0,gbr)");
550 break;
551 case A_BDISP12:
552 case A_BDISP8:
553 (*info->print_address_func) (imm + memaddr, info);
554 break;
555 case A_SR:
556 fprintf_fn (stream, "sr");
557 break;
558 case A_GBR:
559 fprintf_fn (stream, "gbr");
560 break;
561 case A_VBR:
562 fprintf_fn (stream, "vbr");
563 break;
564 case A_DSR:
565 fprintf_fn (stream, "dsr");
566 break;
567 case A_MOD:
568 fprintf_fn (stream, "mod");
569 break;
570 case A_RE:
571 fprintf_fn (stream, "re");
572 break;
573 case A_RS:
574 fprintf_fn (stream, "rs");
575 break;
576 case A_A0:
577 fprintf_fn (stream, "a0");
578 break;
579 case A_X0:
580 fprintf_fn (stream, "x0");
581 break;
582 case A_X1:
583 fprintf_fn (stream, "x1");
584 break;
585 case A_Y0:
586 fprintf_fn (stream, "y0");
587 break;
588 case A_Y1:
589 fprintf_fn (stream, "y1");
590 break;
591 case DSP_REG_M:
592 print_dsp_reg (rm, fprintf_fn, stream);
593 break;
594 case A_SSR:
595 fprintf_fn (stream, "ssr");
596 break;
597 case A_SPC:
598 fprintf_fn (stream, "spc");
599 break;
600 case A_MACH:
601 fprintf_fn (stream, "mach");
602 break;
603 case A_MACL:
604 fprintf_fn (stream, "macl");
605 break;
606 case A_PR:
607 fprintf_fn (stream, "pr");
608 break;
609 case A_SGR:
610 fprintf_fn (stream, "sgr");
611 break;
612 case A_DBR:
613 fprintf_fn (stream, "dbr");
614 break;
615 case F_REG_N:
616 fprintf_fn (stream, "fr%d", rn);
617 break;
618 case F_REG_M:
619 fprintf_fn (stream, "fr%d", rm);
620 break;
621 case DX_REG_N:
622 if (rn & 1)
623 {
624 fprintf_fn (stream, "xd%d", rn & ~1);
625 break;
626 }
627 case D_REG_N:
628 fprintf_fn (stream, "dr%d", rn);
629 break;
630 case DX_REG_M:
631 if (rm & 1)
632 {
633 fprintf_fn (stream, "xd%d", rm & ~1);
634 break;
635 }
636 case D_REG_M:
637 fprintf_fn (stream, "dr%d", rm);
638 break;
639 case FPSCR_M:
640 case FPSCR_N:
641 fprintf_fn (stream, "fpscr");
642 break;
643 case FPUL_M:
644 case FPUL_N:
645 fprintf_fn (stream, "fpul");
646 break;
647 case F_FR0:
648 fprintf_fn (stream, "fr0");
649 break;
650 case V_REG_N:
651 fprintf_fn (stream, "fv%d", rn * 4);
652 break;
653 case V_REG_M:
654 fprintf_fn (stream, "fv%d", rm * 4);
655 break;
656 case XMTRX_M4:
657 fprintf_fn (stream, "xmtrx");
658 break;
659 default:
660 abort ();
661 }
662 }
663
664 #if 0
665 /* This code prints instructions in delay slots on the same line
666 as the instruction which needs the delay slots. This can be
667 confusing, since other disassembler don't work this way, and
668 it means that the instructions are not all in a line. So I
669 disabled it. Ian. */
670 if (!(info->flags & 1)
671 && (op->name[0] == 'j'
672 || (op->name[0] == 'b'
673 && (op->name[1] == 'r'
674 || op->name[1] == 's'))
675 || (op->name[0] == 'r' && op->name[1] == 't')
676 || (op->name[0] == 'b' && op->name[2] == '.')))
677 {
678 info->flags |= 1;
679 fprintf_fn (stream, "\t(slot ");
680 print_insn_shx (memaddr + 2, info);
681 info->flags &= ~1;
682 fprintf_fn (stream, ")");
683 return 4;
684 }
685 #endif
686
687 if (disp_pc && strcmp (op->name, "mova") != 0)
688 {
689 int size;
690 bfd_byte bytes[4];
691
692 if (relmask == ~(bfd_vma) 1)
693 size = 2;
694 else
695 size = 4;
696 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
697 if (status == 0)
698 {
699 unsigned int val;
700
701 if (size == 2)
702 {
703 if ((info->flags & LITTLE_BIT) != 0)
704 val = bfd_getl16 (bytes);
705 else
706 val = bfd_getb16 (bytes);
707 }
708 else
709 {
710 if ((info->flags & LITTLE_BIT) != 0)
711 val = bfd_getl32 (bytes);
712 else
713 val = bfd_getb32 (bytes);
714 }
715 fprintf_fn (stream, "\t! 0x%x", val);
716 }
717 }
718
719 return 2;
720 fail:
721 ;
722
723 }
724 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
725 return 2;
726 }
727
728 int
729 print_insn_shl (memaddr, info)
730 bfd_vma memaddr;
731 struct disassemble_info *info;
732 {
733 int r;
734
735 info->flags = LITTLE_BIT;
736 r = print_insn_shx (memaddr, info);
737 return r;
738 }
739
740 int
741 print_insn_sh (memaddr, info)
742 bfd_vma memaddr;
743 struct disassemble_info *info;
744 {
745 int r;
746
747 info->flags = 0;
748 r = print_insn_shx (memaddr, info);
749 return r;
750 }