1 /* Disassemble h8300 instructions.
2 Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #define h8_opcodes h8ops
23 #include "opcode/h8300.h"
26 #include "libiberty.h"
31 const struct h8_opcode
*opcode
;
34 struct h8_instruction
*h8_instructions
;
36 static void bfd_h8_disassemble_init
PARAMS ((void));
37 static void print_one_arg
PARAMS ((disassemble_info
*, bfd_vma
, op_type
,
38 int, int, int, int, const char **, int));
39 static unsigned int bfd_h8_disassemble
PARAMS ((bfd_vma
,
42 static void extract_immediate
PARAMS ((FILE *,
46 const struct h8_opcode
*));
48 static void print_colon_thingie
PARAMS ((op_type
*));
51 print_colon_thingie (op_type
*nib
)
53 switch (*nib
& SIZE
) {
54 case L_2
: fprintf (stdout
, "2"); break;
56 case L_3NZ
: fprintf (stdout
, "3"); break;
57 case L_4
: fprintf (stdout
, "4"); break;
58 case L_5
: fprintf (stdout
, "5"); break;
59 case L_8
: fprintf (stdout
, "8"); break;
61 case L_16U
: fprintf (stdout
, "16"); break;
62 case L_24
: fprintf (stdout
, "24"); break;
63 case L_32
: fprintf (stdout
, "32"); break;
67 /* Run through the opcodes and sort them into order to make them easy
71 bfd_h8_disassemble_init ()
74 unsigned int nopcodes
;
75 const struct h8_opcode
*p
;
76 struct h8_instruction
*pi
;
78 nopcodes
= sizeof (h8_opcodes
) / sizeof (struct h8_opcode
);
80 h8_instructions
= (struct h8_instruction
*)
81 xmalloc (nopcodes
* sizeof (struct h8_instruction
));
83 for (p
= h8_opcodes
, pi
= h8_instructions
; p
->name
; p
++, pi
++)
88 if ((int) p
->data
.nib
[0] < 16)
89 n1
= (int) p
->data
.nib
[0];
93 if ((int) p
->data
.nib
[1] < 16)
94 n2
= (int) p
->data
.nib
[1];
98 /* Just make sure there are an even number of nibbles in it, and
99 that the count is the same as the length. */
100 for (i
= 0; p
->data
.nib
[i
] != (op_type
) E
; i
++)
105 fprintf (stderr
, "Internal error, h8_disassemble_init.\n");
113 /* Add entry for the NULL vector terminator. */
119 extract_immediate (stream
, looking_for
, thisnib
, data
, cst
, len
, q
)
125 const struct h8_opcode
*q
;
127 switch (looking_for
& SIZE
)
133 /* DISP2 special treatment. */
134 if ((looking_for
& MODE
) == DISP
)
136 if (OP_KIND (q
->how
) == O_MOVAB
||
137 OP_KIND (q
->how
) == O_MOVAW
||
138 OP_KIND (q
->how
) == O_MOVAL
)
140 /* Handling for mova insn. */
141 switch (q
->args
.nib
[0] & MODE
) {
155 /* Handling for non-mova insn. */
156 switch (OP_SIZE (q
->how
)) {
175 *cst
= (data
[0] << 8) + data
[1];
177 if ((looking_for
& SIZE
) == L_16
)
178 *cst
= (short) *cst
; /* sign extend */
183 *cst
= (data
[0] << 24) + (data
[1] << 16) + (data
[2] << 8) + data
[3];
188 fprintf (stream
, "DISP bad size\n");
193 static const char *regnames
[] =
195 "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
196 "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"
198 static const char *wregnames
[] =
200 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
201 "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
203 static const char *lregnames
[] =
205 "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
206 "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
208 static const char *cregnames
[] =
210 "ccr", "exr", "mach", "macl", "", "", "vbr", "sbr"
214 print_one_arg (info
, addr
, x
, cst
, cstlen
, rdisp_n
, rn
, pregnames
, len
)
215 disassemble_info
*info
;
218 int cst
, cstlen
, rdisp_n
, rn
;
219 const char **pregnames
;
222 void *stream
= info
->stream
;
223 fprintf_ftype outfn
= info
->fprintf_func
;
225 if ((x
& SIZE
) == L_3
||
228 outfn (stream
, "#0x%x", (unsigned) cst
);
230 else if ((x
& MODE
) == IMM
)
232 outfn (stream
, "#0x%x", (unsigned) cst
);
234 else if ((x
& MODE
) == DBIT
||
237 outfn (stream
, "#%d", (unsigned) cst
);
239 else if ((x
& MODE
) == CONST_2
)
240 outfn (stream
, "#2");
241 else if ((x
& MODE
) == CONST_4
)
242 outfn (stream
, "#4");
243 else if ((x
& MODE
) == CONST_8
)
244 outfn (stream
, "#8");
245 else if ((x
& MODE
) == CONST_16
)
246 outfn (stream
, "#16");
247 else if ((x
& MODE
) == REG
)
252 outfn (stream
, "%s", regnames
[rn
]);
256 outfn (stream
, "%s", wregnames
[rn
]);
260 outfn (stream
, "%s", lregnames
[rn
]);
264 else if ((x
& MODE
) == LOWREG
)
269 /* Always take low half of reg. */
270 outfn (stream
, "%s.b", regnames
[rn
< 8 ? rn
+ 8 : rn
]);
274 /* Always take low half of reg. */
275 outfn (stream
, "%s.w", wregnames
[rn
< 8 ? rn
: rn
- 8]);
279 outfn (stream
, "%s.l", lregnames
[rn
]);
283 else if ((x
& MODE
) == POSTINC
)
285 outfn (stream
, "@%s+", pregnames
[rn
]);
287 else if ((x
& MODE
) == POSTDEC
)
289 outfn (stream
, "@%s-", pregnames
[rn
]);
291 else if ((x
& MODE
) == PREINC
)
293 outfn (stream
, "@+%s", pregnames
[rn
]);
295 else if ((x
& MODE
) == PREDEC
)
297 outfn (stream
, "@-%s", pregnames
[rn
]);
299 else if ((x
& MODE
) == IND
)
301 outfn (stream
, "@%s", pregnames
[rn
]);
303 else if ((x
& MODE
) == ABS
|| (x
& ABSJMP
))
305 outfn (stream
, "@0x%x:%d", (unsigned) cst
, cstlen
);
307 else if ((x
& MODE
) == MEMIND
)
309 outfn (stream
, "@@%d (0x%x)", cst
, cst
);
311 else if ((x
& MODE
) == VECIND
)
313 /* FIXME Multiplier should be 2 or 4, depending on processor mode,
314 by which is meant "normal" vs. "middle", "advanced", "maximum". */
316 int offset
= (cst
+ 0x80) * 4;
317 outfn (stream
, "@@%d (0x%x)", offset
, offset
);
319 else if ((x
& MODE
) == PCREL
)
321 if ((x
& SIZE
) == L_16
||
324 outfn (stream
, ".%s%d (0x%x)",
325 (short) cst
> 0 ? "+" : "",
327 addr
+ (short) cst
+ len
);
331 outfn (stream
, ".%s%d (0x%x)",
332 (char) cst
> 0 ? "+" : "",
334 addr
+ (char) cst
+ len
);
337 else if ((x
& MODE
) == DISP
)
339 outfn (stream
, "@(0x%x:%d,%s)", cst
, cstlen
,
342 else if ((x
& MODE
) == INDEXB
)
344 /* Always take low half of reg. */
345 outfn (stream
, "@(0x%x:%d,%s.b)", cst
, cstlen
,
346 regnames
[rdisp_n
< 8 ? rdisp_n
+ 8 : rdisp_n
]);
348 else if ((x
& MODE
) == INDEXW
)
350 /* Always take low half of reg. */
351 outfn (stream
, "@(0x%x:%d,%s.w)", cst
, cstlen
,
352 wregnames
[rdisp_n
< 8 ? rdisp_n
: rdisp_n
- 8]);
354 else if ((x
& MODE
) == INDEXL
)
356 outfn (stream
, "@(0x%x:%d,%s.l)", cst
, cstlen
,
361 outfn (stream
, cregnames
[rn
]);
363 else if ((x
& MODE
) == CCR
)
365 outfn (stream
, "ccr");
367 else if ((x
& MODE
) == EXR
)
369 outfn (stream
, "exr");
371 else if ((x
& MODE
) == MACREG
)
373 outfn (stream
, "mac%c", cst
? 'l' : 'h');
376 /* xgettext:c-format */
377 outfn (stream
, _("Hmmmm 0x%x"), x
);
381 bfd_h8_disassemble (addr
, info
, mach
)
383 disassemble_info
*info
;
386 /* Find the first entry in the table for this opcode. */
387 int regno
[3] = { 0, 0, 0 };
388 int dispregno
[3] = { 0, 0, 0 };
389 int cst
[3] = { 0, 0, 0 };
390 int cstlen
[3] = { 0, 0, 0 };
391 static bfd_boolean init
= 0;
392 const struct h8_instruction
*qi
;
393 char const **pregnames
= mach
!= 0 ? lregnames
: wregnames
;
396 unsigned char data
[MAX_CODE_NIBBLES
];
397 void *stream
= info
->stream
;
398 fprintf_ftype outfn
= info
->fprintf_func
;
402 bfd_h8_disassemble_init ();
406 status
= info
->read_memory_func (addr
, data
, 2, info
);
409 info
->memory_error_func (status
, addr
, info
);
413 for (l
= 2; status
== 0 && l
< sizeof (data
) / 2; l
+= 2)
414 status
= info
->read_memory_func (addr
+ l
, data
+ l
, 2, info
);
416 /* Find the exact opcode/arg combo. */
417 for (qi
= h8_instructions
; qi
->opcode
->name
; qi
++)
419 const struct h8_opcode
*q
= qi
->opcode
;
420 op_type
*nib
= q
->data
.nib
;
421 unsigned int len
= 0;
425 op_type looking_for
= *nib
;
426 int thisnib
= data
[len
/ 2];
429 thisnib
= (len
& 1) ? (thisnib
& 0xf) : ((thisnib
/ 16) & 0xf);
430 opnr
= ((looking_for
& OP3
) == OP3
? 2
431 : (looking_for
& DST
) == DST
? 1 : 0);
433 if (looking_for
< 16 && looking_for
>= 0)
435 if (looking_for
!= thisnib
)
440 if ((int) looking_for
& (int) B31
)
442 if (!((thisnib
& 0x8) != 0))
445 looking_for
= (op_type
) ((int) looking_for
& ~(int) B31
);
448 else if ((int) looking_for
& (int) B30
)
450 if (!((thisnib
& 0x8) == 0))
453 looking_for
= (op_type
) ((int) looking_for
& ~(int) B30
);
456 if ((int) looking_for
& (int) B21
)
458 if (!((thisnib
& 0x4) != 0))
461 looking_for
= (op_type
) ((int) looking_for
& ~(int) B21
);
464 else if ((int) looking_for
& (int) B20
)
466 if (!((thisnib
& 0x4) == 0))
469 looking_for
= (op_type
) ((int) looking_for
& ~(int) B20
);
471 if ((int) looking_for
& (int) B11
)
473 if (!((thisnib
& 0x2) != 0))
476 looking_for
= (op_type
) ((int) looking_for
& ~(int) B11
);
479 else if ((int) looking_for
& (int) B10
)
481 if (!((thisnib
& 0x2) == 0))
484 looking_for
= (op_type
) ((int) looking_for
& ~(int) B10
);
487 if ((int) looking_for
& (int) B01
)
489 if (!((thisnib
& 0x1) != 0))
492 looking_for
= (op_type
) ((int) looking_for
& ~(int) B01
);
495 else if ((int) looking_for
& (int) B00
)
497 if (!((thisnib
& 0x1) == 0))
500 looking_for
= (op_type
) ((int) looking_for
& ~(int) B00
);
503 if (looking_for
& IGNORE
)
505 /* Hitachi has declared that IGNORE must be zero. */
509 else if ((looking_for
& MODE
) == DATA
)
511 ; /* Skip embedded data. */
513 else if ((looking_for
& MODE
) == DBIT
)
515 /* Exclude adds/subs by looking at bit 0 and 2, and
516 make sure the operand size, either w or l,
517 matches by looking at bit 1. */
518 if ((looking_for
& 7) != (thisnib
& 7))
521 cst
[opnr
] = (thisnib
& 0x8) ? 2 : 1;
523 else if ((looking_for
& MODE
) == DISP
||
524 (looking_for
& MODE
) == ABS
||
525 (looking_for
& MODE
) == PCREL
||
526 (looking_for
& MODE
) == INDEXB
||
527 (looking_for
& MODE
) == INDEXW
||
528 (looking_for
& MODE
) == INDEXL
)
530 extract_immediate (stream
, looking_for
, thisnib
,
531 data
+ len
/ 2, cst
+ opnr
,
533 /* Even address == bra, odd == bra/s. */
534 if (q
->how
== O (O_BRAS
, SB
))
537 else if ((looking_for
& MODE
) == REG
||
538 (looking_for
& MODE
) == LOWREG
||
539 (looking_for
& MODE
) == IND
||
540 (looking_for
& MODE
) == PREINC
||
541 (looking_for
& MODE
) == POSTINC
||
542 (looking_for
& MODE
) == PREDEC
||
543 (looking_for
& MODE
) == POSTDEC
)
545 regno
[opnr
] = thisnib
;
547 else if (looking_for
& CTRL
) /* Control Register */
550 if (((looking_for
& MODE
) == CCR
&& (thisnib
!= C_CCR
)) ||
551 ((looking_for
& MODE
) == EXR
&& (thisnib
!= C_EXR
)) ||
552 ((looking_for
& MODE
) == MACH
&& (thisnib
!= C_MACH
)) ||
553 ((looking_for
& MODE
) == MACL
&& (thisnib
!= C_MACL
)) ||
554 ((looking_for
& MODE
) == VBR
&& (thisnib
!= C_VBR
)) ||
555 ((looking_for
& MODE
) == SBR
&& (thisnib
!= C_SBR
)))
557 if (((looking_for
& MODE
) == CCR_EXR
&&
558 (thisnib
!= C_CCR
&& thisnib
!= C_EXR
)) ||
559 ((looking_for
& MODE
) == VBR_SBR
&&
560 (thisnib
!= C_VBR
&& thisnib
!= C_SBR
)) ||
561 ((looking_for
& MODE
) == MACREG
&&
562 (thisnib
!= C_MACH
&& thisnib
!= C_MACL
)))
564 if (((looking_for
& MODE
) == CC_EX_VB_SB
&&
565 (thisnib
!= C_CCR
&& thisnib
!= C_EXR
&&
566 thisnib
!= C_VBR
&& thisnib
!= C_SBR
)))
569 regno
[opnr
] = thisnib
;
571 else if ((looking_for
& SIZE
) == L_5
)
573 cst
[opnr
] = data
[len
/ 2] & 31;
576 else if ((looking_for
& SIZE
) == L_4
)
581 else if ((looking_for
& SIZE
) == L_16
||
582 (looking_for
& SIZE
) == L_16U
)
584 cst
[opnr
] = (data
[len
/ 2]) * 256 + data
[(len
+ 2) / 2];
587 else if ((looking_for
& MODE
) == MEMIND
)
591 else if ((looking_for
& MODE
) == VECIND
)
593 cst
[opnr
] = data
[1] & 0x7f;
595 else if ((looking_for
& SIZE
) == L_32
)
599 cst
[opnr
] = ((data
[i
] << 24)
600 | (data
[i
+ 1] << 16)
606 else if ((looking_for
& SIZE
) == L_24
)
611 (data
[i
] << 16) | (data
[i
+ 1] << 8) | (data
[i
+ 2]);
614 else if (looking_for
& IGNORE
)
618 else if (looking_for
& DISPREG
)
620 dispregno
[opnr
] = thisnib
& 7;
622 else if ((looking_for
& MODE
) == KBIT
)
639 else if ((looking_for
& SIZE
) == L_8
)
642 cst
[opnr
] = data
[len
/ 2];
644 else if ((looking_for
& SIZE
) == L_3
||
645 (looking_for
& SIZE
) == L_3NZ
)
647 cst
[opnr
] = thisnib
& 0x7;
648 if (cst
[opnr
] == 0 && (looking_for
& SIZE
) == L_3NZ
)
651 else if ((looking_for
& SIZE
) == L_2
)
654 cst
[opnr
] = thisnib
& 0x3;
656 else if ((looking_for
& MODE
) == MACREG
)
658 cst
[opnr
] = (thisnib
== 3);
660 else if (looking_for
== (op_type
) E
)
664 for (i
= 0; i
< qi
->length
; i
++)
665 outfn (stream
, "%02x ", data
[i
]);
670 outfn (stream
, "%s\t", q
->name
);
672 /* Gross. Disgusting. */
673 if (strcmp (q
->name
, "ldm.l") == 0)
677 count
= (data
[1] / 16) & 0x3;
680 outfn (stream
, "@sp+,er%d-er%d", high
- count
, high
);
684 if (strcmp (q
->name
, "stm.l") == 0)
688 count
= (data
[1] / 16) & 0x3;
691 outfn (stream
, "er%d-er%d,@-sp", low
, low
+ count
);
694 if (strcmp (q
->name
, "rte/l") == 0
695 || strcmp (q
->name
, "rts/l") == 0)
698 outfn (stream
, "er%d", regno
[1]);
701 outfn (stream
, "er%d-er%d", regno
[1] - regno
[0],
706 if (strncmp (q
->name
, "mova", 4) == 0)
708 op_type
*args
= q
->args
.nib
;
710 if (args
[1] == (op_type
) E
)
713 print_one_arg (info
, addr
, args
[0], cst
[0],
714 cstlen
[0], dispregno
[0], regno
[0],
715 pregnames
, qi
->length
);
716 outfn (stream
, ",er%d", dispregno
[0]);
720 outfn (stream
, "@(0x%x:%d,", cst
[0], cstlen
[0]);
721 print_one_arg (info
, addr
, args
[1], cst
[1],
722 cstlen
[1], dispregno
[1], regno
[1],
723 pregnames
, qi
->length
);
724 outfn (stream
, ".%c),",
725 (args
[0] & MODE
) == INDEXB
? 'b' : 'w');
726 print_one_arg (info
, addr
, args
[2], cst
[2],
727 cstlen
[2], dispregno
[2], regno
[2],
728 pregnames
, qi
->length
);
732 /* Fill in the args. */
734 op_type
*args
= q
->args
.nib
;
739 nargs
< 3 && args
[nargs
] != (op_type
) E
;
747 print_one_arg (info
, addr
, x
,
748 cst
[nargs
], cstlen
[nargs
],
749 dispregno
[nargs
], regno
[nargs
],
750 pregnames
, qi
->length
);
759 /* xgettext:c-format */
760 outfn (stream
, _("Don't understand 0x%x \n"), looking_for
);
771 /* Fell off the end. */
772 outfn (stream
, "%02x %02x .word\tH'%x,H'%x",
779 print_insn_h8300 (addr
, info
)
781 disassemble_info
*info
;
783 return bfd_h8_disassemble (addr
, info
, 0);
787 print_insn_h8300h (addr
, info
)
789 disassemble_info
*info
;
791 return bfd_h8_disassemble (addr
, info
, 1);
795 print_insn_h8300s (addr
, info
)
797 disassemble_info
*info
;
799 return bfd_h8_disassemble (addr
, info
, 2);