v850-dis.c revision 1.1.1.5 1 1.1 skrll /* Disassemble V850 instructions.
2 1.1.1.5 christos Copyright (C) 1996-2016 Free Software Foundation, Inc.
3 1.1 skrll
4 1.1 skrll This file is part of the GNU opcodes library.
5 1.1 skrll
6 1.1 skrll This library is free software; you can redistribute it and/or modify
7 1.1 skrll it under the terms of the GNU General Public License as published by
8 1.1 skrll the Free Software Foundation; either version 3, or (at your option)
9 1.1 skrll any later version.
10 1.1 skrll
11 1.1 skrll It is distributed in the hope that it will be useful, but WITHOUT
12 1.1 skrll ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 1.1 skrll or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 1.1 skrll License for more details.
15 1.1 skrll
16 1.1 skrll You should have received a copy of the GNU General Public License
17 1.1 skrll along with this program; if not, write to the Free Software
18 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1 skrll MA 02110-1301, USA. */
20 1.1 skrll
21 1.1 skrll
22 1.1 skrll #include "sysdep.h"
23 1.1.1.3 christos #include <stdio.h>
24 1.1.1.4 christos #include <string.h>
25 1.1 skrll #include "opcode/v850.h"
26 1.1 skrll #include "dis-asm.h"
27 1.1 skrll #include "opintl.h"
28 1.1 skrll
29 1.1 skrll static const char *const v850_reg_names[] =
30 1.1.1.2 christos {
31 1.1.1.2 christos "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
32 1.1 skrll "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
33 1.1 skrll "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
34 1.1.1.2 christos "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
35 1.1.1.2 christos };
36 1.1 skrll
37 1.1 skrll static const char *const v850_sreg_names[] =
38 1.1.1.2 christos {
39 1.1.1.2 christos "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
40 1.1.1.2 christos "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
41 1.1.1.2 christos "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
42 1.1.1.2 christos "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
43 1.1.1.2 christos "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
44 1.1.1.2 christos "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
45 1.1.1.2 christos "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
46 1.1.1.2 christos "fewr", "dbwr", "bsel"
47 1.1.1.2 christos };
48 1.1 skrll
49 1.1 skrll static const char *const v850_cc_names[] =
50 1.1.1.2 christos {
51 1.1.1.2 christos "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
52 1.1.1.2 christos "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
53 1.1.1.2 christos };
54 1.1 skrll
55 1.1.1.2 christos static const char *const v850_float_cc_names[] =
56 1.1 skrll {
57 1.1.1.2 christos "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
58 1.1.1.2 christos "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
59 1.1.1.2 christos };
60 1.1 skrll
61 1.1 skrll
62 1.1.1.4 christos static const char *const v850_vreg_names[] =
63 1.1.1.4 christos {
64 1.1.1.4 christos "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", "vr8", "vr9",
65 1.1.1.4 christos "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", "vr16", "vr17", "vr18",
66 1.1.1.4 christos "vr19", "vr20", "vr21", "vr22", "vr23", "vr24", "vr25", "vr26", "vr27",
67 1.1.1.4 christos "vr28", "vr29", "vr30", "vr31"
68 1.1.1.4 christos };
69 1.1.1.4 christos
70 1.1.1.4 christos static const char *const v850_cacheop_names[] =
71 1.1.1.4 christos {
72 1.1.1.4 christos "chbii", "cibii", "cfali", "cisti", "cildi", "chbid", "chbiwbd",
73 1.1.1.4 christos "chbwbd", "cibid", "cibiwbd", "cibwbd", "cfald", "cistd", "cildd"
74 1.1.1.4 christos };
75 1.1.1.4 christos
76 1.1.1.4 christos static const int v850_cacheop_codes[] =
77 1.1.1.4 christos {
78 1.1.1.4 christos 0x00, 0x20, 0x40, 0x60, 0x61, 0x04, 0x06,
79 1.1.1.4 christos 0x07, 0x24, 0x26, 0x27, 0x44, 0x64, 0x65, -1
80 1.1.1.4 christos };
81 1.1.1.4 christos
82 1.1.1.4 christos static const char *const v850_prefop_names[] =
83 1.1.1.4 christos { "prefi", "prefd" };
84 1.1.1.4 christos
85 1.1.1.4 christos static const int v850_prefop_codes[] =
86 1.1.1.4 christos { 0x00, 0x04, -1};
87 1.1.1.4 christos
88 1.1.1.2 christos static void
89 1.1.1.4 christos print_value (int flags,
90 1.1.1.4 christos bfd_vma memaddr,
91 1.1.1.4 christos struct disassemble_info *info,
92 1.1.1.4 christos long value)
93 1.1.1.2 christos {
94 1.1.1.2 christos if (flags & V850_PCREL)
95 1.1.1.2 christos {
96 1.1.1.2 christos bfd_vma addr = value + memaddr;
97 1.1.1.4 christos
98 1.1.1.4 christos if (flags & V850_INVERSE_PCREL)
99 1.1.1.4 christos addr = memaddr - value;
100 1.1.1.2 christos info->print_address_func (addr, info);
101 1.1.1.2 christos }
102 1.1.1.2 christos else if (flags & V850_OPERAND_DISP)
103 1.1.1.2 christos {
104 1.1.1.2 christos if (flags & V850_OPERAND_SIGNED)
105 1.1.1.2 christos {
106 1.1.1.2 christos info->fprintf_func (info->stream, "%ld", value);
107 1.1.1.2 christos }
108 1.1.1.2 christos else
109 1.1.1.2 christos {
110 1.1.1.2 christos info->fprintf_func (info->stream, "%lu", value);
111 1.1.1.2 christos }
112 1.1.1.2 christos }
113 1.1.1.4 christos else if ((flags & V850E_IMMEDIATE32)
114 1.1.1.4 christos || (flags & V850E_IMMEDIATE16HI))
115 1.1.1.2 christos {
116 1.1.1.2 christos info->fprintf_func (info->stream, "0x%lx", value);
117 1.1.1.2 christos }
118 1.1.1.2 christos else
119 1.1.1.2 christos {
120 1.1.1.2 christos if (flags & V850_OPERAND_SIGNED)
121 1.1.1.2 christos {
122 1.1.1.2 christos info->fprintf_func (info->stream, "%ld", value);
123 1.1.1.2 christos }
124 1.1.1.2 christos else
125 1.1.1.2 christos {
126 1.1.1.2 christos info->fprintf_func (info->stream, "%lu", value);
127 1.1.1.2 christos }
128 1.1.1.2 christos }
129 1.1.1.2 christos }
130 1.1 skrll
131 1.1.1.2 christos static long
132 1.1.1.2 christos get_operand_value (const struct v850_operand *operand,
133 1.1.1.2 christos unsigned long insn,
134 1.1.1.2 christos int bytes_read,
135 1.1.1.2 christos bfd_vma memaddr,
136 1.1.1.2 christos struct disassemble_info * info,
137 1.1.1.2 christos bfd_boolean noerror,
138 1.1.1.2 christos int *invalid)
139 1.1.1.2 christos {
140 1.1.1.2 christos long value;
141 1.1.1.2 christos bfd_byte buffer[4];
142 1.1.1.2 christos
143 1.1.1.2 christos if ((operand->flags & V850E_IMMEDIATE16)
144 1.1.1.2 christos || (operand->flags & V850E_IMMEDIATE16HI))
145 1.1.1.2 christos {
146 1.1.1.2 christos int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
147 1.1.1.2 christos
148 1.1.1.2 christos if (status == 0)
149 1.1.1.2 christos {
150 1.1.1.2 christos value = bfd_getl16 (buffer);
151 1.1.1.2 christos
152 1.1.1.2 christos if (operand->flags & V850E_IMMEDIATE16HI)
153 1.1.1.2 christos value <<= 16;
154 1.1.1.4 christos else if (value & 0x8000)
155 1.1.1.4 christos value |= (-1UL << 16);
156 1.1.1.2 christos
157 1.1.1.2 christos return value;
158 1.1.1.2 christos }
159 1.1.1.2 christos
160 1.1.1.2 christos if (!noerror)
161 1.1.1.2 christos info->memory_error_func (status, memaddr + bytes_read, info);
162 1.1.1.2 christos
163 1.1.1.2 christos return 0;
164 1.1.1.2 christos }
165 1.1.1.2 christos
166 1.1.1.2 christos if (operand->flags & V850E_IMMEDIATE23)
167 1.1.1.2 christos {
168 1.1.1.2 christos int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
169 1.1.1.2 christos
170 1.1.1.2 christos if (status == 0)
171 1.1.1.2 christos {
172 1.1.1.2 christos value = bfd_getl32 (buffer);
173 1.1.1.2 christos
174 1.1.1.2 christos value = (operand->extract) (value, invalid);
175 1.1.1.2 christos
176 1.1.1.2 christos return value;
177 1.1.1.2 christos }
178 1.1.1.2 christos
179 1.1.1.2 christos if (!noerror)
180 1.1.1.2 christos info->memory_error_func (status, memaddr + bytes_read, info);
181 1.1.1.2 christos
182 1.1.1.2 christos return 0;
183 1.1.1.2 christos }
184 1.1.1.2 christos
185 1.1.1.2 christos if (operand->flags & V850E_IMMEDIATE32)
186 1.1.1.2 christos {
187 1.1.1.2 christos int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
188 1.1.1.2 christos
189 1.1.1.2 christos if (status == 0)
190 1.1.1.2 christos {
191 1.1.1.2 christos bytes_read += 4;
192 1.1.1.2 christos value = bfd_getl32 (buffer);
193 1.1.1.2 christos
194 1.1.1.2 christos return value;
195 1.1.1.2 christos }
196 1.1.1.2 christos
197 1.1.1.2 christos if (!noerror)
198 1.1.1.2 christos info->memory_error_func (status, memaddr + bytes_read, info);
199 1.1.1.2 christos
200 1.1.1.2 christos return 0;
201 1.1.1.2 christos }
202 1.1.1.2 christos
203 1.1.1.2 christos if (operand->extract)
204 1.1.1.2 christos value = (operand->extract) (insn, invalid);
205 1.1.1.2 christos else
206 1.1.1.2 christos {
207 1.1.1.2 christos if (operand->bits == -1)
208 1.1.1.2 christos value = (insn & operand->shift);
209 1.1.1.2 christos else
210 1.1.1.2 christos value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
211 1.1.1.2 christos
212 1.1.1.2 christos if (operand->flags & V850_OPERAND_SIGNED)
213 1.1.1.2 christos value = ((long)(value << (sizeof (long)*8 - operand->bits))
214 1.1.1.2 christos >> (sizeof (long)*8 - operand->bits));
215 1.1.1.2 christos }
216 1.1.1.2 christos
217 1.1.1.2 christos return value;
218 1.1.1.2 christos }
219 1.1.1.2 christos
220 1.1.1.2 christos
221 1.1.1.2 christos static int
222 1.1.1.4 christos disassemble (bfd_vma memaddr,
223 1.1.1.4 christos struct disassemble_info *info,
224 1.1.1.4 christos int bytes_read,
225 1.1.1.4 christos unsigned long insn)
226 1.1.1.2 christos {
227 1.1.1.4 christos struct v850_opcode *op = (struct v850_opcode *) v850_opcodes;
228 1.1.1.2 christos const struct v850_operand *operand;
229 1.1.1.2 christos int match = 0;
230 1.1.1.2 christos int target_processor;
231 1.1 skrll
232 1.1 skrll switch (info->mach)
233 1.1 skrll {
234 1.1 skrll case 0:
235 1.1 skrll default:
236 1.1 skrll target_processor = PROCESSOR_V850;
237 1.1 skrll break;
238 1.1 skrll
239 1.1 skrll case bfd_mach_v850e:
240 1.1 skrll target_processor = PROCESSOR_V850E;
241 1.1 skrll break;
242 1.1 skrll
243 1.1 skrll case bfd_mach_v850e1:
244 1.1.1.2 christos target_processor = PROCESSOR_V850E;
245 1.1.1.2 christos break;
246 1.1.1.2 christos
247 1.1.1.2 christos case bfd_mach_v850e2:
248 1.1.1.2 christos target_processor = PROCESSOR_V850E2;
249 1.1.1.2 christos break;
250 1.1.1.2 christos
251 1.1.1.2 christos case bfd_mach_v850e2v3:
252 1.1.1.2 christos target_processor = PROCESSOR_V850E2V3;
253 1.1 skrll break;
254 1.1.1.4 christos
255 1.1.1.4 christos case bfd_mach_v850e3v5:
256 1.1.1.4 christos target_processor = PROCESSOR_V850E3V5;
257 1.1.1.4 christos break;
258 1.1 skrll }
259 1.1 skrll
260 1.1.1.2 christos /* If this is a two byte insn, then mask off the high bits. */
261 1.1.1.2 christos if (bytes_read == 2)
262 1.1.1.2 christos insn &= 0xffff;
263 1.1.1.2 christos
264 1.1 skrll /* Find the opcode. */
265 1.1 skrll while (op->name)
266 1.1 skrll {
267 1.1 skrll if ((op->mask & insn) == op->opcode
268 1.1.1.2 christos && (op->processors & target_processor)
269 1.1.1.2 christos && !(op->processors & PROCESSOR_OPTION_ALIAS))
270 1.1 skrll {
271 1.1.1.2 christos /* Code check start. */
272 1.1 skrll const unsigned char *opindex_ptr;
273 1.1 skrll unsigned int opnum;
274 1.1 skrll unsigned int memop;
275 1.1 skrll
276 1.1.1.2 christos for (opindex_ptr = op->operands, opnum = 1;
277 1.1.1.2 christos *opindex_ptr != 0;
278 1.1.1.2 christos opindex_ptr++, opnum++)
279 1.1.1.2 christos {
280 1.1.1.2 christos int invalid = 0;
281 1.1.1.2 christos long value;
282 1.1.1.2 christos
283 1.1.1.2 christos operand = &v850_operands[*opindex_ptr];
284 1.1.1.2 christos
285 1.1.1.4 christos value = get_operand_value (operand, insn, bytes_read, memaddr,
286 1.1.1.4 christos info, 1, &invalid);
287 1.1.1.2 christos
288 1.1.1.2 christos if (invalid)
289 1.1.1.2 christos goto next_opcode;
290 1.1.1.2 christos
291 1.1.1.2 christos if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
292 1.1.1.2 christos goto next_opcode;
293 1.1.1.2 christos
294 1.1.1.2 christos if ((operand->flags & V850_NOT_SA) && value == 0xd)
295 1.1.1.2 christos goto next_opcode;
296 1.1.1.2 christos
297 1.1.1.2 christos if ((operand->flags & V850_NOT_IMM0) && value == 0)
298 1.1.1.2 christos goto next_opcode;
299 1.1.1.2 christos }
300 1.1.1.2 christos
301 1.1.1.2 christos /* Code check end. */
302 1.1.1.2 christos
303 1.1 skrll match = 1;
304 1.1 skrll (*info->fprintf_func) (info->stream, "%s\t", op->name);
305 1.1.1.2 christos #if 0
306 1.1.1.2 christos fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
307 1.1.1.2 christos insn, op->mask, op->opcode, op->name );
308 1.1.1.2 christos #endif
309 1.1 skrll
310 1.1 skrll memop = op->memop;
311 1.1 skrll /* Now print the operands.
312 1.1 skrll
313 1.1 skrll MEMOP is the operand number at which a memory
314 1.1 skrll address specification starts, or zero if this
315 1.1 skrll instruction has no memory addresses.
316 1.1 skrll
317 1.1 skrll A memory address is always two arguments.
318 1.1 skrll
319 1.1 skrll This information allows us to determine when to
320 1.1 skrll insert commas into the output stream as well as
321 1.1 skrll when to insert disp[reg] expressions onto the
322 1.1 skrll output stream. */
323 1.1 skrll
324 1.1 skrll for (opindex_ptr = op->operands, opnum = 1;
325 1.1 skrll *opindex_ptr != 0;
326 1.1 skrll opindex_ptr++, opnum++)
327 1.1 skrll {
328 1.1.1.3 christos bfd_boolean square = FALSE;
329 1.1 skrll long value;
330 1.1 skrll int flag;
331 1.1.1.2 christos char *prefix;
332 1.1 skrll
333 1.1 skrll operand = &v850_operands[*opindex_ptr];
334 1.1 skrll
335 1.1.1.4 christos value = get_operand_value (operand, insn, bytes_read, memaddr,
336 1.1.1.4 christos info, 0, 0);
337 1.1 skrll
338 1.1 skrll /* The first operand is always output without any
339 1.1 skrll special handling.
340 1.1 skrll
341 1.1 skrll For the following arguments:
342 1.1 skrll
343 1.1 skrll If memop && opnum == memop + 1, then we need '[' since
344 1.1 skrll we're about to output the register used in a memory
345 1.1 skrll reference.
346 1.1 skrll
347 1.1 skrll If memop && opnum == memop + 2, then we need ']' since
348 1.1 skrll we just finished the register in a memory reference. We
349 1.1 skrll also need a ',' before this operand.
350 1.1 skrll
351 1.1 skrll Else we just need a comma.
352 1.1 skrll
353 1.1 skrll We may need to output a trailing ']' if the last operand
354 1.1 skrll in an instruction is the register for a memory address.
355 1.1 skrll
356 1.1.1.4 christos The exception (and there's always an exception) are the
357 1.1 skrll "jmp" insn which needs square brackets around it's only
358 1.1.1.4 christos register argument, and the clr1/not1/set1/tst1 insns
359 1.1.1.4 christos which [...] around their second register argument. */
360 1.1.1.4 christos
361 1.1.1.2 christos prefix = "";
362 1.1.1.2 christos if (operand->flags & V850_OPERAND_BANG)
363 1.1.1.2 christos {
364 1.1.1.2 christos prefix = "!";
365 1.1.1.2 christos }
366 1.1.1.2 christos else if (operand->flags & V850_OPERAND_PERCENT)
367 1.1.1.2 christos {
368 1.1.1.2 christos prefix = "%";
369 1.1.1.2 christos }
370 1.1 skrll
371 1.1.1.2 christos if (opnum == 1 && opnum == memop)
372 1.1.1.3 christos {
373 1.1.1.3 christos info->fprintf_func (info->stream, "%s[", prefix);
374 1.1.1.3 christos square = TRUE;
375 1.1.1.3 christos }
376 1.1.1.4 christos else if ( (strcmp ("stc.w", op->name) == 0
377 1.1.1.4 christos || strcmp ("cache", op->name) == 0
378 1.1.1.4 christos || strcmp ("pref", op->name) == 0)
379 1.1.1.4 christos && opnum == 2 && opnum == memop)
380 1.1.1.4 christos {
381 1.1.1.4 christos info->fprintf_func (info->stream, ", [");
382 1.1.1.4 christos square = TRUE;
383 1.1.1.4 christos }
384 1.1.1.4 christos else if ( (strcmp (op->name, "pushsp") == 0
385 1.1.1.4 christos || strcmp (op->name, "popsp") == 0
386 1.1.1.4 christos || strcmp (op->name, "dbpush" ) == 0)
387 1.1.1.4 christos && opnum == 2)
388 1.1.1.4 christos {
389 1.1.1.4 christos info->fprintf_func (info->stream, "-");
390 1.1.1.4 christos }
391 1.1.1.2 christos else if (opnum > 1
392 1.1.1.4 christos && (v850_operands[*(opindex_ptr - 1)].flags
393 1.1.1.4 christos & V850_OPERAND_DISP) != 0
394 1.1.1.2 christos && opnum == memop)
395 1.1.1.3 christos {
396 1.1.1.3 christos info->fprintf_func (info->stream, "%s[", prefix);
397 1.1.1.3 christos square = TRUE;
398 1.1.1.3 christos }
399 1.1.1.4 christos else if (opnum == 2
400 1.1.1.4 christos && ( op->opcode == 0x00e407e0 /* clr1 */
401 1.1.1.4 christos || op->opcode == 0x00e207e0 /* not1 */
402 1.1.1.4 christos || op->opcode == 0x00e007e0 /* set1 */
403 1.1.1.4 christos || op->opcode == 0x00e607e0 /* tst1 */
404 1.1.1.4 christos ))
405 1.1.1.4 christos {
406 1.1.1.4 christos info->fprintf_func (info->stream, ", %s[", prefix);
407 1.1.1.4 christos square = TRUE;
408 1.1.1.4 christos }
409 1.1.1.2 christos else if (opnum > 1)
410 1.1.1.2 christos info->fprintf_func (info->stream, ", %s", prefix);
411 1.1.1.2 christos
412 1.1.1.4 christos /* Extract the flags, ignoring ones which do not
413 1.1.1.4 christos effect disassembly output. */
414 1.1.1.2 christos flag = operand->flags & (V850_OPERAND_REG
415 1.1.1.2 christos | V850_REG_EVEN
416 1.1.1.2 christos | V850_OPERAND_EP
417 1.1.1.2 christos | V850_OPERAND_SRG
418 1.1.1.2 christos | V850E_OPERAND_REG_LIST
419 1.1.1.2 christos | V850_OPERAND_CC
420 1.1.1.4 christos | V850_OPERAND_VREG
421 1.1.1.4 christos | V850_OPERAND_CACHEOP
422 1.1.1.4 christos | V850_OPERAND_PREFOP
423 1.1.1.2 christos | V850_OPERAND_FLOAT_CC);
424 1.1 skrll
425 1.1 skrll switch (flag)
426 1.1 skrll {
427 1.1.1.4 christos case V850_OPERAND_REG:
428 1.1.1.4 christos info->fprintf_func (info->stream, "%s", v850_reg_names[value]);
429 1.1.1.4 christos break;
430 1.1.1.4 christos case (V850_OPERAND_REG|V850_REG_EVEN):
431 1.1.1.4 christos info->fprintf_func (info->stream, "%s", v850_reg_names[value * 2]);
432 1.1.1.4 christos break;
433 1.1.1.4 christos case V850_OPERAND_EP:
434 1.1.1.4 christos info->fprintf_func (info->stream, "ep");
435 1.1.1.4 christos break;
436 1.1.1.4 christos case V850_OPERAND_SRG:
437 1.1.1.4 christos info->fprintf_func (info->stream, "%s", v850_sreg_names[value]);
438 1.1.1.4 christos break;
439 1.1.1.2 christos case V850E_OPERAND_REG_LIST:
440 1.1 skrll {
441 1.1.1.2 christos static int list12_regs[32] = { 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
442 1.1.1.2 christos 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
443 1.1 skrll int *regs;
444 1.1 skrll int i;
445 1.1 skrll unsigned long int mask = 0;
446 1.1 skrll int pc = 0;
447 1.1.1.2 christos
448 1.1 skrll switch (operand->shift)
449 1.1 skrll {
450 1.1 skrll case 0xffe00001: regs = list12_regs; break;
451 1.1 skrll default:
452 1.1 skrll /* xgettext:c-format */
453 1.1.1.4 christos fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift);
454 1.1 skrll abort ();
455 1.1 skrll }
456 1.1 skrll
457 1.1 skrll for (i = 0; i < 32; i++)
458 1.1 skrll {
459 1.1 skrll if (value & (1 << i))
460 1.1 skrll {
461 1.1 skrll switch (regs[ i ])
462 1.1 skrll {
463 1.1 skrll default: mask |= (1 << regs[ i ]); break;
464 1.1 skrll /* xgettext:c-format */
465 1.1.1.2 christos case 0: fprintf (stderr, _("unknown reg: %d\n"), i ); abort ();
466 1.1 skrll case -1: pc = 1; break;
467 1.1 skrll }
468 1.1 skrll }
469 1.1 skrll }
470 1.1 skrll
471 1.1 skrll info->fprintf_func (info->stream, "{");
472 1.1 skrll
473 1.1.1.2 christos if (mask || pc)
474 1.1 skrll {
475 1.1 skrll if (mask)
476 1.1 skrll {
477 1.1 skrll unsigned int bit;
478 1.1 skrll int shown_one = 0;
479 1.1 skrll
480 1.1 skrll for (bit = 0; bit < 32; bit++)
481 1.1 skrll if (mask & (1 << bit))
482 1.1 skrll {
483 1.1 skrll unsigned long int first = bit;
484 1.1 skrll unsigned long int last;
485 1.1 skrll
486 1.1 skrll if (shown_one)
487 1.1 skrll info->fprintf_func (info->stream, ", ");
488 1.1 skrll else
489 1.1 skrll shown_one = 1;
490 1.1 skrll
491 1.1.1.3 christos info->fprintf_func (info->stream, "%s", v850_reg_names[first]);
492 1.1 skrll
493 1.1 skrll for (bit++; bit < 32; bit++)
494 1.1 skrll if ((mask & (1 << bit)) == 0)
495 1.1 skrll break;
496 1.1 skrll
497 1.1 skrll last = bit;
498 1.1 skrll
499 1.1 skrll if (last > first + 1)
500 1.1.1.2 christos {
501 1.1.1.2 christos info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
502 1.1.1.2 christos }
503 1.1 skrll }
504 1.1 skrll }
505 1.1 skrll
506 1.1 skrll if (pc)
507 1.1 skrll info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
508 1.1 skrll }
509 1.1 skrll
510 1.1 skrll info->fprintf_func (info->stream, "}");
511 1.1 skrll }
512 1.1 skrll break;
513 1.1 skrll
514 1.1.1.4 christos case V850_OPERAND_CC:
515 1.1.1.4 christos info->fprintf_func (info->stream, "%s", v850_cc_names[value]);
516 1.1.1.4 christos break;
517 1.1.1.4 christos
518 1.1.1.4 christos case V850_OPERAND_FLOAT_CC:
519 1.1.1.4 christos info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]);
520 1.1.1.4 christos break;
521 1.1.1.4 christos
522 1.1.1.4 christos case V850_OPERAND_CACHEOP:
523 1.1.1.4 christos {
524 1.1.1.4 christos int idx;
525 1.1.1.4 christos
526 1.1.1.4 christos for (idx = 0; v850_cacheop_codes[idx] != -1; idx++)
527 1.1.1.4 christos {
528 1.1.1.4 christos if (value == v850_cacheop_codes[idx])
529 1.1.1.4 christos {
530 1.1.1.4 christos info->fprintf_func (info->stream, "%s",
531 1.1.1.4 christos v850_cacheop_names[idx]);
532 1.1.1.4 christos goto MATCH_CACHEOP_CODE;
533 1.1.1.4 christos }
534 1.1.1.4 christos }
535 1.1.1.4 christos info->fprintf_func (info->stream, "%d", (int) value);
536 1.1.1.4 christos }
537 1.1.1.4 christos MATCH_CACHEOP_CODE:
538 1.1.1.4 christos break;
539 1.1.1.4 christos
540 1.1.1.4 christos case V850_OPERAND_PREFOP:
541 1.1.1.4 christos {
542 1.1.1.4 christos int idx;
543 1.1.1.4 christos
544 1.1.1.4 christos for (idx = 0; v850_prefop_codes[idx] != -1; idx++)
545 1.1.1.4 christos {
546 1.1.1.4 christos if (value == v850_prefop_codes[idx])
547 1.1.1.4 christos {
548 1.1.1.4 christos info->fprintf_func (info->stream, "%s",
549 1.1.1.4 christos v850_prefop_names[idx]);
550 1.1.1.4 christos goto MATCH_PREFOP_CODE;
551 1.1.1.4 christos }
552 1.1.1.4 christos }
553 1.1.1.4 christos info->fprintf_func (info->stream, "%d", (int) value);
554 1.1.1.4 christos }
555 1.1.1.4 christos MATCH_PREFOP_CODE:
556 1.1.1.4 christos break;
557 1.1.1.4 christos
558 1.1.1.4 christos case V850_OPERAND_VREG:
559 1.1.1.4 christos info->fprintf_func (info->stream, "%s", v850_vreg_names[value]);
560 1.1.1.4 christos break;
561 1.1.1.2 christos
562 1.1.1.2 christos default:
563 1.1.1.2 christos print_value (operand->flags, memaddr, info, value);
564 1.1 skrll break;
565 1.1 skrll }
566 1.1 skrll
567 1.1.1.3 christos if (square)
568 1.1 skrll (*info->fprintf_func) (info->stream, "]");
569 1.1 skrll }
570 1.1 skrll
571 1.1 skrll /* All done. */
572 1.1 skrll break;
573 1.1 skrll }
574 1.1.1.2 christos next_opcode:
575 1.1 skrll op++;
576 1.1 skrll }
577 1.1 skrll
578 1.1.1.2 christos return match;
579 1.1 skrll }
580 1.1 skrll
581 1.1 skrll int
582 1.1 skrll print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
583 1.1 skrll {
584 1.1.1.2 christos int status, status2, match;
585 1.1.1.2 christos bfd_byte buffer[8];
586 1.1.1.2 christos int length = 0, code_length = 0;
587 1.1.1.2 christos unsigned long insn = 0, insn2 = 0;
588 1.1.1.2 christos int target_processor;
589 1.1.1.2 christos
590 1.1.1.2 christos switch (info->mach)
591 1.1.1.2 christos {
592 1.1.1.2 christos case 0:
593 1.1.1.2 christos default:
594 1.1.1.2 christos target_processor = PROCESSOR_V850;
595 1.1.1.2 christos break;
596 1.1.1.2 christos
597 1.1.1.2 christos case bfd_mach_v850e:
598 1.1.1.2 christos target_processor = PROCESSOR_V850E;
599 1.1.1.2 christos break;
600 1.1.1.2 christos
601 1.1.1.2 christos case bfd_mach_v850e1:
602 1.1.1.2 christos target_processor = PROCESSOR_V850E;
603 1.1.1.2 christos break;
604 1.1.1.2 christos
605 1.1.1.2 christos case bfd_mach_v850e2:
606 1.1.1.2 christos target_processor = PROCESSOR_V850E2;
607 1.1.1.2 christos break;
608 1.1.1.2 christos
609 1.1.1.2 christos case bfd_mach_v850e2v3:
610 1.1.1.2 christos target_processor = PROCESSOR_V850E2V3;
611 1.1.1.2 christos break;
612 1.1.1.4 christos
613 1.1.1.4 christos case bfd_mach_v850e3v5:
614 1.1.1.4 christos target_processor = PROCESSOR_V850E3V5;
615 1.1.1.4 christos break;
616 1.1.1.2 christos }
617 1.1 skrll
618 1.1 skrll status = info->read_memory_func (memaddr, buffer, 2, info);
619 1.1.1.2 christos
620 1.1.1.2 christos if (status)
621 1.1 skrll {
622 1.1.1.2 christos info->memory_error_func (status, memaddr, info);
623 1.1.1.2 christos return -1;
624 1.1.1.2 christos }
625 1.1 skrll
626 1.1.1.2 christos insn = bfd_getl16 (buffer);
627 1.1.1.2 christos
628 1.1.1.2 christos status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
629 1.1.1.2 christos
630 1.1.1.2 christos if (!status2)
631 1.1.1.2 christos {
632 1.1.1.2 christos insn2 = bfd_getl16 (buffer);
633 1.1.1.2 christos /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
634 1.1.1.2 christos }
635 1.1.1.2 christos
636 1.1.1.2 christos /* Special case. */
637 1.1.1.2 christos if (length == 0
638 1.1.1.4 christos && ((target_processor & PROCESSOR_V850E2_UP) != 0))
639 1.1.1.2 christos {
640 1.1.1.2 christos if ((insn & 0xffff) == 0x02e0 /* jr 32bit */
641 1.1.1.2 christos && !status2 && (insn2 & 0x1) == 0)
642 1.1.1.2 christos {
643 1.1.1.2 christos length = 2;
644 1.1.1.2 christos code_length = 6;
645 1.1.1.2 christos }
646 1.1.1.2 christos else if ((insn & 0xffe0) == 0x02e0 /* jarl 32bit */
647 1.1.1.2 christos && !status2 && (insn2 & 0x1) == 0)
648 1.1.1.2 christos {
649 1.1.1.2 christos length = 2;
650 1.1.1.2 christos code_length = 6;
651 1.1.1.2 christos }
652 1.1.1.2 christos else if ((insn & 0xffe0) == 0x06e0 /* jmp 32bit */
653 1.1.1.2 christos && !status2 && (insn2 & 0x1) == 0)
654 1.1 skrll {
655 1.1.1.2 christos length = 2;
656 1.1.1.2 christos code_length = 6;
657 1.1.1.2 christos }
658 1.1.1.2 christos }
659 1.1 skrll
660 1.1.1.2 christos if (length == 0
661 1.1.1.4 christos && ((target_processor & PROCESSOR_V850E3V5_UP) != 0))
662 1.1.1.4 christos {
663 1.1.1.4 christos if ( ((insn & 0xffe0) == 0x07a0 /* ld.dw 23bit (v850e3v5) */
664 1.1.1.4 christos && !status2 && (insn2 & 0x000f) == 0x0009)
665 1.1.1.4 christos || ((insn & 0xffe0) == 0x07a0 /* st.dw 23bit (v850e3v5) */
666 1.1.1.4 christos && !status2 && (insn2 & 0x000f) == 0x000f))
667 1.1.1.4 christos {
668 1.1.1.4 christos length = 4;
669 1.1.1.4 christos code_length = 6;
670 1.1.1.4 christos }
671 1.1.1.4 christos }
672 1.1.1.4 christos
673 1.1.1.4 christos if (length == 0
674 1.1.1.4 christos && ((target_processor & PROCESSOR_V850E2V3_UP) != 0))
675 1.1.1.2 christos {
676 1.1.1.2 christos if (((insn & 0xffe0) == 0x0780 /* ld.b 23bit */
677 1.1.1.2 christos && !status2 && (insn2 & 0x000f) == 0x0005)
678 1.1.1.2 christos || ((insn & 0xffe0) == 0x07a0 /* ld.bu 23bit */
679 1.1.1.2 christos && !status2 && (insn2 & 0x000f) == 0x0005)
680 1.1.1.2 christos || ((insn & 0xffe0) == 0x0780 /* ld.h 23bit */
681 1.1.1.2 christos && !status2 && (insn2 & 0x000f) == 0x0007)
682 1.1.1.2 christos || ((insn & 0xffe0) == 0x07a0 /* ld.hu 23bit */
683 1.1.1.2 christos && !status2 && (insn2 & 0x000f) == 0x0007)
684 1.1.1.2 christos || ((insn & 0xffe0) == 0x0780 /* ld.w 23bit */
685 1.1.1.2 christos && !status2 && (insn2 & 0x000f) == 0x0009))
686 1.1.1.2 christos {
687 1.1.1.2 christos length = 4;
688 1.1.1.2 christos code_length = 6;
689 1.1.1.2 christos }
690 1.1.1.2 christos else if (((insn & 0xffe0) == 0x0780 /* st.b 23bit */
691 1.1.1.2 christos && !status2 && (insn2 & 0x000f) == 0x000d)
692 1.1.1.2 christos || ((insn & 0xffe0) == 0x07a0 /* st.h 23bit */
693 1.1.1.2 christos && !status2 && (insn2 & 0x000f) == 0x000d)
694 1.1.1.2 christos || ((insn & 0xffe0) == 0x0780 /* st.w 23bit */
695 1.1.1.2 christos && !status2 && (insn2 & 0x000f) == 0x000f))
696 1.1.1.2 christos {
697 1.1.1.2 christos length = 4;
698 1.1.1.2 christos code_length = 6;
699 1.1 skrll }
700 1.1 skrll }
701 1.1 skrll
702 1.1.1.2 christos if (length == 0
703 1.1.1.2 christos && target_processor != PROCESSOR_V850)
704 1.1 skrll {
705 1.1.1.2 christos if ((insn & 0xffe0) == 0x0620) /* 32 bit MOV */
706 1.1.1.2 christos {
707 1.1.1.2 christos length = 2;
708 1.1.1.2 christos code_length = 6;
709 1.1.1.2 christos }
710 1.1.1.2 christos else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm16<<16 */
711 1.1.1.2 christos && !status2 && (insn2 & 0x001f) == 0x0013)
712 1.1.1.2 christos {
713 1.1.1.2 christos length = 4;
714 1.1.1.2 christos code_length = 6;
715 1.1.1.2 christos }
716 1.1.1.2 christos else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm16 */
717 1.1.1.2 christos && !status2 && (insn2 & 0x001f) == 0x000b)
718 1.1.1.2 christos {
719 1.1.1.2 christos length = 4;
720 1.1.1.2 christos code_length = 6;
721 1.1.1.2 christos }
722 1.1.1.2 christos else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm32 */
723 1.1.1.2 christos && !status2 && (insn2 & 0x001f) == 0x001b)
724 1.1.1.2 christos {
725 1.1.1.2 christos length = 4;
726 1.1.1.2 christos code_length = 8;
727 1.1.1.2 christos }
728 1.1.1.2 christos }
729 1.1.1.2 christos
730 1.1.1.2 christos if (length == 4
731 1.1.1.2 christos || (length == 0
732 1.1.1.2 christos && (insn & 0x0600) == 0x0600))
733 1.1.1.2 christos {
734 1.1.1.2 christos /* This is a 4 byte insn. */
735 1.1.1.2 christos status = info->read_memory_func (memaddr, buffer, 4, info);
736 1.1.1.2 christos if (!status)
737 1.1.1.2 christos {
738 1.1.1.2 christos insn = bfd_getl32 (buffer);
739 1.1.1.2 christos
740 1.1.1.2 christos if (!length)
741 1.1.1.2 christos length = code_length = 4;
742 1.1.1.2 christos }
743 1.1.1.2 christos }
744 1.1.1.2 christos
745 1.1.1.2 christos if (code_length > length)
746 1.1.1.2 christos {
747 1.1.1.2 christos status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
748 1.1.1.2 christos if (status)
749 1.1.1.2 christos length = 0;
750 1.1.1.2 christos }
751 1.1.1.2 christos
752 1.1.1.2 christos if (length == 0 && !status)
753 1.1.1.2 christos length = code_length = 2;
754 1.1.1.2 christos
755 1.1.1.2 christos if (length == 2)
756 1.1.1.2 christos insn &= 0xffff;
757 1.1.1.2 christos
758 1.1.1.4 christos /* when the last 2 bytes of section is 0xffff, length will be 0 and cause infinitive loop */
759 1.1.1.4 christos if (length == 0)
760 1.1.1.4 christos return -1;
761 1.1.1.4 christos
762 1.1.1.2 christos match = disassemble (memaddr, info, length, insn);
763 1.1.1.2 christos
764 1.1.1.2 christos if (!match)
765 1.1.1.2 christos {
766 1.1.1.2 christos int l = 0;
767 1.1.1.2 christos
768 1.1.1.2 christos status = info->read_memory_func (memaddr, buffer, code_length, info);
769 1.1.1.2 christos
770 1.1.1.2 christos while (l < code_length)
771 1.1.1.2 christos {
772 1.1.1.2 christos if (code_length - l == 2)
773 1.1.1.2 christos {
774 1.1.1.2 christos insn = bfd_getl16 (buffer + l) & 0xffff;
775 1.1.1.2 christos info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
776 1.1.1.2 christos l += 2;
777 1.1.1.2 christos }
778 1.1.1.2 christos else
779 1.1.1.2 christos {
780 1.1.1.2 christos insn = bfd_getl32 (buffer + l);
781 1.1.1.2 christos info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
782 1.1.1.2 christos l += 4;
783 1.1.1.2 christos }
784 1.1.1.2 christos }
785 1.1 skrll }
786 1.1 skrll
787 1.1.1.2 christos return code_length;
788 1.1 skrll }
789