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