+void arc_insn_decode (bfd_vma addr,
+ struct disassemble_info *info,
+ disassembler_ftype disasm_func,
+ struct arc_instruction *insn)
+{
+ const struct arc_opcode *opcode;
+ struct arc_disassemble_info *arc_infop;
+
+ /* Ensure that insn would be in the reset state. */
+ memset (insn, 0, sizeof (struct arc_instruction));
+
+ /* There was an error when disassembling, for example memory read error. */
+ if (disasm_func (addr, info) < 0)
+ {
+ insn->valid = FALSE;
+ return;
+ }
+
+ assert (info->private_data != NULL);
+ arc_infop = info->private_data;
+
+ insn->length = arc_infop->insn_len;;
+ insn->address = addr;
+
+ /* Quick exit if memory at this address is not an instruction. */
+ if (info->insn_type == dis_noninsn)
+ {
+ insn->valid = FALSE;
+ return;
+ }
+
+ insn->valid = TRUE;
+
+ opcode = (const struct arc_opcode *) arc_infop->opcode;
+ insn->insn_class = opcode->insn_class;
+ insn->limm_value = arc_infop->limm;
+ insn->limm_p = arc_infop->limm_p;
+
+ insn->is_control_flow = (info->insn_type == dis_branch
+ || info->insn_type == dis_condbranch
+ || info->insn_type == dis_jsr
+ || info->insn_type == dis_condjsr);
+
+ insn->has_delay_slot = info->branch_delay_insns;
+ insn->writeback_mode
+ = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode;
+ insn->data_size_mode = info->data_size;
+ insn->condition_code = arc_infop->condition_code;
+ memcpy (insn->operands, arc_infop->operands,
+ sizeof (struct arc_insn_operand) * MAX_INSN_ARGS);
+ insn->operands_count = arc_infop->operands_count;
+}