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