This commit was generated by cvs2svn to track changes on a CVS vendor
[deliverable/binutils-gdb.git] / opcodes / sh-dis.c
1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005
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., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
19
20 #include <stdio.h>
21 #include "sysdep.h"
22 #define STATIC_TABLE
23 #define DEFINE_TABLE
24
25 #include "sh-opc.h"
26 #include "dis-asm.h"
27
28 #ifdef ARCH_all
29 #define INCLUDE_SHMEDIA
30 #endif
31
32 static void
33 print_movxy (const sh_opcode_info *op,
34 int rn,
35 int rm,
36 fprintf_ftype fprintf_fn,
37 void *stream)
38 {
39 int n;
40
41 fprintf_fn (stream, "%s\t", op->name);
42 for (n = 0; n < 2; n++)
43 {
44 switch (op->arg[n])
45 {
46 case A_IND_N:
47 case AX_IND_N:
48 case AXY_IND_N:
49 case AY_IND_N:
50 case AYX_IND_N:
51 fprintf_fn (stream, "@r%d", rn);
52 break;
53 case A_INC_N:
54 case AX_INC_N:
55 case AXY_INC_N:
56 case AY_INC_N:
57 case AYX_INC_N:
58 fprintf_fn (stream, "@r%d+", rn);
59 break;
60 case AX_PMOD_N:
61 case AXY_PMOD_N:
62 fprintf_fn (stream, "@r%d+r8", rn);
63 break;
64 case AY_PMOD_N:
65 case AYX_PMOD_N:
66 fprintf_fn (stream, "@r%d+r9", rn);
67 break;
68 case DSP_REG_A_M:
69 fprintf_fn (stream, "a%c", '0' + rm);
70 break;
71 case DSP_REG_X:
72 fprintf_fn (stream, "x%c", '0' + rm);
73 break;
74 case DSP_REG_Y:
75 fprintf_fn (stream, "y%c", '0' + rm);
76 break;
77 case DSP_REG_AX:
78 fprintf_fn (stream, "%c%c",
79 (rm & 1) ? 'x' : 'a',
80 (rm & 2) ? '1' : '0');
81 break;
82 case DSP_REG_XY:
83 fprintf_fn (stream, "%c%c",
84 (rm & 1) ? 'y' : 'x',
85 (rm & 2) ? '1' : '0');
86 break;
87 case DSP_REG_AY:
88 fprintf_fn (stream, "%c%c",
89 (rm & 2) ? 'y' : 'a',
90 (rm & 1) ? '1' : '0');
91 break;
92 case DSP_REG_YX:
93 fprintf_fn (stream, "%c%c",
94 (rm & 2) ? 'x' : 'y',
95 (rm & 1) ? '1' : '0');
96 break;
97 default:
98 abort ();
99 }
100 if (n == 0)
101 fprintf_fn (stream, ",");
102 }
103 }
104
105 /* Print a double data transfer insn. INSN is just the lower three
106 nibbles of the insn, i.e. field a and the bit that indicates if
107 a parallel processing insn follows.
108 Return nonzero if a field b of a parallel processing insns follows. */
109
110 static void
111 print_insn_ddt (int insn, struct disassemble_info *info)
112 {
113 fprintf_ftype fprintf_fn = info->fprintf_func;
114 void *stream = info->stream;
115
116 /* If this is just a nop, make sure to emit something. */
117 if (insn == 0x000)
118 fprintf_fn (stream, "nopx\tnopy");
119
120 /* If a parallel processing insn was printed before,
121 and we got a non-nop, emit a tab. */
122 if ((insn & 0x800) && (insn & 0x3ff))
123 fprintf_fn (stream, "\t");
124
125 /* Check if either the x or y part is invalid. */
126 if (((insn & 0xc) == 0 && (insn & 0x2a0))
127 || ((insn & 3) == 0 && (insn & 0x150)))
128 if (info->mach != bfd_mach_sh_dsp
129 && info->mach != bfd_mach_sh3_dsp)
130 {
131 static const sh_opcode_info *first_movx, *first_movy;
132 const sh_opcode_info *op;
133 int is_movy;
134
135 if (! first_movx)
136 {
137 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX_NOPY;)
138 first_movx++;
139 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY_NOPX;)
140 first_movy++;
141 }
142
143 is_movy = ((insn & 3) != 0);
144
145 if (is_movy)
146 op = first_movy;
147 else
148 op = first_movx;
149
150 while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
151 || op->nibbles[3] != (unsigned) (insn & 0xf))
152 op++;
153
154 print_movxy (op,
155 (4 * ((insn & (is_movy ? 0x200 : 0x100)) == 0)
156 + 2 * is_movy
157 + 1 * ((insn & (is_movy ? 0x100 : 0x200)) != 0)),
158 (insn >> 6) & 3,
159 fprintf_fn, stream);
160 }
161 else
162 fprintf_fn (stream, ".word 0x%x", insn);
163 else
164 {
165 static const sh_opcode_info *first_movx, *first_movy;
166 const sh_opcode_info *opx, *opy;
167 unsigned int insn_x, insn_y;
168
169 if (! first_movx)
170 {
171 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
172 first_movx++;
173 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
174 first_movy++;
175 }
176 insn_x = (insn >> 2) & 0xb;
177 if (insn_x)
178 {
179 for (opx = first_movx; opx->nibbles[2] != insn_x;)
180 opx++;
181 print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
182 fprintf_fn, stream);
183 }
184 insn_y = (insn & 3) | ((insn >> 1) & 8);
185 if (insn_y)
186 {
187 if (insn_x)
188 fprintf_fn (stream, "\t");
189 for (opy = first_movy; opy->nibbles[2] != insn_y;)
190 opy++;
191 print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
192 fprintf_fn, stream);
193 }
194 }
195 }
196
197 static void
198 print_dsp_reg (int rm, fprintf_ftype fprintf_fn, void *stream)
199 {
200 switch (rm)
201 {
202 case A_A1_NUM:
203 fprintf_fn (stream, "a1");
204 break;
205 case A_A0_NUM:
206 fprintf_fn (stream, "a0");
207 break;
208 case A_X0_NUM:
209 fprintf_fn (stream, "x0");
210 break;
211 case A_X1_NUM:
212 fprintf_fn (stream, "x1");
213 break;
214 case A_Y0_NUM:
215 fprintf_fn (stream, "y0");
216 break;
217 case A_Y1_NUM:
218 fprintf_fn (stream, "y1");
219 break;
220 case A_M0_NUM:
221 fprintf_fn (stream, "m0");
222 break;
223 case A_A1G_NUM:
224 fprintf_fn (stream, "a1g");
225 break;
226 case A_M1_NUM:
227 fprintf_fn (stream, "m1");
228 break;
229 case A_A0G_NUM:
230 fprintf_fn (stream, "a0g");
231 break;
232 default:
233 fprintf_fn (stream, "0x%x", rm);
234 break;
235 }
236 }
237
238 static void
239 print_insn_ppi (int field_b, struct disassemble_info *info)
240 {
241 static char *sx_tab[] = { "x0", "x1", "a0", "a1" };
242 static char *sy_tab[] = { "y0", "y1", "m0", "m1" };
243 fprintf_ftype fprintf_fn = info->fprintf_func;
244 void *stream = info->stream;
245 unsigned int nib1, nib2, nib3;
246 unsigned int altnib1, nib4;
247 char *dc = NULL;
248 const sh_opcode_info *op;
249
250 if ((field_b & 0xe800) == 0)
251 {
252 fprintf_fn (stream, "psh%c\t#%d,",
253 field_b & 0x1000 ? 'a' : 'l',
254 (field_b >> 4) & 127);
255 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
256 return;
257 }
258 if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
259 {
260 static char *du_tab[] = { "x0", "y0", "a0", "a1" };
261 static char *se_tab[] = { "x0", "x1", "y0", "a1" };
262 static char *sf_tab[] = { "y0", "y1", "x0", "a1" };
263 static char *sg_tab[] = { "m0", "m1", "a0", "a1" };
264
265 if (field_b & 0x2000)
266 fprintf_fn (stream, "p%s %s,%s,%s\t",
267 (field_b & 0x1000) ? "add" : "sub",
268 sx_tab[(field_b >> 6) & 3],
269 sy_tab[(field_b >> 4) & 3],
270 du_tab[(field_b >> 0) & 3]);
271
272 else if ((field_b & 0xf0) == 0x10
273 && info->mach != bfd_mach_sh_dsp
274 && info->mach != bfd_mach_sh3_dsp)
275 fprintf_fn (stream, "pclr %s \t", du_tab[(field_b >> 0) & 3]);
276
277 else if ((field_b & 0xf3) != 0)
278 fprintf_fn (stream, ".word 0x%x\t", field_b);
279
280 fprintf_fn (stream, "pmuls%c%s,%s,%s",
281 field_b & 0x2000 ? ' ' : '\t',
282 se_tab[(field_b >> 10) & 3],
283 sf_tab[(field_b >> 8) & 3],
284 sg_tab[(field_b >> 2) & 3]);
285 return;
286 }
287
288 nib1 = PPIC;
289 nib2 = field_b >> 12 & 0xf;
290 nib3 = field_b >> 8 & 0xf;
291 nib4 = field_b >> 4 & 0xf;
292 switch (nib3 & 0x3)
293 {
294 case 0:
295 dc = "";
296 nib1 = PPI3;
297 break;
298 case 1:
299 dc = "";
300 break;
301 case 2:
302 dc = "dct ";
303 nib3 -= 1;
304 break;
305 case 3:
306 dc = "dcf ";
307 nib3 -= 2;
308 break;
309 }
310 if (nib1 == PPI3)
311 altnib1 = PPI3NC;
312 else
313 altnib1 = nib1;
314 for (op = sh_table; op->name; op++)
315 {
316 if ((op->nibbles[1] == nib1 || op->nibbles[1] == altnib1)
317 && op->nibbles[2] == nib2
318 && op->nibbles[3] == nib3)
319 {
320 int n;
321
322 switch (op->nibbles[4])
323 {
324 case HEX_0:
325 break;
326 case HEX_XX00:
327 if ((nib4 & 3) != 0)
328 continue;
329 break;
330 case HEX_1:
331 if ((nib4 & 3) != 1)
332 continue;
333 break;
334 case HEX_00YY:
335 if ((nib4 & 0xc) != 0)
336 continue;
337 break;
338 case HEX_4:
339 if ((nib4 & 0xc) != 4)
340 continue;
341 break;
342 default:
343 abort ();
344 }
345 fprintf_fn (stream, "%s%s\t", dc, op->name);
346 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
347 {
348 if (n && op->arg[1] != A_END)
349 fprintf_fn (stream, ",");
350 switch (op->arg[n])
351 {
352 case DSP_REG_N:
353 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
354 break;
355 case DSP_REG_X:
356 fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
357 break;
358 case DSP_REG_Y:
359 fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
360 break;
361 case A_MACH:
362 fprintf_fn (stream, "mach");
363 break;
364 case A_MACL:
365 fprintf_fn (stream, "macl");
366 break;
367 default:
368 abort ();
369 }
370 }
371 return;
372 }
373 }
374 /* Not found. */
375 fprintf_fn (stream, ".word 0x%x", field_b);
376 }
377
378 /* FIXME mvs: movx insns print as ".word 0x%03x", insn & 0xfff
379 (ie. the upper nibble is missing). */
380
381 int
382 print_insn_sh (bfd_vma memaddr, struct disassemble_info *info)
383 {
384 fprintf_ftype fprintf_fn = info->fprintf_func;
385 void *stream = info->stream;
386 unsigned char insn[4];
387 unsigned char nibs[8];
388 int status;
389 bfd_vma relmask = ~(bfd_vma) 0;
390 const sh_opcode_info *op;
391 unsigned int target_arch;
392 int allow_op32;
393
394 switch (info->mach)
395 {
396 case bfd_mach_sh:
397 target_arch = arch_sh1;
398 /* SH coff object files lack information about the machine type, so
399 we end up with bfd_mach_sh unless it was set explicitly (which
400 could have happended if this is a call from gdb or the simulator.) */
401 if (info->symbols
402 && bfd_asymbol_flavour(*info->symbols) == bfd_target_coff_flavour)
403 target_arch = arch_sh4;
404 break;
405 case bfd_mach_sh5:
406 #ifdef INCLUDE_SHMEDIA
407 status = print_insn_sh64 (memaddr, info);
408 if (status != -2)
409 return status;
410 #endif
411 /* When we get here for sh64, it's because we want to disassemble
412 SHcompact, i.e. arch_sh4. */
413 target_arch = arch_sh4;
414 break;
415 default:
416 target_arch = sh_get_arch_from_bfd_mach (info->mach);
417 }
418
419 status = info->read_memory_func (memaddr, insn, 2, info);
420
421 if (status != 0)
422 {
423 info->memory_error_func (status, memaddr, info);
424 return -1;
425 }
426
427 if (info->endian == BFD_ENDIAN_LITTLE)
428 {
429 nibs[0] = (insn[1] >> 4) & 0xf;
430 nibs[1] = insn[1] & 0xf;
431
432 nibs[2] = (insn[0] >> 4) & 0xf;
433 nibs[3] = insn[0] & 0xf;
434 }
435 else
436 {
437 nibs[0] = (insn[0] >> 4) & 0xf;
438 nibs[1] = insn[0] & 0xf;
439
440 nibs[2] = (insn[1] >> 4) & 0xf;
441 nibs[3] = insn[1] & 0xf;
442 }
443 status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
444 if (status != 0)
445 allow_op32 = 0;
446 else
447 {
448 allow_op32 = 1;
449
450 if (info->endian == BFD_ENDIAN_LITTLE)
451 {
452 nibs[4] = (insn[3] >> 4) & 0xf;
453 nibs[5] = insn[3] & 0xf;
454
455 nibs[6] = (insn[2] >> 4) & 0xf;
456 nibs[7] = insn[2] & 0xf;
457 }
458 else
459 {
460 nibs[4] = (insn[2] >> 4) & 0xf;
461 nibs[5] = insn[2] & 0xf;
462
463 nibs[6] = (insn[3] >> 4) & 0xf;
464 nibs[7] = insn[3] & 0xf;
465 }
466 }
467
468 if (nibs[0] == 0xf && (nibs[1] & 4) == 0
469 && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
470 {
471 if (nibs[1] & 8)
472 {
473 int field_b;
474
475 status = info->read_memory_func (memaddr + 2, insn, 2, info);
476
477 if (status != 0)
478 {
479 info->memory_error_func (status, memaddr + 2, info);
480 return -1;
481 }
482
483 if (info->endian == BFD_ENDIAN_LITTLE)
484 field_b = insn[1] << 8 | insn[0];
485 else
486 field_b = insn[0] << 8 | insn[1];
487
488 print_insn_ppi (field_b, info);
489 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
490 return 4;
491 }
492 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
493 return 2;
494 }
495 for (op = sh_table; op->name; op++)
496 {
497 int n;
498 int imm = 0;
499 int rn = 0;
500 int rm = 0;
501 int rb = 0;
502 int disp_pc;
503 bfd_vma disp_pc_addr = 0;
504 int disp = 0;
505 int has_disp = 0;
506 int max_n = SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 8 : 4;
507
508 if (!allow_op32
509 && SH_MERGE_ARCH_SET (op->arch, arch_op32))
510 goto fail;
511
512 if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
513 goto fail;
514 for (n = 0; n < max_n; n++)
515 {
516 int i = op->nibbles[n];
517
518 if (i < 16)
519 {
520 if (nibs[n] == i)
521 continue;
522 goto fail;
523 }
524 switch (i)
525 {
526 case BRANCH_8:
527 imm = (nibs[2] << 4) | (nibs[3]);
528 if (imm & 0x80)
529 imm |= ~0xff;
530 imm = ((char) imm) * 2 + 4;
531 goto ok;
532 case BRANCH_12:
533 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
534 if (imm & 0x800)
535 imm |= ~0xfff;
536 imm = imm * 2 + 4;
537 goto ok;
538 case IMM0_3c:
539 if (nibs[3] & 0x8)
540 goto fail;
541 imm = nibs[3] & 0x7;
542 break;
543 case IMM0_3s:
544 if (!(nibs[3] & 0x8))
545 goto fail;
546 imm = nibs[3] & 0x7;
547 break;
548 case IMM0_3Uc:
549 if (nibs[2] & 0x8)
550 goto fail;
551 imm = nibs[2] & 0x7;
552 break;
553 case IMM0_3Us:
554 if (!(nibs[2] & 0x8))
555 goto fail;
556 imm = nibs[2] & 0x7;
557 break;
558 case DISP0_12:
559 case DISP1_12:
560 disp = (nibs[5] << 8) | (nibs[6] << 4) | nibs[7];
561 has_disp = 1;
562 goto ok;
563 case DISP0_12BY2:
564 case DISP1_12BY2:
565 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 1;
566 relmask = ~(bfd_vma) 1;
567 has_disp = 1;
568 goto ok;
569 case DISP0_12BY4:
570 case DISP1_12BY4:
571 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 2;
572 relmask = ~(bfd_vma) 3;
573 has_disp = 1;
574 goto ok;
575 case DISP0_12BY8:
576 case DISP1_12BY8:
577 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 3;
578 relmask = ~(bfd_vma) 7;
579 has_disp = 1;
580 goto ok;
581 case IMM0_20_4:
582 break;
583 case IMM0_20:
584 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
585 | (nibs[6] << 4) | nibs[7]);
586 if (imm & 0x80000)
587 imm -= 0x100000;
588 goto ok;
589 case IMM0_20BY8:
590 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
591 | (nibs[6] << 4) | nibs[7]);
592 imm <<= 8;
593 if (imm & 0x8000000)
594 imm -= 0x10000000;
595 goto ok;
596 case IMM0_4:
597 case IMM1_4:
598 imm = nibs[3];
599 goto ok;
600 case IMM0_4BY2:
601 case IMM1_4BY2:
602 imm = nibs[3] << 1;
603 goto ok;
604 case IMM0_4BY4:
605 case IMM1_4BY4:
606 imm = nibs[3] << 2;
607 goto ok;
608 case IMM0_8:
609 case IMM1_8:
610 imm = (nibs[2] << 4) | nibs[3];
611 disp = imm;
612 has_disp = 1;
613 if (imm & 0x80)
614 imm -= 0x100;
615 goto ok;
616 case PCRELIMM_8BY2:
617 imm = ((nibs[2] << 4) | nibs[3]) << 1;
618 relmask = ~(bfd_vma) 1;
619 goto ok;
620 case PCRELIMM_8BY4:
621 imm = ((nibs[2] << 4) | nibs[3]) << 2;
622 relmask = ~(bfd_vma) 3;
623 goto ok;
624 case IMM0_8BY2:
625 case IMM1_8BY2:
626 imm = ((nibs[2] << 4) | nibs[3]) << 1;
627 goto ok;
628 case IMM0_8BY4:
629 case IMM1_8BY4:
630 imm = ((nibs[2] << 4) | nibs[3]) << 2;
631 goto ok;
632 case REG_N_D:
633 if ((nibs[n] & 1) != 0)
634 goto fail;
635 /* Fall through. */
636 case REG_N:
637 rn = nibs[n];
638 break;
639 case REG_M:
640 rm = nibs[n];
641 break;
642 case REG_N_B01:
643 if ((nibs[n] & 0x3) != 1 /* binary 01 */)
644 goto fail;
645 rn = (nibs[n] & 0xc) >> 2;
646 break;
647 case REG_NM:
648 rn = (nibs[n] & 0xc) >> 2;
649 rm = (nibs[n] & 0x3);
650 break;
651 case REG_B:
652 rb = nibs[n] & 0x07;
653 break;
654 case SDT_REG_N:
655 /* sh-dsp: single data transfer. */
656 rn = nibs[n];
657 if ((rn & 0xc) != 4)
658 goto fail;
659 rn = rn & 0x3;
660 rn |= (!(rn & 2)) << 2;
661 break;
662 case PPI:
663 case REPEAT:
664 goto fail;
665 default:
666 abort ();
667 }
668 }
669
670 ok:
671 /* sh2a has D_REG but not X_REG. We don't know the pattern
672 doesn't match unless we check the output args to see if they
673 make sense. */
674 if (target_arch == arch_sh2a
675 && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
676 || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
677 goto fail;
678
679 fprintf_fn (stream, "%s\t", op->name);
680 disp_pc = 0;
681 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
682 {
683 if (n && op->arg[1] != A_END)
684 fprintf_fn (stream, ",");
685 switch (op->arg[n])
686 {
687 case A_IMM:
688 fprintf_fn (stream, "#%d", imm);
689 break;
690 case A_R0:
691 fprintf_fn (stream, "r0");
692 break;
693 case A_REG_N:
694 fprintf_fn (stream, "r%d", rn);
695 break;
696 case A_INC_N:
697 case AS_INC_N:
698 fprintf_fn (stream, "@r%d+", rn);
699 break;
700 case A_DEC_N:
701 case AS_DEC_N:
702 fprintf_fn (stream, "@-r%d", rn);
703 break;
704 case A_IND_N:
705 case AS_IND_N:
706 fprintf_fn (stream, "@r%d", rn);
707 break;
708 case A_DISP_REG_N:
709 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
710 break;
711 case AS_PMOD_N:
712 fprintf_fn (stream, "@r%d+r8", rn);
713 break;
714 case A_REG_M:
715 fprintf_fn (stream, "r%d", rm);
716 break;
717 case A_INC_M:
718 fprintf_fn (stream, "@r%d+", rm);
719 break;
720 case A_DEC_M:
721 fprintf_fn (stream, "@-r%d", rm);
722 break;
723 case A_IND_M:
724 fprintf_fn (stream, "@r%d", rm);
725 break;
726 case A_DISP_REG_M:
727 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
728 break;
729 case A_REG_B:
730 fprintf_fn (stream, "r%d_bank", rb);
731 break;
732 case A_DISP_PC:
733 disp_pc = 1;
734 disp_pc_addr = imm + 4 + (memaddr & relmask);
735 (*info->print_address_func) (disp_pc_addr, info);
736 break;
737 case A_IND_R0_REG_N:
738 fprintf_fn (stream, "@(r0,r%d)", rn);
739 break;
740 case A_IND_R0_REG_M:
741 fprintf_fn (stream, "@(r0,r%d)", rm);
742 break;
743 case A_DISP_GBR:
744 fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
745 break;
746 case A_TBR:
747 fprintf_fn (stream, "tbr");
748 break;
749 case A_DISP2_TBR:
750 fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
751 break;
752 case A_INC_R15:
753 fprintf_fn (stream, "@r15+");
754 break;
755 case A_DEC_R15:
756 fprintf_fn (stream, "@-r15");
757 break;
758 case A_R0_GBR:
759 fprintf_fn (stream, "@(r0,gbr)");
760 break;
761 case A_BDISP12:
762 case A_BDISP8:
763 (*info->print_address_func) (imm + memaddr, info);
764 break;
765 case A_SR:
766 fprintf_fn (stream, "sr");
767 break;
768 case A_GBR:
769 fprintf_fn (stream, "gbr");
770 break;
771 case A_VBR:
772 fprintf_fn (stream, "vbr");
773 break;
774 case A_DSR:
775 fprintf_fn (stream, "dsr");
776 break;
777 case A_MOD:
778 fprintf_fn (stream, "mod");
779 break;
780 case A_RE:
781 fprintf_fn (stream, "re");
782 break;
783 case A_RS:
784 fprintf_fn (stream, "rs");
785 break;
786 case A_A0:
787 fprintf_fn (stream, "a0");
788 break;
789 case A_X0:
790 fprintf_fn (stream, "x0");
791 break;
792 case A_X1:
793 fprintf_fn (stream, "x1");
794 break;
795 case A_Y0:
796 fprintf_fn (stream, "y0");
797 break;
798 case A_Y1:
799 fprintf_fn (stream, "y1");
800 break;
801 case DSP_REG_M:
802 print_dsp_reg (rm, fprintf_fn, stream);
803 break;
804 case A_SSR:
805 fprintf_fn (stream, "ssr");
806 break;
807 case A_SPC:
808 fprintf_fn (stream, "spc");
809 break;
810 case A_MACH:
811 fprintf_fn (stream, "mach");
812 break;
813 case A_MACL:
814 fprintf_fn (stream, "macl");
815 break;
816 case A_PR:
817 fprintf_fn (stream, "pr");
818 break;
819 case A_SGR:
820 fprintf_fn (stream, "sgr");
821 break;
822 case A_DBR:
823 fprintf_fn (stream, "dbr");
824 break;
825 case F_REG_N:
826 fprintf_fn (stream, "fr%d", rn);
827 break;
828 case F_REG_M:
829 fprintf_fn (stream, "fr%d", rm);
830 break;
831 case DX_REG_N:
832 if (rn & 1)
833 {
834 fprintf_fn (stream, "xd%d", rn & ~1);
835 break;
836 }
837 case D_REG_N:
838 fprintf_fn (stream, "dr%d", rn);
839 break;
840 case DX_REG_M:
841 if (rm & 1)
842 {
843 fprintf_fn (stream, "xd%d", rm & ~1);
844 break;
845 }
846 case D_REG_M:
847 fprintf_fn (stream, "dr%d", rm);
848 break;
849 case FPSCR_M:
850 case FPSCR_N:
851 fprintf_fn (stream, "fpscr");
852 break;
853 case FPUL_M:
854 case FPUL_N:
855 fprintf_fn (stream, "fpul");
856 break;
857 case F_FR0:
858 fprintf_fn (stream, "fr0");
859 break;
860 case V_REG_N:
861 fprintf_fn (stream, "fv%d", rn * 4);
862 break;
863 case V_REG_M:
864 fprintf_fn (stream, "fv%d", rm * 4);
865 break;
866 case XMTRX_M4:
867 fprintf_fn (stream, "xmtrx");
868 break;
869 default:
870 abort ();
871 }
872 }
873
874 #if 0
875 /* This code prints instructions in delay slots on the same line
876 as the instruction which needs the delay slots. This can be
877 confusing, since other disassembler don't work this way, and
878 it means that the instructions are not all in a line. So I
879 disabled it. Ian. */
880 if (!(info->flags & 1)
881 && (op->name[0] == 'j'
882 || (op->name[0] == 'b'
883 && (op->name[1] == 'r'
884 || op->name[1] == 's'))
885 || (op->name[0] == 'r' && op->name[1] == 't')
886 || (op->name[0] == 'b' && op->name[2] == '.')))
887 {
888 info->flags |= 1;
889 fprintf_fn (stream, "\t(slot ");
890 print_insn_sh (memaddr + 2, info);
891 info->flags &= ~1;
892 fprintf_fn (stream, ")");
893 return 4;
894 }
895 #endif
896
897 if (disp_pc && strcmp (op->name, "mova") != 0)
898 {
899 int size;
900 bfd_byte bytes[4];
901
902 if (relmask == ~(bfd_vma) 1)
903 size = 2;
904 else
905 size = 4;
906 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
907 if (status == 0)
908 {
909 unsigned int val;
910
911 if (size == 2)
912 {
913 if (info->endian == BFD_ENDIAN_LITTLE)
914 val = bfd_getl16 (bytes);
915 else
916 val = bfd_getb16 (bytes);
917 }
918 else
919 {
920 if (info->endian == BFD_ENDIAN_LITTLE)
921 val = bfd_getl32 (bytes);
922 else
923 val = bfd_getb32 (bytes);
924 }
925 if ((*info->symbol_at_address_func) (val, info))
926 {
927 fprintf_fn (stream, "\t! 0x");
928 (*info->print_address_func) (val, info);
929 }
930 else
931 fprintf_fn (stream, "\t! 0x%x", val);
932 }
933 }
934
935 return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
936 fail:
937 ;
938
939 }
940 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
941 return 2;
942 }
This page took 0.049218 seconds and 5 git commands to generate.