3ca5130968bc17c1ca9f688043e52aa4b8b529dc
[deliverable/binutils-gdb.git] / opcodes / sh-dis.c
1 /* Disassemble SH instructions.
2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004
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 unsigned 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_sh5:
419 #ifdef INCLUDE_SHMEDIA
420 status = print_insn_sh64 (memaddr, info);
421 if (status != -2)
422 return status;
423 #endif
424 /* When we get here for sh64, it's because we want to disassemble
425 SHcompact, i.e. arch_sh4. */
426 target_arch = arch_sh4;
427 break;
428 default:
429 target_arch = sh_get_arch_from_bfd_mach (info->mach);
430 }
431
432 status = info->read_memory_func (memaddr, insn, 2, info);
433
434 if (status != 0)
435 {
436 info->memory_error_func (status, memaddr, info);
437 return -1;
438 }
439
440 if (info->endian == BFD_ENDIAN_LITTLE)
441 {
442 nibs[0] = (insn[1] >> 4) & 0xf;
443 nibs[1] = insn[1] & 0xf;
444
445 nibs[2] = (insn[0] >> 4) & 0xf;
446 nibs[3] = insn[0] & 0xf;
447 }
448 else
449 {
450 nibs[0] = (insn[0] >> 4) & 0xf;
451 nibs[1] = insn[0] & 0xf;
452
453 nibs[2] = (insn[1] >> 4) & 0xf;
454 nibs[3] = insn[1] & 0xf;
455 }
456
457 if (nibs[0] == 0xf && (nibs[1] & 4) == 0
458 && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
459 {
460 if (nibs[1] & 8)
461 {
462 int field_b;
463
464 status = info->read_memory_func (memaddr + 2, insn, 2, info);
465
466 if (status != 0)
467 {
468 info->memory_error_func (status, memaddr + 2, info);
469 return -1;
470 }
471
472 if (info->endian == BFD_ENDIAN_LITTLE)
473 field_b = insn[1] << 8 | insn[0];
474 else
475 field_b = insn[0] << 8 | insn[1];
476
477 print_insn_ppi (field_b, info);
478 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
479 return 4;
480 }
481 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
482 return 2;
483 }
484 for (op = sh_table; op->name; op++)
485 {
486 int n;
487 int imm = 0;
488 int rn = 0;
489 int rm = 0;
490 int rb = 0;
491 int disp_pc;
492 bfd_vma disp_pc_addr = 0;
493
494 if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
495 goto fail;
496 for (n = 0; n < 4; n++)
497 {
498 int i = op->nibbles[n];
499
500 if (i < 16)
501 {
502 if (nibs[n] == i)
503 continue;
504 goto fail;
505 }
506 switch (i)
507 {
508 case BRANCH_8:
509 imm = (nibs[2] << 4) | (nibs[3]);
510 if (imm & 0x80)
511 imm |= ~0xff;
512 imm = ((char) imm) * 2 + 4;
513 goto ok;
514 case BRANCH_12:
515 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
516 if (imm & 0x800)
517 imm |= ~0xfff;
518 imm = imm * 2 + 4;
519 goto ok;
520 case IMM0_4:
521 case IMM1_4:
522 imm = nibs[3];
523 goto ok;
524 case IMM0_4BY2:
525 case IMM1_4BY2:
526 imm = nibs[3] << 1;
527 goto ok;
528 case IMM0_4BY4:
529 case IMM1_4BY4:
530 imm = nibs[3] << 2;
531 goto ok;
532 case IMM0_8:
533 case IMM1_8:
534 imm = (nibs[2] << 4) | nibs[3];
535 goto ok;
536 case PCRELIMM_8BY2:
537 imm = ((nibs[2] << 4) | nibs[3]) << 1;
538 relmask = ~(bfd_vma) 1;
539 goto ok;
540 case PCRELIMM_8BY4:
541 imm = ((nibs[2] << 4) | nibs[3]) << 2;
542 relmask = ~(bfd_vma) 3;
543 goto ok;
544 case IMM0_8BY2:
545 case IMM1_8BY2:
546 imm = ((nibs[2] << 4) | nibs[3]) << 1;
547 goto ok;
548 case IMM0_8BY4:
549 case IMM1_8BY4:
550 imm = ((nibs[2] << 4) | nibs[3]) << 2;
551 goto ok;
552 case REG_N_D:
553 if ((nibs[n] & 1) != 0)
554 goto fail;
555 /* fall through */
556 case REG_N:
557 rn = nibs[n];
558 break;
559 case REG_M:
560 rm = nibs[n];
561 break;
562 case REG_N_B01:
563 if ((nibs[n] & 0x3) != 1 /* binary 01 */)
564 goto fail;
565 rn = (nibs[n] & 0xc) >> 2;
566 break;
567 case REG_NM:
568 rn = (nibs[n] & 0xc) >> 2;
569 rm = (nibs[n] & 0x3);
570 break;
571 case REG_B:
572 rb = nibs[n] & 0x07;
573 break;
574 case SDT_REG_N:
575 /* sh-dsp: single data transfer. */
576 rn = nibs[n];
577 if ((rn & 0xc) != 4)
578 goto fail;
579 rn = rn & 0x3;
580 rn |= (!(rn & 2)) << 2;
581 break;
582 case PPI:
583 case REPEAT:
584 goto fail;
585 default:
586 abort ();
587 }
588 }
589
590 ok:
591 fprintf_fn (stream, "%s\t", op->name);
592 disp_pc = 0;
593 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
594 {
595 if (n && op->arg[1] != A_END)
596 fprintf_fn (stream, ",");
597 switch (op->arg[n])
598 {
599 case A_IMM:
600 fprintf_fn (stream, "#%d", (char) (imm));
601 break;
602 case A_R0:
603 fprintf_fn (stream, "r0");
604 break;
605 case A_REG_N:
606 fprintf_fn (stream, "r%d", rn);
607 break;
608 case A_INC_N:
609 case AS_INC_N:
610 fprintf_fn (stream, "@r%d+", rn);
611 break;
612 case A_DEC_N:
613 case AS_DEC_N:
614 fprintf_fn (stream, "@-r%d", rn);
615 break;
616 case A_IND_N:
617 case AS_IND_N:
618 fprintf_fn (stream, "@r%d", rn);
619 break;
620 case A_DISP_REG_N:
621 fprintf_fn (stream, "@(%d,r%d)", imm, rn);
622 break;
623 case AS_PMOD_N:
624 fprintf_fn (stream, "@r%d+r8", rn);
625 break;
626 case A_REG_M:
627 fprintf_fn (stream, "r%d", rm);
628 break;
629 case A_INC_M:
630 fprintf_fn (stream, "@r%d+", rm);
631 break;
632 case A_DEC_M:
633 fprintf_fn (stream, "@-r%d", rm);
634 break;
635 case A_IND_M:
636 fprintf_fn (stream, "@r%d", rm);
637 break;
638 case A_DISP_REG_M:
639 fprintf_fn (stream, "@(%d,r%d)", imm, rm);
640 break;
641 case A_REG_B:
642 fprintf_fn (stream, "r%d_bank", rb);
643 break;
644 case A_DISP_PC:
645 disp_pc = 1;
646 disp_pc_addr = imm + 4 + (memaddr & relmask);
647 (*info->print_address_func) (disp_pc_addr, info);
648 break;
649 case A_IND_R0_REG_N:
650 fprintf_fn (stream, "@(r0,r%d)", rn);
651 break;
652 case A_IND_R0_REG_M:
653 fprintf_fn (stream, "@(r0,r%d)", rm);
654 break;
655 case A_DISP_GBR:
656 fprintf_fn (stream, "@(%d,gbr)", imm);
657 break;
658 case A_R0_GBR:
659 fprintf_fn (stream, "@(r0,gbr)");
660 break;
661 case A_BDISP12:
662 case A_BDISP8:
663 (*info->print_address_func) (imm + memaddr, info);
664 break;
665 case A_SR:
666 fprintf_fn (stream, "sr");
667 break;
668 case A_GBR:
669 fprintf_fn (stream, "gbr");
670 break;
671 case A_VBR:
672 fprintf_fn (stream, "vbr");
673 break;
674 case A_DSR:
675 fprintf_fn (stream, "dsr");
676 break;
677 case A_MOD:
678 fprintf_fn (stream, "mod");
679 break;
680 case A_RE:
681 fprintf_fn (stream, "re");
682 break;
683 case A_RS:
684 fprintf_fn (stream, "rs");
685 break;
686 case A_A0:
687 fprintf_fn (stream, "a0");
688 break;
689 case A_X0:
690 fprintf_fn (stream, "x0");
691 break;
692 case A_X1:
693 fprintf_fn (stream, "x1");
694 break;
695 case A_Y0:
696 fprintf_fn (stream, "y0");
697 break;
698 case A_Y1:
699 fprintf_fn (stream, "y1");
700 break;
701 case DSP_REG_M:
702 print_dsp_reg (rm, fprintf_fn, stream);
703 break;
704 case A_SSR:
705 fprintf_fn (stream, "ssr");
706 break;
707 case A_SPC:
708 fprintf_fn (stream, "spc");
709 break;
710 case A_MACH:
711 fprintf_fn (stream, "mach");
712 break;
713 case A_MACL:
714 fprintf_fn (stream, "macl");
715 break;
716 case A_PR:
717 fprintf_fn (stream, "pr");
718 break;
719 case A_SGR:
720 fprintf_fn (stream, "sgr");
721 break;
722 case A_DBR:
723 fprintf_fn (stream, "dbr");
724 break;
725 case F_REG_N:
726 fprintf_fn (stream, "fr%d", rn);
727 break;
728 case F_REG_M:
729 fprintf_fn (stream, "fr%d", rm);
730 break;
731 case DX_REG_N:
732 if (rn & 1)
733 {
734 fprintf_fn (stream, "xd%d", rn & ~1);
735 break;
736 }
737 case D_REG_N:
738 fprintf_fn (stream, "dr%d", rn);
739 break;
740 case DX_REG_M:
741 if (rm & 1)
742 {
743 fprintf_fn (stream, "xd%d", rm & ~1);
744 break;
745 }
746 case D_REG_M:
747 fprintf_fn (stream, "dr%d", rm);
748 break;
749 case FPSCR_M:
750 case FPSCR_N:
751 fprintf_fn (stream, "fpscr");
752 break;
753 case FPUL_M:
754 case FPUL_N:
755 fprintf_fn (stream, "fpul");
756 break;
757 case F_FR0:
758 fprintf_fn (stream, "fr0");
759 break;
760 case V_REG_N:
761 fprintf_fn (stream, "fv%d", rn * 4);
762 break;
763 case V_REG_M:
764 fprintf_fn (stream, "fv%d", rm * 4);
765 break;
766 case XMTRX_M4:
767 fprintf_fn (stream, "xmtrx");
768 break;
769 default:
770 abort ();
771 }
772 }
773
774 #if 0
775 /* This code prints instructions in delay slots on the same line
776 as the instruction which needs the delay slots. This can be
777 confusing, since other disassembler don't work this way, and
778 it means that the instructions are not all in a line. So I
779 disabled it. Ian. */
780 if (!(info->flags & 1)
781 && (op->name[0] == 'j'
782 || (op->name[0] == 'b'
783 && (op->name[1] == 'r'
784 || op->name[1] == 's'))
785 || (op->name[0] == 'r' && op->name[1] == 't')
786 || (op->name[0] == 'b' && op->name[2] == '.')))
787 {
788 info->flags |= 1;
789 fprintf_fn (stream, "\t(slot ");
790 print_insn_sh (memaddr + 2, info);
791 info->flags &= ~1;
792 fprintf_fn (stream, ")");
793 return 4;
794 }
795 #endif
796
797 if (disp_pc && strcmp (op->name, "mova") != 0)
798 {
799 int size;
800 bfd_byte bytes[4];
801
802 if (relmask == ~(bfd_vma) 1)
803 size = 2;
804 else
805 size = 4;
806 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
807 if (status == 0)
808 {
809 unsigned int val;
810
811 if (size == 2)
812 {
813 if (info->endian == BFD_ENDIAN_LITTLE)
814 val = bfd_getl16 (bytes);
815 else
816 val = bfd_getb16 (bytes);
817 }
818 else
819 {
820 if (info->endian == BFD_ENDIAN_LITTLE)
821 val = bfd_getl32 (bytes);
822 else
823 val = bfd_getb32 (bytes);
824 }
825 if ((*info->symbol_at_address_func) (val, info))
826 {
827 fprintf_fn (stream, "\t! 0x");
828 (*info->print_address_func) (val, info);
829 }
830 else
831 fprintf_fn (stream, "\t! 0x%x", val);
832 }
833 }
834
835 return 2;
836 fail:
837 ;
838
839 }
840 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
841 return 2;
842 }
This page took 0.063375 seconds and 3 git commands to generate.