/* Disassemble AVR instructions.
- Copyright (C) 1999-2019 Free Software Foundation, Inc.
+ Copyright (C) 1999-2023 Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
#include "disassemble.h"
#include "opintl.h"
#include "libiberty.h"
-#include "bfd_stdint.h"
+#include <stdint.h>
struct avr_opcodes_s
{
static const char * comment_start = "0x";
static int
-avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constraint,
- char *opcode_str, char *buf, char *comment, int regs, int *sym, bfd_vma *sym_addr)
+avr_operand (unsigned int insn,
+ unsigned int insn2,
+ unsigned int pc,
+ int constraint,
+ char * opcode_str,
+ char * buf,
+ char * comment,
+ enum disassembler_style * style,
+ int regs,
+ int * sym,
+ bfd_vma * sym_addr,
+ disassemble_info * info)
{
int ok = 1;
*sym = 0;
insn = (insn & 0x01f0) >> 4; /* Destination register. */
sprintf (buf, "r%d", insn);
+ *style = dis_style_register;
break;
case 'd':
sprintf (buf, "r%d", 16 + (insn & 0xf));
else
sprintf (buf, "r%d", 16 + ((insn & 0xf0) >> 4));
+ *style = dis_style_register;
break;
case 'w':
sprintf (buf, "r%d", 24 + ((insn & 0x30) >> 3));
+ *style = dis_style_register;
break;
case 'a':
sprintf (buf, "r%d", 16 + (insn & 7));
else
sprintf (buf, "r%d", 16 + ((insn >> 4) & 7));
+ *style = dis_style_register;
break;
case 'v':
sprintf (buf, "r%d", (insn & 0xf) * 2);
else
sprintf (buf, "r%d", ((insn & 0xf0) >> 3));
+ *style = dis_style_register;
break;
case 'e':
if (AVR_UNDEF_P (insn))
sprintf (comment, _("undefined"));
}
+ *style = dis_style_register;
break;
case 'z':
*buf = '\0';
if (AVR_UNDEF_P (insn))
sprintf (comment, _("undefined"));
+ *style = dis_style_register;
break;
case 'b':
*buf++ = 'Z';
sprintf (buf, "+%d", x);
sprintf (comment, "0x%02x", x);
+ *style = dis_style_register;
}
break;
objdump_print_address() which would affect many targets. */
sprintf (buf, "%#lx", (unsigned long) *sym_addr);
strcpy (comment, comment_start);
+ info->insn_info_valid = 1;
+ info->insn_type = dis_jsr;
+ info->target = *sym_addr;
+ *style = dis_style_address;
break;
case 'L':
*sym = 1;
*sym_addr = pc + 2 + rel_addr;
strcpy (comment, comment_start);
+ info->insn_info_valid = 1;
+ info->insn_type = dis_branch;
+ info->target = *sym_addr;
+ *style = dis_style_address_offset;
}
break;
*sym = 1;
*sym_addr = pc + 2 + rel_addr;
strcpy (comment, comment_start);
+ info->insn_info_valid = 1;
+ info->insn_type = dis_condbranch;
+ info->target = *sym_addr;
+ *style = dis_style_address_offset;
}
break;
*sym_addr = val;
sprintf (buf, "0x%04X", insn2);
strcpy (comment, comment_start);
+ *style = dis_style_immediate;
}
break;
*sym_addr = val | 0x800000;
sprintf (buf, "0x%02x", val);
strcpy (comment, comment_start);
+ *style = dis_style_immediate;
}
break;
case 'M':
sprintf (buf, "0x%02X", ((insn & 0xf00) >> 4) | (insn & 0xf));
sprintf (comment, "%d", ((insn & 0xf00) >> 4) | (insn & 0xf));
+ *style = dis_style_immediate;
break;
case 'n':
/* xgettext:c-format */
opcodes_error_handler (_("internal disassembler error"));
ok = 0;
+ *style = dis_style_immediate;
break;
case 'K':
x = (insn & 0xf) | ((insn >> 2) & 0x30);
sprintf (buf, "0x%02x", x);
sprintf (comment, "%d", x);
+ *style = dis_style_immediate;
}
break;
case 's':
sprintf (buf, "%d", insn & 7);
+ *style = dis_style_immediate;
break;
case 'S':
sprintf (buf, "%d", (insn >> 4) & 7);
+ *style = dis_style_immediate;
break;
case 'P':
x |= (insn >> 5) & 0x30;
sprintf (buf, "0x%02x", x);
sprintf (comment, "%d", x);
+ *style = dis_style_address;
}
break;
x = (insn >> 3) & 0x1f;
sprintf (buf, "0x%02x", x);
sprintf (comment, "%d", x);
+ *style = dis_style_address;
}
break;
case 'E':
sprintf (buf, "%d", (insn >> 4) & 15);
+ *style = dis_style_immediate;
break;
case '?':
const struct avr_opcodes_s *opcode;
static unsigned int *maskptr;
void *stream = info->stream;
- fprintf_ftype prin = info->fprintf_func;
+ fprintf_styled_ftype prin = info->fprintf_styled_func;
static unsigned int *avr_bin_masks;
static int initialized;
int cmd_len = 2;
int ok = 0;
char op1[20], op2[20], comment1[40], comment2[40];
+ enum disassembler_style style_op1, style_op2;
int sym_op1 = 0, sym_op2 = 0;
bfd_vma sym_addr1, sym_addr2;
+ /* Clear instruction information field. */
+ info->insn_info_valid = 0;
+ info->branch_delay_insns = 0;
+ info->data_size = 0;
+ info->insn_type = dis_noninsn;
+ info->target = 0;
+ info->target2 = 0;
if (!initialized)
{
op2[0] = 0;
comment1[0] = 0;
comment2[0] = 0;
+ style_op1 = dis_style_text;
+ style_op2 = dis_style_text;
if (opcode->name)
{
{
int regs = REGISTER_P (*constraints);
- ok = avr_operand (insn, insn2, addr, *constraints, opcode_str, op1, comment1, 0, &sym_op1, &sym_addr1);
+ ok = avr_operand (insn, insn2, addr, *constraints, opcode_str, op1,
+ comment1, &style_op1, 0, &sym_op1, &sym_addr1,
+ info);
if (ok && *(++constraints) == ',')
- ok = avr_operand (insn, insn2, addr, *(++constraints), opcode_str, op2,
- *comment1 ? comment2 : comment1, regs, &sym_op2, &sym_addr2);
+ ok = avr_operand (insn, insn2, addr, *(++constraints), opcode_str,
+ op2, *comment1 ? comment2 : comment1,
+ &style_op2, regs, &sym_op2, &sym_addr2,
+ info);
}
}
comment2[0] = 0;
}
- (*prin) (stream, "%s", ok ? opcode->name : ".word");
-
+ (*prin) (stream, ok ? dis_style_mnemonic : dis_style_assembler_directive,
+ "%s", ok ? opcode->name : ".word");
+
if (*op1)
- (*prin) (stream, "\t%s", op1);
+ (*prin) (stream, style_op1, "\t%s", op1);
if (*op2)
- (*prin) (stream, ", %s", op2);
+ {
+ (*prin) (stream, dis_style_text, ", ");
+ (*prin) (stream, style_op2, "%s", op2);
+ }
if (*comment1)
- (*prin) (stream, "\t; %s", comment1);
+ (*prin) (stream, dis_style_comment_start, "\t; %s", comment1);
if (sym_op1)
info->print_address_func (sym_addr1, info);
if (*comment2)
- (*prin) (stream, " %s", comment2);
+ (*prin) (stream, dis_style_comment_start, " %s", comment2);
if (sym_op2)
info->print_address_func (sym_addr2, info);