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