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