From: Cerion Armour-Brown Date: Thu, 10 Feb 2005 16:11:35 +0000 (+0000) Subject: hdefs: MulL, MFence X-Git-Tag: svn/VALGRIND_3_0_1^2~452 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f0fbe90eb5d2166e7460ad2c41d8e6cbc5ff331;p=thirdparty%2Fvalgrind.git hdefs: MulL, MFence isel: Iop_64HIto32 Iop_64to32 iselInt64Expr: Iop_MullU32 Iop_MullS32 Ist_MFence Had a go at implementing long multiplies (last shortcut was wrong) git-svn-id: svn://svn.valgrind.org/vex/trunk@882 --- diff --git a/VEX/priv/host-ppc32/hdefs.c b/VEX/priv/host-ppc32/hdefs.c index 7439f4d540..643f25bac7 100644 --- a/VEX/priv/host-ppc32/hdefs.c +++ b/VEX/priv/host-ppc32/hdefs.c @@ -471,14 +471,17 @@ PPC32Instr* PPC32Instr_Unary32 ( PPC32UnaryOp op, HReg dst ) { i->Pin.Unary32.dst = dst; return i; } -//.. X86Instr* X86Instr_MulL ( Bool syned, X86ScalarSz ssz , X86RM* src ) { -//.. X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); -//.. i->tag = Xin_MulL; -//.. i->Xin.MulL.syned = syned; -//.. i->Xin.MulL.ssz = ssz; -//.. i->Xin.MulL.src = src; -//.. return i; -//.. } +PPC32Instr* PPC32Instr_MulL ( Bool syned, Bool word, HReg dst, + HReg src1, PPC32RI* src2 ) { + PPC32Instr* i = LibVEX_Alloc(sizeof(PPC32Instr)); + i->tag = Pin_MulL; + i->Pin.MulL.syned = syned; + i->Pin.MulL.word = word; + i->Pin.MulL.dst = dst; + i->Pin.MulL.src1 = src1; + i->Pin.MulL.src2 = src2; + return i; +} //.. X86Instr* X86Instr_Div ( Bool syned, X86ScalarSz ssz, X86RM* src ) { //.. X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); //.. i->tag = Xin_Div; @@ -564,16 +567,15 @@ PPC32Instr* PPC32Instr_Set32 ( PPC32CondCode cond, HReg dst ) { //.. i->Xin.Bsfr32.dst = dst; //.. return i; //.. } -//.. X86Instr* X86Instr_MFence ( VexSubArch subarch ) -//.. { -//.. X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); -//.. i->tag = Xin_MFence; -//.. i->Xin.MFence.subarch = subarch; -//.. vassert(subarch == VexSubArchX86_sse0 -//.. || subarch == VexSubArchX86_sse1 -//.. || subarch == VexSubArchX86_sse2); -//.. return i; -//.. } +PPC32Instr* PPC32Instr_MFence ( VexSubArch subarch ) +{ + PPC32Instr* i = LibVEX_Alloc(sizeof(PPC32Instr)); + i->tag = Pin_MFence; + i->Pin.MFence.subarch = subarch; + vassert(subarch == VexSubArchPPC32_AV + || subarch == VexSubArchPPC32_noAV); + return i; +} //.. X86Instr* X86Instr_FpUnary ( X86FpOp op, HReg src, HReg dst ) { //.. X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); @@ -697,12 +699,20 @@ void ppPPC32Instr ( PPC32Instr* i ) vex_printf("%sl ", showPPC32UnaryOp(i->Pin.Unary32.op)); ppHRegPPC32(i->Pin.Unary32.dst); return; -//.. case Xin_MulL: -//.. vex_printf("%cmul%s ", -//.. i->Xin.MulL.syned ? 's' : 'u', -//.. showX86ScalarSz(i->Xin.MulL.ssz)); -//.. ppX86RM(i->Xin.MulL.src); -//.. return; + case Pin_MulL: + if (i->Pin.MulL.src2->tag == Pri_Imm) { + vex_printf("mulli "); + } else { + vex_printf("mul%s%c ", + i->Pin.MulL.word ? "hw" : "lw", + i->Pin.MulL.syned ? 's' : 'u'); + } + ppHRegPPC32(i->Pin.MulL.dst); + vex_printf(","); + ppHRegPPC32(i->Pin.MulL.src1); + vex_printf(","); + ppPPC32RI(i->Pin.MulL.src2); + return; //.. case Xin_Div: //.. vex_printf("%cdiv%s ", //.. i->Xin.Div.syned ? 's' : 'u', @@ -797,10 +807,10 @@ void ppPPC32Instr ( PPC32Instr* i ) //.. vex_printf(","); //.. ppHRegX86(i->Xin.Bsfr32.dst); //.. return; -//.. case Xin_MFence: -//.. vex_printf("mfence(%s)", -//.. LibVEX_ppVexSubArch(i->Xin.MFence.subarch)); -//.. return; + case Pin_MFence: + vex_printf("mfence(%s)", + LibVEX_ppVexSubArch(i->Pin.MFence.subarch)); + return; //.. case Xin_FpUnary: //.. vex_printf("g%sD ", showX86FpOp(i->Xin.FpUnary.op)); //.. ppHRegX86(i->Xin.FpUnary.src); @@ -973,11 +983,11 @@ void getRegUsage_PPC32Instr ( HRegUsage* u, PPC32Instr* i ) case Pin_Unary32: addHRegUse(u, HRmModify, i->Pin.Unary32.dst); return; -//.. case Xin_MulL: -//.. addRegUsage_X86RM(u, i->Xin.MulL.src, HRmRead); -//.. addHRegUse(u, HRmModify, hregX86_EAX()); -//.. addHRegUse(u, HRmWrite, hregX86_EDX()); -//.. return; + case Pin_MulL: + addHRegUse(u, HRmWrite, i->Pin.MulL.dst); + addHRegUse(u, HRmRead, i->Pin.MulL.src1); + addRegUsage_PPC32RI(u, i->Pin.MulL.src2); + return; //.. case Xin_Div: //.. addRegUsage_X86RM(u, i->Xin.Div.src, HRmRead); //.. addHRegUse(u, HRmModify, hregX86_EAX()); @@ -1058,8 +1068,8 @@ void getRegUsage_PPC32Instr ( HRegUsage* u, PPC32Instr* i ) //.. addHRegUse(u, HRmRead, i->Xin.Bsfr32.src); //.. addHRegUse(u, HRmWrite, i->Xin.Bsfr32.dst); //.. return; -//.. case Xin_MFence: -//.. return; + case Pin_MFence: + return; //.. case Xin_FpUnary: //.. addHRegUse(u, HRmRead, i->Xin.FpUnary.src); //.. addHRegUse(u, HRmWrite, i->Xin.FpUnary.dst); @@ -1200,9 +1210,11 @@ void mapRegs_PPC32Instr (HRegRemap* m, PPC32Instr* i) case Pin_Unary32: mapReg(m, &i->Pin.Unary32.dst); return; -//.. case Xin_MulL: -//.. mapRegs_X86RM(m, i->Xin.MulL.src); -//.. return; + case Pin_MulL: + mapReg(m, &i->Pin.MulL.dst); + mapReg(m, &i->Pin.MulL.src1); + mapRegs_PPC32RI(m, i->Pin.MulL.src2); + return; //.. case Xin_Div: //.. mapRegs_X86RM(m, i->Xin.Div.src); //.. return; @@ -1237,8 +1249,8 @@ void mapRegs_PPC32Instr (HRegRemap* m, PPC32Instr* i) //.. mapReg(m, &i->Xin.Bsfr32.src); //.. mapReg(m, &i->Xin.Bsfr32.dst); //.. return; -//.. case Xin_MFence: -//.. return; + case Pin_MFence: + return; //.. case Xin_FpUnary: //.. mapReg(m, &i->Xin.FpUnary.src); //.. mapReg(m, &i->Xin.FpUnary.dst); diff --git a/VEX/priv/host-ppc32/hdefs.h b/VEX/priv/host-ppc32/hdefs.h index e5b552f969..918ec7e669 100644 --- a/VEX/priv/host-ppc32/hdefs.h +++ b/VEX/priv/host-ppc32/hdefs.h @@ -290,7 +290,7 @@ typedef Pin_Sh32, /* 32-bit shift/rotate */ Pin_Test32, /* 32-bit test (AND, set flags, discard result) */ Pin_Unary32, /* 32-bit not and neg */ -//.. Xin_MulL, /* widening multiply */ + Pin_MulL, /* widening multiply */ //.. Xin_Div, /* div and mod */ //.. Xin_Sh3232, /* shldl or shrdl */ //.. Xin_Push, /* push (32-bit?) value on stack */ @@ -301,7 +301,7 @@ typedef Pin_Store, /* store a 8|16|32 bit value to mem */ Pin_Set32, /* convert condition code to 32-bit value */ //.. Xin_Bsfr32, /* 32-bit bsf/bsr */ -//.. Xin_MFence, /* mem fence (not just sse2, but sse0 and 1 too) */ + Pin_MFence, /* mem fence (not just sse2, but sse0 and 1 too) */ //.. Xin_FpUnary, /* FP fake unary op */ //.. Xin_FpBinary, /* FP fake binary op */ @@ -343,12 +343,14 @@ typedef PPC32UnaryOp op; HReg dst; } Unary32; -//.. /* DX:AX = AX *s/u r/m16, or EDX:EAX = EAX *s/u r/m32 */ -//.. struct { -//.. Bool syned; -//.. X86ScalarSz ssz; -//.. X86RM* src; -//.. } MulL; + /* DX:AX = AX *s/u r/m16, or EDX:EAX = EAX *s/u r/m32 */ + struct { + Bool syned; + Bool word; /* low=0, hi=1 */ + HReg dst; + HReg src1; + PPC32RI* src2; + } MulL; //.. /* x86 div/idiv instruction. Modifies EDX and EAX and reads src. */ //.. struct { //.. Bool syned; @@ -413,16 +415,16 @@ typedef //.. HReg src; //.. HReg dst; //.. } Bsfr32; -//.. /* Mem fence (not just sse2, but sse0 and 1 too). In short, -//.. an insn which flushes all preceding loads and stores as -//.. much as possible before continuing. On SSE2 we emit a -//.. real "mfence", on SSE1 "sfence ; lock addl $0,0(%esp)" and -//.. on SSE0 "lock addl $0,0(%esp)". This insn therefore -//.. carries the subarch so the assembler knows what to -//.. emit. */ -//.. struct { -//.. VexSubArch subarch; -//.. } MFence; + /* Mem fence (not just sse2, but sse0 and 1 too). In short, + an insn which flushes all preceding loads and stores as + much as possible before continuing. On SSE2 we emit a + real "mfence", on SSE1 "sfence ; lock addl $0,0(%esp)" and + on SSE0 "lock addl $0,0(%esp)". This insn therefore + carries the subarch so the assembler knows what to + emit. */ + struct { + VexSubArch subarch; + } MFence; //.. /* X86 Floating point (fake 3-operand, "flat reg file" insns) */ //.. struct { @@ -492,7 +494,7 @@ 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 X86Instr* X86Instr_MulL ( Bool syned, X86ScalarSz, X86RM* ); +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 ); //.. extern X86Instr* X86Instr_Push ( X86RMI* ); @@ -504,7 +506,7 @@ extern PPC32Instr* PPC32Instr_LoadEX ( UChar sz, Bool syned, extern PPC32Instr* PPC32Instr_Store ( UChar sz, PPC32AMode* dst, HReg src ); extern PPC32Instr* PPC32Instr_Set32 ( PPC32CondCode cond, HReg dst ); //.. extern X86Instr* X86Instr_Bsfr32 ( Bool isFwds, HReg src, HReg dst ); -//.. extern X86Instr* X86Instr_MFence ( VexSubArch ); +extern PPC32Instr* PPC32Instr_MFence ( VexSubArch ); //.. //.. extern X86Instr* X86Instr_FpUnary ( X86FpOp op, HReg src, HReg dst ); //.. extern X86Instr* X86Instr_FpBinary ( X86FpOp op, HReg srcL, HReg srcR, HReg dst ); diff --git a/VEX/priv/host-ppc32/isel.c b/VEX/priv/host-ppc32/isel.c index e97710b6d3..b2dfbf7334 100644 --- a/VEX/priv/host-ppc32/isel.c +++ b/VEX/priv/host-ppc32/isel.c @@ -185,7 +185,6 @@ static HReg lookupIRTemp ( ISelEnv* env, IRTemp tmp ) return env->vregmap[tmp]; } -#if 0 static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp ) { vassert(tmp >= 0); @@ -194,7 +193,6 @@ static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp ) *vrLO = env->vregmap[tmp]; *vrHI = env->vregmapHI[tmp]; } -#endif static void addInstr ( ISelEnv* env, PPC32Instr* instr ) { @@ -246,12 +244,10 @@ static HReg iselIntExpr_R ( ISelEnv* env, IRExpr* e ); static PPC32AMode* iselIntExpr_AMode_wrk ( ISelEnv* env, IRExpr* e ); static PPC32AMode* iselIntExpr_AMode ( ISelEnv* env, IRExpr* e ); -#if 0 static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ); static void iselInt64Expr ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ); -#endif static PPC32CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ); static PPC32CondCode iselCondCode ( ISelEnv* env, IRExpr* e ); @@ -1055,14 +1051,20 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) return dst; } case Iop_64HIto32: { - - /* 64HIto32(MullU32(expr,expr)) */ + HReg rHi, rLo; + iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg); + return rHi; /* and abandon rLo .. poor wee thing :-) */ + } + case Iop_64to32: { +#if 1 +// CAB: This right? + /* 64to32(MullS32(expr,expr)) */ { - DECLARE_PATTERN(p_MullU32_then_64HIto32); - DEFINE_PATTERN(p_MullU32_then_64HIto32, - unop(Iop_64HIto32, - binop(Iop_MullU32, bind(0), bind(1)))); - if (matchIRExpr(&mi,p_MullU32_then_64HIto32,e)) { + DECLARE_PATTERN(p_MullS32_then_64to32); + DEFINE_PATTERN(p_MullS32_then_64to32, + unop(Iop_64to32, + binop(Iop_MullS32, bind(0), bind(1)))); + if (matchIRExpr(&mi,p_MullS32_then_64to32,e)) { HReg dst = newVRegI(env); HReg src1 = iselIntExpr_R( env, mi.bindee[0] ); PPC32RI* src2 = iselIntExpr_RI( env, mi.bindee[1] ); @@ -1070,20 +1072,12 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) return dst; } } - -#if 0 - HReg rHi, rLo; - iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg); - return rHi; /* and abandon rLo .. poor wee thing :-) */ -#endif - } -#if 0 - case Iop_64to32: { +#else 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: { HReg dst = newVRegI(env); @@ -1548,7 +1542,6 @@ static PPC32CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) } -#if 0 /*---------------------------------------------------------*/ /*--- ISEL: Integer expressions (64 bit) ---*/ /*---------------------------------------------------------*/ @@ -1577,7 +1570,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) vassert(e); vassert(typeOfIRExpr(env->type_env,e) == Ity_I64); - vex_printf("@iselInt64Expr_wrk: tag=%d\n", e->tag); +// vex_printf("@iselInt64Expr_wrk: tag=%d\n", e->tag); //.. /* 64-bit literal */ //.. if (e->tag == Iex_Const) { @@ -1670,26 +1663,19 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) /* 32 x 32 -> 64 multiply */ case Iop_MullU32: case Iop_MullS32: { -#if 0 /* get one operand into %r3, and the other into a R/I. Need to make an educated guess about which is better in which. */ - HReg tLo = newVRegI(env); - HReg tHi = newVRegI(env); - Bool syned = e->Iex.Binop.op == Iop_MullS32; - PPC32RI* rmLeft = iselIntExpr_RI(env, e->Iex.Binop.arg1); - HReg rRight = iselIntExpr_R(env, e->Iex.Binop.arg2); - addInstr(env, mk_iMOVsd_RR(rRight, hregPPC32_GPR3())); - - addInstr(env, PPC32Instr_MulL(syned, Pss_32, rmLeft)); - - /* Result is now in EDX:EAX. Tell the caller. */ - addInstr(env, mk_iMOVds_RR(tHi, hregPPC32_EDX())); - addInstr(env, mk_iMOVds_RR(tLo, hregPPC32_EAX())); + HReg tLo = newVRegI(env); + HReg tHi = newVRegI(env); + Bool syned = e->Iex.Binop.op == Iop_MullS32; + HReg rLeft = iselIntExpr_R(env, e->Iex.Binop.arg1); + PPC32RI* riRight = iselIntExpr_RI(env, e->Iex.Binop.arg2); + addInstr(env, PPC32Instr_MulL(syned, 0, tLo, rLeft, riRight)); + addInstr(env, PPC32Instr_MulL(syned, 1, tHi, rLeft, riRight)); *rHi = tHi; *rLo = tLo; return; -#endif } //.. /* 64 x 32 -> (32(rem),32(div)) division */ @@ -2212,7 +2198,6 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) ppIRExpr(e); vpanic("iselInt64Expr(ppc32)"); } -#endif //.. /*---------------------------------------------------------*/ @@ -3251,10 +3236,10 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) //.. break; //.. } -//.. /* --------- MEM FENCE --------- */ -//.. case Ist_MFence: -//.. addInstr(env, X86Instr_MFence(env->subarch)); -//.. return; + /* --------- MEM FENCE --------- */ + case Ist_MFence: + addInstr(env, PPC32Instr_MFence(env->subarch)); + return; /* --------- EXIT --------- */ case Ist_Exit: {