diff --git a/arch/LoongArch/LoongArchMapping.c b/arch/LoongArch/LoongArchMapping.c index 83b07271cd..6aaf206935 100644 --- a/arch/LoongArch/LoongArchMapping.c +++ b/arch/LoongArch/LoongArchMapping.c @@ -264,18 +264,10 @@ void LoongArch_rewrite_memory_operand(MCInst *MI) case LOONGARCH_INSN_FORM_FMT2RI10_VRI: // vldrepl.w case LOONGARCH_INSN_FORM_FMT2RI11_VRI: // vldrepl.h case LOONGARCH_INSN_FORM_FMT2RI12_VRI: // vld, vldrepl, vst - case LOONGARCH_INSN_FORM_FMT2RI8I1_VRII: // vstelm.d - case LOONGARCH_INSN_FORM_FMT2RI8I2_VRII: // vstelm.w - case LOONGARCH_INSN_FORM_FMT2RI8I3_VRII: // vstelm.h - case LOONGARCH_INSN_FORM_FMT2RI8I4_VRII: // vstelm.b case LOONGARCH_INSN_FORM_FMT2RI9_XRI: // xvldrepl.d case LOONGARCH_INSN_FORM_FMT2RI10_XRI: // xvldrepl.w case LOONGARCH_INSN_FORM_FMT2RI11_XRI: // xvldrepl.h case LOONGARCH_INSN_FORM_FMT2RI12_XRI: // xvld, xvldrepl, xvst - case LOONGARCH_INSN_FORM_FMT2RI8I2_XRII: // xvstelm.d - case LOONGARCH_INSN_FORM_FMT2RI8I3_XRII: // xvstelm.w - case LOONGARCH_INSN_FORM_FMT2RI8I4_XRII: // xvstelm.h - case LOONGARCH_INSN_FORM_FMT2RI8I5_XRII: // xvstelm.b case LOONGARCH_INSN_FORM_FMTPRELD: // preld case LOONGARCH_INSN_FORM_FPFMT2RI12: // fld, fst // immediate offset @@ -289,6 +281,27 @@ void LoongArch_rewrite_memory_operand(MCInst *MI) LoongArch_dec_op_count(MI); break; + case LOONGARCH_INSN_FORM_FMT2RI8I1_VRII: // vstelm.d + case LOONGARCH_INSN_FORM_FMT2RI8I2_VRII: // vstelm.w + case LOONGARCH_INSN_FORM_FMT2RI8I3_VRII: // vstelm.h + case LOONGARCH_INSN_FORM_FMT2RI8I4_VRII: // vstelm.b + case LOONGARCH_INSN_FORM_FMT2RI8I2_XRII: // xvstelm.d + case LOONGARCH_INSN_FORM_FMT2RI8I3_XRII: // xvstelm.w + case LOONGARCH_INSN_FORM_FMT2RI8I4_XRII: // xvstelm.h + case LOONGARCH_INSN_FORM_FMT2RI8I5_XRII: // xvstelm.b + // immediate offset followed by the element index + LoongArch_get_detail_op(MI, -3)->type = LOONGARCH_OP_MEM; + base = LoongArch_get_detail_op(MI, -3)->reg; + LoongArch_get_detail_op(MI, -3)->mem.base = base; + LoongArch_get_detail_op(MI, -3)->mem.disp = + LoongArch_get_detail_op(MI, -2)->imm; + LoongArch_get_detail_op(MI, -3)->access = + suppl_info->memory_access; + *LoongArch_get_detail_op(MI, -2) = + *LoongArch_get_detail_op(MI, -1); + LoongArch_dec_op_count(MI); + break; + case LOONGARCH_INSN_FORM_FMT3R: // ldx, stx, amo if (suppl_info->memory_access == CS_AC_READ_WRITE) { // amo: read + write diff --git a/tests/details/loongarch.yaml b/tests/details/loongarch.yaml index 97fd4fdfc0..a5db8d6d68 100644 --- a/tests/details/loongarch.yaml +++ b/tests/details/loongarch.yaml @@ -165,3 +165,49 @@ test_cases: type: LOONGARCH_OP_IMM imm: 0x1bf0 groups: [ LOONGARCH_GRP_CALL ] + - + input: + bytes: [ 0x1a, 0xae, 0x45, 0x33, 0x81, 0xf4, 0x97, 0x31 ] + arch: "loongarch" + options: [ CS_OPT_DETAIL, CS_MODE_LOONGARCH64 ] + address: 0x1000 + expected: + insns: + - + asm_text: "xvstelm.h $xr26, $t4, 0xd6, 1" + details: + loongarch: + operands: + - + type: LOONGARCH_OP_REG + reg: xr26 + access: CS_AC_READ + - + type: LOONGARCH_OP_MEM + mem_base: t4 + mem_disp: 0xd6 + access: CS_AC_WRITE + - + type: LOONGARCH_OP_IMM + imm: 0x1 + access: CS_AC_READ + regs_read: [ xr26, t4 ] + - + asm_text: "vstelm.b $vr1, $a0, -3, 5" + details: + loongarch: + operands: + - + type: LOONGARCH_OP_REG + reg: vr1 + access: CS_AC_READ + - + type: LOONGARCH_OP_MEM + mem_base: a0 + mem_disp: -3 + access: CS_AC_WRITE + - + type: LOONGARCH_OP_IMM + imm: 0x5 + access: CS_AC_READ + regs_read: [ vr1, a0 ]