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