From f53f9d1f2969606e2d06df5cba1e444618e5c1a4 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Sat, 22 Oct 2005 12:49:49 +0000 Subject: [PATCH] Fill in a few missing Altivec cases: - rename Iop_Perm to Iop_Perm8x16 - backend: handle Iop_CmpNEZ8x16 - frontend: for vperm, mask off all irrelevant parts of the steering values git-svn-id: svn://svn.valgrind.org/vex/trunk@1424 --- VEX/priv/guest-ppc32/toIR.c | 18 ++++++++++++------ VEX/priv/host-ppc32/hdefs.c | 14 +++++++++++--- VEX/priv/host-ppc32/isel.c | 12 ++++++++++-- VEX/priv/ir/irdefs.c | 4 ++-- VEX/pub/libvex_ir.h | 7 +++++-- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/VEX/priv/guest-ppc32/toIR.c b/VEX/priv/guest-ppc32/toIR.c index 0732193bb9..66cb952813 100644 --- a/VEX/priv/guest-ppc32/toIR.c +++ b/VEX/priv/guest-ppc32/toIR.c @@ -5977,12 +5977,18 @@ static Bool dis_av_permute ( UInt theInstr ) case 0x2B: { // vperm (Permute, AV p218) /* limited to two args for IR, so have to play games... */ - IRTemp a_perm = newTemp(Ity_V128); - IRTemp b_perm = newTemp(Ity_V128); - IRTemp mask = newTemp(Ity_V128); - DIP("vperma v%d,v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr, vC_addr); - assign( a_perm, binop(Iop_Perm, mkexpr(vA), mkexpr(vC)) ); - assign( b_perm, binop(Iop_Perm, mkexpr(vB), mkexpr(vC)) ); + IRTemp a_perm = newTemp(Ity_V128); + IRTemp b_perm = newTemp(Ity_V128); + IRTemp mask = newTemp(Ity_V128); + IRTemp vC_andF = newTemp(Ity_V128); + DIP("vperm v%d,v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr, vC_addr); + /* Limit the Perm8x16 steering values to 0 .. 15 as that is what + IR specifies, and also to hide irrelevant bits from + memcheck */ + assign( vC_andF, binop(Iop_AndV128, mkexpr(vC), + unop(Iop_Dup8x16, mkU8(0xF))) ); + assign( a_perm, binop(Iop_Perm8x16, mkexpr(vA), mkexpr(vC_andF)) ); + assign( b_perm, binop(Iop_Perm8x16, mkexpr(vB), mkexpr(vC_andF)) ); // mask[i8] = (vC[i8]_4 == 1) ? 0xFF : 0x0 assign( mask, binop(Iop_SarN8x16, binop(Iop_ShlN8x16, mkexpr(vC), mkU8(3)), diff --git a/VEX/priv/host-ppc32/hdefs.c b/VEX/priv/host-ppc32/hdefs.c index 4d6815eac0..54c7bf248b 100644 --- a/VEX/priv/host-ppc32/hdefs.c +++ b/VEX/priv/host-ppc32/hdefs.c @@ -1608,9 +1608,17 @@ void getRegUsage_PPC32Instr ( HRegUsage* u, PPC32Instr* i ) addHRegUse(u, HRmRead, i->Pin.AvUnary.src); return; case Pin_AvBinary: - addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst); - addHRegUse(u, HRmRead, i->Pin.AvBinary.srcL); - addHRegUse(u, HRmRead, i->Pin.AvBinary.srcR); + if (i->Pin.AvBinary.op == Pav_XOR + && i->Pin.AvBinary.dst == i->Pin.AvBinary.srcL + && i->Pin.AvBinary.dst == i->Pin.AvBinary.srcR) { + /* reg-alloc needs to understand 'xor r,r,r' as a write of r */ + /* (as opposed to a rite of passage :-) */ + addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst); + } else { + addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst); + addHRegUse(u, HRmRead, i->Pin.AvBinary.srcL); + addHRegUse(u, HRmRead, i->Pin.AvBinary.srcR); + } return; case Pin_AvBin8x16: addHRegUse(u, HRmWrite, i->Pin.AvBin8x16.dst); diff --git a/VEX/priv/host-ppc32/isel.c b/VEX/priv/host-ppc32/isel.c index 974d64518f..137e3a7aee 100644 --- a/VEX/priv/host-ppc32/isel.c +++ b/VEX/priv/host-ppc32/isel.c @@ -2999,7 +2999,15 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) //.. return dst; //.. } //.. -//.. case Iop_CmpNEZ8x16: + case Iop_CmpNEZ8x16: { + HReg arg = iselVecExpr(env, e->Iex.Unop.arg); + HReg zero = newVRegV(env); + HReg dst = newVRegV(env); + addInstr(env, PPC32Instr_AvBinary(Pav_XOR, zero, zero, zero)); + addInstr(env, PPC32Instr_AvBin8x16(Pav_CMPEQU, dst, arg, zero)); + addInstr(env, PPC32Instr_AvUnary(Pav_NOT, dst, dst)); + return dst; + } //.. case Iop_CmpNEZ16x8: { //.. /* We can use SSE2 instructions for this. */ //.. HReg arg; @@ -3433,7 +3441,7 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) return dst; } - case Iop_Perm: { + case Iop_Perm8x16: { HReg dst = newVRegV(env); HReg v_src = iselVecExpr(env, e->Iex.Binop.arg1); HReg v_ctl = iselVecExpr(env, e->Iex.Binop.arg2); diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index 885dd519ce..1dcdd1cbcb 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -519,7 +519,7 @@ void ppIROp ( IROp op ) case Iop_InterleaveLO32x4: vex_printf("InterleaveLO32x4"); return; case Iop_InterleaveLO64x2: vex_printf("InterleaveLO64x2"); return; - case Iop_Perm: vex_printf("Perm"); return; + case Iop_Perm8x16: vex_printf("Perm8x16"); return; default: vpanic("ppIROp(1)"); } @@ -1574,7 +1574,7 @@ void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 ) case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2: case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8: case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2: - case Iop_Perm: + case Iop_Perm8x16: BINARY(Ity_V128, Ity_V128,Ity_V128); case Iop_NotV128: diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 03de4321b2..b0d2de4398 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -597,8 +597,11 @@ typedef Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4, /* PERMUTING -- copy src bytes to dst, - as indexed by control vector bytes: dst[i] = src[ ctl[i] ] */ - Iop_Perm + as indexed by control vector bytes: + for i in 0 .. 15 . result[i] = argL[ argR[i] ] + argR[i] values may only be in the range 0 .. 15, else behaviour + is undefined. */ + Iop_Perm8x16 } IROp; -- 2.47.3