|
From: <sv...@va...> - 2009-09-18 16:56:43
|
Author: sewardj
Date: 2009-09-18 17:56:27 +0100 (Fri, 18 Sep 2009)
New Revision: 1922
Log:
Add support to make it possible for Memcheck to track definedness
flows exactly in sse2-based strlen routines that are based on
pmovmskb.
* new primop, Iop_GetMSBs8x8, to represent behaviour of pmovmskb
directly instead of via helper functions, which are opaque to
Memcheck. Front-end and back-end mods to match.
* new primops Iop_ExpCmpNE{8,16,32,64}, which are exactly like
Iop_ExpCmpNE{8,16,32,64}, except carrying the additional hint
that they require expensive definedness tracking. These are
used in bsf/bsr, since it may be the case that their input is
generated by pmovmskb. (so far x86 only; amd64 fe is todo).
Modified:
branches/ICC111/priv/guest_amd64_defs.h
branches/ICC111/priv/guest_amd64_helpers.c
branches/ICC111/priv/guest_amd64_toIR.c
branches/ICC111/priv/guest_x86_defs.h
branches/ICC111/priv/guest_x86_helpers.c
branches/ICC111/priv/guest_x86_toIR.c
branches/ICC111/priv/host_amd64_isel.c
branches/ICC111/priv/host_generic_simd64.c
branches/ICC111/priv/host_generic_simd64.h
branches/ICC111/priv/host_x86_isel.c
branches/ICC111/priv/ir_defs.c
branches/ICC111/priv/ir_opt.c
branches/ICC111/pub/libvex_ir.h
Modified: branches/ICC111/priv/guest_amd64_defs.h
===================================================================
--- branches/ICC111/priv/guest_amd64_defs.h 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/guest_amd64_defs.h 2009-09-18 16:56:27 UTC (rev 1922)
@@ -140,8 +140,6 @@
extern ULong amd64g_calculate_mmx_pmaddwd ( ULong, ULong );
extern ULong amd64g_calculate_mmx_psadbw ( ULong, ULong );
-extern ULong amd64g_calculate_mmx_pmovmskb ( ULong );
-extern ULong amd64g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo );
/* --- DIRTY HELPERS --- */
Modified: branches/ICC111/priv/guest_amd64_helpers.c
===================================================================
--- branches/ICC111/priv/guest_amd64_helpers.c 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/guest_amd64_helpers.c 2009-09-18 16:56:27 UTC (rev 1922)
@@ -2277,21 +2277,6 @@
}
/* CALLED FROM GENERATED CODE: CLEAN HELPER */
-ULong amd64g_calculate_mmx_pmovmskb ( ULong xx )
-{
- ULong r = 0;
- if (xx & (1ULL << (64-1))) r |= (1<<7);
- if (xx & (1ULL << (56-1))) r |= (1<<6);
- if (xx & (1ULL << (48-1))) r |= (1<<5);
- if (xx & (1ULL << (40-1))) r |= (1<<4);
- if (xx & (1ULL << (32-1))) r |= (1<<3);
- if (xx & (1ULL << (24-1))) r |= (1<<2);
- if (xx & (1ULL << (16-1))) r |= (1<<1);
- if (xx & (1ULL << ( 8-1))) r |= (1<<0);
- return r;
-}
-
-/* CALLED FROM GENERATED CODE: CLEAN HELPER */
ULong amd64g_calculate_mmx_psadbw ( ULong xx, ULong yy )
{
UInt t = 0;
@@ -2307,15 +2292,7 @@
return (ULong)t;
}
-/* CALLED FROM GENERATED CODE: CLEAN HELPER */
-ULong amd64g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo )
-{
- ULong rHi8 = amd64g_calculate_mmx_pmovmskb ( w64hi );
- ULong rLo8 = amd64g_calculate_mmx_pmovmskb ( w64lo );
- return ((rHi8 & 0xFF) << 8) | (rLo8 & 0xFF);
-}
-
/*---------------------------------------------------------------*/
/*--- Helpers for dealing with, and describing, ---*/
/*--- guest state as a whole. ---*/
Modified: branches/ICC111/priv/guest_amd64_toIR.c
===================================================================
--- branches/ICC111/priv/guest_amd64_toIR.c 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/guest_amd64_toIR.c 2009-09-18 16:56:27 UTC (rev 1922)
@@ -9902,7 +9902,7 @@
/* ***--- this is an MMX class insn introduced in SSE1 ---*** */
/* 0F D7 = PMOVMSKB -- extract sign bits from each of 8 lanes in
- mmx(G), turn them into a byte, and put zero-extend of it in
+ mmx(E), turn them into a byte, and put zero-extend of it in
ireg(G). */
if (haveNo66noF2noF3(pfx) && sz == 4
&& insn[0] == 0x0F && insn[1] == 0xD7) {
@@ -9910,14 +9910,10 @@
if (epartIsReg(modrm)) {
do_MMX_preamble();
t0 = newTemp(Ity_I64);
- t1 = newTemp(Ity_I64);
+ t1 = newTemp(Ity_I32);
assign(t0, getMMXReg(eregLO3ofRM(modrm)));
- assign(t1, mkIRExprCCall(
- Ity_I64, 0/*regparms*/,
- "amd64g_calculate_mmx_pmovmskb",
- &amd64g_calculate_mmx_pmovmskb,
- mkIRExprVec_1(mkexpr(t0))));
- putIReg32(gregOfRexRM(pfx,modrm), unop(Iop_64to32,mkexpr(t1)));
+ assign(t1, unop(Iop_8Uto32, unop(Iop_GetMSBs8x8, mkexpr(t0))));
+ putIReg32(gregOfRexRM(pfx,modrm), mkexpr(t1));
DIP("pmovmskb %s,%s\n", nameMMXReg(eregLO3ofRM(modrm)),
nameIReg32(gregOfRexRM(pfx,modrm)));
delta += 3;
@@ -11829,13 +11825,13 @@
t1 = newTemp(Ity_I64);
assign(t0, getXMMRegLane64(eregOfRexRM(pfx,modrm), 0));
assign(t1, getXMMRegLane64(eregOfRexRM(pfx,modrm), 1));
- t5 = newTemp(Ity_I64);
- assign(t5, mkIRExprCCall(
- Ity_I64, 0/*regparms*/,
- "amd64g_calculate_sse_pmovmskb",
- &amd64g_calculate_sse_pmovmskb,
- mkIRExprVec_2( mkexpr(t1), mkexpr(t0) )));
- putIReg32(gregOfRexRM(pfx,modrm), unop(Iop_64to32,mkexpr(t5)));
+ t5 = newTemp(Ity_I32);
+ assign(t5,
+ unop(Iop_16Uto32,
+ binop(Iop_8HLto16,
+ unop(Iop_GetMSBs8x8, mkexpr(t1)),
+ unop(Iop_GetMSBs8x8, mkexpr(t0)))));
+ putIReg32(gregOfRexRM(pfx,modrm), mkexpr(t5));
DIP("pmovmskb %s,%s\n", nameXMMReg(eregOfRexRM(pfx,modrm)),
nameIReg32(gregOfRexRM(pfx,modrm)));
delta += 3;
Modified: branches/ICC111/priv/guest_x86_defs.h
===================================================================
--- branches/ICC111/priv/guest_x86_defs.h 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/guest_x86_defs.h 2009-09-18 16:56:27 UTC (rev 1922)
@@ -137,8 +137,6 @@
extern ULong x86g_calculate_mmx_pmaddwd ( ULong, ULong );
extern ULong x86g_calculate_mmx_psadbw ( ULong, ULong );
-extern UInt x86g_calculate_mmx_pmovmskb ( ULong );
-extern UInt x86g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo );
/* --- DIRTY HELPERS --- */
Modified: branches/ICC111/priv/guest_x86_helpers.c
===================================================================
--- branches/ICC111/priv/guest_x86_helpers.c 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/guest_x86_helpers.c 2009-09-18 16:56:27 UTC (rev 1922)
@@ -2424,21 +2424,6 @@
}
/* CALLED FROM GENERATED CODE: CLEAN HELPER */
-UInt x86g_calculate_mmx_pmovmskb ( ULong xx )
-{
- UInt r = 0;
- if (xx & (1ULL << (64-1))) r |= (1<<7);
- if (xx & (1ULL << (56-1))) r |= (1<<6);
- if (xx & (1ULL << (48-1))) r |= (1<<5);
- if (xx & (1ULL << (40-1))) r |= (1<<4);
- if (xx & (1ULL << (32-1))) r |= (1<<3);
- if (xx & (1ULL << (24-1))) r |= (1<<2);
- if (xx & (1ULL << (16-1))) r |= (1<<1);
- if (xx & (1ULL << ( 8-1))) r |= (1<<0);
- return r;
-}
-
-/* CALLED FROM GENERATED CODE: CLEAN HELPER */
ULong x86g_calculate_mmx_psadbw ( ULong xx, ULong yy )
{
UInt t = 0;
@@ -2454,15 +2439,7 @@
return (ULong)t;
}
-/* CALLED FROM GENERATED CODE: CLEAN HELPER */
-UInt x86g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo )
-{
- UInt rHi8 = x86g_calculate_mmx_pmovmskb ( w64hi );
- UInt rLo8 = x86g_calculate_mmx_pmovmskb ( w64lo );
- return ((rHi8 & 0xFF) << 8) | (rLo8 & 0xFF);
-}
-
/*---------------------------------------------------------------*/
/*--- Helpers for dealing with segment overrides. ---*/
/*---------------------------------------------------------------*/
Modified: branches/ICC111/priv/guest_x86_toIR.c
===================================================================
--- branches/ICC111/priv/guest_x86_toIR.c 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/guest_x86_toIR.c 2009-09-18 16:56:27 UTC (rev 1922)
@@ -723,6 +723,7 @@
|| op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
|| op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8
|| op8 == Iop_CasCmpNE8
+ || op8 == Iop_ExpCmpNE8
|| op8 == Iop_Not8);
adj = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);
return adj + op8;
@@ -6308,10 +6309,14 @@
( isReg ? nameIReg(sz, eregOfRM(modrm)) : dis_buf ),
nameIReg(sz, gregOfRM(modrm)));
- /* Generate an 8-bit expression which is zero iff the
- original is zero, and nonzero otherwise */
+ /* Generate an 8-bit expression which is zero iff the original is
+ zero, and nonzero otherwise. Ask for an ExpCmpNE version which,
+ if instrumented by Memcheck, is instrumented expensively, since
+ this may be used on the output of a preceding movmskb insn,
+ which has been known to be partially defined, and in need of
+ careful handling. */
assign( src8,
- unop(Iop_1Uto8, binop(mkSizedOp(ty,Iop_CmpNE8),
+ unop(Iop_1Uto8, binop(mkSizedOp(ty,Iop_ExpCmpNE8),
mkexpr(src), mkU(ty,0))) );
/* Flags: Z is 1 iff source value is zero. All others
@@ -8883,7 +8888,7 @@
/* ***--- this is an MMX class insn introduced in SSE1 ---*** */
/* 0F D7 = PMOVMSKB -- extract sign bits from each of 8 lanes in
- mmx(G), turn them into a byte, and put zero-extend of it in
+ mmx(E), turn them into a byte, and put zero-extend of it in
ireg(G). */
if (sz == 4 && insn[0] == 0x0F && insn[1] == 0xD7) {
modrm = insn[2];
@@ -8892,11 +8897,7 @@
t0 = newTemp(Ity_I64);
t1 = newTemp(Ity_I32);
assign(t0, getMMXReg(eregOfRM(modrm)));
- assign(t1, mkIRExprCCall(
- Ity_I32, 0/*regparms*/,
- "x86g_calculate_mmx_pmovmskb",
- &x86g_calculate_mmx_pmovmskb,
- mkIRExprVec_1(mkexpr(t0))));
+ assign(t1, unop(Iop_8Uto32, unop(Iop_GetMSBs8x8, mkexpr(t0))));
putIReg(4, gregOfRM(modrm), mkexpr(t1));
DIP("pmovmskb %s,%s\n", nameMMXReg(eregOfRM(modrm)),
nameIReg(4,gregOfRM(modrm)));
@@ -10720,11 +10721,9 @@
goto decode_success;
}
- /* 66 0F D7 = PMOVMSKB -- extract sign bits from each of 16 lanes in
- xmm(G), turn them into a byte, and put zero-extend of it in
- ireg(G). Doing this directly is just too cumbersome; give up
- therefore and call a helper. */
- /* UInt x86g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo ); */
+ /* 66 0F D7 = PMOVMSKB -- extract sign bits from each of 16 lanes
+ in xmm(E), turn them into a byte, and put zero-extend of it in
+ ireg(G). */
if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xD7) {
modrm = insn[2];
if (epartIsReg(modrm)) {
@@ -10733,11 +10732,11 @@
assign(t0, getXMMRegLane64(eregOfRM(modrm), 0));
assign(t1, getXMMRegLane64(eregOfRM(modrm), 1));
t5 = newTemp(Ity_I32);
- assign(t5, mkIRExprCCall(
- Ity_I32, 0/*regparms*/,
- "x86g_calculate_sse_pmovmskb",
- &x86g_calculate_sse_pmovmskb,
- mkIRExprVec_2( mkexpr(t1), mkexpr(t0) )));
+ assign(t5,
+ unop(Iop_16Uto32,
+ binop(Iop_8HLto16,
+ unop(Iop_GetMSBs8x8, mkexpr(t1)),
+ unop(Iop_GetMSBs8x8, mkexpr(t0)))));
putIReg(4, gregOfRM(modrm), mkexpr(t5));
DIP("pmovmskb %s,%s\n", nameXMMReg(eregOfRM(modrm)),
nameIReg(4,gregOfRM(modrm)));
Modified: branches/ICC111/priv/host_amd64_isel.c
===================================================================
--- branches/ICC111/priv/host_amd64_isel.c 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/host_amd64_isel.c 2009-09-18 16:56:27 UTC (rev 1922)
@@ -815,7 +815,7 @@
This should handle expressions of 64, 32, 16 and 8-bit type. All
results are returned in a 64-bit register. For 32-, 16- and 8-bit
- expressions, the upper 32/16/24 bits are arbitrary, so you should
+ expressions, the upper 32/48/56 bits are arbitrary, so you should
mask or sign extend partial values if necessary.
*/
@@ -1632,6 +1632,20 @@
/* These are no-ops. */
return iselIntExpr_R(env, e->Iex.Unop.arg);
+ case Iop_GetMSBs8x8: {
+ /* Note: the following assumes the helper is of
+ signature
+ UInt fn ( ULong ), and is not a regparm fn.
+ */
+ HReg dst = newVRegI(env);
+ HReg arg = iselIntExpr_R(env, e->Iex.Unop.arg);
+ fn = (HWord)h_generic_calc_GetMSBs8x8;
+ addInstr(env, mk_iMOVsd_RR(arg, hregAMD64_RDI()) );
+ addInstr(env, AMD64Instr_Call( Acc_ALWAYS, (ULong)fn, 1 ));
+ addInstr(env, AMD64Instr_MovZLQ(hregAMD64_RAX(), dst));
+ return dst;
+ }
+
default:
break;
}
Modified: branches/ICC111/priv/host_generic_simd64.c
===================================================================
--- branches/ICC111/priv/host_generic_simd64.c 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/host_generic_simd64.c 2009-09-18 16:56:27 UTC (rev 1922)
@@ -1041,6 +1041,19 @@
);
}
+UInt h_generic_calc_GetMSBs8x8 ( ULong xx )
+{
+ UInt r = 0;
+ if (xx & (1ULL << (64-1))) r |= (1<<7);
+ if (xx & (1ULL << (56-1))) r |= (1<<6);
+ if (xx & (1ULL << (48-1))) r |= (1<<5);
+ if (xx & (1ULL << (40-1))) r |= (1<<4);
+ if (xx & (1ULL << (32-1))) r |= (1<<3);
+ if (xx & (1ULL << (24-1))) r |= (1<<2);
+ if (xx & (1ULL << (16-1))) r |= (1<<1);
+ if (xx & (1ULL << ( 8-1))) r |= (1<<0);
+ return r;
+}
/*---------------------------------------------------------------*/
/*--- end host_generic_simd64.c ---*/
Modified: branches/ICC111/priv/host_generic_simd64.h
===================================================================
--- branches/ICC111/priv/host_generic_simd64.h 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/host_generic_simd64.h 2009-09-18 16:56:27 UTC (rev 1922)
@@ -132,6 +132,7 @@
extern ULong h_generic_calc_Min16Sx4 ( ULong, ULong );
extern ULong h_generic_calc_Min8Ux8 ( ULong, ULong );
+extern UInt h_generic_calc_GetMSBs8x8 ( ULong );
#endif /* ndef __VEX_HOST_GENERIC_SIMD64_H */
Modified: branches/ICC111/priv/host_x86_isel.c
===================================================================
--- branches/ICC111/priv/host_x86_isel.c 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/host_x86_isel.c 2009-09-18 16:56:27 UTC (rev 1922)
@@ -1286,6 +1286,23 @@
/* These are no-ops. */
return iselIntExpr_R(env, e->Iex.Unop.arg);
+ case Iop_GetMSBs8x8: {
+ /* Note: the following assumes the helper is of
+ signature
+ UInt fn ( ULong ), and is not a regparm fn.
+ */
+ HReg xLo, xHi;
+ HReg dst = newVRegI(env);
+ HWord fn = (HWord)h_generic_calc_GetMSBs8x8;
+ iselInt64Expr(&xHi, &xLo, env, e->Iex.Unop.arg);
+ addInstr(env, X86Instr_Push(X86RMI_Reg(xHi)));
+ addInstr(env, X86Instr_Push(X86RMI_Reg(xLo)));
+ addInstr(env, X86Instr_Call( Xcc_ALWAYS, (UInt)fn, 0 ));
+ add_to_esp(env, 2*4);
+ addInstr(env, mk_iMOVsd_RR(hregX86_EAX(), dst));
+ return dst;
+ }
+
default:
break;
}
@@ -1833,7 +1850,8 @@
&& (e->Iex.Binop.op == Iop_CmpEQ16
|| e->Iex.Binop.op == Iop_CmpNE16
|| e->Iex.Binop.op == Iop_CasCmpEQ16
- || e->Iex.Binop.op == Iop_CasCmpNE16)) {
+ || e->Iex.Binop.op == Iop_CasCmpNE16
+ || e->Iex.Binop.op == Iop_ExpCmpNE16)) {
HReg r1 = iselIntExpr_R(env, e->Iex.Binop.arg1);
X86RMI* rmi2 = iselIntExpr_RMI(env, e->Iex.Binop.arg2);
HReg r = newVRegI(env);
@@ -1842,7 +1860,8 @@
addInstr(env, X86Instr_Test32(0xFFFF,X86RM_Reg(r)));
switch (e->Iex.Binop.op) {
case Iop_CmpEQ16: case Iop_CasCmpEQ16: return Xcc_Z;
- case Iop_CmpNE16: case Iop_CasCmpNE16: return Xcc_NZ;
+ case Iop_CmpNE16:
+ case Iop_CasCmpNE16: case Iop_ExpCmpNE16: return Xcc_NZ;
default: vpanic("iselCondCode(x86): CmpXX16");
}
}
@@ -1856,13 +1875,15 @@
|| e->Iex.Binop.op == Iop_CmpLE32S
|| e->Iex.Binop.op == Iop_CmpLE32U
|| e->Iex.Binop.op == Iop_CasCmpEQ32
- || e->Iex.Binop.op == Iop_CasCmpNE32)) {
+ || e->Iex.Binop.op == Iop_CasCmpNE32
+ || e->Iex.Binop.op == Iop_ExpCmpNE32)) {
HReg r1 = iselIntExpr_R(env, e->Iex.Binop.arg1);
X86RMI* rmi2 = iselIntExpr_RMI(env, e->Iex.Binop.arg2);
addInstr(env, X86Instr_Alu32R(Xalu_CMP,rmi2,r1));
switch (e->Iex.Binop.op) {
case Iop_CmpEQ32: case Iop_CasCmpEQ32: return Xcc_Z;
- case Iop_CmpNE32: case Iop_CasCmpNE32: return Xcc_NZ;
+ case Iop_CmpNE32:
+ case Iop_CasCmpNE32: case Iop_ExpCmpNE32: return Xcc_NZ;
case Iop_CmpLT32S: return Xcc_L;
case Iop_CmpLT32U: return Xcc_B;
case Iop_CmpLE32S: return Xcc_LE;
Modified: branches/ICC111/priv/ir_defs.c
===================================================================
--- branches/ICC111/priv/ir_defs.c 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/ir_defs.c 2009-09-18 16:56:27 UTC (rev 1922)
@@ -148,6 +148,8 @@
str = "CasCmpEQ"; base = Iop_CasCmpEQ8; break;
case Iop_CasCmpNE8 ... Iop_CasCmpNE64:
str = "CasCmpNE"; base = Iop_CasCmpNE8; break;
+ case Iop_ExpCmpNE8 ... Iop_ExpCmpNE64:
+ str = "ExpCmpNE"; base = Iop_ExpCmpNE8; break;
case Iop_Not8 ... Iop_Not64:
str = "Not"; base = Iop_Not8; break;
/* other cases must explicitly "return;" */
@@ -371,6 +373,7 @@
case Iop_CatOddLanes16x4: vex_printf("CatOddLanes16x4"); return;
case Iop_CatEvenLanes16x4: vex_printf("CatEvenLanes16x4"); return;
case Iop_Perm8x8: vex_printf("Perm8x8"); return;
+ case Iop_GetMSBs8x8: vex_printf("GetMSBs8x8"); return;
case Iop_CmpNEZ32x2: vex_printf("CmpNEZ32x2"); return;
case Iop_CmpNEZ16x4: vex_printf("CmpNEZ16x4"); return;
@@ -1647,18 +1650,18 @@
UNARY(Ity_I64, Ity_I64);
case Iop_CmpEQ8: case Iop_CmpNE8:
- case Iop_CasCmpEQ8: case Iop_CasCmpNE8:
+ case Iop_CasCmpEQ8: case Iop_CasCmpNE8: case Iop_ExpCmpNE8:
COMPARISON(Ity_I8);
case Iop_CmpEQ16: case Iop_CmpNE16:
- case Iop_CasCmpEQ16: case Iop_CasCmpNE16:
+ case Iop_CasCmpEQ16: case Iop_CasCmpNE16: case Iop_ExpCmpNE16:
COMPARISON(Ity_I16);
case Iop_CmpEQ32: case Iop_CmpNE32:
- case Iop_CasCmpEQ32: case Iop_CasCmpNE32:
+ case Iop_CasCmpEQ32: case Iop_CasCmpNE32: case Iop_ExpCmpNE32:
case Iop_CmpLT32S: case Iop_CmpLE32S:
case Iop_CmpLT32U: case Iop_CmpLE32U:
COMPARISON(Ity_I32);
case Iop_CmpEQ64: case Iop_CmpNE64:
- case Iop_CasCmpEQ64: case Iop_CasCmpNE64:
+ case Iop_CasCmpEQ64: case Iop_CasCmpNE64: case Iop_ExpCmpNE64:
case Iop_CmpLT64S: case Iop_CmpLE64S:
case Iop_CmpLT64U: case Iop_CmpLE64U:
COMPARISON(Ity_I64);
@@ -1672,6 +1675,7 @@
case Iop_Left16: UNARY(Ity_I16,Ity_I16);
case Iop_CmpwNEZ32: case Iop_Left32: UNARY(Ity_I32,Ity_I32);
case Iop_CmpwNEZ64: case Iop_Left64: UNARY(Ity_I64,Ity_I64);
+ case Iop_GetMSBs8x8: UNARY(Ity_I64, Ity_I8);
case Iop_MullU8: case Iop_MullS8:
BINARY(Ity_I8,Ity_I8, Ity_I16);
Modified: branches/ICC111/priv/ir_opt.c
===================================================================
--- branches/ICC111/priv/ir_opt.c 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/priv/ir_opt.c 2009-09-18 16:56:27 UTC (rev 1922)
@@ -1336,16 +1336,22 @@
/* -- CmpNE -- */
case Iop_CmpNE8:
+ case Iop_CasCmpNE8:
+ case Iop_ExpCmpNE8:
e2 = IRExpr_Const(IRConst_U1(toBool(
((0xFF & e->Iex.Binop.arg1->Iex.Const.con->Ico.U8)
!= (0xFF & e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))));
break;
case Iop_CmpNE32:
+ case Iop_CasCmpNE32:
+ case Iop_ExpCmpNE32:
e2 = IRExpr_Const(IRConst_U1(toBool(
(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32
!= e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))));
break;
case Iop_CmpNE64:
+ case Iop_CasCmpNE64:
+ case Iop_ExpCmpNE64:
e2 = IRExpr_Const(IRConst_U1(toBool(
(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64
!= e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))));
Modified: branches/ICC111/pub/libvex_ir.h
===================================================================
--- branches/ICC111/pub/libvex_ir.h 2009-09-18 14:52:41 UTC (rev 1921)
+++ branches/ICC111/pub/libvex_ir.h 2009-09-18 16:56:27 UTC (rev 1922)
@@ -431,6 +431,10 @@
Iop_CasCmpEQ8, Iop_CasCmpEQ16, Iop_CasCmpEQ32, Iop_CasCmpEQ64,
Iop_CasCmpNE8, Iop_CasCmpNE16, Iop_CasCmpNE32, Iop_CasCmpNE64,
+ /* Exactly like CmpNE8/16/32/64, but carrying the additional
+ hint that these needs expensive definedness tracking. */
+ Iop_ExpCmpNE8, Iop_ExpCmpNE16, Iop_ExpCmpNE32, Iop_ExpCmpNE64,
+
/* -- Ordering not important after here. -- */
/* Widening multiplies */
@@ -718,6 +722,10 @@
is undefined. */
Iop_Perm8x8,
+ /* MISC CONVERSION -- get high bits of each byte lane, a la
+ x86/amd64 pmovmskb */
+ Iop_GetMSBs8x8, /* I64 -> I8 */
+
/* ------------------ 128-bit SIMD FP. ------------------ */
/* --- 32x4 vector FP --- */
|