2004-09-12 Andrew Cagney <cagney@gnu.org>
[deliverable/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
0b0ac059
AO
393/* FIXME mvs: movx insns print as ".word 0x%03x", insn & 0xfff
394 (ie. the upper nibble is missing). */
1c509ca8
JR
395int
396print_insn_sh (memaddr, info)
252b5132
RH
397 bfd_vma memaddr;
398 struct disassemble_info *info;
399{
400 fprintf_ftype fprintf_fn = info->fprintf_func;
401 void *stream = info->stream;
f532f3fa 402 unsigned char insn[4];
0b0ac059 403 unsigned char nibs[8];
252b5132 404 int status;
69eb4bbf 405 bfd_vma relmask = ~(bfd_vma) 0;
6a51a8a8 406 const sh_opcode_info *op;
f6f9408f 407 unsigned int target_arch;
0b0ac059 408 int allow_op32;
d4845d57
JR
409
410 switch (info->mach)
411 {
412 case bfd_mach_sh:
413 target_arch = arch_sh1;
426e6456
JR
414 /* SH coff object files lack information about the machine type, so
415 we end up with bfd_mach_sh unless it was set explicitly (which
416 could have happended if this is a call from gdb or the simulator.) */
4ee33023
JR
417 if (info->symbols
418 && bfd_asymbol_flavour(*info->symbols) == bfd_target_coff_flavour)
426e6456 419 target_arch = arch_sh4;
d4845d57 420 break;
d28847ce 421 case bfd_mach_sh5:
1c509ca8
JR
422#ifdef INCLUDE_SHMEDIA
423 status = print_insn_sh64 (memaddr, info);
424 if (status != -2)
425 return status;
426#endif
d28847ce
AO
427 /* When we get here for sh64, it's because we want to disassemble
428 SHcompact, i.e. arch_sh4. */
429 target_arch = arch_sh4;
430 break;
d4845d57 431 default:
f6f9408f 432 target_arch = sh_get_arch_from_bfd_mach (info->mach);
d4845d57 433 }
252b5132
RH
434
435 status = info->read_memory_func (memaddr, insn, 2, info);
436
69eb4bbf 437 if (status != 0)
252b5132
RH
438 {
439 info->memory_error_func (status, memaddr, info);
440 return -1;
441 }
442
1c509ca8 443 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
444 {
445 nibs[0] = (insn[1] >> 4) & 0xf;
446 nibs[1] = insn[1] & 0xf;
447
448 nibs[2] = (insn[0] >> 4) & 0xf;
449 nibs[3] = insn[0] & 0xf;
450 }
69eb4bbf 451 else
252b5132
RH
452 {
453 nibs[0] = (insn[0] >> 4) & 0xf;
454 nibs[1] = insn[0] & 0xf;
455
456 nibs[2] = (insn[1] >> 4) & 0xf;
457 nibs[3] = insn[1] & 0xf;
458 }
0b0ac059
AO
459 status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
460 if (status != 0)
461 allow_op32 = 0;
462 else
463 {
464 allow_op32 = 1;
465
466 if (info->endian == BFD_ENDIAN_LITTLE)
467 {
468 nibs[4] = (insn[3] >> 4) & 0xf;
469 nibs[5] = insn[3] & 0xf;
470
471 nibs[6] = (insn[2] >> 4) & 0xf;
472 nibs[7] = insn[2] & 0xf;
473 }
474 else
475 {
476 nibs[4] = (insn[2] >> 4) & 0xf;
477 nibs[5] = insn[2] & 0xf;
478
479 nibs[6] = (insn[3] >> 4) & 0xf;
480 nibs[7] = insn[3] & 0xf;
481 }
482 }
252b5132 483
f6f9408f
JR
484 if (nibs[0] == 0xf && (nibs[1] & 4) == 0
485 && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
d4845d57
JR
486 {
487 if (nibs[1] & 8)
488 {
489 int field_b;
490
491 status = info->read_memory_func (memaddr + 2, insn, 2, info);
492
69eb4bbf 493 if (status != 0)
d4845d57
JR
494 {
495 info->memory_error_func (status, memaddr + 2, info);
496 return -1;
497 }
498
1c509ca8 499 if (info->endian == BFD_ENDIAN_LITTLE)
d4845d57
JR
500 field_b = insn[1] << 8 | insn[0];
501 else
502 field_b = insn[0] << 8 | insn[1];
503
504 print_insn_ppi (field_b, info);
505 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
506 return 4;
507 }
508 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
509 return 2;
510 }
69eb4bbf 511 for (op = sh_table; op->name; op++)
252b5132
RH
512 {
513 int n;
514 int imm = 0;
515 int rn = 0;
516 int rm = 0;
517 int rb = 0;
518 int disp_pc;
519 bfd_vma disp_pc_addr = 0;
0b0ac059
AO
520 int disp = 0;
521 int has_disp = 0;
522 int max_n = SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 8 : 4;
523
524 if (!allow_op32
525 && SH_MERGE_ARCH_SET (op->arch, arch_op32))
526 goto fail;
252b5132 527
f6f9408f 528 if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
d4845d57 529 goto fail;
0b0ac059 530 for (n = 0; n < max_n; n++)
252b5132
RH
531 {
532 int i = op->nibbles[n];
533
69eb4bbf 534 if (i < 16)
252b5132
RH
535 {
536 if (nibs[n] == i)
537 continue;
538 goto fail;
539 }
540 switch (i)
541 {
542 case BRANCH_8:
69eb4bbf 543 imm = (nibs[2] << 4) | (nibs[3]);
252b5132
RH
544 if (imm & 0x80)
545 imm |= ~0xff;
69eb4bbf 546 imm = ((char) imm) * 2 + 4;
252b5132
RH
547 goto ok;
548 case BRANCH_12:
549 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
550 if (imm & 0x800)
551 imm |= ~0xfff;
552 imm = imm * 2 + 4;
553 goto ok;
0b0ac059
AO
554 case IMM0_3c:
555 if (nibs[3] & 0x8)
556 goto fail;
557 imm = nibs[3] & 0x7;
558 break;
559 case IMM0_3s:
560 if (!(nibs[3] & 0x8))
561 goto fail;
562 imm = nibs[3] & 0x7;
563 break;
564 case IMM0_3Uc:
565 if (nibs[2] & 0x8)
566 goto fail;
567 imm = nibs[2] & 0x7;
568 break;
569 case IMM0_3Us:
570 if (!(nibs[2] & 0x8))
571 goto fail;
572 imm = nibs[2] & 0x7;
573 break;
574 case DISP0_12:
575 case DISP1_12:
576 disp = (nibs[5] << 8) | (nibs[6] << 4) | nibs[7];
577 has_disp = 1;
578 goto ok;
579 case DISP0_12BY2:
580 case DISP1_12BY2:
581 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 1;
582 relmask = ~(bfd_vma) 1;
583 has_disp = 1;
584 goto ok;
585 case DISP0_12BY4:
586 case DISP1_12BY4:
587 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 2;
588 relmask = ~(bfd_vma) 3;
589 has_disp = 1;
590 goto ok;
591 case DISP0_12BY8:
592 case DISP1_12BY8:
593 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 3;
594 relmask = ~(bfd_vma) 7;
595 has_disp = 1;
596 goto ok;
597 case IMM0_20_4:
598 break;
599 case IMM0_20:
600 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
601 | (nibs[6] << 4) | nibs[7]);
602 if (imm & 0x80000)
603 imm -= 0x100000;
604 goto ok;
605 case IMM0_20BY8:
606 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
607 | (nibs[6] << 4) | nibs[7]);
608 imm <<= 8;
609 if (imm & 0x8000000)
610 imm -= 0x10000000;
611 goto ok;
015551fc
JR
612 case IMM0_4:
613 case IMM1_4:
252b5132
RH
614 imm = nibs[3];
615 goto ok;
015551fc
JR
616 case IMM0_4BY2:
617 case IMM1_4BY2:
69eb4bbf 618 imm = nibs[3] << 1;
252b5132 619 goto ok;
015551fc
JR
620 case IMM0_4BY4:
621 case IMM1_4BY4:
69eb4bbf 622 imm = nibs[3] << 2;
252b5132 623 goto ok;
015551fc
JR
624 case IMM0_8:
625 case IMM1_8:
252b5132 626 imm = (nibs[2] << 4) | nibs[3];
0b0ac059
AO
627 disp = imm;
628 has_disp = 1;
629 if (imm & 0x80)
630 imm -= 0x100;
252b5132
RH
631 goto ok;
632 case PCRELIMM_8BY2:
69eb4bbf
KH
633 imm = ((nibs[2] << 4) | nibs[3]) << 1;
634 relmask = ~(bfd_vma) 1;
252b5132
RH
635 goto ok;
636 case PCRELIMM_8BY4:
69eb4bbf
KH
637 imm = ((nibs[2] << 4) | nibs[3]) << 2;
638 relmask = ~(bfd_vma) 3;
252b5132 639 goto ok;
015551fc
JR
640 case IMM0_8BY2:
641 case IMM1_8BY2:
69eb4bbf 642 imm = ((nibs[2] << 4) | nibs[3]) << 1;
252b5132 643 goto ok;
015551fc
JR
644 case IMM0_8BY4:
645 case IMM1_8BY4:
69eb4bbf 646 imm = ((nibs[2] << 4) | nibs[3]) << 2;
252b5132 647 goto ok;
6a5709a5
JR
648 case REG_N_D:
649 if ((nibs[n] & 1) != 0)
650 goto fail;
651 /* fall through */
252b5132
RH
652 case REG_N:
653 rn = nibs[n];
654 break;
655 case REG_M:
656 rm = nibs[n];
657 break;
6a5709a5
JR
658 case REG_N_B01:
659 if ((nibs[n] & 0x3) != 1 /* binary 01 */)
660 goto fail;
661 rn = (nibs[n] & 0xc) >> 2;
662 break;
252b5132
RH
663 case REG_NM:
664 rn = (nibs[n] & 0xc) >> 2;
665 rm = (nibs[n] & 0x3);
666 break;
667 case REG_B:
668 rb = nibs[n] & 0x07;
69eb4bbf 669 break;
d4845d57
JR
670 case SDT_REG_N:
671 /* sh-dsp: single data transfer. */
672 rn = nibs[n];
673 if ((rn & 0xc) != 4)
674 goto fail;
675 rn = rn & 0x3;
ddb68265 676 rn |= (!(rn & 2)) << 2;
d4845d57
JR
677 break;
678 case PPI:
015551fc 679 case REPEAT:
d4845d57 680 goto fail;
252b5132 681 default:
69eb4bbf 682 abort ();
252b5132
RH
683 }
684 }
685
686 ok:
0b0ac059
AO
687 /* sh2a has D_REG but not X_REG. We don't know the pattern
688 doesn't match unless we check the output args to see if they
689 make sense. */
690 if (target_arch == arch_sh2a
691 && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
692 || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
693 goto fail;
694
69eb4bbf 695 fprintf_fn (stream, "%s\t", op->name);
252b5132 696 disp_pc = 0;
69eb4bbf 697 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
252b5132
RH
698 {
699 if (n && op->arg[1] != A_END)
700 fprintf_fn (stream, ",");
69eb4bbf 701 switch (op->arg[n])
252b5132
RH
702 {
703 case A_IMM:
0b0ac059 704 fprintf_fn (stream, "#%d", imm);
252b5132
RH
705 break;
706 case A_R0:
707 fprintf_fn (stream, "r0");
708 break;
709 case A_REG_N:
710 fprintf_fn (stream, "r%d", rn);
711 break;
712 case A_INC_N:
aeadede6 713 case AS_INC_N:
69eb4bbf 714 fprintf_fn (stream, "@r%d+", rn);
252b5132
RH
715 break;
716 case A_DEC_N:
aeadede6 717 case AS_DEC_N:
69eb4bbf 718 fprintf_fn (stream, "@-r%d", rn);
252b5132
RH
719 break;
720 case A_IND_N:
aeadede6 721 case AS_IND_N:
69eb4bbf 722 fprintf_fn (stream, "@r%d", rn);
252b5132
RH
723 break;
724 case A_DISP_REG_N:
0b0ac059 725 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
252b5132 726 break;
aeadede6 727 case AS_PMOD_N:
69eb4bbf 728 fprintf_fn (stream, "@r%d+r8", rn);
d4845d57 729 break;
252b5132
RH
730 case A_REG_M:
731 fprintf_fn (stream, "r%d", rm);
732 break;
733 case A_INC_M:
69eb4bbf 734 fprintf_fn (stream, "@r%d+", rm);
252b5132
RH
735 break;
736 case A_DEC_M:
69eb4bbf 737 fprintf_fn (stream, "@-r%d", rm);
252b5132
RH
738 break;
739 case A_IND_M:
69eb4bbf 740 fprintf_fn (stream, "@r%d", rm);
252b5132
RH
741 break;
742 case A_DISP_REG_M:
0b0ac059 743 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
252b5132
RH
744 break;
745 case A_REG_B:
746 fprintf_fn (stream, "r%d_bank", rb);
747 break;
748 case A_DISP_PC:
749 disp_pc = 1;
750 disp_pc_addr = imm + 4 + (memaddr & relmask);
751 (*info->print_address_func) (disp_pc_addr, info);
752 break;
753 case A_IND_R0_REG_N:
754 fprintf_fn (stream, "@(r0,r%d)", rn);
69eb4bbf 755 break;
252b5132
RH
756 case A_IND_R0_REG_M:
757 fprintf_fn (stream, "@(r0,r%d)", rm);
69eb4bbf 758 break;
252b5132 759 case A_DISP_GBR:
0b0ac059
AO
760 fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
761 break;
762 case A_TBR:
763 fprintf_fn (stream, "tbr");
764 break;
765 case A_DISP2_TBR:
766 fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
767 break;
768 case A_INC_R15:
769 fprintf_fn (stream, "@r15+");
770 break;
771 case A_DEC_R15:
772 fprintf_fn (stream, "@-r15");
252b5132
RH
773 break;
774 case A_R0_GBR:
775 fprintf_fn (stream, "@(r0,gbr)");
776 break;
777 case A_BDISP12:
778 case A_BDISP8:
779 (*info->print_address_func) (imm + memaddr, info);
780 break;
781 case A_SR:
782 fprintf_fn (stream, "sr");
783 break;
784 case A_GBR:
785 fprintf_fn (stream, "gbr");
786 break;
787 case A_VBR:
788 fprintf_fn (stream, "vbr");
789 break;
d4845d57
JR
790 case A_DSR:
791 fprintf_fn (stream, "dsr");
792 break;
793 case A_MOD:
794 fprintf_fn (stream, "mod");
795 break;
796 case A_RE:
797 fprintf_fn (stream, "re");
798 break;
799 case A_RS:
800 fprintf_fn (stream, "rs");
801 break;
802 case A_A0:
803 fprintf_fn (stream, "a0");
804 break;
805 case A_X0:
806 fprintf_fn (stream, "x0");
807 break;
808 case A_X1:
809 fprintf_fn (stream, "x1");
810 break;
811 case A_Y0:
812 fprintf_fn (stream, "y0");
813 break;
814 case A_Y1:
815 fprintf_fn (stream, "y1");
816 break;
817 case DSP_REG_M:
818 print_dsp_reg (rm, fprintf_fn, stream);
819 break;
252b5132
RH
820 case A_SSR:
821 fprintf_fn (stream, "ssr");
822 break;
823 case A_SPC:
824 fprintf_fn (stream, "spc");
825 break;
826 case A_MACH:
827 fprintf_fn (stream, "mach");
828 break;
829 case A_MACL:
69eb4bbf 830 fprintf_fn (stream, "macl");
252b5132
RH
831 break;
832 case A_PR:
833 fprintf_fn (stream, "pr");
834 break;
835 case A_SGR:
836 fprintf_fn (stream, "sgr");
837 break;
838 case A_DBR:
839 fprintf_fn (stream, "dbr");
840 break;
252b5132
RH
841 case F_REG_N:
842 fprintf_fn (stream, "fr%d", rn);
843 break;
844 case F_REG_M:
845 fprintf_fn (stream, "fr%d", rm);
846 break;
847 case DX_REG_N:
848 if (rn & 1)
849 {
850 fprintf_fn (stream, "xd%d", rn & ~1);
851 break;
852 }
252b5132
RH
853 case D_REG_N:
854 fprintf_fn (stream, "dr%d", rn);
855 break;
856 case DX_REG_M:
857 if (rm & 1)
858 {
859 fprintf_fn (stream, "xd%d", rm & ~1);
860 break;
861 }
862 case D_REG_M:
863 fprintf_fn (stream, "dr%d", rm);
864 break;
865 case FPSCR_M:
866 case FPSCR_N:
867 fprintf_fn (stream, "fpscr");
868 break;
869 case FPUL_M:
870 case FPUL_N:
871 fprintf_fn (stream, "fpul");
872 break;
873 case F_FR0:
874 fprintf_fn (stream, "fr0");
875 break;
876 case V_REG_N:
69eb4bbf 877 fprintf_fn (stream, "fv%d", rn * 4);
252b5132
RH
878 break;
879 case V_REG_M:
69eb4bbf 880 fprintf_fn (stream, "fv%d", rm * 4);
252b5132
RH
881 break;
882 case XMTRX_M4:
883 fprintf_fn (stream, "xmtrx");
884 break;
885 default:
69eb4bbf 886 abort ();
252b5132
RH
887 }
888 }
889
890#if 0
891 /* This code prints instructions in delay slots on the same line
892 as the instruction which needs the delay slots. This can be
893 confusing, since other disassembler don't work this way, and
894 it means that the instructions are not all in a line. So I
895 disabled it. Ian. */
896 if (!(info->flags & 1)
897 && (op->name[0] == 'j'
898 || (op->name[0] == 'b'
69eb4bbf 899 && (op->name[1] == 'r'
252b5132
RH
900 || op->name[1] == 's'))
901 || (op->name[0] == 'r' && op->name[1] == 't')
902 || (op->name[0] == 'b' && op->name[2] == '.')))
903 {
904 info->flags |= 1;
905 fprintf_fn (stream, "\t(slot ");
1c509ca8 906 print_insn_sh (memaddr + 2, info);
252b5132
RH
907 info->flags &= ~1;
908 fprintf_fn (stream, ")");
909 return 4;
910 }
911#endif
912
913 if (disp_pc && strcmp (op->name, "mova") != 0)
914 {
915 int size;
916 bfd_byte bytes[4];
917
69eb4bbf 918 if (relmask == ~(bfd_vma) 1)
252b5132
RH
919 size = 2;
920 else
921 size = 4;
922 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
923 if (status == 0)
924 {
925 unsigned int val;
926
927 if (size == 2)
928 {
1c509ca8 929 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
930 val = bfd_getl16 (bytes);
931 else
932 val = bfd_getb16 (bytes);
933 }
934 else
935 {
1c509ca8 936 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
937 val = bfd_getl32 (bytes);
938 else
939 val = bfd_getb32 (bytes);
940 }
1f1799d5
KK
941 if ((*info->symbol_at_address_func) (val, info))
942 {
943 fprintf_fn (stream, "\t! 0x");
944 (*info->print_address_func) (val, info);
945 }
946 else
947 fprintf_fn (stream, "\t! 0x%x", val);
252b5132
RH
948 }
949 }
950
0b0ac059 951 return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
252b5132
RH
952 fail:
953 ;
954
955 }
956 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
957 return 2;
958}
This page took 0.317104 seconds and 4 git commands to generate.