diff --git a/core/arch/aarch64/decode.c b/core/arch/aarch64/decode.c index c4eab819eaf..8ef41a59c8a 100644 --- a/core/arch/aarch64/decode.c +++ b/core/arch/aarch64/decode.c @@ -175,9 +175,25 @@ decode_common(dcontext_t *dcontext, byte *pc, byte *orig_pc, instr_t *instr) instr->src0 = opnd_create_reg(DR_REG_X0 + (enc & 31)); } else { + /* We use OP_xx for instructions not yet handled by the decoder. + * If an A64 instruction accesses a general-purpose register + * (except X30) then the number of that register appears in one + * of four possible places in the instruction word, so we can + * pessimistically assume that an unrecognised instruction reads + * and writes all four of those registers, and this is + * sufficient to enable correct (though often excessive) mangling. + */ instr_set_opcode(instr, OP_xx); - instr_set_num_opnds(dcontext, instr, 0, 1); + instr_set_num_opnds(dcontext, instr, 4, 5); instr->src0 = OPND_CREATE_INT32(enc); + instr->srcs[0] = opnd_create_reg(DR_REG_X0 + (enc & 31)); + instr->dsts[0] = opnd_create_reg(DR_REG_X0 + (enc & 31)); + instr->srcs[1] = opnd_create_reg(DR_REG_X0 + (enc >> 5 & 31)); + instr->dsts[1] = opnd_create_reg(DR_REG_X0 + (enc >> 5 & 31)); + instr->srcs[2] = opnd_create_reg(DR_REG_X0 + (enc >> 10 & 31)); + instr->dsts[2] = opnd_create_reg(DR_REG_X0 + (enc >> 10 & 31)); + instr->srcs[3] = opnd_create_reg(DR_REG_X0 + (enc >> 16 & 31)); + instr->dsts[3] = opnd_create_reg(DR_REG_X0 + (enc >> 16 & 31)); } instr_set_operands_valid(instr, true);