From: Cerion Armour-Brown Date: Thu, 10 Feb 2005 19:51:03 +0000 (+0000) Subject: Added CLZ X-Git-Tag: svn/VALGRIND_3_0_1^2~451 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=53d36370cb1b7cb7db690fcef7cbd334b9d5ecd4;p=thirdparty%2Fvalgrind.git Added CLZ Fixed Unary32 Added genSpill_PPC32, genReload_PPC32 git-svn-id: svn://svn.valgrind.org/vex/trunk@883 --- diff --git a/VEX/priv/host-ppc32/hdefs.c b/VEX/priv/host-ppc32/hdefs.c index 643f25bac7..edca1ef613 100644 --- a/VEX/priv/host-ppc32/hdefs.c +++ b/VEX/priv/host-ppc32/hdefs.c @@ -385,6 +385,7 @@ HChar* showPPC32UnaryOp ( PPC32UnaryOp op ) { switch (op) { case Pun_NOT: return "not"; case Pun_NEG: return "neg"; + case Pun_CLZ: return "cntlzw"; default: vpanic("showPPC32UnaryOp"); } } @@ -464,11 +465,12 @@ PPC32Instr* PPC32Instr_Test32 ( HReg dst, PPC32RI* src ) { i->Pin.Test32.src = src; return i; } -PPC32Instr* PPC32Instr_Unary32 ( PPC32UnaryOp op, HReg dst ) { +PPC32Instr* PPC32Instr_Unary32 ( PPC32UnaryOp op, HReg dst, HReg src ) { PPC32Instr* i = LibVEX_Alloc(sizeof(PPC32Instr)); i->tag = Pin_Unary32; i->Pin.Unary32.op = op; i->Pin.Unary32.dst = dst; + i->Pin.Unary32.src = src; return i; } PPC32Instr* PPC32Instr_MulL ( Bool syned, Bool word, HReg dst, @@ -696,8 +698,10 @@ void ppPPC32Instr ( PPC32Instr* i ) ppPPC32RI(i->Pin.Test32.src); return; case Pin_Unary32: - vex_printf("%sl ", showPPC32UnaryOp(i->Pin.Unary32.op)); + vex_printf("%s ", showPPC32UnaryOp(i->Pin.Unary32.op)); ppHRegPPC32(i->Pin.Unary32.dst); + vex_printf(","); + ppHRegPPC32(i->Pin.Unary32.src); return; case Pin_MulL: if (i->Pin.MulL.src2->tag == Pri_Imm) { @@ -981,7 +985,8 @@ void getRegUsage_PPC32Instr ( HRegUsage* u, PPC32Instr* i ) addRegUsage_PPC32RI(u, i->Pin.Test32.src); return; case Pin_Unary32: - addHRegUse(u, HRmModify, i->Pin.Unary32.dst); + addHRegUse(u, HRmWrite, i->Pin.Unary32.dst); + addHRegUse(u, HRmRead, i->Pin.Unary32.src); return; case Pin_MulL: addHRegUse(u, HRmWrite, i->Pin.MulL.dst); @@ -1209,6 +1214,7 @@ void mapRegs_PPC32Instr (HRegRemap* m, PPC32Instr* i) return; case Pin_Unary32: mapReg(m, &i->Pin.Unary32.dst); + mapReg(m, &i->Pin.Unary32.src); return; case Pin_MulL: mapReg(m, &i->Pin.MulL.dst); @@ -1366,47 +1372,48 @@ Bool isMove_PPC32Instr ( PPC32Instr* i, HReg* src, HReg* dst ) } -/* Generate x86 spill/reload instructions under the direction of the +/* Generate ppc32 spill/reload instructions under the direction of the register allocator. Note it's critical these don't write the condition codes. */ PPC32Instr* genSpill_PPC32 ( HReg rreg, Int offsetB ) -{ vassert(0); -//.. X86AMode* am; -//.. vassert(offsetB >= 0); -//.. vassert(!hregIsVirtual(rreg)); -//.. am = X86AMode_IR(offsetB, hregX86_EBP()); -//.. -//.. switch (hregClass(rreg)) { -//.. case HRcInt32: -//.. return X86Instr_Alu32M ( Xalu_MOV, X86RI_Reg(rreg), am ); -//.. case HRcFlt64: -//.. return X86Instr_FpLdSt ( False/*store*/, 8, rreg, am ); -//.. case HRcVec128: -//.. return X86Instr_SseLdSt ( False/*store*/, rreg, am ); -//.. default: -//.. ppHRegClass(hregClass(rreg)); -//.. vpanic("genSpill_X86: unimplemented regclass"); -//.. } +{ + PPC32AMode* am; + vassert(offsetB >= 0); + vassert(!hregIsVirtual(rreg)); + am = PPC32AMode_IR(offsetB, GuestStatePtr); + + switch (hregClass(rreg)) { + case HRcInt32: + return PPC32Instr_Store( 4, am, rreg); + //case HRcFlt64: + // return PPC32Instr_FpLdSt ( False/*store*/, 8, rreg, am ); + //case HRcVec128: + // return PPC32Instr_SseLdSt ( False/*store*/, rreg, am ); + default: + ppHRegClass(hregClass(rreg)); + vpanic("genSpill_PPC32: unimplemented regclass"); + } } PPC32Instr* genReload_PPC32 ( HReg rreg, Int offsetB ) -{ vassert(0); -//.. X86AMode* am; -//.. vassert(offsetB >= 0); -//.. vassert(!hregIsVirtual(rreg)); -//.. am = X86AMode_IR(offsetB, hregX86_EBP()); -//.. switch (hregClass(rreg)) { -//.. case HRcInt32: -//.. return X86Instr_Alu32R ( Xalu_MOV, X86RMI_Mem(am), rreg ); -//.. case HRcFlt64: -//.. return X86Instr_FpLdSt ( True/*load*/, 8, rreg, am ); -//.. case HRcVec128: -//.. return X86Instr_SseLdSt ( True/*load*/, rreg, am ); -//.. default: -//.. ppHRegClass(hregClass(rreg)); -//.. vpanic("genReload_X86: unimplemented regclass"); -//.. } +{ + PPC32AMode* am; + vassert(offsetB >= 0); + vassert(!hregIsVirtual(rreg)); + am = PPC32AMode_IR(offsetB, GuestStatePtr); + + switch (hregClass(rreg)) { + case HRcInt32: + return PPC32Instr_LoadEX( 4, False, rreg, am ); + //case HRcFlt64: + // return PPC32Instr_FpLdSt ( True/*load*/, 8, rreg, am ); + //case HRcVec128: + // return PPC32Instr_SseLdSt ( True/*load*/, rreg, am ); + default: + ppHRegClass(hregClass(rreg)); + vpanic("genReload_PPC32: unimplemented regclass"); + } } diff --git a/VEX/priv/host-ppc32/hdefs.h b/VEX/priv/host-ppc32/hdefs.h index 918ec7e669..9d6bfd15b2 100644 --- a/VEX/priv/host-ppc32/hdefs.h +++ b/VEX/priv/host-ppc32/hdefs.h @@ -234,7 +234,8 @@ extern void ppPPC32RI ( PPC32RI* ); typedef enum { Pun_NEG, - Pun_NOT + Pun_NOT, + Pun_CLZ } PPC32UnaryOp; @@ -342,6 +343,7 @@ typedef struct { PPC32UnaryOp op; HReg dst; + HReg src; } Unary32; /* DX:AX = AX *s/u r/m16, or EDX:EAX = EAX *s/u r/m32 */ struct { @@ -493,7 +495,7 @@ typedef extern PPC32Instr* PPC32Instr_Alu32 ( PPC32AluOp, HReg, HReg, PPC32RI* ); extern PPC32Instr* PPC32Instr_Sh32 ( PPC32ShiftOp, HReg, HReg, PPC32RI* ); extern PPC32Instr* PPC32Instr_Test32 ( HReg dst, PPC32RI* src ); -extern PPC32Instr* PPC32Instr_Unary32 ( PPC32UnaryOp op, HReg dst ); +extern PPC32Instr* PPC32Instr_Unary32 ( PPC32UnaryOp op, HReg dst, HReg src ); extern PPC32Instr* PPC32Instr_MulL ( Bool syned, Bool word, HReg, HReg, PPC32RI* ); //.. extern X86Instr* X86Instr_Div ( Bool syned, X86ScalarSz, X86RM* ); //.. extern X86Instr* X86Instr_Sh3232 ( X86ShiftOp, UInt amt, HReg src, HReg dst ); diff --git a/VEX/priv/host-ppc32/isel.c b/VEX/priv/host-ppc32/isel.c index b2dfbf7334..71406b2c4d 100644 --- a/VEX/priv/host-ppc32/isel.c +++ b/VEX/priv/host-ppc32/isel.c @@ -1046,8 +1046,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) case Iop_Not32: { HReg dst = newVRegI(env); HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); - addInstr(env, mk_iMOVds_RR(dst,src) ); - addInstr(env, PPC32Instr_Unary32(Pun_NOT,dst)); + addInstr(env, PPC32Instr_Unary32(Pun_NOT,dst,src)); return dst; } case Iop_64HIto32: { @@ -1056,8 +1055,9 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) return rHi; /* and abandon rLo .. poor wee thing :-) */ } case Iop_64to32: { + #if 1 -// CAB: This right? +// CAB: This right? Need to figure out sign issues... /* 64to32(MullS32(expr,expr)) */ { DECLARE_PATTERN(p_MullS32_then_64to32); @@ -1072,11 +1072,29 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) return dst; } } -#else +#endif + +#if 0 +// CAB: This right? Need to figure out sign issues... + /* 64to32(MullU32(expr,expr)) */ + { + DECLARE_PATTERN(p_MullU32_then_64to32); + DEFINE_PATTERN(p_MullU32_then_64to32, + unop(Iop_64to32, + binop(Iop_MullU32, bind(0), bind(1)))); + if (matchIRExpr(&mi,p_MullU32_then_64to32,e)) { + HReg dst = newVRegI(env); + HReg src1 = iselIntExpr_R( env, mi.bindee[0] ); + PPC32RI* src2 = iselIntExpr_RI( env, mi.bindee[1] ); + addInstr(env, PPC32Instr_Alu32(Palu_MUL, dst, src1, src2)); + return dst; + } + } +#endif + HReg rHi, rLo; iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg); return rLo; /* similar stupid comment to the above ... */ -#endif } case Iop_16HIto8: case Iop_32HIto16: { @@ -1112,20 +1130,13 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) //.. addInstr(env, X86Instr_Bsfr32(True,src,dst)); //.. return dst; //.. } -//.. case Iop_Clz32: { -//.. /* Count leading zeroes. Do 'bsrl' to establish the index -//.. of the highest set bit, and subtract that value from -//.. 31. */ -//.. HReg tmp = newVRegI(env); -//.. HReg dst = newVRegI(env); -//.. HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); -//.. addInstr(env, X86Instr_Bsfr32(False,src,tmp)); -//.. addInstr(env, X86Instr_Alu32R(Xalu_MOV, -//.. X86RMI_Imm(31), dst)); -//.. addInstr(env, X86Instr_Alu32R(Xalu_SUB, -//.. X86RMI_Reg(tmp), dst)); -//.. return dst; -//.. } + case Iop_Clz32: { + /* Count leading zeroes. */ + HReg dst = newVRegI(env); + HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); + addInstr(env, PPC32Instr_Unary32(Pun_CLZ,dst,src)); + return dst; + } //.. case Iop_128to32: { //.. HReg dst = newVRegI(env);