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