Fix typos in ChangeLogs; fix dates in copyright notices
[deliverable/binutils-gdb.git] / opcodes / sh-dis.c
1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000
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
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;
35 {
36 int n;
37
38 fprintf_fn (stream, "%s\t", op->name);
39 for (n = 0; n < 2; n++)
40 {
41 switch (op->arg[n])
42 {
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 ();
66 }
67 if (n == 0)
68 fprintf_fn (stream, ",");
69 }
70 }
71
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. */
76
77 static void
78 print_insn_ddt (insn, info)
79 int insn;
80 struct disassemble_info *info;
81 {
82 fprintf_ftype fprintf_fn = info->fprintf_func;
83 void *stream = info->stream;
84
85 /* If this is just a nop, make sure to emit something. */
86 if (insn == 0x000)
87 fprintf_fn (stream, "nopx\tnopy");
88
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");
93
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
99 {
100 static sh_opcode_info *first_movx, *first_movy;
101 sh_opcode_info *opx, *opy;
102 unsigned int insn_x, insn_y;
103
104 if (! first_movx)
105 {
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++;
110 }
111 insn_x = (insn >> 2) & 0xb;
112 if (insn_x)
113 {
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);
118 }
119 insn_y = (insn & 3) | ((insn >> 1) & 8);
120 if (insn_y)
121 {
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);
128 }
129 }
130 }
131
132 static void
133 print_dsp_reg (rm, fprintf_fn, stream)
134 int rm;
135 fprintf_ftype fprintf_fn;
136 void *stream;
137 {
138 switch (rm)
139 {
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;
173 }
174 }
175
176 static void
177 print_insn_ppi (field_b, info)
178 int field_b;
179 struct disassemble_info *info;
180 {
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 unsigned int nib1, nib2, nib3;
186 char *dc = NULL;
187 sh_opcode_info *op;
188
189 if ((field_b & 0xe800) == 0)
190 {
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;
196 }
197 if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
198 {
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" };
203
204 if (field_b & 0x2000)
205 {
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]);
211 }
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;
218 }
219
220 nib1 = PPIC;
221 nib2 = field_b >> 12 & 0xf;
222 nib3 = field_b >> 8 & 0xf;
223 switch (nib3 & 0x3)
224 {
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;
240 }
241 for (op = sh_table; op->name; op++)
242 {
243 if (op->nibbles[1] == nib1
244 && op->nibbles[2] == nib2
245 && op->nibbles[3] == nib3)
246 {
247 int n;
248
249 fprintf_fn (stream, "%s%s\t", dc, op->name);
250 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
251 {
252 if (n && op->arg[1] != A_END)
253 fprintf_fn (stream, ",");
254 switch (op->arg[n])
255 {
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 ();
273 }
274 }
275 return;
276 }
277 }
278 /* Not found. */
279 fprintf_fn (stream, ".word 0x%x", field_b);
280 }
281
282 static int
283 print_insn_shx (memaddr, info)
284 bfd_vma memaddr;
285 struct disassemble_info *info;
286 {
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;
295
296 switch (info->mach)
297 {
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 ();
321 }
322
323 status = info->read_memory_func (memaddr, insn, 2, info);
324
325 if (status != 0)
326 {
327 info->memory_error_func (status, memaddr, info);
328 return -1;
329 }
330
331 if (info->flags & LITTLE_BIT)
332 {
333 nibs[0] = (insn[1] >> 4) & 0xf;
334 nibs[1] = insn[1] & 0xf;
335
336 nibs[2] = (insn[0] >> 4) & 0xf;
337 nibs[3] = insn[0] & 0xf;
338 }
339 else
340 {
341 nibs[0] = (insn[0] >> 4) & 0xf;
342 nibs[1] = insn[0] & 0xf;
343
344 nibs[2] = (insn[1] >> 4) & 0xf;
345 nibs[3] = insn[1] & 0xf;
346 }
347
348 if (nibs[0] == 0xf && (nibs[1] & 4) == 0 && target_arch & arch_sh_dsp_up)
349 {
350 if (nibs[1] & 8)
351 {
352 int field_b;
353
354 status = info->read_memory_func (memaddr + 2, insn, 2, info);
355
356 if (status != 0)
357 {
358 info->memory_error_func (status, memaddr + 2, info);
359 return -1;
360 }
361
362 if (info->flags & LITTLE_BIT)
363 field_b = insn[1] << 8 | insn[0];
364 else
365 field_b = insn[0] << 8 | insn[1];
366
367 print_insn_ppi (field_b, info);
368 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
369 return 4;
370 }
371 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
372 return 2;
373 }
374 for (op = sh_table; op->name; op++)
375 {
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;
383
384 if ((op->arch & target_arch) == 0)
385 goto fail;
386 for (n = 0; n < 4; n++)
387 {
388 int i = op->nibbles[n];
389
390 if (i < 16)
391 {
392 if (nibs[n] == i)
393 continue;
394 goto fail;
395 }
396 switch (i)
397 {
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 ();
468 }
469 }
470
471 ok:
472 fprintf_fn (stream, "%s\t", op->name);
473 disp_pc = 0;
474 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
475 {
476 if (n && op->arg[1] != A_END)
477 fprintf_fn (stream, ",");
478 switch (op->arg[n])
479 {
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)
611 {
612 fprintf_fn (stream, "xd%d", rn & ~1);
613 break;
614 }
615 case D_REG_N:
616 fprintf_fn (stream, "dr%d", rn);
617 break;
618 case DX_REG_M:
619 if (rm & 1)
620 {
621 fprintf_fn (stream, "xd%d", rm & ~1);
622 break;
623 }
624 case D_REG_M:
625 fprintf_fn (stream, "dr%d", rm);
626 break;
627 case FPSCR_M:
628 case FPSCR_N:
629 fprintf_fn (stream, "fpscr");
630 break;
631 case FPUL_M:
632 case FPUL_N:
633 fprintf_fn (stream, "fpul");
634 break;
635 case F_FR0:
636 fprintf_fn (stream, "fr0");
637 break;
638 case V_REG_N:
639 fprintf_fn (stream, "fv%d", rn * 4);
640 break;
641 case V_REG_M:
642 fprintf_fn (stream, "fv%d", rm * 4);
643 break;
644 case XMTRX_M4:
645 fprintf_fn (stream, "xmtrx");
646 break;
647 default:
648 abort ();
649 }
650 }
651
652 #if 0
653 /* This code prints instructions in delay slots on the same line
654 as the instruction which needs the delay slots. This can be
655 confusing, since other disassembler don't work this way, and
656 it means that the instructions are not all in a line. So I
657 disabled it. Ian. */
658 if (!(info->flags & 1)
659 && (op->name[0] == 'j'
660 || (op->name[0] == 'b'
661 && (op->name[1] == 'r'
662 || op->name[1] == 's'))
663 || (op->name[0] == 'r' && op->name[1] == 't')
664 || (op->name[0] == 'b' && op->name[2] == '.')))
665 {
666 info->flags |= 1;
667 fprintf_fn (stream, "\t(slot ");
668 print_insn_shx (memaddr + 2, info);
669 info->flags &= ~1;
670 fprintf_fn (stream, ")");
671 return 4;
672 }
673 #endif
674
675 if (disp_pc && strcmp (op->name, "mova") != 0)
676 {
677 int size;
678 bfd_byte bytes[4];
679
680 if (relmask == ~(bfd_vma) 1)
681 size = 2;
682 else
683 size = 4;
684 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
685 if (status == 0)
686 {
687 unsigned int val;
688
689 if (size == 2)
690 {
691 if ((info->flags & LITTLE_BIT) != 0)
692 val = bfd_getl16 (bytes);
693 else
694 val = bfd_getb16 (bytes);
695 }
696 else
697 {
698 if ((info->flags & LITTLE_BIT) != 0)
699 val = bfd_getl32 (bytes);
700 else
701 val = bfd_getb32 (bytes);
702 }
703 fprintf_fn (stream, "\t! 0x%x", val);
704 }
705 }
706
707 return 2;
708 fail:
709 ;
710
711 }
712 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
713 return 2;
714 }
715
716 int
717 print_insn_shl (memaddr, info)
718 bfd_vma memaddr;
719 struct disassemble_info *info;
720 {
721 int r;
722
723 info->flags = LITTLE_BIT;
724 r = print_insn_shx (memaddr, info);
725 return r;
726 }
727
728 int
729 print_insn_sh (memaddr, info)
730 bfd_vma memaddr;
731 struct disassemble_info *info;
732 {
733 int r;
734
735 info->flags = 0;
736 r = print_insn_shx (memaddr, info);
737 return r;
738 }
This page took 0.069143 seconds and 5 git commands to generate.