]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/sh-dis.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / opcodes / sh-dis.c
CommitLineData
252b5132 1/* Disassemble SH instructions.
fd67aa11 2 Copyright (C) 1993-2024 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
d4845d57 30static void
47b0e7ad
NC
31print_movxy (const sh_opcode_info *op,
32 int rn,
33 int rm,
34 fprintf_ftype fprintf_fn,
35 void *stream)
d4845d57
JR
36{
37 int n;
38
69eb4bbf 39 fprintf_fn (stream, "%s\t", op->name);
d4845d57
JR
40 for (n = 0; n < 2; n++)
41 {
42 switch (op->arg[n])
43 {
44 case A_IND_N:
aeadede6
MS
45 case AX_IND_N:
46 case AXY_IND_N:
47 case AY_IND_N:
48 case AYX_IND_N:
69eb4bbf 49 fprintf_fn (stream, "@r%d", rn);
d4845d57
JR
50 break;
51 case A_INC_N:
aeadede6
MS
52 case AX_INC_N:
53 case AXY_INC_N:
54 case AY_INC_N:
55 case AYX_INC_N:
69eb4bbf 56 fprintf_fn (stream, "@r%d+", rn);
d4845d57 57 break;
aeadede6
MS
58 case AX_PMOD_N:
59 case AXY_PMOD_N:
69eb4bbf 60 fprintf_fn (stream, "@r%d+r8", rn);
d4845d57 61 break;
aeadede6
MS
62 case AY_PMOD_N:
63 case AYX_PMOD_N:
69eb4bbf 64 fprintf_fn (stream, "@r%d+r9", rn);
d4845d57 65 break;
aeadede6 66 case DSP_REG_A_M:
d4845d57
JR
67 fprintf_fn (stream, "a%c", '0' + rm);
68 break;
69 case DSP_REG_X:
70 fprintf_fn (stream, "x%c", '0' + rm);
71 break;
72 case DSP_REG_Y:
73 fprintf_fn (stream, "y%c", '0' + rm);
74 break;
aeadede6
MS
75 case DSP_REG_AX:
76 fprintf_fn (stream, "%c%c",
77 (rm & 1) ? 'x' : 'a',
78 (rm & 2) ? '1' : '0');
79 break;
80 case DSP_REG_XY:
81 fprintf_fn (stream, "%c%c",
82 (rm & 1) ? 'y' : 'x',
83 (rm & 2) ? '1' : '0');
84 break;
85 case DSP_REG_AY:
86 fprintf_fn (stream, "%c%c",
87 (rm & 2) ? 'y' : 'a',
88 (rm & 1) ? '1' : '0');
89 break;
90 case DSP_REG_YX:
91 fprintf_fn (stream, "%c%c",
92 (rm & 2) ? 'x' : 'y',
93 (rm & 1) ? '1' : '0');
94 break;
d4845d57
JR
95 default:
96 abort ();
97 }
98 if (n == 0)
69eb4bbf 99 fprintf_fn (stream, ",");
d4845d57
JR
100 }
101}
102
103/* Print a double data transfer insn. INSN is just the lower three
104 nibbles of the insn, i.e. field a and the bit that indicates if
cda8d785 105 a parallel processing insn follows. */
69eb4bbf 106
d4845d57 107static void
47b0e7ad 108print_insn_ddt (int insn, struct disassemble_info *info)
d4845d57
JR
109{
110 fprintf_ftype fprintf_fn = info->fprintf_func;
111 void *stream = info->stream;
112
113 /* If this is just a nop, make sure to emit something. */
114 if (insn == 0x000)
cda8d785
AM
115 {
116 fprintf_fn (stream, "nopx\tnopy");
117 return;
118 }
d4845d57
JR
119
120 /* If a parallel processing insn was printed before,
121 and we got a non-nop, emit a tab. */
122 if ((insn & 0x800) && (insn & 0x3ff))
123 fprintf_fn (stream, "\t");
124
125 /* Check if either the x or y part is invalid. */
cda8d785
AM
126 if (((insn & 3) != 0 && (insn & 0xc) == 0 && (insn & 0x2a0))
127 || ((insn & 3) == 0 && (insn & 0xc) != 0 && (insn & 0x150)))
aeadede6
MS
128 if (info->mach != bfd_mach_sh_dsp
129 && info->mach != bfd_mach_sh3_dsp)
130 {
131 static const sh_opcode_info *first_movx, *first_movy;
132 const sh_opcode_info *op;
133 int is_movy;
134
135 if (! first_movx)
136 {
137 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX_NOPY;)
138 first_movx++;
139 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY_NOPX;)
140 first_movy++;
141 }
142
143 is_movy = ((insn & 3) != 0);
144
145 if (is_movy)
146 op = first_movy;
147 else
148 op = first_movx;
149
150 while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
151 || op->nibbles[3] != (unsigned) (insn & 0xf))
152 op++;
43e65147 153
aeadede6
MS
154 print_movxy (op,
155 (4 * ((insn & (is_movy ? 0x200 : 0x100)) == 0)
156 + 2 * is_movy
157 + 1 * ((insn & (is_movy ? 0x100 : 0x200)) != 0)),
158 (insn >> 6) & 3,
159 fprintf_fn, stream);
160 }
161 else
cda8d785 162 fprintf_fn (stream, ".word 0x%x", insn | 0xf000);
d4845d57
JR
163 else
164 {
6a51a8a8
AM
165 static const sh_opcode_info *first_movx, *first_movy;
166 const sh_opcode_info *opx, *opy;
caaaf822 167 unsigned int insn_x, insn_y;
d4845d57
JR
168
169 if (! first_movx)
170 {
69eb4bbf 171 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
d4845d57 172 first_movx++;
69eb4bbf 173 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
d4845d57
JR
174 first_movy++;
175 }
176 insn_x = (insn >> 2) & 0xb;
177 if (insn_x)
178 {
69eb4bbf
KH
179 for (opx = first_movx; opx->nibbles[2] != insn_x;)
180 opx++;
d4845d57
JR
181 print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
182 fprintf_fn, stream);
183 }
184 insn_y = (insn & 3) | ((insn >> 1) & 8);
185 if (insn_y)
186 {
187 if (insn_x)
188 fprintf_fn (stream, "\t");
69eb4bbf
KH
189 for (opy = first_movy; opy->nibbles[2] != insn_y;)
190 opy++;
d4845d57
JR
191 print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
192 fprintf_fn, stream);
193 }
cda8d785
AM
194 if (!insn_x && !insn_y && ((insn & 0x3ff) != 0 || (insn & 0x800) == 0))
195 fprintf_fn (stream, ".word 0x%x", insn | 0xf000);
d4845d57
JR
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;
d4845d57 407 default:
f6f9408f 408 target_arch = sh_get_arch_from_bfd_mach (info->mach);
d4845d57 409 }
252b5132
RH
410
411 status = info->read_memory_func (memaddr, insn, 2, info);
412
69eb4bbf 413 if (status != 0)
252b5132
RH
414 {
415 info->memory_error_func (status, memaddr, info);
416 return -1;
417 }
418
1c509ca8 419 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
420 {
421 nibs[0] = (insn[1] >> 4) & 0xf;
422 nibs[1] = insn[1] & 0xf;
423
424 nibs[2] = (insn[0] >> 4) & 0xf;
425 nibs[3] = insn[0] & 0xf;
426 }
69eb4bbf 427 else
252b5132
RH
428 {
429 nibs[0] = (insn[0] >> 4) & 0xf;
430 nibs[1] = insn[0] & 0xf;
431
432 nibs[2] = (insn[1] >> 4) & 0xf;
433 nibs[3] = insn[1] & 0xf;
434 }
0b0ac059
AO
435 status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
436 if (status != 0)
437 allow_op32 = 0;
438 else
439 {
440 allow_op32 = 1;
441
442 if (info->endian == BFD_ENDIAN_LITTLE)
443 {
444 nibs[4] = (insn[3] >> 4) & 0xf;
445 nibs[5] = insn[3] & 0xf;
446
447 nibs[6] = (insn[2] >> 4) & 0xf;
448 nibs[7] = insn[2] & 0xf;
449 }
450 else
451 {
452 nibs[4] = (insn[2] >> 4) & 0xf;
453 nibs[5] = insn[2] & 0xf;
454
455 nibs[6] = (insn[3] >> 4) & 0xf;
456 nibs[7] = insn[3] & 0xf;
457 }
458 }
252b5132 459
f6f9408f
JR
460 if (nibs[0] == 0xf && (nibs[1] & 4) == 0
461 && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
d4845d57
JR
462 {
463 if (nibs[1] & 8)
464 {
465 int field_b;
466
467 status = info->read_memory_func (memaddr + 2, insn, 2, info);
468
69eb4bbf 469 if (status != 0)
d4845d57
JR
470 {
471 info->memory_error_func (status, memaddr + 2, info);
472 return -1;
473 }
474
1c509ca8 475 if (info->endian == BFD_ENDIAN_LITTLE)
d4845d57
JR
476 field_b = insn[1] << 8 | insn[0];
477 else
478 field_b = insn[0] << 8 | insn[1];
479
480 print_insn_ppi (field_b, info);
481 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
482 return 4;
483 }
484 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
485 return 2;
486 }
69eb4bbf 487 for (op = sh_table; op->name; op++)
252b5132
RH
488 {
489 int n;
490 int imm = 0;
491 int rn = 0;
492 int rm = 0;
493 int rb = 0;
494 int disp_pc;
495 bfd_vma disp_pc_addr = 0;
0b0ac059
AO
496 int disp = 0;
497 int has_disp = 0;
498 int max_n = SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 8 : 4;
499
500 if (!allow_op32
501 && SH_MERGE_ARCH_SET (op->arch, arch_op32))
502 goto fail;
252b5132 503
f6f9408f 504 if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
d4845d57 505 goto fail;
0b0ac059 506 for (n = 0; n < max_n; n++)
252b5132
RH
507 {
508 int i = op->nibbles[n];
509
69eb4bbf 510 if (i < 16)
252b5132
RH
511 {
512 if (nibs[n] == i)
513 continue;
514 goto fail;
515 }
516 switch (i)
517 {
518 case BRANCH_8:
69eb4bbf 519 imm = (nibs[2] << 4) | (nibs[3]);
252b5132
RH
520 if (imm & 0x80)
521 imm |= ~0xff;
69eb4bbf 522 imm = ((char) imm) * 2 + 4;
252b5132
RH
523 goto ok;
524 case BRANCH_12:
525 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
526 if (imm & 0x800)
527 imm |= ~0xfff;
528 imm = imm * 2 + 4;
529 goto ok;
0b0ac059
AO
530 case IMM0_3c:
531 if (nibs[3] & 0x8)
532 goto fail;
533 imm = nibs[3] & 0x7;
534 break;
535 case IMM0_3s:
536 if (!(nibs[3] & 0x8))
537 goto fail;
538 imm = nibs[3] & 0x7;
539 break;
540 case IMM0_3Uc:
541 if (nibs[2] & 0x8)
542 goto fail;
543 imm = nibs[2] & 0x7;
544 break;
545 case IMM0_3Us:
546 if (!(nibs[2] & 0x8))
547 goto fail;
548 imm = nibs[2] & 0x7;
549 break;
550 case DISP0_12:
551 case DISP1_12:
552 disp = (nibs[5] << 8) | (nibs[6] << 4) | nibs[7];
553 has_disp = 1;
554 goto ok;
555 case DISP0_12BY2:
556 case DISP1_12BY2:
557 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 1;
558 relmask = ~(bfd_vma) 1;
559 has_disp = 1;
560 goto ok;
561 case DISP0_12BY4:
562 case DISP1_12BY4:
563 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 2;
564 relmask = ~(bfd_vma) 3;
565 has_disp = 1;
566 goto ok;
567 case DISP0_12BY8:
568 case DISP1_12BY8:
569 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 3;
570 relmask = ~(bfd_vma) 7;
571 has_disp = 1;
572 goto ok;
573 case IMM0_20_4:
574 break;
575 case IMM0_20:
576 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
577 | (nibs[6] << 4) | nibs[7]);
578 if (imm & 0x80000)
579 imm -= 0x100000;
580 goto ok;
581 case IMM0_20BY8:
582 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
583 | (nibs[6] << 4) | nibs[7]);
584 imm <<= 8;
585 if (imm & 0x8000000)
586 imm -= 0x10000000;
587 goto ok;
015551fc
JR
588 case IMM0_4:
589 case IMM1_4:
252b5132
RH
590 imm = nibs[3];
591 goto ok;
015551fc
JR
592 case IMM0_4BY2:
593 case IMM1_4BY2:
69eb4bbf 594 imm = nibs[3] << 1;
252b5132 595 goto ok;
015551fc
JR
596 case IMM0_4BY4:
597 case IMM1_4BY4:
69eb4bbf 598 imm = nibs[3] << 2;
252b5132 599 goto ok;
5c936ef5 600 case IMM0_8S:
015551fc 601 case IMM1_8:
252b5132 602 imm = (nibs[2] << 4) | nibs[3];
0b0ac059
AO
603 disp = imm;
604 has_disp = 1;
605 if (imm & 0x80)
606 imm -= 0x100;
252b5132 607 goto ok;
5c936ef5
NC
608 case IMM0_8U:
609 disp = imm = (nibs[2] << 4) | nibs[3];
610 has_disp = 1;
611 goto ok;
252b5132 612 case PCRELIMM_8BY2:
69eb4bbf
KH
613 imm = ((nibs[2] << 4) | nibs[3]) << 1;
614 relmask = ~(bfd_vma) 1;
252b5132
RH
615 goto ok;
616 case PCRELIMM_8BY4:
69eb4bbf
KH
617 imm = ((nibs[2] << 4) | nibs[3]) << 2;
618 relmask = ~(bfd_vma) 3;
252b5132 619 goto ok;
015551fc
JR
620 case IMM0_8BY2:
621 case IMM1_8BY2:
69eb4bbf 622 imm = ((nibs[2] << 4) | nibs[3]) << 1;
252b5132 623 goto ok;
015551fc
JR
624 case IMM0_8BY4:
625 case IMM1_8BY4:
69eb4bbf 626 imm = ((nibs[2] << 4) | nibs[3]) << 2;
252b5132 627 goto ok;
6a5709a5
JR
628 case REG_N_D:
629 if ((nibs[n] & 1) != 0)
630 goto fail;
47b0e7ad 631 /* Fall through. */
252b5132
RH
632 case REG_N:
633 rn = nibs[n];
634 break;
635 case REG_M:
636 rm = nibs[n];
637 break;
6a5709a5
JR
638 case REG_N_B01:
639 if ((nibs[n] & 0x3) != 1 /* binary 01 */)
640 goto fail;
641 rn = (nibs[n] & 0xc) >> 2;
642 break;
252b5132
RH
643 case REG_NM:
644 rn = (nibs[n] & 0xc) >> 2;
645 rm = (nibs[n] & 0x3);
646 break;
647 case REG_B:
3b8e069a
YS
648 if (!(nibs[n] & 0x08)) /* Must always be 1. */
649 goto fail;
252b5132 650 rb = nibs[n] & 0x07;
69eb4bbf 651 break;
d4845d57
JR
652 case SDT_REG_N:
653 /* sh-dsp: single data transfer. */
654 rn = nibs[n];
655 if ((rn & 0xc) != 4)
656 goto fail;
657 rn = rn & 0x3;
ddb68265 658 rn |= (!(rn & 2)) << 2;
d4845d57
JR
659 break;
660 case PPI:
015551fc 661 case REPEAT:
d4845d57 662 goto fail;
252b5132 663 default:
69eb4bbf 664 abort ();
252b5132
RH
665 }
666 }
667
668 ok:
0b0ac059
AO
669 /* sh2a has D_REG but not X_REG. We don't know the pattern
670 doesn't match unless we check the output args to see if they
671 make sense. */
672 if (target_arch == arch_sh2a
673 && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
674 || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
675 goto fail;
676
69eb4bbf 677 fprintf_fn (stream, "%s\t", op->name);
252b5132 678 disp_pc = 0;
69eb4bbf 679 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
252b5132
RH
680 {
681 if (n && op->arg[1] != A_END)
682 fprintf_fn (stream, ",");
69eb4bbf 683 switch (op->arg[n])
252b5132
RH
684 {
685 case A_IMM:
0b0ac059 686 fprintf_fn (stream, "#%d", imm);
252b5132
RH
687 break;
688 case A_R0:
689 fprintf_fn (stream, "r0");
690 break;
691 case A_REG_N:
692 fprintf_fn (stream, "r%d", rn);
693 break;
694 case A_INC_N:
aeadede6 695 case AS_INC_N:
69eb4bbf 696 fprintf_fn (stream, "@r%d+", rn);
252b5132
RH
697 break;
698 case A_DEC_N:
aeadede6 699 case AS_DEC_N:
69eb4bbf 700 fprintf_fn (stream, "@-r%d", rn);
252b5132
RH
701 break;
702 case A_IND_N:
aeadede6 703 case AS_IND_N:
69eb4bbf 704 fprintf_fn (stream, "@r%d", rn);
252b5132
RH
705 break;
706 case A_DISP_REG_N:
0b0ac059 707 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
252b5132 708 break;
aeadede6 709 case AS_PMOD_N:
69eb4bbf 710 fprintf_fn (stream, "@r%d+r8", rn);
d4845d57 711 break;
252b5132
RH
712 case A_REG_M:
713 fprintf_fn (stream, "r%d", rm);
714 break;
715 case A_INC_M:
69eb4bbf 716 fprintf_fn (stream, "@r%d+", rm);
252b5132
RH
717 break;
718 case A_DEC_M:
69eb4bbf 719 fprintf_fn (stream, "@-r%d", rm);
252b5132
RH
720 break;
721 case A_IND_M:
69eb4bbf 722 fprintf_fn (stream, "@r%d", rm);
252b5132
RH
723 break;
724 case A_DISP_REG_M:
0b0ac059 725 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
252b5132
RH
726 break;
727 case A_REG_B:
728 fprintf_fn (stream, "r%d_bank", rb);
729 break;
730 case A_DISP_PC:
731 disp_pc = 1;
732 disp_pc_addr = imm + 4 + (memaddr & relmask);
733 (*info->print_address_func) (disp_pc_addr, info);
734 break;
735 case A_IND_R0_REG_N:
736 fprintf_fn (stream, "@(r0,r%d)", rn);
69eb4bbf 737 break;
252b5132
RH
738 case A_IND_R0_REG_M:
739 fprintf_fn (stream, "@(r0,r%d)", rm);
69eb4bbf 740 break;
252b5132 741 case A_DISP_GBR:
0b0ac059
AO
742 fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
743 break;
744 case A_TBR:
745 fprintf_fn (stream, "tbr");
746 break;
747 case A_DISP2_TBR:
748 fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
749 break;
750 case A_INC_R15:
751 fprintf_fn (stream, "@r15+");
752 break;
753 case A_DEC_R15:
754 fprintf_fn (stream, "@-r15");
252b5132
RH
755 break;
756 case A_R0_GBR:
757 fprintf_fn (stream, "@(r0,gbr)");
758 break;
759 case A_BDISP12:
760 case A_BDISP8:
761 (*info->print_address_func) (imm + memaddr, info);
762 break;
763 case A_SR:
764 fprintf_fn (stream, "sr");
765 break;
766 case A_GBR:
767 fprintf_fn (stream, "gbr");
768 break;
769 case A_VBR:
770 fprintf_fn (stream, "vbr");
771 break;
d4845d57
JR
772 case A_DSR:
773 fprintf_fn (stream, "dsr");
774 break;
775 case A_MOD:
776 fprintf_fn (stream, "mod");
777 break;
778 case A_RE:
779 fprintf_fn (stream, "re");
780 break;
781 case A_RS:
782 fprintf_fn (stream, "rs");
783 break;
784 case A_A0:
785 fprintf_fn (stream, "a0");
786 break;
787 case A_X0:
788 fprintf_fn (stream, "x0");
789 break;
790 case A_X1:
791 fprintf_fn (stream, "x1");
792 break;
793 case A_Y0:
794 fprintf_fn (stream, "y0");
795 break;
796 case A_Y1:
797 fprintf_fn (stream, "y1");
798 break;
799 case DSP_REG_M:
800 print_dsp_reg (rm, fprintf_fn, stream);
801 break;
252b5132
RH
802 case A_SSR:
803 fprintf_fn (stream, "ssr");
804 break;
805 case A_SPC:
806 fprintf_fn (stream, "spc");
807 break;
808 case A_MACH:
809 fprintf_fn (stream, "mach");
810 break;
811 case A_MACL:
69eb4bbf 812 fprintf_fn (stream, "macl");
252b5132
RH
813 break;
814 case A_PR:
815 fprintf_fn (stream, "pr");
816 break;
817 case A_SGR:
818 fprintf_fn (stream, "sgr");
819 break;
820 case A_DBR:
821 fprintf_fn (stream, "dbr");
822 break;
252b5132
RH
823 case F_REG_N:
824 fprintf_fn (stream, "fr%d", rn);
825 break;
826 case F_REG_M:
827 fprintf_fn (stream, "fr%d", rm);
828 break;
829 case DX_REG_N:
830 if (rn & 1)
831 {
832 fprintf_fn (stream, "xd%d", rn & ~1);
833 break;
834 }
1a0670f3 835 /* Fall through. */
252b5132
RH
836 case D_REG_N:
837 fprintf_fn (stream, "dr%d", rn);
838 break;
839 case DX_REG_M:
840 if (rm & 1)
841 {
842 fprintf_fn (stream, "xd%d", rm & ~1);
843 break;
844 }
1a0670f3 845 /* Fall through. */
252b5132
RH
846 case D_REG_M:
847 fprintf_fn (stream, "dr%d", rm);
848 break;
849 case FPSCR_M:
850 case FPSCR_N:
851 fprintf_fn (stream, "fpscr");
852 break;
853 case FPUL_M:
854 case FPUL_N:
855 fprintf_fn (stream, "fpul");
856 break;
857 case F_FR0:
858 fprintf_fn (stream, "fr0");
859 break;
860 case V_REG_N:
69eb4bbf 861 fprintf_fn (stream, "fv%d", rn * 4);
252b5132
RH
862 break;
863 case V_REG_M:
69eb4bbf 864 fprintf_fn (stream, "fv%d", rm * 4);
252b5132
RH
865 break;
866 case XMTRX_M4:
867 fprintf_fn (stream, "xmtrx");
868 break;
869 default:
69eb4bbf 870 abort ();
252b5132
RH
871 }
872 }
873
874#if 0
875 /* This code prints instructions in delay slots on the same line
876 as the instruction which needs the delay slots. This can be
877 confusing, since other disassembler don't work this way, and
878 it means that the instructions are not all in a line. So I
879 disabled it. Ian. */
880 if (!(info->flags & 1)
881 && (op->name[0] == 'j'
882 || (op->name[0] == 'b'
69eb4bbf 883 && (op->name[1] == 'r'
252b5132
RH
884 || op->name[1] == 's'))
885 || (op->name[0] == 'r' && op->name[1] == 't')
886 || (op->name[0] == 'b' && op->name[2] == '.')))
887 {
888 info->flags |= 1;
889 fprintf_fn (stream, "\t(slot ");
1c509ca8 890 print_insn_sh (memaddr + 2, info);
252b5132
RH
891 info->flags &= ~1;
892 fprintf_fn (stream, ")");
893 return 4;
894 }
895#endif
896
897 if (disp_pc && strcmp (op->name, "mova") != 0)
898 {
899 int size;
900 bfd_byte bytes[4];
901
69eb4bbf 902 if (relmask == ~(bfd_vma) 1)
252b5132
RH
903 size = 2;
904 else
905 size = 4;
bdc4de1b
NC
906 /* Not reading an instruction - disable stop_vma. */
907 info->stop_vma = 0;
252b5132
RH
908 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
909 if (status == 0)
910 {
911 unsigned int val;
912
913 if (size == 2)
914 {
1c509ca8 915 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
916 val = bfd_getl16 (bytes);
917 else
918 val = bfd_getb16 (bytes);
919 }
920 else
921 {
1c509ca8 922 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
923 val = bfd_getl32 (bytes);
924 else
925 val = bfd_getb32 (bytes);
926 }
1f1799d5
KK
927 if ((*info->symbol_at_address_func) (val, info))
928 {
f3b8f628 929 fprintf_fn (stream, "\t! ");
1f1799d5
KK
930 (*info->print_address_func) (val, info);
931 }
932 else
f3b8f628 933 fprintf_fn (stream, "\t! %x", val);
252b5132
RH
934 }
935 }
936
0b0ac059 937 return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
252b5132
RH
938 fail:
939 ;
940
941 }
942 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
943 return 2;
944}