From: Julian Seward Date: Mon, 30 Aug 2004 17:54:18 +0000 (+0000) Subject: Add FP conditional move insn (host) and isel rule to generate it. X-Git-Tag: svn/VALGRIND_3_0_1^2~1112 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=12ceeeb125078b1e8c87547be73ffb9a5efbad82;p=thirdparty%2Fvalgrind.git Add FP conditional move insn (host) and isel rule to generate it. git-svn-id: svn://svn.valgrind.org/vex/trunk@222 --- diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index ef53f78809..6171ad9ef4 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -580,6 +580,15 @@ X86Instr* X86Instr_FpI64 ( Bool toInt, HReg freg, HReg iregHi, HReg iregLo ) { i->Xin.FpI64.iregLo = iregLo; return i; } +X86Instr* X86Instr_FpCMov ( X86CondCode cond, HReg src, HReg dst ) { + X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); + i->tag = Xin_FpCMov; + i->Xin.FpCMov.cond = cond; + i->Xin.FpCMov.src = src; + i->Xin.FpCMov.dst = dst; + vassert(cond != Xcc_ALWAYS); + return i; +} void ppX86Instr ( X86Instr* i ) { @@ -725,6 +734,12 @@ void ppX86Instr ( X86Instr* i ) { ppHRegX86(i->Xin.FpI64.freg); } return; + case Xin_FpCMov: + vex_printf("gcmov%s ", showX86CondCode(i->Xin.FpCMov.cond)); + ppHRegX86(i->Xin.FpCMov.src); + vex_printf(","); + ppHRegX86(i->Xin.FpCMov.dst); + return; default: vpanic("ppX86Instr"); } diff --git a/VEX/priv/host-x86/hdefs.h b/VEX/priv/host-x86/hdefs.h index b77e30d9c9..9e15ac9e1c 100644 --- a/VEX/priv/host-x86/hdefs.h +++ b/VEX/priv/host-x86/hdefs.h @@ -277,7 +277,8 @@ typedef Xin_FpUnary, /* FP fake unary op */ Xin_FpBinary, /* FP fake binary op */ Xin_FpLdSt, /* FP fake load/store */ - Xin_FpI64 /* FP fake to/from 64-bit signed int */ + Xin_FpI64, /* FP fake to/from 64-bit signed int */ + Xin_FpCMov /* FP fake floating point conditional move */ } X86InstrTag; @@ -396,7 +397,14 @@ typedef HReg iregHi; HReg iregLo; } FpI64; - } Xin; + /* Mov src to dst on the given condition, which may not + be the bogus Xcc_ALWAYS. */ + struct { + X86CondCode cond; + HReg src; + HReg dst; + } FpCMov; + } Xin; } X86Instr; @@ -421,6 +429,7 @@ extern X86Instr* X86Instr_FpBinary ( X86FpOp op, HReg srcL, HReg srcR, HReg dst extern X86Instr* X86Instr_FpLdSt ( Bool isLoad, UChar sz, HReg reg, X86AMode* ); extern X86Instr* X86Instr_FpI64 ( Bool toInt, HReg freg, HReg iregHi, HReg iregLo ); +extern X86Instr* X86Instr_FpCMov ( X86CondCode, HReg src, HReg dst ); extern void ppX86Instr ( X86Instr* ); diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index 86b2c2d28b..b1d1880d3f 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -622,6 +622,22 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) break; } + case Iex_GetI: { + /* First off, compute the index expression into an integer reg. + The referenced address will then be 0 + ebp + reg*1, that is, + an X86AMode_IRRS. */ + HReg idx = iselIntExpr_R(env, e->Iex.GetI.offset); + HReg dst = newVRegI(env); + if (ty == Ity_I8) { + addInstr(env, + X86Instr_LoadEX( + 1, False, + X86AMode_IRRS(0, hregX86_EBP(), idx, 0), + dst )); + return dst; + } + } + /* --------- CCALL --------- */ case Iex_CCall: { Addr64 helper; @@ -1251,9 +1267,10 @@ static void iselIntExpr64_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) static HReg iselDblExpr ( ISelEnv* env, IRExpr* e ) { - // MatchInfo mi; + // MatchInfo mi; + IRType ty = typeOfIRExpr(env->type_env,e); vassert(e); - vassert(typeOfIRExpr(env->type_env,e) == Ity_F64); + vassert(ty == Ity_F64); if (e->tag == Iex_Tmp) { return lookupIRTemp(env, e->Iex.Tmp.tmp); @@ -1288,8 +1305,8 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e ) if (e->tag == Iex_GetI) { /* First off, compute the index expression into an integer reg. - The written address will then be 0 + ebp + reg*1, that is, an - X86AMode_IRRS. */ + The referenced address will then be 0 + ebp + reg*1, that is, + an X86AMode_IRRS. */ HReg idx = iselIntExpr_R(env, e->Iex.GetI.offset); HReg res = newVRegF(env); addInstr(env, @@ -1324,6 +1341,21 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e ) } } + /* --------- MULTIPLEX --------- */ + if (e->tag == Iex_Mux0X) { + if (ty == Ity_F64 + && typeOfIRExpr(env->type_env,e->Iex.Mux0X.cond) == Ity_I8) { + HReg r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond); + HReg rX = iselDblExpr(env, e->Iex.Mux0X.exprX); + HReg r0 = iselDblExpr(env, e->Iex.Mux0X.expr0); + HReg dst = newVRegF(env); + addInstr(env, X86Instr_FpCMov(Xcc_ALWAYS,rX,dst)); + addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8))); + addInstr(env, X86Instr_FpCMov(Xcc_Z,r0,dst)); + return dst; + } + } + ppIRExpr(e); vpanic("iselDblExpr"); }