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