forked from Imagelibrary/binutils-gdb
* avr-dis.c (avr_operand): Use PARAMS macro in declaration.
Change return type from void to int. Check the combination of operands, return 1 if valid. Fix to avoid BUF overflow. Report undefined combinations of operands in COMMENT. Report internal errors to stderr. Output the adiw/sbiw constant operand in both decimal and hex. (print_insn_avr): Disassemble ldd/std with displacement of 0 as ld/st. Check avr_operand () return value, handle invalid combinations of operands like unknown opcodes.
This commit is contained in:
@@ -1,3 +1,15 @@
|
|||||||
|
2000-07-29 Marek Michalkiewicz <marekm@linux.org.pl>
|
||||||
|
|
||||||
|
* avr-dis.c (avr_operand): Use PARAMS macro in declaration.
|
||||||
|
Change return type from void to int. Check the combination
|
||||||
|
of operands, return 1 if valid. Fix to avoid BUF overflow.
|
||||||
|
Report undefined combinations of operands in COMMENT.
|
||||||
|
Report internal errors to stderr. Output the adiw/sbiw
|
||||||
|
constant operand in both decimal and hex.
|
||||||
|
(print_insn_avr): Disassemble ldd/std with displacement of 0
|
||||||
|
as ld/st. Check avr_operand () return value, handle invalid
|
||||||
|
combinations of operands like unknown opcodes.
|
||||||
|
|
||||||
2000-08-04 Ben Elliston <bje@redhat.com>
|
2000-08-04 Ben Elliston <bje@redhat.com>
|
||||||
|
|
||||||
* cgen-dis.in, cgen-asm.in, cgen-ibld.in: New files.
|
* cgen-dis.in, cgen-asm.in, cgen-ibld.in: New files.
|
||||||
|
|||||||
@@ -43,12 +43,10 @@ struct avr_opcodes_s avr_opcodes[] =
|
|||||||
{NULL, NULL, NULL, 0, 0, 0, 0}
|
{NULL, NULL, NULL, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int avr_operand PARAMS ((unsigned int, unsigned int,
|
||||||
|
unsigned int, int, char *, char *, int));
|
||||||
|
|
||||||
static void avr_operand (unsigned int insn, unsigned int insn2,
|
static int
|
||||||
unsigned int pc, int constraint, char *buf,
|
|
||||||
char *comment, int regs);
|
|
||||||
|
|
||||||
static void
|
|
||||||
avr_operand (insn, insn2, pc, constraint, buf, comment, regs)
|
avr_operand (insn, insn2, pc, constraint, buf, comment, regs)
|
||||||
unsigned int insn;
|
unsigned int insn;
|
||||||
unsigned int insn2;
|
unsigned int insn2;
|
||||||
@@ -58,6 +56,8 @@ avr_operand (insn, insn2, pc, constraint, buf, comment, regs)
|
|||||||
char *comment;
|
char *comment;
|
||||||
int regs;
|
int regs;
|
||||||
{
|
{
|
||||||
|
int ok = 1;
|
||||||
|
|
||||||
switch (constraint)
|
switch (constraint)
|
||||||
{
|
{
|
||||||
/* Any register operand. */
|
/* Any register operand. */
|
||||||
@@ -96,18 +96,27 @@ avr_operand (insn, insn2, pc, constraint, buf, comment, regs)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
if (insn & 0x2)
|
|
||||||
*buf++ = '-';
|
|
||||||
switch ((insn >> 2) & 0x3)
|
|
||||||
{
|
{
|
||||||
case 0: *buf++ = 'Z'; break;
|
char *xyz;
|
||||||
case 2: *buf++ = 'Y'; break;
|
|
||||||
case 3: *buf++ = 'X'; break;
|
switch (insn & 0x100f)
|
||||||
default: buf += sprintf (buf, _(" unknown register ")); break;
|
{
|
||||||
|
case 0x0000: xyz = "Z"; break;
|
||||||
|
case 0x1001: xyz = "Z+"; break;
|
||||||
|
case 0x1002: xyz = "-Z"; break;
|
||||||
|
case 0x0008: xyz = "Y"; break;
|
||||||
|
case 0x1009: xyz = "Y+"; break;
|
||||||
|
case 0x100a: xyz = "-Y"; break;
|
||||||
|
case 0x100c: xyz = "X"; break;
|
||||||
|
case 0x100d: xyz = "X+"; break;
|
||||||
|
case 0x100e: xyz = "-X"; break;
|
||||||
|
default: xyz = "??"; ok = 0;
|
||||||
|
}
|
||||||
|
sprintf (buf, xyz);
|
||||||
|
|
||||||
|
if (AVR_UNDEF_P (insn))
|
||||||
|
sprintf (comment, _("undefined"));
|
||||||
}
|
}
|
||||||
if (insn & 0x1)
|
|
||||||
*buf++ = '+';
|
|
||||||
*buf = '\0';
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'z':
|
case 'z':
|
||||||
@@ -115,11 +124,13 @@ avr_operand (insn, insn2, pc, constraint, buf, comment, regs)
|
|||||||
if (insn & 0x1)
|
if (insn & 0x1)
|
||||||
*buf++ = '+';
|
*buf++ = '+';
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
|
if (AVR_UNDEF_P (insn))
|
||||||
|
sprintf (comment, _("undefined"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
{
|
{
|
||||||
unsigned int x = insn;
|
unsigned int x;
|
||||||
|
|
||||||
x = (insn & 7);
|
x = (insn & 7);
|
||||||
x |= (insn >> 7) & (3 << 3);
|
x |= (insn >> 7) & (3 << 3);
|
||||||
@@ -165,11 +176,19 @@ avr_operand (insn, insn2, pc, constraint, buf, comment, regs)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
sprintf (buf, _("Internal disassembler error"));
|
sprintf (buf, "??");
|
||||||
|
fprintf (stderr, _("Internal disassembler error"));
|
||||||
|
ok = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'K':
|
case 'K':
|
||||||
sprintf (buf, "%d", (insn & 0xf) | ((insn >> 2) & 0x30));
|
{
|
||||||
|
unsigned int x;
|
||||||
|
|
||||||
|
x = (insn & 0xf) | ((insn >> 2) & 0x30);
|
||||||
|
sprintf (buf, "0x%02x", x);
|
||||||
|
sprintf (comment, "%d", x);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
@@ -205,8 +224,12 @@ avr_operand (insn, insn2, pc, constraint, buf, comment, regs)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sprintf (buf, _("unknown constraint `%c'"), constraint);
|
sprintf (buf, "??");
|
||||||
|
fprintf (stderr, _("unknown constraint `%c'"), constraint);
|
||||||
|
ok = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short avrdis_opcode PARAMS ((bfd_vma, disassemble_info *));
|
static unsigned short avrdis_opcode PARAMS ((bfd_vma, disassemble_info *));
|
||||||
@@ -239,6 +262,8 @@ print_insn_avr(addr, info)
|
|||||||
fprintf_ftype prin = info->fprintf_func;
|
fprintf_ftype prin = info->fprintf_func;
|
||||||
static int initialized;
|
static int initialized;
|
||||||
int cmd_len = 2;
|
int cmd_len = 2;
|
||||||
|
int ok = 0;
|
||||||
|
char op1[20], op2[20], comment1[40], comment2[40];
|
||||||
|
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
{
|
{
|
||||||
@@ -271,16 +296,23 @@ print_insn_avr(addr, info)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode->name)
|
/* Special case: disassemble `ldd r,b+0' as `ld r,b', and
|
||||||
{
|
`std b+0,r' as `st b,r' (next entry in the table). */
|
||||||
char op1[20], op2[20], comment1[40], comment2[40];
|
|
||||||
char *op = opcode->constraints;
|
if (AVR_DISP0_P (insn))
|
||||||
|
opcode++;
|
||||||
|
|
||||||
op1[0] = 0;
|
op1[0] = 0;
|
||||||
op2[0] = 0;
|
op2[0] = 0;
|
||||||
comment1[0] = 0;
|
comment1[0] = 0;
|
||||||
comment2[0] = 0;
|
comment2[0] = 0;
|
||||||
|
|
||||||
|
if (opcode->name)
|
||||||
|
{
|
||||||
|
char *op = opcode->constraints;
|
||||||
|
|
||||||
insn2 = 0;
|
insn2 = 0;
|
||||||
|
ok = 1;
|
||||||
|
|
||||||
if (opcode->insn_size > 1)
|
if (opcode->insn_size > 1)
|
||||||
{
|
{
|
||||||
@@ -292,17 +324,27 @@ print_insn_avr(addr, info)
|
|||||||
{
|
{
|
||||||
int regs = REGISTER_P (*op);
|
int regs = REGISTER_P (*op);
|
||||||
|
|
||||||
avr_operand (insn, insn2, addr, *op, op1, comment1, 0);
|
ok = avr_operand (insn, insn2, addr, *op, op1, comment1, 0);
|
||||||
|
|
||||||
if (*(++op) == ',')
|
if (ok && *(++op) == ',')
|
||||||
avr_operand (insn, insn2, addr, *(++op), op2,
|
ok = avr_operand (insn, insn2, addr, *(++op), op2,
|
||||||
*comment1 ? comment2 : comment1, regs);
|
*comment1 ? comment2 : comment1, regs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(*prin) (stream, " %-8s", opcode->name);
|
if (!ok)
|
||||||
|
{
|
||||||
|
/* Unknown opcode, or invalid combination of operands. */
|
||||||
|
sprintf (op1, "0x%04x", insn);
|
||||||
|
op2[0] = 0;
|
||||||
|
sprintf (comment1, "????");
|
||||||
|
comment2[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*prin) (stream, "%s", ok ? opcode->name : ".word");
|
||||||
|
|
||||||
if (*op1)
|
if (*op1)
|
||||||
(*prin) (stream, "%s", op1);
|
(*prin) (stream, "\t%s", op1);
|
||||||
|
|
||||||
if (*op2)
|
if (*op2)
|
||||||
(*prin) (stream, ", %s", op2);
|
(*prin) (stream, ", %s", op2);
|
||||||
@@ -312,9 +354,6 @@ print_insn_avr(addr, info)
|
|||||||
|
|
||||||
if (*comment2)
|
if (*comment2)
|
||||||
(*prin) (stream, " %s", comment2);
|
(*prin) (stream, " %s", comment2);
|
||||||
}
|
|
||||||
else
|
|
||||||
(*prin) (stream, ".word 0x%04x\t; ????", insn);
|
|
||||||
|
|
||||||
return cmd_len;
|
return cmd_len;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user