"r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
};
+static const char * const addrtypenames[ARC_NUM_ADDRTYPES] =
+{
+ "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd",
+ "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd"
+};
+
+static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1;
+
+static const char * const addrtypeunknown = "unknown";
+
/* This structure keeps track which instruction class(es)
should be ignored durring disassembling. */
/* If we found an incompatibility then we must skip. */
if (t != NULL)
return TRUE;
-
+
/* Even if we do not precisely know the if the right mnemonics
is correctly displayed, keep the disassmbled code class
consistent. */
{
const struct arc_opcode *opcode = NULL;
bfd_boolean needs_limm;
- const extInstruction_t *einsn;
+ const extInstruction_t *einsn, *i;
/* First, try the extension instructions. */
einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
- if (einsn != NULL)
+ for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
{
const char *errmsg = NULL;
- opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
+ opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
if (opcode == NULL)
{
(*info->fprintf_func) (info->stream, "\
return NULL;
}
+/* Convert a value representing an address type to a string used to refer to
+ the address type in assembly code. */
+
+static const char *
+get_addrtype (int value)
+{
+ if (value < 0 || value > addrtypenames_max)
+ return addrtypeunknown;
+
+ return addrtypenames[value];
+}
+
/* Calculate the instruction length for an instruction starting with MSB
and LSB, the most and least significant byte. The ISA_MASK is used to
filter the instructions considered to only those that are part of the
case bfd_mach_arc_arcv2:
default:
isa_mask = ARC_OPCODE_ARCv2EM;
- if ((header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
+ /* TODO: Perhaps remove defitinion of header since it is only used at
+ this location. */
+ if (header != NULL
+ && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
{
isa_mask = ARC_OPCODE_ARCv2HS;
/* FPU instructions are not extensions for HS. */
}
/* Only take input from real operands. */
- if ((operand->flags & ARC_OPERAND_FAKE)
- && !(operand->flags & ARC_OPERAND_BRAKET))
+ if (ARC_OPERAND_IS_FAKE (operand))
continue;
if ((operand->flags & ARC_OPERAND_IGNORE)
&& value == -1)
continue;
+ if (operand->flags & ARC_OPERAND_COLON)
+ {
+ (*info->fprintf_func) (info->stream, ":");
+ continue;
+ }
+
if (need_comma)
(*info->fprintf_func) (info->stream, ",");
continue;
}
+ need_comma = TRUE;
+
/* Print the operand as directed by the flags. */
if (operand->flags & ARC_OPERAND_IR)
{
else if (operand->flags & ARC_OPERAND_LIMM)
{
const char *rname = get_auxreg (opcode, value, isa_mask);
+
if (rname && open_braket)
(*info->fprintf_func) (info->stream, "%s", rname);
else
else
(*info->fprintf_func) (info->stream, "%d", value);
}
+ else if (operand->flags & ARC_OPERAND_ADDRTYPE)
+ {
+ const char *addrtype = get_addrtype (value);
+ (*info->fprintf_func) (info->stream, "%s", addrtype);
+ /* A colon follow an address type. */
+ need_comma = FALSE;
+ }
else
{
if (operand->flags & ARC_OPERAND_TRUNCATE
(*info->fprintf_func) (info->stream, "%#x", value);
}
}
-
- need_comma = TRUE;
}
return insn_len;
disassembler_ftype
arc_get_disassembler (bfd *abfd)
{
- /* Read the extenssion insns and registers, if any. */
- build_ARC_extmap (abfd);
+ /* BFD my be absent, if opcodes is invoked from the debugger that
+ has connected to remote target and doesn't have an ELF file. */
+ if (abfd != NULL)
+ {
+ /* Read the extension insns and registers, if any. */
+ build_ARC_extmap (abfd);
#ifdef DEBUG
- dump_ARC_extmap ();
+ dump_ARC_extmap ();
#endif
+ }
return print_insn_arc;
}