From: Andreas Arnez Date: Mon, 15 Sep 2025 13:39:11 +0000 (+0200) Subject: Bug 509517 - s390x: Fix even/odd lane confusion for VME etc. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6ac493c0ea305b2f7645c86ae0b0318db0fbf3e3;p=thirdparty%2Fvalgrind.git Bug 509517 - s390x: Fix even/odd lane confusion for VME etc. Fix the swapping of even/odd IROps generation in guest_s390_toIR.c for VME, VMO, VMLE, VMLO, VMAE, VMAO, VMALE, and VMALO. Adjust the code generation for the according IROps to match the documentation in libvex_ir.h. --- diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index f40cd15e8..1f18fee66 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -18431,25 +18431,25 @@ s390_irgen_VMH(UChar v1, UChar v2, UChar v3, UChar m4) } static const HChar * -s390_irgen_VME(UChar v1, UChar v2, UChar v3, UChar m4) +s390_irgen_VMO(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vme", m4 <= 2); + s390_insn_assert("vmo", m4 <= 2); const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - return "vme"; + return "vmo"; } static const HChar * -s390_irgen_VMLE(UChar v1, UChar v2, UChar v3, UChar m4) +s390_irgen_VMLO(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmle", m4 <= 2); + s390_insn_assert("vmlo", m4 <= 2); const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4 }; put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); - return "vmle"; + return "vmlo"; } static const HChar * @@ -18853,43 +18853,43 @@ s390_irgen_VSRD(UChar v1, UChar v2, UChar v3, UChar i4) } static const HChar * -s390_irgen_VMO(UChar v1, UChar v2, UChar v3, UChar m4) +s390_irgen_VME(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmo", m4 <= 2); + s390_insn_assert("vme", m4 <= 2); const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4 }; UChar shifts[] = { 8, 16, 32 }; IRExpr* result = binop(ops[m4], - binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m4])), - binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m4])) + binop(Iop_ShrV128, get_vr_qw(v2), mkU8(shifts[m4])), + binop(Iop_ShrV128, get_vr_qw(v3), mkU8(shifts[m4])) ); put_vr_qw(v1, result); - return "vmo"; + return "vme"; } static const HChar * -s390_irgen_VMLO(UChar v1, UChar v2, UChar v3, UChar m4) +s390_irgen_VMLE(UChar v1, UChar v2, UChar v3, UChar m4) { - s390_insn_assert("vmlo", m4 <= 2); + s390_insn_assert("vmle", m4 <= 2); const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4 }; UChar shifts[] = { 8, 16, 32 }; IRExpr* result = binop(ops[m4], - binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m4])), - binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m4])) + binop(Iop_ShrV128, get_vr_qw(v2), mkU8(shifts[m4])), + binop(Iop_ShrV128, get_vr_qw(v3), mkU8(shifts[m4])) ); put_vr_qw(v1, result); - return "vmlo"; + return "vmle"; } static const HChar * -s390_irgen_VMAE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) +s390_irgen_VMAO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmae", m5 <= 2); + s390_insn_assert("vmao", m5 <= 2); const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4 }; @@ -18899,13 +18899,13 @@ s390_irgen_VMAE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4)); put_vr_qw(v1, result); - return "vmae"; + return "vmao"; } static const HChar * -s390_irgen_VMALE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) +s390_irgen_VMALO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmale", m5 <= 2); + s390_insn_assert("vmalo", m5 <= 2); const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4 }; @@ -18915,13 +18915,13 @@ s390_irgen_VMALE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4)); put_vr_qw(v1, result); - return "vmale"; + return "vmalo"; } static const HChar * -s390_irgen_VMAO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) +s390_irgen_VMAE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmao", m5 <= 2); + s390_insn_assert("vmae", m5 <= 2); const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4 }; @@ -18930,18 +18930,18 @@ s390_irgen_VMAO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) IRExpr* mul_result = binop(mul_ops[m5], - binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m5])), - binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m5]))); + binop(Iop_ShrV128, get_vr_qw(v2), mkU8(shifts[m5])), + binop(Iop_ShrV128, get_vr_qw(v3), mkU8(shifts[m5]))); IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4)); put_vr_qw(v1, result); - return "vmao"; + return "vmae"; } static const HChar * -s390_irgen_VMALO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) +s390_irgen_VMALE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) { - s390_insn_assert("vmalo", m5 <= 2); + s390_insn_assert("vmale", m5 <= 2); const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4 }; @@ -18949,16 +18949,16 @@ s390_irgen_VMALO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) UChar shifts[] = { 8, 16, 32 }; IRExpr* mul_result = binop(mul_ops[m5], - binop(Iop_ShlV128, + binop(Iop_ShrV128, get_vr_qw(v2), mkU8(shifts[m5])), - binop(Iop_ShlV128, + binop(Iop_ShrV128, get_vr_qw(v3), mkU8(shifts[m5])) ); IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4)); put_vr_qw(v1, result); - return "vmalo"; + return "vmale"; } static const HChar * diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index c79aa11c0..a3b91071d 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -6083,21 +6083,21 @@ s390_emit_VML(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) } static UChar * -s390_emit_VME(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) +s390_emit_VMO(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vme", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); + S390_DISASM(XMNM("vmo", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000a6ULL, v1, v2, v3, m4); + return emit_VRR_VVVM(p, 0xE700000000a7ULL, v1, v2, v3, m4); } static UChar * -s390_emit_VMLE(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) +s390_emit_VMLO(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(XMNM("vmle", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); + S390_DISASM(XMNM("vmlo", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); - return emit_VRR_VVVM(p, 0xE700000000a4ULL, v1, v2, v3, m4); + return emit_VRR_VVVM(p, 0xE700000000a5ULL, v1, v2, v3, m4); } static UChar * @@ -8208,8 +8208,8 @@ s390_insn_as_string(const s390_insn *insn) case S390_VEC_INT_MUL_HIGHS: op = "v-vintmulhis"; break; case S390_VEC_INT_MUL_HIGHU: op = "v-vintmulhiu"; break; case S390_VEC_INT_MUL_LOW: op = "v-vintmullo"; break; - case S390_VEC_INT_MUL_EVENS: op = "v-vintmulevens"; break; - case S390_VEC_INT_MUL_EVENU: op = "v-vintmulevenu"; break; + case S390_VEC_INT_MUL_ODDS: op = "v-vintmulodds"; break; + case S390_VEC_INT_MUL_ODDU: op = "v-vintmuloddu"; break; case S390_VEC_ELEM_SHL_V: op = "v-velemshl"; break; case S390_VEC_ELEM_SHRA_V: op = "v-vshrav"; break; case S390_VEC_ELEM_SHRL_V: op = "v-vshrlv"; break; @@ -11523,10 +11523,10 @@ s390_insn_vec_binop_emit(UChar *buf, const s390_insn *insn) return s390_emit_VMLH(buf, v1, v2, v3, s390_getM_from_size(size)); case S390_VEC_INT_MUL_LOW: return s390_emit_VML(buf, v1, v2, v3, s390_getM_from_size(size)); - case S390_VEC_INT_MUL_EVENS: - return s390_emit_VME(buf, v1, v2, v3, s390_getM_from_size(size)); - case S390_VEC_INT_MUL_EVENU: - return s390_emit_VMLE(buf, v1, v2, v3, s390_getM_from_size(size)); + case S390_VEC_INT_MUL_ODDS: + return s390_emit_VMO(buf, v1, v2, v3, s390_getM_from_size(size)); + case S390_VEC_INT_MUL_ODDU: + return s390_emit_VMLO(buf, v1, v2, v3, s390_getM_from_size(size)); case S390_VEC_ELEM_SHL_V: return s390_emit_VESLV(buf, v1, v2, v3, s390_getM_from_size(size)); case S390_VEC_ELEM_SHRA_V: diff --git a/VEX/priv/host_s390_defs.h b/VEX/priv/host_s390_defs.h index ddbaed5fe..87726c3e5 100644 --- a/VEX/priv/host_s390_defs.h +++ b/VEX/priv/host_s390_defs.h @@ -382,8 +382,8 @@ typedef enum { S390_VEC_INT_MUL_HIGHS, S390_VEC_INT_MUL_HIGHU, S390_VEC_INT_MUL_LOW, - S390_VEC_INT_MUL_EVENS, - S390_VEC_INT_MUL_EVENU, + S390_VEC_INT_MUL_ODDS, + S390_VEC_INT_MUL_ODDU, S390_VEC_ELEM_SHL_V, S390_VEC_ELEM_SHRA_V, S390_VEC_ELEM_SHRL_V, diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index c4e9ee764..cf0a0a7ee 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -4503,27 +4503,27 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr) case Iop_MullEven8Sx16: size = 1; - vec_binop = S390_VEC_INT_MUL_EVENS; + vec_binop = S390_VEC_INT_MUL_ODDS; goto Iop_VV_wrk; case Iop_MullEven8Ux16: size = 1; - vec_binop = S390_VEC_INT_MUL_EVENU; + vec_binop = S390_VEC_INT_MUL_ODDU; goto Iop_VV_wrk; case Iop_MullEven16Sx8: size = 2; - vec_binop = S390_VEC_INT_MUL_EVENS; + vec_binop = S390_VEC_INT_MUL_ODDS; goto Iop_VV_wrk; case Iop_MullEven16Ux8: size = 2; - vec_binop = S390_VEC_INT_MUL_EVENU; + vec_binop = S390_VEC_INT_MUL_ODDU; goto Iop_VV_wrk; case Iop_MullEven32Sx4: size = 4; - vec_binop = S390_VEC_INT_MUL_EVENS; + vec_binop = S390_VEC_INT_MUL_ODDS; goto Iop_VV_wrk; case Iop_MullEven32Ux4: size = 4; - vec_binop = S390_VEC_INT_MUL_EVENU; + vec_binop = S390_VEC_INT_MUL_ODDU; goto Iop_VV_wrk; case Iop_Shl8x16: