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