From: Julian Seward Date: Wed, 4 Jan 2023 16:04:03 +0000 (+0100) Subject: amd64 and x86 front ends: add a few more spec rules. X-Git-Tag: VALGRIND_3_21_0~240 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fe4e6578d451327829a6908a01bb27995c198acb;p=thirdparty%2Fvalgrind.git amd64 and x86 front ends: add a few more spec rules. amd64: S and NS after LOGICQ (per comments from Eyal Soha on the dev list) S after SHLQ NZ after SHLL x86: NZ after SHRL Z after SHLL I would have liked to have added the inverse conditions in all cases (eg, both S and NS, or both Z and NZ), but finding use cases for some of these is almost impossible, hence they are sometimes omitted. All of the added cases have been tested. --- diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c index abd2a1e370..42ec80e036 100644 --- a/VEX/priv/guest_amd64_helpers.c +++ b/VEX/priv/guest_amd64_helpers.c @@ -1684,6 +1684,19 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, mkU64(0))); } + // Verified + if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondS)) { + /* long long and/or/xor, then S --> (ULong)result[63] */ + return binop(Iop_Shr64, cc_dep1, mkU8(63)); + } + // Verified + if (isU64(cc_op, AMD64G_CC_OP_LOGICQ) && isU64(cond, AMD64CondNS)) { + /* long long and/or/xor, then S --> (ULong) ~ result[63] */ + return binop(Iop_Xor64, + binop(Iop_Shr64, cc_dep1, mkU8(63)), + mkU64(1)); + } + /*---------------- LOGICL ----------------*/ if (isU64(cc_op, AMD64G_CC_OP_LOGICL) && isU64(cond, AMD64CondZ)) { @@ -1932,10 +1945,12 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, binop(Iop_CmpNE64, cc_dep1, mkU64(0))); } - //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondS)) { - // /* SHLQ, then S --> (ULong)result[63] */ - // vassert(0); - //} + // Verified + if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondS)) { + /* SHLQ, then S --> (ULong)result[63] */ + return binop(Iop_Shr64, cc_dep1, mkU8(63)); + } + // No known test case //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondNS)) { // /* SHLQ, then NS --> (ULong) ~ result[63] */ // vassert(0); @@ -1949,10 +1964,13 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, binop(Iop_CmpEQ32, unop(Iop_64to32, cc_dep1), mkU32(0))); } - //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNZ)) { - // /* SHLL, then NZ --> test dep1 != 0 */ - // vassert(0); - //} + // Verified + if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNZ)) { + /* SHLL, then NZ --> test dep1 != 0 */ + return unop(Iop_1Uto64, + binop(Iop_CmpNE32, unop(Iop_64to32, cc_dep1), + mkU32(0))); + } if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondS)) { /* SHLL, then S --> (ULong)result[31] */ @@ -1960,6 +1978,7 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, binop(Iop_Shr64, cc_dep1, mkU8(31)), mkU64(1)); } + // No known test case //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNS)) { // /* SHLL, then NS --> (ULong) ~ result[31] */ // vassert(0); diff --git a/VEX/priv/guest_x86_helpers.c b/VEX/priv/guest_x86_helpers.c index 7b229cb795..a1d086369d 100644 --- a/VEX/priv/guest_x86_helpers.c +++ b/VEX/priv/guest_x86_helpers.c @@ -1203,9 +1203,24 @@ IRExpr* guest_x86_spechelper ( const HChar* function_name, /*---------------- SHRL ----------------*/ if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondZ)) { - /* SHRL, then Z --> test dep1 == 0 */ + /* SHRL, then Z --> test dep1(result) == 0 */ return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); } + if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondNZ)) { + /* SHRL, then NZ --> test dep1(result) != 0 */ + return unop(Iop_1Uto32,binop(Iop_CmpNE32, cc_dep1, mkU32(0))); + } + + /*---------------- SHLL ----------------*/ + + if (isU32(cc_op, X86G_CC_OP_SHLL) && isU32(cond, X86CondZ)) { + /* SHLL, then Z --> test dep1(result) == 0 */ + return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); + } + //if (isU32(cc_op, X86G_CC_OP_SHLL) && isU32(cond, X86CondNZ)) { + // /* SHLL, then NZ --> test dep1(result) != 0 */ + // vassert(0); // No test case yet observed + //} /*---------------- COPY ----------------*/ /* This can happen, as a result of x87 FP compares: "fcom ... ;