From: Andreas Arnez Date: Wed, 7 Apr 2021 10:29:32 +0000 (+0200) Subject: s390x: Vec-enh-2, extend VSL, VSRA, and VSRL X-Git-Tag: VALGRIND_3_18_0~93 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db3c2f6a8531f674e6282280a236e895907b2698;p=thirdparty%2Fvalgrind.git s390x: Vec-enh-2, extend VSL, VSRA, and VSRL The vector-enhancements facility 2 extends the existing bitwise vector shift instructions VSL, VSRA, and VSRL. Now they allow the shift vector (the third operand) to contain different shift amounts for each byte. Add support for these new forms. --- diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index 9f7d98f8c6..622d5a02e0 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -17983,30 +17983,66 @@ s390_irgen_VERLL(UChar v1, IRTemp op2addr, UChar v3, UChar m4) static const HChar * s390_irgen_VSL(UChar v1, UChar v2, UChar v3) { - IRTemp shift_amount = newTemp(Ity_I8); - assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b00000111))); - - put_vr_qw(v1, binop(Iop_ShlV128, get_vr_qw(v2), mkexpr(shift_amount))); + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + + put_vr_qw(v1, + binop(Iop_OrV128, + binop(Iop_Shl8x16, mkexpr(a), mkexpr(b)), + binop(Iop_Shr8x16, + binop(Iop_Shr8x16, + binop(Iop_ShlV128, mkexpr(a), mkU8(8)), + unop(Iop_NotV128, mkexpr(b))), + unop(Iop_Dup8x16, mkU8(1))))); return "vsl"; } static const HChar * s390_irgen_VSRL(UChar v1, UChar v2, UChar v3) { - IRTemp shift_amount = newTemp(Ity_I8); - assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b00000111))); + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); - put_vr_qw(v1, binop(Iop_ShrV128, get_vr_qw(v2), mkexpr(shift_amount))); + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + + put_vr_qw(v1, + binop(Iop_OrV128, + binop(Iop_Shr8x16, mkexpr(a), mkexpr(b)), + binop(Iop_Shl8x16, + binop(Iop_Shl8x16, + binop(Iop_ShrV128, mkexpr(a), mkU8(8)), + unop(Iop_NotV128, mkexpr(b))), + unop(Iop_Dup8x16, mkU8(1))))); return "vsrl"; } static const HChar * s390_irgen_VSRA(UChar v1, UChar v2, UChar v3) { - IRTemp shift_amount = newTemp(Ity_I8); - assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b00000111))); - - put_vr_qw(v1, binop(Iop_SarV128, get_vr_qw(v2), mkexpr(shift_amount))); + IRTemp a = newTemp(Ity_V128); + IRTemp b = newTemp(Ity_V128); + + assign(a, get_vr_qw(v2)); + assign(b, get_vr_qw(v3)); + + /* Shift-right: first byte arithmetically, all others logically */ + IRExpr* elems_shifted = + binop(Iop_Sar8x16, + binop(Iop_Shr8x16, mkexpr(a), + binop(Iop_AndV128, mkexpr(b), mkV128(0x7fff))), + binop(Iop_AndV128, mkexpr(b), mkV128(0x8000))); + /* Then OR the appropriate bits from the byte to the left */ + put_vr_qw(v1, + binop(Iop_OrV128, elems_shifted, + binop(Iop_Shl8x16, + binop(Iop_Shl8x16, + binop(Iop_ShrV128, mkexpr(a), mkU8(8)), + unop(Iop_NotV128, mkexpr(b))), + unop(Iop_Dup8x16, mkU8(1))))); return "vsra"; }