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