2003-06-03 Michael Snyder <msnyder@redhat.com>

and Bernd Schmidt   <bernds@redhat.com>
	and Alexandre Oliva <aoliva@redhat.com>
	* disassemble.c (disassembler): Add support for h8300sx.
	* h8300-dis.c: Ditto.
This commit is contained in:
Michael Snyder 2003-06-03 21:32:52 +00:00
parent 7ee7b84dfa
commit 20dc5b5ae3
2 changed files with 541 additions and 193 deletions

View file

@ -1,3 +1,9 @@
2003-06-03 Michael Snyder <msnyder@redhat.com>
and Bernd Schmidt <bernds@redhat.com>
and Alexandre Oliva <aoliva@redhat.com>
* disassemble.c (disassembler): Add support for h8300sx.
* h8300-dis.c: Ditto.
2003-06-03 Nick Clifton <nickc@redhat.com> 2003-06-03 Nick Clifton <nickc@redhat.com>
* frv-desc.c: Regenerate. * frv-desc.c: Regenerate.

View file

@ -1,5 +1,5 @@
/* Disassemble h8300 instructions. /* Disassemble h8300 instructions.
Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002 Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003
Free Software Foundation, Inc. Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@ -34,11 +34,39 @@ struct h8_instruction
struct h8_instruction *h8_instructions; struct h8_instruction *h8_instructions;
static void bfd_h8_disassemble_init PARAMS ((void)); static void bfd_h8_disassemble_init PARAMS ((void));
static unsigned int bfd_h8_disassemble static void print_one_arg PARAMS ((disassemble_info *, bfd_vma, op_type,
PARAMS ((bfd_vma, disassemble_info *, int)); int, int, int, int, const char **, int));
static unsigned int bfd_h8_disassemble PARAMS ((bfd_vma,
disassemble_info *,
int));
static void extract_immediate PARAMS ((FILE *,
op_type, int,
unsigned char *,
int *, int *,
const struct h8_opcode *));
static void print_colon_thingie PARAMS ((op_type *));
static void
print_colon_thingie (op_type *nib)
{
switch (*nib & SIZE) {
case L_2: fprintf (stdout, "2"); break;
case L_3:
case L_3NZ: fprintf (stdout, "3"); break;
case L_4: fprintf (stdout, "4"); break;
case L_5: fprintf (stdout, "5"); break;
case L_8: fprintf (stdout, "8"); break;
case L_16:
case L_16U: fprintf (stdout, "16"); break;
case L_24: fprintf (stdout, "24"); break;
case L_32: fprintf (stdout, "32"); break;
}
}
/* Run through the opcodes and sort them into order to make them easy /* Run through the opcodes and sort them into order to make them easy
to disassemble. */ to disassemble. */
static void static void
bfd_h8_disassemble_init () bfd_h8_disassemble_init ()
{ {
@ -69,11 +97,14 @@ bfd_h8_disassemble_init ()
/* Just make sure there are an even number of nibbles in it, and /* Just make sure there are an even number of nibbles in it, and
that the count is the same as the length. */ that the count is the same as the length. */
for (i = 0; p->data.nib[i] != E; i++) for (i = 0; p->data.nib[i] != (op_type) E; i++)
; ;
if (i & 1) if (i & 1)
{
fprintf (stderr, "Internal error, h8_disassemble_init.\n");
abort (); abort ();
}
pi->length = i / 2; pi->length = i / 2;
pi->opcode = p; pi->opcode = p;
@ -84,42 +115,287 @@ bfd_h8_disassemble_init ()
pi->opcode = p; pi->opcode = p;
} }
static unsigned int static void
bfd_h8_disassemble (addr, info, mode) extract_immediate (stream, looking_for, thisnib, data, cst, len, q)
bfd_vma addr; FILE *stream;
disassemble_info *info; op_type looking_for;
int mode; int thisnib;
unsigned char *data;
int *cst, *len;
const struct h8_opcode *q;
{ {
/* Find the first entry in the table for this opcode. */ switch (looking_for & SIZE)
static const char *regnames[] =
{ {
case L_2:
*len = 2;
*cst = thisnib & 3;
/* DISP2 special treatment. */
if ((looking_for & MODE) == DISP)
{
if (OP_KIND (q->how) == O_MOVAB ||
OP_KIND (q->how) == O_MOVAW ||
OP_KIND (q->how) == O_MOVAL)
{
/* Handling for mova insn. */
switch (q->args.nib[0] & MODE) {
case INDEXB:
default:
break;
case INDEXW:
*cst *= 2;
break;
case INDEXL:
*cst *= 4;
break;
}
}
else
{
/* Handling for non-mova insn. */
switch (OP_SIZE (q->how)) {
default: break;
case SW:
*cst *= 2;
break;
case SL:
*cst *= 4;
break;
}
}
}
break;
case L_8:
*len = 8;
*cst = data[0];
break;
case L_16:
case L_16U:
*len = 16;
*cst = (data[0] << 8) + data [1];
#if 0
if ((looking_for & SIZE) == L_16)
*cst = (short) *cst; /* sign extend */
#endif
break;
case L_32:
*len = 32;
*cst = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
break;
default:
*len = 0;
*cst = 0;
fprintf (stream, "DISP bad size\n");
break;
}
}
static const char *regnames[] =
{
"r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h", "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
"r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l" "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"
}; };
static const char *wregnames[] = static const char *wregnames[] =
{ {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
}; };
static const char *lregnames[] = static const char *lregnames[] =
{ {
"er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7", "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
"er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
}; };
int rs = 0; static const char *cregnames[] =
int rd = 0; {
int rdisp = 0; "ccr", "exr", "mach", "macl", "", "", "vbr", "sbr"
int abs = 0; };
int bit = 0;
int plen = 0; static void
print_one_arg (info, addr, x, cst, cstlen, rdisp_n, rn, pregnames, len)
disassemble_info *info;
bfd_vma addr;
op_type x;
int cst, cstlen, rdisp_n, rn;
const char **pregnames;
int len;
{
void *stream = info->stream;
fprintf_ftype outfn = info->fprintf_func;
if ((x & SIZE) == L_3 ||
(x & SIZE) == L_3NZ)
{
outfn (stream, "#0x%x", (unsigned) cst);
}
else if ((x & MODE) == IMM)
{
outfn (stream, "#0x%x", (unsigned) cst);
}
else if ((x & MODE) == DBIT ||
(x & MODE) == KBIT)
{
outfn (stream, "#%d", (unsigned) cst);
}
else if ((x & MODE) == CONST_2)
outfn (stream, "#2");
else if ((x & MODE) == CONST_4)
outfn (stream, "#4");
else if ((x & MODE) == CONST_8)
outfn (stream, "#8");
else if ((x & MODE) == CONST_16)
outfn (stream, "#16");
else if ((x & MODE) == REG)
{
switch (x & SIZE)
{
case L_8:
outfn (stream, "%s", regnames[rn]);
break;
case L_16:
case L_16U:
outfn (stream, "%s", wregnames[rn]);
break;
case L_P:
case L_32:
outfn (stream, "%s", lregnames[rn]);
break;
}
}
else if ((x & MODE) == LOWREG)
{
switch (x & SIZE)
{
case L_8:
/* Always take low half of reg. */
outfn (stream, "%s.b", regnames[rn < 8 ? rn + 8 : rn]);
break;
case L_16:
case L_16U:
/* Always take low half of reg. */
outfn (stream, "%s.w", wregnames[rn < 8 ? rn : rn - 8]);
break;
case L_P:
case L_32:
outfn (stream, "%s.l", lregnames[rn]);
break;
}
}
else if ((x & MODE) == POSTINC)
{
outfn (stream, "@%s+", pregnames[rn]);
}
else if ((x & MODE) == POSTDEC)
{
outfn (stream, "@%s-", pregnames[rn]);
}
else if ((x & MODE) == PREINC)
{
outfn (stream, "@+%s", pregnames[rn]);
}
else if ((x & MODE) == PREDEC)
{
outfn (stream, "@-%s", pregnames[rn]);
}
else if ((x & MODE) == IND)
{
outfn (stream, "@%s", pregnames[rn]);
}
else if ((x & MODE) == ABS || (x & ABSJMP))
{
outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen);
}
else if ((x & MODE) == MEMIND)
{
outfn (stream, "@@%d (0x%x)", cst, cst);
}
else if ((x & MODE) == VECIND)
{
/* FIXME Multiplier should be 2 or 4, depending on processor mode,
by which is meant "normal" vs. "middle", "advanced", "maximum". */
int offset = (cst + 0x80) * 4;
outfn (stream, "@@%d (0x%x)", offset, offset);
}
else if ((x & MODE) == PCREL)
{
if ((x & SIZE) == L_16 ||
(x & SIZE) == L_16U)
{
outfn (stream, ".%s%d (0x%x)",
(short) cst > 0 ? "+" : "",
(short) cst,
addr + (short) cst + len);
}
else
{
outfn (stream, ".%s%d (0x%x)",
(char) cst > 0 ? "+" : "",
(char) cst,
addr + (char) cst + len);
}
}
else if ((x & MODE) == DISP)
{
outfn (stream, "@(0x%x:%d,%s)", cst, cstlen,
pregnames[rdisp_n]);
}
else if ((x & MODE) == INDEXB)
{
/* Always take low half of reg. */
outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen,
regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]);
}
else if ((x & MODE) == INDEXW)
{
/* Always take low half of reg. */
outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen,
wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]);
}
else if ((x & MODE) == INDEXL)
{
outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen,
lregnames[rdisp_n]);
}
else if (x & CTRL)
{
outfn (stream, cregnames[rn]);
}
else if ((x & MODE) == CCR)
{
outfn (stream, "ccr");
}
else if ((x & MODE) == EXR)
{
outfn (stream, "exr");
}
else if ((x & MODE) == MACREG)
{
outfn (stream, "mac%c", cst ? 'l' : 'h');
}
else
/* xgettext:c-format */
outfn (stream, _("Hmmmm 0x%x"), x);
}
static unsigned int
bfd_h8_disassemble (addr, info, mach)
bfd_vma addr;
disassemble_info *info;
int mach;
{
/* Find the first entry in the table for this opcode. */
int regno[3] = { 0, 0, 0 };
int dispregno[3] = { 0, 0, 0 };
int cst[3] = { 0, 0, 0 };
int cstlen[3] = { 0, 0, 0 };
static bfd_boolean init = 0; static bfd_boolean init = 0;
const struct h8_instruction *qi; const struct h8_instruction *qi;
char const **pregnames = mode != 0 ? lregnames : wregnames; char const **pregnames = mach != 0 ? lregnames : wregnames;
int status; int status;
int l; unsigned int l;
unsigned char data[20]; unsigned char data[MAX_CODE_NIBBLES];
void *stream = info->stream; void *stream = info->stream;
fprintf_ftype fprintf = info->fprintf_func; fprintf_ftype outfn = info->fprintf_func;
if (!init) if (!init)
{ {
@ -134,7 +410,7 @@ bfd_h8_disassemble (addr, info, mode)
return -1; return -1;
} }
for (l = 2; status == 0 && l < 10; l += 2) for (l = 2; status == 0 && l < sizeof (data) / 2; l += 2)
status = info->read_memory_func (addr + l, data + l, 2, info); status = info->read_memory_func (addr + l, data + l, 2, info);
/* Find the exact opcode/arg combo. */ /* Find the exact opcode/arg combo. */
@ -147,9 +423,12 @@ bfd_h8_disassemble (addr, info, mode)
while (1) while (1)
{ {
op_type looking_for = *nib; op_type looking_for = *nib;
int thisnib = data[len >> 1]; int thisnib = data[len / 2];
int opnr;
thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf); thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf);
opnr = ((looking_for & OP3) == OP3 ? 2
: (looking_for & DST) == DST ? 1 : 0);
if (looking_for < 16 && looking_for >= 0) if (looking_for < 16 && looking_for >= 0)
{ {
@ -160,21 +439,78 @@ bfd_h8_disassemble (addr, info, mode)
{ {
if ((int) looking_for & (int) B31) if ((int) looking_for & (int) B31)
{ {
if (!(((int) thisnib & 0x8) != 0)) if (!((thisnib & 0x8) != 0))
goto fail; goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B31); looking_for = (op_type) ((int) looking_for & ~(int) B31);
thisnib &= 0x7;
} }
else if ((int) looking_for & (int) B30)
if ((int) looking_for & (int) B30)
{ {
if (!(((int) thisnib & 0x8) == 0)) if (!((thisnib & 0x8) == 0))
goto fail; goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B30); looking_for = (op_type) ((int) looking_for & ~(int) B30);
} }
if (looking_for & DBIT) if ((int) looking_for & (int) B21)
{
if (!((thisnib & 0x4) != 0))
goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B21);
thisnib &= 0xb;
}
else if ((int) looking_for & (int) B20)
{
if (!((thisnib & 0x4) == 0))
goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B20);
}
if ((int) looking_for & (int) B11)
{
if (!((thisnib & 0x2) != 0))
goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B11);
thisnib &= 0xd;
}
else if ((int) looking_for & (int) B10)
{
if (!((thisnib & 0x2) == 0))
goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B10);
}
if ((int) looking_for & (int) B01)
{
if (!((thisnib & 0x1) != 0))
goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B01);
thisnib &= 0xe;
}
else if ((int) looking_for & (int) B00)
{
if (!((thisnib & 0x1) == 0))
goto fail;
looking_for = (op_type) ((int) looking_for & ~(int) B00);
}
if (looking_for & IGNORE)
{
/* Hitachi has declared that IGNORE must be zero. */
if (thisnib != 0)
goto fail;
}
else if ((looking_for & MODE) == DATA)
{
; /* Skip embedded data. */
}
else if ((looking_for & MODE) == DBIT)
{ {
/* Exclude adds/subs by looking at bit 0 and 2, and /* Exclude adds/subs by looking at bit 0 and 2, and
make sure the operand size, either w or l, make sure the operand size, either w or l,
@ -182,45 +518,98 @@ bfd_h8_disassemble (addr, info, mode)
if ((looking_for & 7) != (thisnib & 7)) if ((looking_for & 7) != (thisnib & 7))
goto fail; goto fail;
abs = (thisnib & 0x8) ? 2 : 1; cst[opnr] = (thisnib & 0x8) ? 2 : 1;
} }
else if (looking_for & (REG | IND | INC | DEC)) else if ((looking_for & MODE) == DISP ||
(looking_for & MODE) == ABS ||
(looking_for & MODE) == PCREL ||
(looking_for & MODE) == INDEXB ||
(looking_for & MODE) == INDEXW ||
(looking_for & MODE) == INDEXL)
{ {
if (looking_for & SRC) extract_immediate (stream, looking_for, thisnib,
rs = thisnib; data + len / 2, cst + opnr,
else cstlen + opnr, q);
rd = thisnib; /* Even address == bra, odd == bra/s. */
if (q->how == O (O_BRAS, SB))
cst[opnr] -= 1;
} }
else if (looking_for & L_16) else if ((looking_for & MODE) == REG ||
(looking_for & MODE) == LOWREG ||
(looking_for & MODE) == IND ||
(looking_for & MODE) == PREINC ||
(looking_for & MODE) == POSTINC ||
(looking_for & MODE) == PREDEC ||
(looking_for & MODE) == POSTDEC)
{ {
abs = (data[len >> 1]) * 256 + data[(len + 2) >> 1]; regno[opnr] = thisnib;
plen = 16;
} }
else if (looking_for & ABSJMP) else if (looking_for & CTRL) /* Control Register */
{ {
abs = (data[1] << 16) | (data[2] << 8) | (data[3]); thisnib &= 7;
} if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) ||
else if (looking_for & MEMIND) ((looking_for & MODE) == EXR && (thisnib != C_EXR)) ||
{ ((looking_for & MODE) == MACH && (thisnib != C_MACH)) ||
abs = data[1]; ((looking_for & MODE) == MACL && (thisnib != C_MACL)) ||
} ((looking_for & MODE) == VBR && (thisnib != C_VBR)) ||
else if (looking_for & L_32) ((looking_for & MODE) == SBR && (thisnib != C_SBR)))
{ goto fail;
int i = len >> 1; if (((looking_for & MODE) == CCR_EXR &&
(thisnib != C_CCR && thisnib != C_EXR)) ||
((looking_for & MODE) == VBR_SBR &&
(thisnib != C_VBR && thisnib != C_SBR)) ||
((looking_for & MODE) == MACREG &&
(thisnib != C_MACH && thisnib != C_MACL)))
goto fail;
if (((looking_for & MODE) == CC_EX_VB_SB &&
(thisnib != C_CCR && thisnib != C_EXR &&
thisnib != C_VBR && thisnib != C_SBR)))
goto fail;
abs = (data[i] << 24) regno[opnr] = thisnib;
}
else if ((looking_for & SIZE) == L_5)
{
cst[opnr] = data[len / 2] & 31;
cstlen[opnr] = 5;
}
else if ((looking_for & SIZE) == L_4)
{
cst[opnr] = thisnib;
cstlen[opnr] = 4;
}
else if ((looking_for & SIZE) == L_16 ||
(looking_for & SIZE) == L_16U)
{
cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2];
cstlen[opnr] = 16;
}
else if ((looking_for & MODE) == MEMIND)
{
cst[opnr] = data[1];
}
else if ((looking_for & MODE) == VECIND)
{
cst[opnr] = data[1] & 0x7f;
}
else if ((looking_for & SIZE) == L_32)
{
int i = len / 2;
cst[opnr] = ((data[i] << 24)
| (data[i + 1] << 16) | (data[i + 1] << 16)
| (data[i + 2] << 8) | (data[i + 2] << 8)
| (data[i + 3]); | (data[i + 3]));
plen = 32; cstlen[opnr] = 32;
} }
else if (looking_for & L_24) else if ((looking_for & SIZE) == L_24)
{ {
int i = len >> 1; int i = len / 2;
abs = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]); cst[opnr] =
plen = 24; (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
cstlen[opnr] = 24;
} }
else if (looking_for & IGNORE) else if (looking_for & IGNORE)
{ {
@ -228,64 +617,67 @@ bfd_h8_disassemble (addr, info, mode)
} }
else if (looking_for & DISPREG) else if (looking_for & DISPREG)
{ {
rdisp = thisnib; dispregno[opnr] = thisnib & 7;
} }
else if (looking_for & KBIT) else if ((looking_for & MODE) == KBIT)
{ {
switch (thisnib) switch (thisnib)
{ {
case 9: case 9:
abs = 4; cst[opnr] = 4;
break; break;
case 8: case 8:
abs = 2; cst[opnr] = 2;
break; break;
case 0: case 0:
abs = 1; cst[opnr] = 1;
break; break;
default: default:
goto fail; goto fail;
} }
} }
else if (looking_for & L_8) else if ((looking_for & SIZE) == L_8)
{ {
plen = 8; cstlen[opnr] = 8;
abs = data[len >> 1]; cst[opnr] = data[len / 2];
} }
else if (looking_for & L_3) else if ((looking_for & SIZE) == L_3 ||
(looking_for & SIZE) == L_3NZ)
{ {
bit = thisnib & 0x7; cst[opnr] = thisnib & 0x7;
if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ)
goto fail;
} }
else if (looking_for & L_2) else if ((looking_for & SIZE) == L_2)
{ {
plen = 2; cstlen[opnr] = 2;
abs = thisnib & 0x3; cst[opnr] = thisnib & 0x3;
} }
else if (looking_for & MACREG) else if ((looking_for & MODE) == MACREG)
{ {
abs = (thisnib == 3); cst[opnr] = (thisnib == 3);
} }
else if (looking_for == E) else if (looking_for == (op_type) E)
{ {
int i; int i;
for (i = 0; i < qi->length; i++) for (i = 0; i < qi->length; i++)
fprintf (stream, "%02x ", data[i]); outfn (stream, "%02x ", data[i]);
for (; i < 6; i++) for (; i < 6; i++)
fprintf (stream, " "); outfn (stream, " ");
fprintf (stream, "%s\t", q->name); outfn (stream, "%s\t", q->name);
/* Gross. Disgusting. */ /* Gross. Disgusting. */
if (strcmp (q->name, "ldm.l") == 0) if (strcmp (q->name, "ldm.l") == 0)
{ {
int count, high; int count, high;
count = (data[1] >> 4) & 0x3; count = (data[1] / 16) & 0x3;
high = data[3] & 0x7; high = regno[1];
fprintf (stream, "@sp+,er%d-er%d", high - count, high); outfn (stream, "@sp+,er%d-er%d", high - count, high);
return qi->length; return qi->length;
} }
@ -293,121 +685,71 @@ bfd_h8_disassemble (addr, info, mode)
{ {
int count, low; int count, low;
count = (data[1] >> 4) & 0x3; count = (data[1] / 16) & 0x3;
low = data[3] & 0x7; low = regno[0];
fprintf (stream, "er%d-er%d,@-sp", low, low + count); outfn (stream, "er%d-er%d,@-sp", low, low + count);
return qi->length; return qi->length;
} }
if (strcmp (q->name, "rte/l") == 0
|| strcmp (q->name, "rts/l") == 0)
{
if (regno[0] == 0)
outfn (stream, "er%d", regno[1]);
else
{
outfn (stream, "(er%d-er%d)", regno[1] - regno[0],
regno[1]);
}
return qi->length;
}
if (strncmp (q->name, "mova", 4) == 0)
{
op_type *args = q->args.nib;
if (args[1] == (op_type) E)
{
/* Short form. */
print_one_arg (info, addr, args[0], cst[0],
cstlen[0], dispregno[0], regno[0],
pregnames, qi->length);
outfn (stream, ",er%d", dispregno[0]);
}
else
{
outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]);
print_one_arg (info, addr, args[1], cst[1],
cstlen[1], dispregno[1], regno[1],
pregnames, qi->length);
outfn (stream, ".%c),",
(args[0] & MODE) == INDEXB ? 'b' : 'w');
print_one_arg (info, addr, args[2], cst[2],
cstlen[2], dispregno[2], regno[2],
pregnames, qi->length);
}
return qi->length;
}
/* Fill in the args. */ /* Fill in the args. */
{ {
op_type *args = q->args.nib; op_type *args = q->args.nib;
int hadone = 0; int hadone = 0;
int nargs;
while (*args != E) for (nargs = 0;
nargs < 3 && args[nargs] != (op_type) E;
nargs++)
{ {
int x = *args; int x = args[nargs];
if (hadone) if (hadone)
fprintf (stream, ","); outfn (stream, ",");
if (x & L_3) print_one_arg (info, addr, x,
{ cst[nargs], cstlen[nargs],
fprintf (stream, "#0x%x", (unsigned) bit); dispregno[nargs], regno[nargs],
} pregnames, qi->length);
else if (x & (IMM | KBIT | DBIT))
{
/* Bletch. For shal #2,er0 and friends. */
if (*(args + 1) & SRC_IN_DST)
abs = 2;
fprintf (stream, "#0x%x", (unsigned) abs);
}
else if (x & REG)
{
int rn = (x & DST) ? rd : rs;
switch (x & SIZE)
{
case L_8:
fprintf (stream, "%s", regnames[rn]);
break;
case L_16:
fprintf (stream, "%s", wregnames[rn]);
break;
case L_P:
case L_32:
fprintf (stream, "%s", lregnames[rn]);
break;
}
}
else if (x & MACREG)
{
fprintf (stream, "mac%c", abs ? 'l' : 'h');
}
else if (x & INC)
{
fprintf (stream, "@%s+", pregnames[rs]);
}
else if (x & DEC)
{
fprintf (stream, "@-%s", pregnames[rd]);
}
else if (x & IND)
{
int rn = (x & DST) ? rd : rs;
fprintf (stream, "@%s", pregnames[rn]);
}
else if (x & ABS8MEM)
{
fprintf (stream, "@0x%x:8", (unsigned) abs);
}
else if (x & (ABS | ABSJMP))
{
fprintf (stream, "@0x%x:%d", (unsigned) abs, plen);
}
else if (x & MEMIND)
{
fprintf (stream, "@@%d (%x)", abs, abs);
}
else if (x & PCREL)
{
if (x & L_16)
{
abs += 2;
fprintf (stream,
".%s%d (%x)",
(short) abs > 0 ? "+" : "",
(short) abs, addr + (short) abs + 2);
}
else
{
fprintf (stream,
".%s%d (%x)",
(char) abs > 0 ? "+" : "",
(char) abs, addr + (char) abs + 2);
}
}
else if (x & DISP)
{
fprintf (stream, "@(0x%x:%d,%s)",
abs, plen, pregnames[rdisp]);
}
else if (x & CCR)
{
fprintf (stream, "ccr");
}
else if (x & EXR)
{
fprintf (stream, "exr");
}
else
/* xgettext:c-format */
fprintf (stream, _("Hmmmm %x"), x);
hadone = 1; hadone = 1;
args++;
} }
} }
@ -415,7 +757,7 @@ bfd_h8_disassemble (addr, info, mode)
} }
else else
/* xgettext:c-format */ /* xgettext:c-format */
fprintf (stream, _("Don't understand %x \n"), looking_for); outfn (stream, _("Don't understand 0x%x \n"), looking_for);
} }
len++; len++;
@ -427,7 +769,7 @@ bfd_h8_disassemble (addr, info, mode)
} }
/* Fell off the end. */ /* Fell off the end. */
fprintf (stream, "%02x %02x .word\tH'%x,H'%x", outfn (stream, "%02x %02x .word\tH'%x,H'%x",
data[0], data[1], data[0], data[1],
data[0], data[1]); data[0], data[1]);
return 2; return 2;