Merge branch 'master' into merge-job
[deliverable/binutils-gdb.git] / opcodes / sh-dis.c
CommitLineData
252b5132 1/* Disassemble SH instructions.
b3adc24a 2 Copyright (C) 1993-2020 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;
015551fc
JR
600 case IMM0_8:
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
RH
607 goto ok;
608 case PCRELIMM_8BY2:
69eb4bbf
KH
609 imm = ((nibs[2] << 4) | nibs[3]) << 1;
610 relmask = ~(bfd_vma) 1;
252b5132
RH
611 goto ok;
612 case PCRELIMM_8BY4:
69eb4bbf
KH
613 imm = ((nibs[2] << 4) | nibs[3]) << 2;
614 relmask = ~(bfd_vma) 3;
252b5132 615 goto ok;
015551fc
JR
616 case IMM0_8BY2:
617 case IMM1_8BY2:
69eb4bbf 618 imm = ((nibs[2] << 4) | nibs[3]) << 1;
252b5132 619 goto ok;
015551fc
JR
620 case IMM0_8BY4:
621 case IMM1_8BY4:
69eb4bbf 622 imm = ((nibs[2] << 4) | nibs[3]) << 2;
252b5132 623 goto ok;
6a5709a5
JR
624 case REG_N_D:
625 if ((nibs[n] & 1) != 0)
626 goto fail;
47b0e7ad 627 /* Fall through. */
252b5132
RH
628 case REG_N:
629 rn = nibs[n];
630 break;
631 case REG_M:
632 rm = nibs[n];
633 break;
6a5709a5
JR
634 case REG_N_B01:
635 if ((nibs[n] & 0x3) != 1 /* binary 01 */)
636 goto fail;
637 rn = (nibs[n] & 0xc) >> 2;
638 break;
252b5132
RH
639 case REG_NM:
640 rn = (nibs[n] & 0xc) >> 2;
641 rm = (nibs[n] & 0x3);
642 break;
643 case REG_B:
644 rb = nibs[n] & 0x07;
69eb4bbf 645 break;
d4845d57
JR
646 case SDT_REG_N:
647 /* sh-dsp: single data transfer. */
648 rn = nibs[n];
649 if ((rn & 0xc) != 4)
650 goto fail;
651 rn = rn & 0x3;
ddb68265 652 rn |= (!(rn & 2)) << 2;
d4845d57
JR
653 break;
654 case PPI:
015551fc 655 case REPEAT:
d4845d57 656 goto fail;
252b5132 657 default:
69eb4bbf 658 abort ();
252b5132
RH
659 }
660 }
661
662 ok:
0b0ac059
AO
663 /* sh2a has D_REG but not X_REG. We don't know the pattern
664 doesn't match unless we check the output args to see if they
665 make sense. */
666 if (target_arch == arch_sh2a
667 && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
668 || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
669 goto fail;
670
69eb4bbf 671 fprintf_fn (stream, "%s\t", op->name);
252b5132 672 disp_pc = 0;
69eb4bbf 673 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
252b5132
RH
674 {
675 if (n && op->arg[1] != A_END)
676 fprintf_fn (stream, ",");
69eb4bbf 677 switch (op->arg[n])
252b5132
RH
678 {
679 case A_IMM:
0b0ac059 680 fprintf_fn (stream, "#%d", imm);
252b5132
RH
681 break;
682 case A_R0:
683 fprintf_fn (stream, "r0");
684 break;
685 case A_REG_N:
686 fprintf_fn (stream, "r%d", rn);
687 break;
688 case A_INC_N:
aeadede6 689 case AS_INC_N:
69eb4bbf 690 fprintf_fn (stream, "@r%d+", rn);
252b5132
RH
691 break;
692 case A_DEC_N:
aeadede6 693 case AS_DEC_N:
69eb4bbf 694 fprintf_fn (stream, "@-r%d", rn);
252b5132
RH
695 break;
696 case A_IND_N:
aeadede6 697 case AS_IND_N:
69eb4bbf 698 fprintf_fn (stream, "@r%d", rn);
252b5132
RH
699 break;
700 case A_DISP_REG_N:
0b0ac059 701 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
252b5132 702 break;
aeadede6 703 case AS_PMOD_N:
69eb4bbf 704 fprintf_fn (stream, "@r%d+r8", rn);
d4845d57 705 break;
252b5132
RH
706 case A_REG_M:
707 fprintf_fn (stream, "r%d", rm);
708 break;
709 case A_INC_M:
69eb4bbf 710 fprintf_fn (stream, "@r%d+", rm);
252b5132
RH
711 break;
712 case A_DEC_M:
69eb4bbf 713 fprintf_fn (stream, "@-r%d", rm);
252b5132
RH
714 break;
715 case A_IND_M:
69eb4bbf 716 fprintf_fn (stream, "@r%d", rm);
252b5132
RH
717 break;
718 case A_DISP_REG_M:
0b0ac059 719 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
252b5132
RH
720 break;
721 case A_REG_B:
722 fprintf_fn (stream, "r%d_bank", rb);
723 break;
724 case A_DISP_PC:
725 disp_pc = 1;
726 disp_pc_addr = imm + 4 + (memaddr & relmask);
727 (*info->print_address_func) (disp_pc_addr, info);
728 break;
729 case A_IND_R0_REG_N:
730 fprintf_fn (stream, "@(r0,r%d)", rn);
69eb4bbf 731 break;
252b5132
RH
732 case A_IND_R0_REG_M:
733 fprintf_fn (stream, "@(r0,r%d)", rm);
69eb4bbf 734 break;
252b5132 735 case A_DISP_GBR:
0b0ac059
AO
736 fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
737 break;
738 case A_TBR:
739 fprintf_fn (stream, "tbr");
740 break;
741 case A_DISP2_TBR:
742 fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
743 break;
744 case A_INC_R15:
745 fprintf_fn (stream, "@r15+");
746 break;
747 case A_DEC_R15:
748 fprintf_fn (stream, "@-r15");
252b5132
RH
749 break;
750 case A_R0_GBR:
751 fprintf_fn (stream, "@(r0,gbr)");
752 break;
753 case A_BDISP12:
754 case A_BDISP8:
755 (*info->print_address_func) (imm + memaddr, info);
756 break;
757 case A_SR:
758 fprintf_fn (stream, "sr");
759 break;
760 case A_GBR:
761 fprintf_fn (stream, "gbr");
762 break;
763 case A_VBR:
764 fprintf_fn (stream, "vbr");
765 break;
d4845d57
JR
766 case A_DSR:
767 fprintf_fn (stream, "dsr");
768 break;
769 case A_MOD:
770 fprintf_fn (stream, "mod");
771 break;
772 case A_RE:
773 fprintf_fn (stream, "re");
774 break;
775 case A_RS:
776 fprintf_fn (stream, "rs");
777 break;
778 case A_A0:
779 fprintf_fn (stream, "a0");
780 break;
781 case A_X0:
782 fprintf_fn (stream, "x0");
783 break;
784 case A_X1:
785 fprintf_fn (stream, "x1");
786 break;
787 case A_Y0:
788 fprintf_fn (stream, "y0");
789 break;
790 case A_Y1:
791 fprintf_fn (stream, "y1");
792 break;
793 case DSP_REG_M:
794 print_dsp_reg (rm, fprintf_fn, stream);
795 break;
252b5132
RH
796 case A_SSR:
797 fprintf_fn (stream, "ssr");
798 break;
799 case A_SPC:
800 fprintf_fn (stream, "spc");
801 break;
802 case A_MACH:
803 fprintf_fn (stream, "mach");
804 break;
805 case A_MACL:
69eb4bbf 806 fprintf_fn (stream, "macl");
252b5132
RH
807 break;
808 case A_PR:
809 fprintf_fn (stream, "pr");
810 break;
811 case A_SGR:
812 fprintf_fn (stream, "sgr");
813 break;
814 case A_DBR:
815 fprintf_fn (stream, "dbr");
816 break;
252b5132
RH
817 case F_REG_N:
818 fprintf_fn (stream, "fr%d", rn);
819 break;
820 case F_REG_M:
821 fprintf_fn (stream, "fr%d", rm);
822 break;
823 case DX_REG_N:
824 if (rn & 1)
825 {
826 fprintf_fn (stream, "xd%d", rn & ~1);
827 break;
828 }
1a0670f3 829 /* Fall through. */
252b5132
RH
830 case D_REG_N:
831 fprintf_fn (stream, "dr%d", rn);
832 break;
833 case DX_REG_M:
834 if (rm & 1)
835 {
836 fprintf_fn (stream, "xd%d", rm & ~1);
837 break;
838 }
1a0670f3 839 /* Fall through. */
252b5132
RH
840 case D_REG_M:
841 fprintf_fn (stream, "dr%d", rm);
842 break;
843 case FPSCR_M:
844 case FPSCR_N:
845 fprintf_fn (stream, "fpscr");
846 break;
847 case FPUL_M:
848 case FPUL_N:
849 fprintf_fn (stream, "fpul");
850 break;
851 case F_FR0:
852 fprintf_fn (stream, "fr0");
853 break;
854 case V_REG_N:
69eb4bbf 855 fprintf_fn (stream, "fv%d", rn * 4);
252b5132
RH
856 break;
857 case V_REG_M:
69eb4bbf 858 fprintf_fn (stream, "fv%d", rm * 4);
252b5132
RH
859 break;
860 case XMTRX_M4:
861 fprintf_fn (stream, "xmtrx");
862 break;
863 default:
69eb4bbf 864 abort ();
252b5132
RH
865 }
866 }
867
868#if 0
869 /* This code prints instructions in delay slots on the same line
870 as the instruction which needs the delay slots. This can be
871 confusing, since other disassembler don't work this way, and
872 it means that the instructions are not all in a line. So I
873 disabled it. Ian. */
874 if (!(info->flags & 1)
875 && (op->name[0] == 'j'
876 || (op->name[0] == 'b'
69eb4bbf 877 && (op->name[1] == 'r'
252b5132
RH
878 || op->name[1] == 's'))
879 || (op->name[0] == 'r' && op->name[1] == 't')
880 || (op->name[0] == 'b' && op->name[2] == '.')))
881 {
882 info->flags |= 1;
883 fprintf_fn (stream, "\t(slot ");
1c509ca8 884 print_insn_sh (memaddr + 2, info);
252b5132
RH
885 info->flags &= ~1;
886 fprintf_fn (stream, ")");
887 return 4;
888 }
889#endif
890
891 if (disp_pc && strcmp (op->name, "mova") != 0)
892 {
893 int size;
894 bfd_byte bytes[4];
895
69eb4bbf 896 if (relmask == ~(bfd_vma) 1)
252b5132
RH
897 size = 2;
898 else
899 size = 4;
bdc4de1b
NC
900 /* Not reading an instruction - disable stop_vma. */
901 info->stop_vma = 0;
252b5132
RH
902 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
903 if (status == 0)
904 {
905 unsigned int val;
906
907 if (size == 2)
908 {
1c509ca8 909 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
910 val = bfd_getl16 (bytes);
911 else
912 val = bfd_getb16 (bytes);
913 }
914 else
915 {
1c509ca8 916 if (info->endian == BFD_ENDIAN_LITTLE)
252b5132
RH
917 val = bfd_getl32 (bytes);
918 else
919 val = bfd_getb32 (bytes);
920 }
1f1799d5
KK
921 if ((*info->symbol_at_address_func) (val, info))
922 {
f3b8f628 923 fprintf_fn (stream, "\t! ");
1f1799d5
KK
924 (*info->print_address_func) (val, info);
925 }
926 else
f3b8f628 927 fprintf_fn (stream, "\t! %x", val);
252b5132
RH
928 }
929 }
930
0b0ac059 931 return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
252b5132
RH
932 fail:
933 ;
934
935 }
936 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
937 return 2;
938}
This page took 0.986829 seconds and 4 git commands to generate.