|
From: <sv...@va...> - 2010-01-15 09:55:05
|
Author: sewardj
Date: 2010-01-15 09:54:55 +0000 (Fri, 15 Jan 2010)
New Revision: 1956
Log:
amd64: add a couple more spec cases: NLE after SUBL, and NZ after LOGICB.
x86: add commented out (ATC) spec case for C flag after SMULL.
Modified:
trunk/priv/guest_amd64_helpers.c
trunk/priv/guest_x86_helpers.c
Modified: trunk/priv/guest_amd64_helpers.c
===================================================================
--- trunk/priv/guest_amd64_helpers.c 2010-01-11 10:46:18 UTC (rev 1955)
+++ trunk/priv/guest_amd64_helpers.c 2010-01-15 09:54:55 UTC (rev 1956)
@@ -995,7 +995,18 @@
binop(Iop_Shl64,cc_dep2,mkU8(32))));
}
+ if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondNLE)) {
+ /* long sub/cmp, then NLE (signed greater than)
+ --> test !(dst <=s src)
+ --> test (dst >s src)
+ --> test (src <s dst) */
+ return unop(Iop_1Uto64,
+ binop(Iop_CmpLT64S,
+ binop(Iop_Shl64,cc_dep2,mkU8(32)),
+ binop(Iop_Shl64,cc_dep1,mkU8(32))));
+ }
+
if (isU64(cc_op, AMD64G_CC_OP_SUBL) && isU64(cond, AMD64CondBE)) {
/* long sub/cmp, then BE (unsigned less than or equal)
--> test dst <=u src */
@@ -1155,6 +1166,12 @@
binop(Iop_CmpEQ64, binop(Iop_And64,cc_dep1,mkU64(255)),
mkU64(0)));
}
+ if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondNZ)) {
+ /* byte and/or/xor, then NZ --> test dst!=0 */
+ return unop(Iop_1Uto64,
+ binop(Iop_CmpNE64, binop(Iop_And64,cc_dep1,mkU64(255)),
+ mkU64(0)));
+ }
if (isU64(cc_op, AMD64G_CC_OP_LOGICB) && isU64(cond, AMD64CondS)) {
/* this is an idiom gcc sometimes uses to find out if the top
Modified: trunk/priv/guest_x86_helpers.c
===================================================================
--- trunk/priv/guest_x86_helpers.c 2010-01-11 10:46:18 UTC (rev 1955)
+++ trunk/priv/guest_x86_helpers.c 2010-01-15 09:54:55 UTC (rev 1956)
@@ -1272,6 +1272,22 @@
binop(Iop_Add32, cc_dep1, cc_dep2),
cc_dep1));
}
+ // ATC, requires verification, no test case known
+ //if (isU32(cc_op, X86G_CC_OP_SMULL)) {
+ // /* C after signed widening multiply denotes the case where
+ // the top half of the result isn't simply the sign extension
+ // of the bottom half (iow the result doesn't fit completely
+ // in the bottom half). Hence:
+ // C = hi-half(dep1 x dep2) != lo-half(dep1 x dep2) >>s 31
+ // where 'x' denotes signed widening multiply.*/
+ // return
+ // unop(Iop_1Uto32,
+ // binop(Iop_CmpNE32,
+ // unop(Iop_64HIto32,
+ // binop(Iop_MullS32, cc_dep1, cc_dep2)),
+ // binop(Iop_Sar32,
+ // binop(Iop_Mul32, cc_dep1, cc_dep2), mkU8(31)) ));
+ //}
# if 0
if (cc_op->tag == Iex_Const) {
vex_printf("CFLAG "); ppIRExpr(cc_op); vex_printf("\n");
|