m10300-dis.c revision 1.1.1.5 1 1.1 christos /* Disassemble MN10300 instructions.
2 1.1.1.5 christos Copyright (C) 1996-2020 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of the GNU opcodes library.
5 1.1 christos
6 1.1 christos This library is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3, or (at your option)
9 1.1 christos any later version.
10 1.1 christos
11 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
12 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 1.1 christos License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program; if not, write to the Free Software
18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1 christos MA 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #include "sysdep.h"
22 1.1 christos #include <stdio.h>
23 1.1 christos #include "opcode/mn10300.h"
24 1.1.1.4 christos #include "disassemble.h"
25 1.1 christos #include "opintl.h"
26 1.1 christos
27 1.1 christos #define HAVE_AM33_2 (info->mach == AM33_2)
28 1.1 christos #define HAVE_AM33 (info->mach == AM33 || HAVE_AM33_2)
29 1.1 christos #define HAVE_AM30 (info->mach == AM30)
30 1.1 christos
31 1.1 christos static void
32 1.1 christos disassemble (bfd_vma memaddr,
33 1.1 christos struct disassemble_info *info,
34 1.1 christos unsigned long insn,
35 1.1 christos unsigned int size)
36 1.1 christos {
37 1.1 christos struct mn10300_opcode *op = (struct mn10300_opcode *) mn10300_opcodes;
38 1.1 christos const struct mn10300_operand *operand;
39 1.1 christos bfd_byte buffer[4];
40 1.1 christos unsigned long extension = 0;
41 1.1 christos int status, match = 0;
42 1.1 christos
43 1.1 christos /* Find the opcode. */
44 1.1 christos while (op->name)
45 1.1 christos {
46 1.1 christos int mysize, extra_shift;
47 1.1 christos
48 1.1 christos if (op->format == FMT_S0)
49 1.1 christos mysize = 1;
50 1.1 christos else if (op->format == FMT_S1
51 1.1 christos || op->format == FMT_D0)
52 1.1 christos mysize = 2;
53 1.1 christos else if (op->format == FMT_S2
54 1.1 christos || op->format == FMT_D1)
55 1.1 christos mysize = 3;
56 1.1 christos else if (op->format == FMT_S4)
57 1.1 christos mysize = 5;
58 1.1 christos else if (op->format == FMT_D2)
59 1.1 christos mysize = 4;
60 1.1 christos else if (op->format == FMT_D3)
61 1.1 christos mysize = 5;
62 1.1 christos else if (op->format == FMT_D4)
63 1.1 christos mysize = 6;
64 1.1 christos else if (op->format == FMT_D6)
65 1.1 christos mysize = 3;
66 1.1 christos else if (op->format == FMT_D7 || op->format == FMT_D10)
67 1.1 christos mysize = 4;
68 1.1 christos else if (op->format == FMT_D8)
69 1.1 christos mysize = 6;
70 1.1 christos else if (op->format == FMT_D9)
71 1.1 christos mysize = 7;
72 1.1 christos else
73 1.1 christos mysize = 7;
74 1.1 christos
75 1.1 christos if ((op->mask & insn) == op->opcode
76 1.1 christos && size == (unsigned int) mysize
77 1.1 christos && (op->machine == 0
78 1.1 christos || (op->machine == AM33_2 && HAVE_AM33_2)
79 1.1 christos || (op->machine == AM33 && HAVE_AM33)
80 1.1 christos || (op->machine == AM30 && HAVE_AM30)))
81 1.1 christos {
82 1.1 christos const unsigned char *opindex_ptr;
83 1.1 christos unsigned int nocomma;
84 1.1 christos int paren = 0;
85 1.1 christos
86 1.1 christos if (op->format == FMT_D1 || op->format == FMT_S1)
87 1.1 christos extra_shift = 8;
88 1.1 christos else if (op->format == FMT_D2 || op->format == FMT_D4
89 1.1 christos || op->format == FMT_S2 || op->format == FMT_S4
90 1.1 christos || op->format == FMT_S6 || op->format == FMT_D5)
91 1.1 christos extra_shift = 16;
92 1.1 christos else if (op->format == FMT_D7
93 1.1 christos || op->format == FMT_D8
94 1.1 christos || op->format == FMT_D9)
95 1.1 christos extra_shift = 8;
96 1.1 christos else
97 1.1 christos extra_shift = 0;
98 1.1 christos
99 1.1 christos if (size == 1 || size == 2)
100 1.1 christos extension = 0;
101 1.1 christos
102 1.1 christos else if (size == 3
103 1.1 christos && (op->format == FMT_D1
104 1.1 christos || op->opcode == 0xdf0000
105 1.1 christos || op->opcode == 0xde0000))
106 1.1 christos extension = 0;
107 1.1 christos
108 1.1 christos else if (size == 3
109 1.1 christos && op->format == FMT_D6)
110 1.1 christos extension = 0;
111 1.1 christos
112 1.1 christos else if (size == 3)
113 1.1 christos {
114 1.1 christos insn &= 0xff0000;
115 1.1 christos status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
116 1.1 christos if (status != 0)
117 1.1 christos {
118 1.1 christos (*info->memory_error_func) (status, memaddr, info);
119 1.1 christos return;
120 1.1 christos }
121 1.1 christos
122 1.1 christos insn |= bfd_getl16 (buffer);
123 1.1 christos extension = 0;
124 1.1 christos }
125 1.1 christos else if (size == 4
126 1.1 christos && (op->opcode == 0xfaf80000
127 1.1 christos || op->opcode == 0xfaf00000
128 1.1 christos || op->opcode == 0xfaf40000))
129 1.1 christos extension = 0;
130 1.1 christos
131 1.1 christos else if (size == 4
132 1.1 christos && (op->format == FMT_D7
133 1.1 christos || op->format == FMT_D10))
134 1.1 christos extension = 0;
135 1.1 christos
136 1.1 christos else if (size == 4)
137 1.1 christos {
138 1.1 christos insn &= 0xffff0000;
139 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
140 1.1 christos if (status != 0)
141 1.1 christos {
142 1.1 christos (*info->memory_error_func) (status, memaddr, info);
143 1.1 christos return;
144 1.1 christos }
145 1.1 christos
146 1.1 christos insn |= bfd_getl16 (buffer);
147 1.1 christos extension = 0;
148 1.1 christos }
149 1.1 christos else if (size == 5 && op->opcode == 0xdc000000)
150 1.1 christos {
151 1.1 christos unsigned long temp = 0;
152 1.1 christos
153 1.1 christos status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
154 1.1 christos if (status != 0)
155 1.1 christos {
156 1.1 christos (*info->memory_error_func) (status, memaddr, info);
157 1.1 christos return;
158 1.1 christos }
159 1.1 christos temp |= bfd_getl32 (buffer);
160 1.1 christos
161 1.1 christos insn &= 0xff000000;
162 1.1 christos insn |= (temp & 0xffffff00) >> 8;
163 1.1 christos extension = temp & 0xff;
164 1.1 christos }
165 1.1 christos else if (size == 5 && op->format == FMT_D3)
166 1.1 christos {
167 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
168 1.1 christos if (status != 0)
169 1.1 christos {
170 1.1 christos (*info->memory_error_func) (status, memaddr, info);
171 1.1 christos return;
172 1.1 christos }
173 1.1 christos insn &= 0xffff0000;
174 1.1 christos insn |= bfd_getl16 (buffer);
175 1.1 christos
176 1.1 christos status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
177 1.1 christos if (status != 0)
178 1.1 christos {
179 1.1 christos (*info->memory_error_func) (status, memaddr, info);
180 1.1 christos return;
181 1.1 christos }
182 1.1 christos extension = *(unsigned char *) buffer;
183 1.1 christos }
184 1.1 christos else if (size == 5)
185 1.1 christos {
186 1.1 christos unsigned long temp = 0;
187 1.1 christos
188 1.1 christos status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
189 1.1 christos if (status != 0)
190 1.1 christos {
191 1.1 christos (*info->memory_error_func) (status, memaddr, info);
192 1.1 christos return;
193 1.1 christos }
194 1.1 christos temp |= bfd_getl16 (buffer);
195 1.1 christos
196 1.1 christos insn &= 0xff0000ff;
197 1.1 christos insn |= temp << 8;
198 1.1 christos
199 1.1 christos status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
200 1.1 christos if (status != 0)
201 1.1 christos {
202 1.1 christos (*info->memory_error_func) (status, memaddr, info);
203 1.1 christos return;
204 1.1 christos }
205 1.1 christos extension = *(unsigned char *) buffer;
206 1.1 christos }
207 1.1 christos else if (size == 6 && op->format == FMT_D8)
208 1.1 christos {
209 1.1 christos insn &= 0xffffff00;
210 1.1 christos status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
211 1.1 christos if (status != 0)
212 1.1 christos {
213 1.1 christos (*info->memory_error_func) (status, memaddr, info);
214 1.1 christos return;
215 1.1 christos }
216 1.1 christos insn |= *(unsigned char *) buffer;
217 1.1 christos
218 1.1 christos status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
219 1.1 christos if (status != 0)
220 1.1 christos {
221 1.1 christos (*info->memory_error_func) (status, memaddr, info);
222 1.1 christos return;
223 1.1 christos }
224 1.1 christos extension = bfd_getl16 (buffer);
225 1.1 christos }
226 1.1 christos else if (size == 6)
227 1.1 christos {
228 1.1 christos unsigned long temp = 0;
229 1.1 christos
230 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
231 1.1 christos if (status != 0)
232 1.1 christos {
233 1.1 christos (*info->memory_error_func) (status, memaddr, info);
234 1.1 christos return;
235 1.1 christos }
236 1.1 christos temp |= bfd_getl32 (buffer);
237 1.1 christos
238 1.1 christos insn &= 0xffff0000;
239 1.1 christos insn |= (temp >> 16) & 0xffff;
240 1.1 christos extension = temp & 0xffff;
241 1.1 christos }
242 1.1 christos else if (size == 7 && op->format == FMT_D9)
243 1.1 christos {
244 1.1 christos insn &= 0xffffff00;
245 1.1 christos status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
246 1.1 christos if (status != 0)
247 1.1 christos {
248 1.1 christos (*info->memory_error_func) (status, memaddr, info);
249 1.1 christos return;
250 1.1 christos }
251 1.1 christos extension = bfd_getl32 (buffer);
252 1.1 christos insn |= (extension & 0xff000000) >> 24;
253 1.1 christos extension &= 0xffffff;
254 1.1 christos }
255 1.1 christos else if (size == 7 && op->opcode == 0xdd000000)
256 1.1 christos {
257 1.1 christos unsigned long temp = 0;
258 1.1 christos
259 1.1 christos status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
260 1.1 christos if (status != 0)
261 1.1 christos {
262 1.1 christos (*info->memory_error_func) (status, memaddr, info);
263 1.1 christos return;
264 1.1 christos }
265 1.1 christos temp |= bfd_getl32 (buffer);
266 1.1 christos
267 1.1 christos insn &= 0xff000000;
268 1.1 christos insn |= (temp >> 8) & 0xffffff;
269 1.1 christos extension = (temp & 0xff) << 16;
270 1.1 christos
271 1.1 christos status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
272 1.1 christos if (status != 0)
273 1.1 christos {
274 1.1 christos (*info->memory_error_func) (status, memaddr, info);
275 1.1 christos return;
276 1.1 christos }
277 1.1 christos extension |= bfd_getb16 (buffer);
278 1.1 christos }
279 1.1 christos else if (size == 7)
280 1.1 christos {
281 1.1 christos unsigned long temp = 0;
282 1.1 christos
283 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
284 1.1 christos if (status != 0)
285 1.1 christos {
286 1.1 christos (*info->memory_error_func) (status, memaddr, info);
287 1.1 christos return;
288 1.1 christos }
289 1.1 christos temp |= bfd_getl32 (buffer);
290 1.1 christos
291 1.1 christos insn &= 0xffff0000;
292 1.1 christos insn |= (temp >> 16) & 0xffff;
293 1.1 christos extension = (temp & 0xffff) << 8;
294 1.1 christos
295 1.1 christos status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
296 1.1 christos if (status != 0)
297 1.1 christos {
298 1.1 christos (*info->memory_error_func) (status, memaddr, info);
299 1.1 christos return;
300 1.1 christos }
301 1.1 christos extension |= *(unsigned char *) buffer;
302 1.1 christos }
303 1.1 christos
304 1.1 christos match = 1;
305 1.1 christos (*info->fprintf_func) (info->stream, "%s\t", op->name);
306 1.1 christos
307 1.1 christos /* Now print the operands. */
308 1.1 christos for (opindex_ptr = op->operands, nocomma = 1;
309 1.1 christos *opindex_ptr != 0;
310 1.1 christos opindex_ptr++)
311 1.1 christos {
312 1.1 christos unsigned long value;
313 1.1 christos
314 1.1 christos operand = &mn10300_operands[*opindex_ptr];
315 1.1 christos
316 1.1 christos /* If this operand is a PLUS (autoincrement), then do not emit
317 1.1 christos a comma before emitting the plus. */
318 1.1 christos if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
319 1.1 christos nocomma = 1;
320 1.1 christos
321 1.1.1.5 christos if ((operand->flags & MN10300_OPERAND_DREG) != 0
322 1.1.1.5 christos || (operand->flags & MN10300_OPERAND_AREG) != 0
323 1.1.1.5 christos || (operand->flags & MN10300_OPERAND_RREG) != 0
324 1.1.1.5 christos || (operand->flags & MN10300_OPERAND_XRREG) != 0)
325 1.1.1.5 christos value = ((insn >> (operand->shift + extra_shift))
326 1.1.1.5 christos & ((1 << operand->bits) - 1));
327 1.1.1.5 christos else if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
328 1.1 christos {
329 1.1 christos unsigned long temp;
330 1.1 christos
331 1.1 christos value = insn & ((1 << operand->bits) - 1);
332 1.1 christos value <<= (32 - operand->bits);
333 1.1 christos temp = extension >> operand->shift;
334 1.1 christos temp &= ((1 << (32 - operand->bits)) - 1);
335 1.1 christos value |= temp;
336 1.1 christos value = ((value ^ (((unsigned long) 1) << 31))
337 1.1 christos - (((unsigned long) 1) << 31));
338 1.1 christos }
339 1.1 christos else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
340 1.1 christos {
341 1.1 christos unsigned long temp;
342 1.1 christos
343 1.1 christos value = insn & ((1 << operand->bits) - 1);
344 1.1 christos value <<= (24 - operand->bits);
345 1.1 christos temp = extension >> operand->shift;
346 1.1 christos temp &= ((1 << (24 - operand->bits)) - 1);
347 1.1 christos value |= temp;
348 1.1 christos if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
349 1.1 christos value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
350 1.1 christos }
351 1.1 christos else if ((operand->flags & (MN10300_OPERAND_FSREG
352 1.1 christos | MN10300_OPERAND_FDREG)))
353 1.1 christos {
354 1.1 christos /* See m10300-opc.c just before #define FSM0 for an
355 1.1 christos explanation of these variables. Note that
356 1.1 christos FMT-implied shifts are not taken into account for
357 1.1 christos FP registers. */
358 1.1 christos unsigned long mask_low, mask_high;
359 1.1 christos int shl_low, shr_high, shl_high;
360 1.1 christos
361 1.1 christos switch (operand->bits)
362 1.1 christos {
363 1.1 christos case 5:
364 1.1 christos /* Handle regular FP registers. */
365 1.1 christos if (operand->shift >= 0)
366 1.1 christos {
367 1.1 christos /* This is an `m' register. */
368 1.1 christos shl_low = operand->shift;
369 1.1 christos shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
370 1.1 christos }
371 1.1 christos else
372 1.1 christos {
373 1.1 christos /* This is an `n' register. */
374 1.1 christos shl_low = -operand->shift;
375 1.1 christos shl_high = shl_low / 4;
376 1.1 christos }
377 1.1 christos mask_low = 0x0f;
378 1.1 christos mask_high = 0x10;
379 1.1 christos shr_high = 4;
380 1.1 christos break;
381 1.1 christos
382 1.1 christos case 3:
383 1.1 christos /* Handle accumulators. */
384 1.1 christos shl_low = -operand->shift;
385 1.1 christos shl_high = 0;
386 1.1 christos mask_low = 0x03;
387 1.1 christos mask_high = 0x04;
388 1.1 christos shr_high = 2;
389 1.1 christos break;
390 1.1 christos
391 1.1 christos default:
392 1.1 christos abort ();
393 1.1 christos }
394 1.1 christos value = ((((insn >> shl_high) << shr_high) & mask_high)
395 1.1 christos | ((insn >> shl_low) & mask_low));
396 1.1 christos }
397 1.1 christos else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
398 1.1 christos value = ((extension >> (operand->shift))
399 1.1 christos & ((1 << operand->bits) - 1));
400 1.1 christos
401 1.1 christos else
402 1.1 christos value = ((insn >> (operand->shift))
403 1.1 christos & ((1 << operand->bits) - 1));
404 1.1 christos
405 1.1 christos if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
406 1.1 christos /* These are properly extended by the code above. */
407 1.1 christos && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
408 1.1 christos value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
409 1.1 christos - (((unsigned long) 1) << (operand->bits - 1)));
410 1.1 christos
411 1.1 christos if (!nocomma
412 1.1 christos && (!paren
413 1.1 christos || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
414 1.1 christos (*info->fprintf_func) (info->stream, ",");
415 1.1 christos
416 1.1 christos nocomma = 0;
417 1.1 christos
418 1.1 christos if ((operand->flags & MN10300_OPERAND_DREG) != 0)
419 1.1.1.5 christos (*info->fprintf_func) (info->stream, "d%d", (int) value);
420 1.1 christos
421 1.1 christos else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
422 1.1.1.5 christos (*info->fprintf_func) (info->stream, "a%d", (int) value);
423 1.1 christos
424 1.1 christos else if ((operand->flags & MN10300_OPERAND_SP) != 0)
425 1.1 christos (*info->fprintf_func) (info->stream, "sp");
426 1.1 christos
427 1.1 christos else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
428 1.1 christos (*info->fprintf_func) (info->stream, "psw");
429 1.1 christos
430 1.1 christos else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
431 1.1 christos (*info->fprintf_func) (info->stream, "mdr");
432 1.1 christos
433 1.1 christos else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
434 1.1 christos {
435 1.1 christos if (value < 8)
436 1.1 christos (*info->fprintf_func) (info->stream, "r%d", (int) value);
437 1.1 christos else if (value < 12)
438 1.1 christos (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
439 1.1 christos else
440 1.1 christos (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
441 1.1 christos }
442 1.1 christos
443 1.1 christos else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
444 1.1 christos {
445 1.1 christos if (value == 0)
446 1.1 christos (*info->fprintf_func) (info->stream, "sp");
447 1.1 christos else
448 1.1 christos (*info->fprintf_func) (info->stream, "xr%d", (int) value);
449 1.1 christos }
450 1.1 christos
451 1.1 christos else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
452 1.1 christos (*info->fprintf_func) (info->stream, "fs%d", (int) value);
453 1.1 christos
454 1.1 christos else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
455 1.1 christos (*info->fprintf_func) (info->stream, "fd%d", (int) value);
456 1.1 christos
457 1.1 christos else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
458 1.1 christos (*info->fprintf_func) (info->stream, "fpcr");
459 1.1 christos
460 1.1 christos else if ((operand->flags & MN10300_OPERAND_USP) != 0)
461 1.1 christos (*info->fprintf_func) (info->stream, "usp");
462 1.1 christos
463 1.1 christos else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
464 1.1 christos (*info->fprintf_func) (info->stream, "ssp");
465 1.1 christos
466 1.1 christos else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
467 1.1 christos (*info->fprintf_func) (info->stream, "msp");
468 1.1 christos
469 1.1 christos else if ((operand->flags & MN10300_OPERAND_PC) != 0)
470 1.1 christos (*info->fprintf_func) (info->stream, "pc");
471 1.1 christos
472 1.1 christos else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
473 1.1 christos (*info->fprintf_func) (info->stream, "epsw");
474 1.1 christos
475 1.1 christos else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
476 1.1 christos (*info->fprintf_func) (info->stream, "+");
477 1.1 christos
478 1.1 christos else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
479 1.1 christos {
480 1.1 christos if (paren)
481 1.1 christos (*info->fprintf_func) (info->stream, ")");
482 1.1 christos else
483 1.1 christos {
484 1.1 christos (*info->fprintf_func) (info->stream, "(");
485 1.1 christos nocomma = 1;
486 1.1 christos }
487 1.1 christos paren = !paren;
488 1.1 christos }
489 1.1 christos
490 1.1 christos else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
491 1.1 christos (*info->print_address_func) ((long) value + memaddr, info);
492 1.1 christos
493 1.1 christos else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
494 1.1 christos (*info->print_address_func) (value, info);
495 1.1 christos
496 1.1 christos else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
497 1.1 christos {
498 1.1 christos int comma = 0;
499 1.1 christos
500 1.1 christos (*info->fprintf_func) (info->stream, "[");
501 1.1 christos if (value & 0x80)
502 1.1 christos {
503 1.1 christos (*info->fprintf_func) (info->stream, "d2");
504 1.1 christos comma = 1;
505 1.1 christos }
506 1.1 christos
507 1.1 christos if (value & 0x40)
508 1.1 christos {
509 1.1 christos if (comma)
510 1.1 christos (*info->fprintf_func) (info->stream, ",");
511 1.1 christos (*info->fprintf_func) (info->stream, "d3");
512 1.1 christos comma = 1;
513 1.1 christos }
514 1.1 christos
515 1.1 christos if (value & 0x20)
516 1.1 christos {
517 1.1 christos if (comma)
518 1.1 christos (*info->fprintf_func) (info->stream, ",");
519 1.1 christos (*info->fprintf_func) (info->stream, "a2");
520 1.1 christos comma = 1;
521 1.1 christos }
522 1.1 christos
523 1.1 christos if (value & 0x10)
524 1.1 christos {
525 1.1 christos if (comma)
526 1.1 christos (*info->fprintf_func) (info->stream, ",");
527 1.1 christos (*info->fprintf_func) (info->stream, "a3");
528 1.1 christos comma = 1;
529 1.1 christos }
530 1.1 christos
531 1.1 christos if (value & 0x08)
532 1.1 christos {
533 1.1 christos if (comma)
534 1.1 christos (*info->fprintf_func) (info->stream, ",");
535 1.1 christos (*info->fprintf_func) (info->stream, "other");
536 1.1 christos comma = 1;
537 1.1 christos }
538 1.1 christos
539 1.1 christos if (value & 0x04)
540 1.1 christos {
541 1.1 christos if (comma)
542 1.1 christos (*info->fprintf_func) (info->stream, ",");
543 1.1 christos (*info->fprintf_func) (info->stream, "exreg0");
544 1.1 christos comma = 1;
545 1.1 christos }
546 1.1 christos if (value & 0x02)
547 1.1 christos {
548 1.1 christos if (comma)
549 1.1 christos (*info->fprintf_func) (info->stream, ",");
550 1.1 christos (*info->fprintf_func) (info->stream, "exreg1");
551 1.1 christos comma = 1;
552 1.1 christos }
553 1.1 christos if (value & 0x01)
554 1.1 christos {
555 1.1 christos if (comma)
556 1.1 christos (*info->fprintf_func) (info->stream, ",");
557 1.1 christos (*info->fprintf_func) (info->stream, "exother");
558 1.1 christos comma = 1;
559 1.1 christos }
560 1.1 christos (*info->fprintf_func) (info->stream, "]");
561 1.1 christos }
562 1.1 christos
563 1.1 christos else
564 1.1 christos (*info->fprintf_func) (info->stream, "%ld", (long) value);
565 1.1 christos }
566 1.1 christos /* All done. */
567 1.1 christos break;
568 1.1 christos }
569 1.1 christos op++;
570 1.1 christos }
571 1.1 christos
572 1.1 christos if (!match)
573 1.1 christos /* xgettext:c-format */
574 1.1 christos (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
575 1.1 christos }
576 1.1 christos
577 1.1 christos int
578 1.1 christos print_insn_mn10300 (bfd_vma memaddr, struct disassemble_info *info)
579 1.1 christos {
580 1.1 christos int status;
581 1.1 christos bfd_byte buffer[4];
582 1.1 christos unsigned long insn;
583 1.1 christos unsigned int consume;
584 1.1 christos
585 1.1 christos /* First figure out how big the opcode is. */
586 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 1, info);
587 1.1 christos if (status != 0)
588 1.1 christos {
589 1.1 christos (*info->memory_error_func) (status, memaddr, info);
590 1.1 christos return -1;
591 1.1 christos }
592 1.1 christos insn = *(unsigned char *) buffer;
593 1.1 christos
594 1.1 christos /* These are one byte insns. */
595 1.1 christos if ((insn & 0xf3) == 0x00
596 1.1 christos || (insn & 0xf0) == 0x10
597 1.1 christos || (insn & 0xfc) == 0x3c
598 1.1 christos || (insn & 0xf3) == 0x41
599 1.1 christos || (insn & 0xf3) == 0x40
600 1.1 christos || (insn & 0xfc) == 0x50
601 1.1 christos || (insn & 0xfc) == 0x54
602 1.1 christos || (insn & 0xf0) == 0x60
603 1.1 christos || (insn & 0xf0) == 0x70
604 1.1 christos || ((insn & 0xf0) == 0x80
605 1.1 christos && (insn & 0x0c) >> 2 != (insn & 0x03))
606 1.1 christos || ((insn & 0xf0) == 0x90
607 1.1 christos && (insn & 0x0c) >> 2 != (insn & 0x03))
608 1.1 christos || ((insn & 0xf0) == 0xa0
609 1.1 christos && (insn & 0x0c) >> 2 != (insn & 0x03))
610 1.1 christos || ((insn & 0xf0) == 0xb0
611 1.1 christos && (insn & 0x0c) >> 2 != (insn & 0x03))
612 1.1 christos || (insn & 0xff) == 0xcb
613 1.1 christos || (insn & 0xfc) == 0xd0
614 1.1 christos || (insn & 0xfc) == 0xd4
615 1.1 christos || (insn & 0xfc) == 0xd8
616 1.1 christos || (insn & 0xf0) == 0xe0
617 1.1 christos || (insn & 0xff) == 0xff)
618 1.1 christos {
619 1.1 christos consume = 1;
620 1.1 christos }
621 1.1 christos
622 1.1 christos /* These are two byte insns. */
623 1.1 christos else if ((insn & 0xf0) == 0x80
624 1.1 christos || (insn & 0xf0) == 0x90
625 1.1 christos || (insn & 0xf0) == 0xa0
626 1.1 christos || (insn & 0xf0) == 0xb0
627 1.1 christos || (insn & 0xfc) == 0x20
628 1.1 christos || (insn & 0xfc) == 0x28
629 1.1 christos || (insn & 0xf3) == 0x43
630 1.1 christos || (insn & 0xf3) == 0x42
631 1.1 christos || (insn & 0xfc) == 0x58
632 1.1 christos || (insn & 0xfc) == 0x5c
633 1.1 christos || ((insn & 0xf0) == 0xc0
634 1.1 christos && (insn & 0xff) != 0xcb
635 1.1 christos && (insn & 0xff) != 0xcc
636 1.1 christos && (insn & 0xff) != 0xcd)
637 1.1 christos || (insn & 0xff) == 0xf0
638 1.1 christos || (insn & 0xff) == 0xf1
639 1.1 christos || (insn & 0xff) == 0xf2
640 1.1 christos || (insn & 0xff) == 0xf3
641 1.1 christos || (insn & 0xff) == 0xf4
642 1.1 christos || (insn & 0xff) == 0xf5
643 1.1 christos || (insn & 0xff) == 0xf6)
644 1.1 christos {
645 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 2, info);
646 1.1 christos if (status != 0)
647 1.1 christos {
648 1.1 christos (*info->memory_error_func) (status, memaddr, info);
649 1.1 christos return -1;
650 1.1 christos }
651 1.1 christos insn = bfd_getb16 (buffer);
652 1.1 christos consume = 2;
653 1.1 christos }
654 1.1 christos
655 1.1 christos /* These are three byte insns. */
656 1.1 christos else if ((insn & 0xff) == 0xf8
657 1.1 christos || (insn & 0xff) == 0xcc
658 1.1 christos || (insn & 0xff) == 0xf9
659 1.1 christos || (insn & 0xf3) == 0x01
660 1.1 christos || (insn & 0xf3) == 0x02
661 1.1 christos || (insn & 0xf3) == 0x03
662 1.1 christos || (insn & 0xfc) == 0x24
663 1.1 christos || (insn & 0xfc) == 0x2c
664 1.1 christos || (insn & 0xfc) == 0x30
665 1.1 christos || (insn & 0xfc) == 0x34
666 1.1 christos || (insn & 0xfc) == 0x38
667 1.1 christos || (insn & 0xff) == 0xde
668 1.1 christos || (insn & 0xff) == 0xdf
669 1.1 christos || (insn & 0xff) == 0xf9
670 1.1 christos || (insn & 0xff) == 0xcc)
671 1.1 christos {
672 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 2, info);
673 1.1 christos if (status != 0)
674 1.1 christos {
675 1.1 christos (*info->memory_error_func) (status, memaddr, info);
676 1.1 christos return -1;
677 1.1 christos }
678 1.1 christos insn = bfd_getb16 (buffer);
679 1.1 christos insn <<= 8;
680 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
681 1.1 christos if (status != 0)
682 1.1 christos {
683 1.1 christos (*info->memory_error_func) (status, memaddr, info);
684 1.1 christos return -1;
685 1.1 christos }
686 1.1 christos insn |= *(unsigned char *) buffer;
687 1.1 christos consume = 3;
688 1.1 christos }
689 1.1 christos
690 1.1 christos /* These are four byte insns. */
691 1.1 christos else if ((insn & 0xff) == 0xfa
692 1.1 christos || (insn & 0xff) == 0xf7
693 1.1 christos || (insn & 0xff) == 0xfb)
694 1.1 christos {
695 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 4, info);
696 1.1 christos if (status != 0)
697 1.1 christos {
698 1.1 christos (*info->memory_error_func) (status, memaddr, info);
699 1.1 christos return -1;
700 1.1 christos }
701 1.1 christos insn = bfd_getb32 (buffer);
702 1.1 christos consume = 4;
703 1.1 christos }
704 1.1 christos
705 1.1 christos /* These are five byte insns. */
706 1.1 christos else if ((insn & 0xff) == 0xcd
707 1.1 christos || (insn & 0xff) == 0xdc)
708 1.1 christos {
709 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 4, info);
710 1.1 christos if (status != 0)
711 1.1 christos {
712 1.1 christos (*info->memory_error_func) (status, memaddr, info);
713 1.1 christos return -1;
714 1.1 christos }
715 1.1 christos insn = bfd_getb32 (buffer);
716 1.1 christos consume = 5;
717 1.1 christos }
718 1.1 christos
719 1.1 christos /* These are six byte insns. */
720 1.1 christos else if ((insn & 0xff) == 0xfd
721 1.1 christos || (insn & 0xff) == 0xfc)
722 1.1 christos {
723 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 4, info);
724 1.1 christos if (status != 0)
725 1.1 christos {
726 1.1 christos (*info->memory_error_func) (status, memaddr, info);
727 1.1 christos return -1;
728 1.1 christos }
729 1.1 christos
730 1.1 christos insn = bfd_getb32 (buffer);
731 1.1 christos consume = 6;
732 1.1 christos }
733 1.1 christos
734 1.1 christos /* Else its a seven byte insns (in theory). */
735 1.1 christos else
736 1.1 christos {
737 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 4, info);
738 1.1 christos if (status != 0)
739 1.1 christos {
740 1.1 christos (*info->memory_error_func) (status, memaddr, info);
741 1.1 christos return -1;
742 1.1 christos }
743 1.1 christos
744 1.1 christos insn = bfd_getb32 (buffer);
745 1.1 christos consume = 7;
746 1.1 christos /* Handle the 5-byte extended instruction codes. */
747 1.1 christos if ((insn & 0xfff80000) == 0xfe800000)
748 1.1 christos consume = 5;
749 1.1 christos }
750 1.1 christos
751 1.1 christos disassemble (memaddr, info, insn, consume);
752 1.1 christos
753 1.1 christos return consume;
754 1.1 christos }
755