From: Julian Seward Date: Thu, 13 Jan 2005 19:16:04 +0000 (+0000) Subject: Add new IR primops: Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2 and X-Git-Tag: svn/VALGRIND_3_0_1^2~619 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=715ca1b7599ab5ebe02c778cd285f49a2fd37b8e;p=thirdparty%2Fvalgrind.git Add new IR primops: Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2 and isel support for them in the x86 back end. They are used for Memcheck annotation of 64-bit SIMD code. git-svn-id: svn://svn.valgrind.org/vex/trunk@715 --- diff --git a/VEX/priv/host-generic/h_generic_simd64.c b/VEX/priv/host-generic/h_generic_simd64.c index 4972e1358a..5255fc1cac 100644 --- a/VEX/priv/host-generic/h_generic_simd64.c +++ b/VEX/priv/host-generic/h_generic_simd64.c @@ -246,6 +246,21 @@ static inline UChar cmpgt8S ( Char xx, Char yy ) return xx>yy ? 0xFF : 0; } +static inline UInt cmpnez32 ( UInt xx ) +{ + return xx==0 ? 0 : 0xFFFFFFFF; +} + +static inline UShort cmpnez16 ( UShort xx ) +{ + return xx==0 ? 0 : 0xFFFF; +} + +static inline UChar cmpnez8 ( UChar xx ) +{ + return xx==0 ? 0 : 0xFF; +} + static inline Short qnarrow32Sto16 ( UInt xx0 ) { Int xx = (Int)xx0; @@ -615,6 +630,38 @@ ULong h_generic_calc_CmpGT8Sx8 ( ULong xx, ULong yy ) ); } +ULong h_generic_calc_CmpNEZ32x2 ( ULong xx ) +{ + return mk32x2( + cmpnez32( sel32x2_1(xx) ), + cmpnez32( sel32x2_0(xx) ) + ); +} + +ULong h_generic_calc_CmpNEZ16x4 ( ULong xx ) +{ + return mk16x4( + cmpnez16( sel16x4_3(xx) ), + cmpnez16( sel16x4_2(xx) ), + cmpnez16( sel16x4_1(xx) ), + cmpnez16( sel16x4_0(xx) ) + ); +} + +ULong h_generic_calc_CmpNEZ8x8 ( ULong xx ) +{ + return mk8x8( + cmpnez8( sel8x8_7(xx) ), + cmpnez8( sel8x8_6(xx) ), + cmpnez8( sel8x8_5(xx) ), + cmpnez8( sel8x8_4(xx) ), + cmpnez8( sel8x8_3(xx) ), + cmpnez8( sel8x8_2(xx) ), + cmpnez8( sel8x8_1(xx) ), + cmpnez8( sel8x8_0(xx) ) + ); +} + /* ------------ Saturating narrowing ------------ */ ULong h_generic_calc_QNarrow32Sx2 ( ULong aa, ULong bb ) diff --git a/VEX/priv/host-generic/h_generic_simd64.h b/VEX/priv/host-generic/h_generic_simd64.h index 6a9a6a13a9..8bbe6a0303 100644 --- a/VEX/priv/host-generic/h_generic_simd64.h +++ b/VEX/priv/host-generic/h_generic_simd64.h @@ -82,6 +82,10 @@ extern ULong h_generic_calc_CmpGT32Sx2 ( ULong, ULong ); extern ULong h_generic_calc_CmpGT16Sx4 ( ULong, ULong ); extern ULong h_generic_calc_CmpGT8Sx8 ( ULong, ULong ); +extern ULong h_generic_calc_CmpNEZ32x2 ( ULong ); +extern ULong h_generic_calc_CmpNEZ16x4 ( ULong ); +extern ULong h_generic_calc_CmpNEZ8x8 ( ULong ); + extern ULong h_generic_calc_QNarrow32Sx2 ( ULong, ULong ); extern ULong h_generic_calc_QNarrow16Sx4 ( ULong, ULong ); extern ULong h_generic_calc_QNarrow16Ux4 ( ULong, ULong ); diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index f5d4938ad7..c0a03c0a3c 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -2218,6 +2218,33 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) return; } + case Iop_CmpNEZ32x2: + fn = (HWord)h_generic_calc_CmpNEZ32x2; goto unish; + case Iop_CmpNEZ16x4: + fn = (HWord)h_generic_calc_CmpNEZ16x4; goto unish; + case Iop_CmpNEZ8x8: + fn = (HWord)h_generic_calc_CmpNEZ8x8; goto unish; + unish: { + /* Note: the following assumes all helpers are of + signature + ULong fn ( ULong ), and they are + not marked as regparm functions. + */ + HReg xLo, xHi; + HReg tLo = newVRegI(env); + HReg tHi = newVRegI(env); + 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_EDX(), tHi)); + addInstr(env, mk_iMOVsd_RR(hregX86_EAX(), tLo)); + *rHi = tHi; + *rLo = tLo; + return; + } + default: break; } diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index cf595d98a4..6fa5804af6 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -268,6 +268,10 @@ void ppIROp ( IROp op ) case Iop_InterleaveLO16x4: vex_printf("InterleaveLO16x4"); return; case Iop_InterleaveLO32x2: vex_printf("InterleaveLO32x2"); return; + case Iop_CmpNEZ32x2: vex_printf("CmpNEZ32x2"); return; + case Iop_CmpNEZ16x4: vex_printf("CmpNEZ16x4"); return; + case Iop_CmpNEZ8x8: vex_printf("CmpNEZ8x8"); return; + case Iop_Add32Fx4: vex_printf("Add32Fx4"); return; case Iop_Add32F0x4: vex_printf("Add32F0x4"); return; case Iop_Add64Fx2: vex_printf("Add64Fx2"); return; @@ -346,6 +350,7 @@ void ppIROp ( IROp op ) case Iop_And128: vex_printf("And128"); return; case Iop_Or128: vex_printf("Or128"); return; case Iop_Xor128: vex_printf("Xor128"); return; + case Iop_CmpNEZ8x16: vex_printf("CmpNEZ8x16"); return; case Iop_CmpNEZ16x8: vex_printf("CmpNEZ16x8"); return; case Iop_CmpNEZ32x4: vex_printf("CmpNEZ32x4"); return; @@ -1206,7 +1211,10 @@ void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 ) case Iop_Not8: UNARY(Ity_I8,Ity_I8); case Iop_Not16: UNARY(Ity_I16,Ity_I16); case Iop_Not32: UNARY(Ity_I32,Ity_I32); - case Iop_Not64: UNARY(Ity_I64,Ity_I64); + + case Iop_Not64: + case Iop_CmpNEZ32x2: case Iop_CmpNEZ16x4: case Iop_CmpNEZ8x8: + UNARY(Ity_I64,Ity_I64); case Iop_CmpEQ8: case Iop_CmpNE8: COMPARISON(Ity_I8); diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 799a0510f9..6e1497d82f 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -330,7 +330,7 @@ typedef /* ------------------ 64-bit SIMD Integer. ------------------ */ /* MISC (vector integer cmp != 0) */ - // Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2, + Iop_CmpNEZ8x8, Iop_CmpNEZ16x4, Iop_CmpNEZ32x2, /* ADDITION (normal / unsigned sat / signed sat) */ Iop_Add8x8, Iop_Add16x4, Iop_Add32x2,