diff --git a/arch/ARM/ARMMapping.c b/arch/ARM/ARMMapping.c index 7e8f5407e1..a38702cef7 100644 --- a/arch/ARM/ARMMapping.c +++ b/arch/ARM/ARMMapping.c @@ -277,7 +277,7 @@ static void ARM_add_not_defined_ops(MCInst *MI) case ARM_VCMPEZS: case ARM_VCMPZH: case ARM_VCMPZS: - ARM_insert_detail_op_imm_at(MI, 1, 0, CS_AC_READ); + ARM_insert_detail_op_imm_at(MI, -1, 0, CS_AC_READ); break; case ARM_MVE_VSHLL_lws16bh: case ARM_MVE_VSHLL_lws16th: @@ -1929,33 +1929,47 @@ void ARM_add_cs_detail(MCInst *MI, int /* arm_op_group */ op_group, add_cs_detail_general(MI, op_group, op_num); } +static void insert_op(MCInst *MI, unsigned index, cs_arm_op op) +{ + if (!detail_is_set(MI)) { + return; + } + ARM_check_safe_inc(); + + cs_arm_op *ops = ARM_get_detail(MI)->operands; + int i = ARM_get_detail(MI)->op_count; + if (index == -1) { + ops[i] = op; + ARM_inc_op_count(MI); + return; + } + for (; i > 0 && i > index; --i) { + ops[i] = ops[i - 1]; + } + ops[index] = op; + ARM_inc_op_count(MI); +} + /// Inserts a register to the detail operands at @index. /// Already present operands are moved. +/// If @index is -1 the operand is appended. void ARM_insert_detail_op_reg_at(MCInst *MI, unsigned index, arm_reg Reg, cs_ac_type access) { if (!detail_is_set(MI)) return; - ARM_check_safe_inc(); - cs_arm_op op; ARM_setup_op(&op); op.type = ARM_OP_REG; op.reg = Reg; op.access = access; - - cs_arm_op *ops = ARM_get_detail(MI)->operands; - int i = ARM_get_detail(MI)->op_count; - for (; i > 0 && i > index; --i) { - ops[i] = ops[i - 1]; - } - ops[index] = op; - ARM_inc_op_count(MI); + insert_op(MI, index, op); } /// Inserts a immediate to the detail operands at @index. /// Already present operands are moved. +/// If @index is -1 the operand is appended. void ARM_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Val, cs_ac_type access) { @@ -1969,13 +1983,7 @@ void ARM_insert_detail_op_imm_at(MCInst *MI, unsigned index, int64_t Val, op.imm = Val; op.access = access; - cs_arm_op *ops = ARM_get_detail(MI)->operands; - int i = ARM_get_detail(MI)->op_count; - for (; i > 0 && i > index; --i) { - ops[i] = ops[i - 1]; - } - ops[index] = op; - ARM_inc_op_count(MI); + insert_op(MI, index, op); } /// Adds a register ARM operand at position OpNum and increases the op_count by diff --git a/tests/issues/issues.yaml b/tests/issues/issues.yaml index 8dc7232b3b..947390e30f 100644 --- a/tests/issues/issues.yaml +++ b/tests/issues/issues.yaml @@ -5031,3 +5031,30 @@ test_cases: vas: AARCH64LAYOUT_VL_D regs_read: [ za0.d, za1.d, za2.d, za3.d, za4.d, za5.d, za6.d, za7.d ] groups: [ HasSME ] + + - + input: + address: 0x0 + name: "issue 2382" + bytes: [ 0x42, 0x40 ] + arch: "CS_ARCH_ARM" + options: [ CS_MODE_BIG_ENDIAN, CS_MODE_THUMB, CS_OPT_DETAIL ] + expected: + insns: + - + asm_text: "rsbs r0, r0, #0" + details: + arm: + operands: + - + type: ARM_OP_REG + reg: r0 + access: CS_AC_WRITE + - + type: ARM_OP_REG + reg: r0 + access: CS_AC_READ + - + type: ARM_OP_IMM + imm: 0 + access: CS_AC_READ