amd64: add spec rules for: S/NS after ADDL, S after ADDQ.

This commit is contained in:
Julian Seward 2021-09-23 15:46:21 +02:00
parent 10922b70b8
commit e3f6c66104

View File

@ -1092,6 +1092,7 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name,
/*---------------- ADDQ ----------------*/
/* 4, */
if (isU64(cc_op, AMD64G_CC_OP_ADDQ) && isU64(cond, AMD64CondZ)) {
/* long long add, then Z --> test (dst+src == 0) */
return unop(Iop_1Uto64,
@ -1100,8 +1101,22 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name,
mkU64(0)));
}
/* 8, */
if (isU64(cc_op, AMD64G_CC_OP_ADDQ) && isU64(cond, AMD64CondS)) {
/* long long add, then S (negative)
--> (dst+src)[63]
--> ((dst + src) >>u 63) & 1
*/
return binop(Iop_And64,
binop(Iop_Shr64,
binop(Iop_Add64, cc_dep1, cc_dep2),
mkU8(63)),
mkU64(1));
}
/*---------------- ADDL ----------------*/
/* 0, */
if (isU64(cc_op, AMD64G_CC_OP_ADDL) && isU64(cond, AMD64CondO)) {
/* This is very commonly generated by Javascript JITs, for
the idiom "do a 32-bit add and jump to out-of-line code if
@ -1127,6 +1142,32 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name,
}
/* 8, 9 */
if (isU64(cc_op, AMD64G_CC_OP_ADDL) && isU64(cond, AMD64CondS)) {
/* long add, then S (negative)
--> (dst+src)[31]
--> ((dst +64 src) >>u 31) & 1
Pointless to narrow the args to 32 bit before the add. */
return binop(Iop_And64,
binop(Iop_Shr64,
binop(Iop_Add64, cc_dep1, cc_dep2),
mkU8(31)),
mkU64(1));
}
if (isU64(cc_op, AMD64G_CC_OP_ADDL) && isU64(cond, AMD64CondNS)) {
/* long add, then NS (not negative)
--> (dst+src)[31] ^ 1
--> (((dst +64 src) >>u 31) & 1) ^ 1
Pointless to narrow the args to 32 bit before the add. */
return binop(Iop_Xor64,
binop(Iop_And64,
binop(Iop_Shr64,
binop(Iop_Add64, cc_dep1, cc_dep2),
mkU8(31)),
mkU64(1)),
mkU64(1));
}
/*---------------- SUBQ ----------------*/
/* 0, */