]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/sh-dis.c
2003-03-03 Andrew Stubbs <andrew.stubbs@superh.com>
[thirdparty/binutils-gdb.git] / opcodes / sh-dis.c
CommitLineData
252b5132 1/* Disassemble SH instructions.
ae51a426 2 Copyright 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004
69eb4bbf 3 Free Software Foundation, Inc.
252b5132 4
5177500f
NC
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.
252b5132 9
5177500f
NC
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.
252b5132 14
5177500f
NC
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. */
252b5132
RH
18
19#include <stdio.h>
0d8dfecf 20#include "sysdep.h"
252b5132
RH
21#define STATIC_TABLE
22#define DEFINE_TABLE
23
24#include "sh-opc.h"
25#include "dis-asm.h"
26
b34976b6
AM
27#ifdef ARCH_all
28#define INCLUDE_SHMEDIA
29#endif
30
d83c6548 31static void print_movxy
6a51a8a8 32 PARAMS ((const sh_opcode_info *, int, int, fprintf_ftype, void *));
d83c6548
AJ
33static void print_insn_ddt PARAMS ((int, struct disassemble_info *));
34static void print_dsp_reg PARAMS ((int, fprintf_ftype, void *));
35static void print_insn_ppi PARAMS ((int, struct disassemble_info *));
d83c6548 36
d4845d57
JR
37static void
38print_movxy (op, rn, rm, fprintf_fn, stream)
6a51a8a8 39 const sh_opcode_info *op;
d4845d57
JR
40 int rn, rm;
41 fprintf_ftype fprintf_fn;
42 void *stream;
43{
44 int n;
45
69eb4bbf 46 fprintf_fn (stream, "%s\t", op->name);
d4845d57
JR
47 for (n = 0; n < 2; n++)
48 {
49 switch (op->arg[n])
50 {
51 case A_IND_N:
aeadede6
MS
52 case AX_IND_N:
53 case AXY_IND_N:
54 case AY_IND_N:
55 case AYX_IND_N:
69eb4bbf 56 fprintf_fn (stream, "@r%d", rn);
d4845d57
JR
57 break;
58 case A_INC_N:
aeadede6
MS
59 case AX_INC_N:
60 case AXY_INC_N:
61 case AY_INC_N:
62 case AYX_INC_N:
69eb4bbf 63 fprintf_fn (stream, "@r%d+", rn);
d4845d57 64 break;
aeadede6
MS
65 case AX_PMOD_N:
66 case AXY_PMOD_N:
69eb4bbf 67 fprintf_fn (stream, "@r%d+r8", rn);
d4845d57 68 break;
aeadede6
MS
69 case AY_PMOD_N:
70 case AYX_PMOD_N:
69eb4bbf 71 fprintf_fn (stream, "@r%d+r9", rn);
d4845d57 72 break;
aeadede6 73 case DSP_REG_A_M:
d4845d57
JR
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;
aeadede6
MS
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;
d4845d57
JR
102 default:
103 abort ();
104 }
105 if (n == 0)
69eb4bbf 106 fprintf_fn (stream, ",");
d4845d57
JR
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. */
69eb4bbf 114
d4845d57
JR
115static void
116print_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)))
aeadede6
MS
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);
d4845d57
JR
170 else
171 {
6a51a8a8
AM
172 static const sh_opcode_info *first_movx, *first_movy;
173 const sh_opcode_info *opx, *opy;
caaaf822 174 unsigned int insn_x, insn_y;
d4845d57
JR
175
176 if (! first_movx)
177 {
69eb4bbf 178 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
d4845d57 179 first_movx++;
69eb4bbf 180 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
d4845d57
JR
181 first_movy++;
182 }
183 insn_x = (insn >> 2) & 0xb;
184 if (insn_x)
185 {
69eb4bbf
KH
186 for (opx = first_movx; opx->nibbles[2] != insn_x;)
187 opx++;
d4845d57
JR
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");
69eb4bbf
KH
196 for (opy = first_movy; opy->nibbles[2] != insn_y;)
197 opy++;
d4845d57
JR
198 print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
199 fprintf_fn, stream);
200 }
201 }
202}
203
204static void
205print_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
248static void
249print_insn_ppi (field_b, info)
250 int field_b;
251 struct disassemble_info *info;
252{
69eb4bbf
KH
253 static char *sx_tab[] = { "x0", "x1", "a0", "a1" };
254 static char *sy_tab[] = { "y0", "y1", "m0", "m1" };
d4845d57
JR
255 fprintf_ftype fprintf_fn = info->fprintf_func;
256 void *stream = info->stream;
caaaf822 257 unsigned int nib1, nib2, nib3;
aeadede6 258 unsigned int altnib1, nib4;
caaaf822 259 char *dc = NULL;
6a51a8a8 260 const sh_opcode_info *op;
d4845d57
JR
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 {
69eb4bbf
KH
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" };
d4845d57
JR
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 }
aeadede6
MS
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 }
d4845d57
JR
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;
aeadede6 306 nib4 = field_b >> 4 & 0xf;
d4845d57
JR
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 }
aeadede6
MS
325 if (nib1 == PPI3)
326 altnib1 = PPI3NC;
327 else
328 altnib1 = nib1;
d4845d57
JR
329 for (op = sh_table; op->name; op++)
330 {
aeadede6 331 if ((op->nibbles[1] == nib1 || op->nibbles[1] == altnib1)
d4845d57
JR
332 && op->nibbles[2] == nib2
333 && op->nibbles[3] == nib3)
334 {
335 int n;
336
aeadede6
MS
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 }
d4845d57 360 fprintf_fn (stream, "%s%s\t", dc, op->name);
69eb4bbf 361 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
d4845d57
JR
362 {
363 if (n && op->arg[1] != A_END)
364 fprintf_fn (stream, ",");
69eb4bbf 365 switch (op->arg[n])
d4845d57
JR
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:
69eb4bbf 380 fprintf_fn (stream, "macl");
d4845d57
JR
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
1c509ca8
JR
393int
394print_insn_sh (memaddr, info)
252b5132
RH
395 bfd_vma memaddr;
396 struct disassemble_info *info;
397{
398 fprintf_ftype fprintf_fn = info->fprintf_func;
399 void *stream = info->stream;
f532f3fa 400 unsigned char insn[4];
252b5132
RH
401 unsigned char nibs[4];
402 int status;
69eb4bbf 403 bfd_vma relmask = ~(bfd_vma) 0;
6a51a8a8 404 const sh_opcode_info *op;
d4845d57
JR
405 int target_arch;
406
407 switch (info->mach)
408 {
409 case bfd_mach_sh:
410 target_arch = arch_sh1;
426e6456
JR
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.) */
4ee33023
JR
414 if (info->symbols
415 && bfd_asymbol_flavour(*info->symbols) == bfd_target_coff_flavour)
426e6456 416 target_arch = arch_sh4;
d4845d57
JR
417 break;
418 case bfd_mach_sh2:
419 target_arch = arch_sh2;
420 break;
5177500f
NC
421 case bfd_mach_sh2e:
422 target_arch = arch_sh2e;
423 break;
d4845d57
JR
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;
aeadede6 436 case bfd_mach_sh4_nofpu:
ae51a426
JR
437 target_arch = arch_sh4_nofpu;
438 break;
439 case bfd_mach_sh4:
d4845d57
JR
440 target_arch = arch_sh4;
441 break;
aeadede6
MS
442 case bfd_mach_sh4a:
443 case bfd_mach_sh4a_nofpu:
444 target_arch = arch_sh4a;
445 break;
446 case bfd_mach_sh4al_dsp:
447 target_arch = arch_sh4al_dsp;
448 break;
ae51a426
JR
449 case bfd_mach_sh4_nommu_nofpu:
450 target_arch = arch_sh4_nommu_nofpu;
451 break;
d28847ce 452 case bfd_mach_sh5:
1c509ca8
JR
453#ifdef INCLUDE_SHMEDIA
454 status = print_insn_sh64 (memaddr, info);
455 if (status != -2)
456 return status;
457#endif
d28847ce
AO
458 /* When we get here for sh64, it's because we want to disassemble
459 SHcompact, i.e. arch_sh4. */
460 target_arch = arch_sh4;
461 break;
d4845d57
JR
462 default:
463 abort ();
464 }
252b5132
RH
465
466 status = info->read_memory_func (memaddr, insn, 2, info);
467
69eb4bbf 468 if (status != 0)
252b5132
RH
469 {
470 info->memory_error_func (status, memaddr, info);
471 return -1;
472 }
473
1c509ca8 474 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
475 {
476 nibs[0] = (insn[1] >> 4) & 0xf;
477 nibs[1] = insn[1] & 0xf;
478
479 nibs[2] = (insn[0] >> 4) & 0xf;
480 nibs[3] = insn[0] & 0xf;
481 }
69eb4bbf 482 else
252b5132
RH
483 {
484 nibs[0] = (insn[0] >> 4) & 0xf;
485 nibs[1] = insn[0] & 0xf;
486
487 nibs[2] = (insn[1] >> 4) & 0xf;
488 nibs[3] = insn[1] & 0xf;
489 }
490
d4845d57
JR
491 if (nibs[0] == 0xf && (nibs[1] & 4) == 0 && target_arch & arch_sh_dsp_up)
492 {
493 if (nibs[1] & 8)
494 {
495 int field_b;
496
497 status = info->read_memory_func (memaddr + 2, insn, 2, info);
498
69eb4bbf 499 if (status != 0)
d4845d57
JR
500 {
501 info->memory_error_func (status, memaddr + 2, info);
502 return -1;
503 }
504
1c509ca8 505 if (info->endian == BFD_ENDIAN_LITTLE)
d4845d57
JR
506 field_b = insn[1] << 8 | insn[0];
507 else
508 field_b = insn[0] << 8 | insn[1];
509
510 print_insn_ppi (field_b, info);
511 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
512 return 4;
513 }
514 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
515 return 2;
516 }
69eb4bbf 517 for (op = sh_table; op->name; op++)
252b5132
RH
518 {
519 int n;
520 int imm = 0;
521 int rn = 0;
522 int rm = 0;
523 int rb = 0;
524 int disp_pc;
525 bfd_vma disp_pc_addr = 0;
526
d4845d57
JR
527 if ((op->arch & target_arch) == 0)
528 goto fail;
252b5132
RH
529 for (n = 0; n < 4; n++)
530 {
531 int i = op->nibbles[n];
532
69eb4bbf 533 if (i < 16)
252b5132
RH
534 {
535 if (nibs[n] == i)
536 continue;
537 goto fail;
538 }
539 switch (i)
540 {
541 case BRANCH_8:
69eb4bbf 542 imm = (nibs[2] << 4) | (nibs[3]);
252b5132
RH
543 if (imm & 0x80)
544 imm |= ~0xff;
69eb4bbf 545 imm = ((char) imm) * 2 + 4;
252b5132
RH
546 goto ok;
547 case BRANCH_12:
548 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
549 if (imm & 0x800)
550 imm |= ~0xfff;
551 imm = imm * 2 + 4;
552 goto ok;
015551fc
JR
553 case IMM0_4:
554 case IMM1_4:
252b5132
RH
555 imm = nibs[3];
556 goto ok;
015551fc
JR
557 case IMM0_4BY2:
558 case IMM1_4BY2:
69eb4bbf 559 imm = nibs[3] << 1;
252b5132 560 goto ok;
015551fc
JR
561 case IMM0_4BY4:
562 case IMM1_4BY4:
69eb4bbf 563 imm = nibs[3] << 2;
252b5132 564 goto ok;
015551fc
JR
565 case IMM0_8:
566 case IMM1_8:
252b5132
RH
567 imm = (nibs[2] << 4) | nibs[3];
568 goto ok;
569 case PCRELIMM_8BY2:
69eb4bbf
KH
570 imm = ((nibs[2] << 4) | nibs[3]) << 1;
571 relmask = ~(bfd_vma) 1;
252b5132
RH
572 goto ok;
573 case PCRELIMM_8BY4:
69eb4bbf
KH
574 imm = ((nibs[2] << 4) | nibs[3]) << 2;
575 relmask = ~(bfd_vma) 3;
252b5132 576 goto ok;
015551fc
JR
577 case IMM0_8BY2:
578 case IMM1_8BY2:
69eb4bbf 579 imm = ((nibs[2] << 4) | nibs[3]) << 1;
252b5132 580 goto ok;
015551fc
JR
581 case IMM0_8BY4:
582 case IMM1_8BY4:
69eb4bbf 583 imm = ((nibs[2] << 4) | nibs[3]) << 2;
252b5132 584 goto ok;
6a5709a5
JR
585 case REG_N_D:
586 if ((nibs[n] & 1) != 0)
587 goto fail;
588 /* fall through */
252b5132
RH
589 case REG_N:
590 rn = nibs[n];
591 break;
592 case REG_M:
593 rm = nibs[n];
594 break;
6a5709a5
JR
595 case REG_N_B01:
596 if ((nibs[n] & 0x3) != 1 /* binary 01 */)
597 goto fail;
598 rn = (nibs[n] & 0xc) >> 2;
599 break;
252b5132
RH
600 case REG_NM:
601 rn = (nibs[n] & 0xc) >> 2;
602 rm = (nibs[n] & 0x3);
603 break;
604 case REG_B:
605 rb = nibs[n] & 0x07;
69eb4bbf 606 break;
d4845d57
JR
607 case SDT_REG_N:
608 /* sh-dsp: single data transfer. */
609 rn = nibs[n];
610 if ((rn & 0xc) != 4)
611 goto fail;
612 rn = rn & 0x3;
ddb68265 613 rn |= (!(rn & 2)) << 2;
d4845d57
JR
614 break;
615 case PPI:
015551fc 616 case REPEAT:
d4845d57 617 goto fail;
252b5132 618 default:
69eb4bbf 619 abort ();
252b5132
RH
620 }
621 }
622
623 ok:
69eb4bbf 624 fprintf_fn (stream, "%s\t", op->name);
252b5132 625 disp_pc = 0;
69eb4bbf 626 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
252b5132
RH
627 {
628 if (n && op->arg[1] != A_END)
629 fprintf_fn (stream, ",");
69eb4bbf 630 switch (op->arg[n])
252b5132
RH
631 {
632 case A_IMM:
69eb4bbf 633 fprintf_fn (stream, "#%d", (char) (imm));
252b5132
RH
634 break;
635 case A_R0:
636 fprintf_fn (stream, "r0");
637 break;
638 case A_REG_N:
639 fprintf_fn (stream, "r%d", rn);
640 break;
641 case A_INC_N:
aeadede6 642 case AS_INC_N:
69eb4bbf 643 fprintf_fn (stream, "@r%d+", rn);
252b5132
RH
644 break;
645 case A_DEC_N:
aeadede6 646 case AS_DEC_N:
69eb4bbf 647 fprintf_fn (stream, "@-r%d", rn);
252b5132
RH
648 break;
649 case A_IND_N:
aeadede6 650 case AS_IND_N:
69eb4bbf 651 fprintf_fn (stream, "@r%d", rn);
252b5132
RH
652 break;
653 case A_DISP_REG_N:
69eb4bbf 654 fprintf_fn (stream, "@(%d,r%d)", imm, rn);
252b5132 655 break;
aeadede6 656 case AS_PMOD_N:
69eb4bbf 657 fprintf_fn (stream, "@r%d+r8", rn);
d4845d57 658 break;
252b5132
RH
659 case A_REG_M:
660 fprintf_fn (stream, "r%d", rm);
661 break;
662 case A_INC_M:
69eb4bbf 663 fprintf_fn (stream, "@r%d+", rm);
252b5132
RH
664 break;
665 case A_DEC_M:
69eb4bbf 666 fprintf_fn (stream, "@-r%d", rm);
252b5132
RH
667 break;
668 case A_IND_M:
69eb4bbf 669 fprintf_fn (stream, "@r%d", rm);
252b5132
RH
670 break;
671 case A_DISP_REG_M:
69eb4bbf 672 fprintf_fn (stream, "@(%d,r%d)", imm, rm);
252b5132
RH
673 break;
674 case A_REG_B:
675 fprintf_fn (stream, "r%d_bank", rb);
676 break;
677 case A_DISP_PC:
678 disp_pc = 1;
679 disp_pc_addr = imm + 4 + (memaddr & relmask);
680 (*info->print_address_func) (disp_pc_addr, info);
681 break;
682 case A_IND_R0_REG_N:
683 fprintf_fn (stream, "@(r0,r%d)", rn);
69eb4bbf 684 break;
252b5132
RH
685 case A_IND_R0_REG_M:
686 fprintf_fn (stream, "@(r0,r%d)", rm);
69eb4bbf 687 break;
252b5132 688 case A_DISP_GBR:
69eb4bbf 689 fprintf_fn (stream, "@(%d,gbr)", imm);
252b5132
RH
690 break;
691 case A_R0_GBR:
692 fprintf_fn (stream, "@(r0,gbr)");
693 break;
694 case A_BDISP12:
695 case A_BDISP8:
696 (*info->print_address_func) (imm + memaddr, info);
697 break;
698 case A_SR:
699 fprintf_fn (stream, "sr");
700 break;
701 case A_GBR:
702 fprintf_fn (stream, "gbr");
703 break;
704 case A_VBR:
705 fprintf_fn (stream, "vbr");
706 break;
d4845d57
JR
707 case A_DSR:
708 fprintf_fn (stream, "dsr");
709 break;
710 case A_MOD:
711 fprintf_fn (stream, "mod");
712 break;
713 case A_RE:
714 fprintf_fn (stream, "re");
715 break;
716 case A_RS:
717 fprintf_fn (stream, "rs");
718 break;
719 case A_A0:
720 fprintf_fn (stream, "a0");
721 break;
722 case A_X0:
723 fprintf_fn (stream, "x0");
724 break;
725 case A_X1:
726 fprintf_fn (stream, "x1");
727 break;
728 case A_Y0:
729 fprintf_fn (stream, "y0");
730 break;
731 case A_Y1:
732 fprintf_fn (stream, "y1");
733 break;
734 case DSP_REG_M:
735 print_dsp_reg (rm, fprintf_fn, stream);
736 break;
252b5132
RH
737 case A_SSR:
738 fprintf_fn (stream, "ssr");
739 break;
740 case A_SPC:
741 fprintf_fn (stream, "spc");
742 break;
743 case A_MACH:
744 fprintf_fn (stream, "mach");
745 break;
746 case A_MACL:
69eb4bbf 747 fprintf_fn (stream, "macl");
252b5132
RH
748 break;
749 case A_PR:
750 fprintf_fn (stream, "pr");
751 break;
752 case A_SGR:
753 fprintf_fn (stream, "sgr");
754 break;
755 case A_DBR:
756 fprintf_fn (stream, "dbr");
757 break;
252b5132
RH
758 case F_REG_N:
759 fprintf_fn (stream, "fr%d", rn);
760 break;
761 case F_REG_M:
762 fprintf_fn (stream, "fr%d", rm);
763 break;
764 case DX_REG_N:
765 if (rn & 1)
766 {
767 fprintf_fn (stream, "xd%d", rn & ~1);
768 break;
769 }
252b5132
RH
770 case D_REG_N:
771 fprintf_fn (stream, "dr%d", rn);
772 break;
773 case DX_REG_M:
774 if (rm & 1)
775 {
776 fprintf_fn (stream, "xd%d", rm & ~1);
777 break;
778 }
779 case D_REG_M:
780 fprintf_fn (stream, "dr%d", rm);
781 break;
782 case FPSCR_M:
783 case FPSCR_N:
784 fprintf_fn (stream, "fpscr");
785 break;
786 case FPUL_M:
787 case FPUL_N:
788 fprintf_fn (stream, "fpul");
789 break;
790 case F_FR0:
791 fprintf_fn (stream, "fr0");
792 break;
793 case V_REG_N:
69eb4bbf 794 fprintf_fn (stream, "fv%d", rn * 4);
252b5132
RH
795 break;
796 case V_REG_M:
69eb4bbf 797 fprintf_fn (stream, "fv%d", rm * 4);
252b5132
RH
798 break;
799 case XMTRX_M4:
800 fprintf_fn (stream, "xmtrx");
801 break;
802 default:
69eb4bbf 803 abort ();
252b5132
RH
804 }
805 }
806
807#if 0
808 /* This code prints instructions in delay slots on the same line
809 as the instruction which needs the delay slots. This can be
810 confusing, since other disassembler don't work this way, and
811 it means that the instructions are not all in a line. So I
812 disabled it. Ian. */
813 if (!(info->flags & 1)
814 && (op->name[0] == 'j'
815 || (op->name[0] == 'b'
69eb4bbf 816 && (op->name[1] == 'r'
252b5132
RH
817 || op->name[1] == 's'))
818 || (op->name[0] == 'r' && op->name[1] == 't')
819 || (op->name[0] == 'b' && op->name[2] == '.')))
820 {
821 info->flags |= 1;
822 fprintf_fn (stream, "\t(slot ");
1c509ca8 823 print_insn_sh (memaddr + 2, info);
252b5132
RH
824 info->flags &= ~1;
825 fprintf_fn (stream, ")");
826 return 4;
827 }
828#endif
829
830 if (disp_pc && strcmp (op->name, "mova") != 0)
831 {
832 int size;
833 bfd_byte bytes[4];
834
69eb4bbf 835 if (relmask == ~(bfd_vma) 1)
252b5132
RH
836 size = 2;
837 else
838 size = 4;
839 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
840 if (status == 0)
841 {
842 unsigned int val;
843
844 if (size == 2)
845 {
1c509ca8 846 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
847 val = bfd_getl16 (bytes);
848 else
849 val = bfd_getb16 (bytes);
850 }
851 else
852 {
1c509ca8 853 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
854 val = bfd_getl32 (bytes);
855 else
856 val = bfd_getb32 (bytes);
857 }
858 fprintf_fn (stream, "\t! 0x%x", val);
859 }
860 }
861
862 return 2;
863 fail:
864 ;
865
866 }
867 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
868 return 2;
869}