From: Julian Seward Date: Tue, 31 Aug 2004 11:47:54 +0000 (+0000) Subject: Fill in enough to get through a simple x86 FP processing program X-Git-Tag: svn/VALGRIND_3_0_1^2~1111 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b6c44c64fc754471baffe501634c880da5c672a7;p=thirdparty%2Fvalgrind.git Fill in enough to get through a simple x86 FP processing program without dying. Doesn't produce the right answer (yet). git-svn-id: svn://svn.valgrind.org/vex/trunk@223 --- diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index 6171ad9ef4..0c3bf5e9ca 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -852,6 +852,10 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i) addHRegUse(u, HRmRead, i->Xin.FpI64.iregLo); } return; + case Xin_FpCMov: + addHRegUse(u, HRmRead, i->Xin.FpCMov.src); + addHRegUse(u, HRmModify, i->Xin.FpCMov.dst); + return; default: ppX86Instr(i); vpanic("getRegUsage_X86Instr"); @@ -933,6 +937,10 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i) mapReg(m, &i->Xin.FpI64.iregHi); mapReg(m, &i->Xin.FpI64.iregLo); return; + case Xin_FpCMov: + mapReg(m, &i->Xin.FpCMov.src); + mapReg(m, &i->Xin.FpCMov.dst); + return; default: ppX86Instr(i); vpanic("mapRegs_X86Instr"); @@ -968,7 +976,7 @@ Bool isMove_X86Instr ( X86Instr* i, HReg* src, HReg* dst ) /* x86 spill/reload using the hacked104 testbed. Spill slots - start at word 51, and there are 24 in total. + start at word 53, and there are 100 in total. */ X86Instr* genSpill_X86 ( HReg rreg, Int offset ) @@ -1752,6 +1760,21 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) goto done; } + case Xin_FpCMov: + /* jmp fwds if !condition */ + *p++ = 0x70 + (i->Xin.FpCMov.cond ^ 1); + *p++ = 0; /* # of bytes in the next bit, which we don't know yet */ + ptmp = p; + + /* ffree %st7 ; fld %st(src) ; fstp %st(1+dst) */ + p = do_ffree_st7(p); + p = do_fld_st(p, 0+hregNumber(i->Xin.FpCMov.src)); + p = do_fstp_st(p, 1+hregNumber(i->Xin.FpCMov.dst)); + + /* Fill in the jump offset. */ + *(ptmp-1) = p - ptmp; + goto done; + default: goto bad; } diff --git a/VEX/priv/host-x86/hdefs.h b/VEX/priv/host-x86/hdefs.h index 9e15ac9e1c..145358f28e 100644 --- a/VEX/priv/host-x86/hdefs.h +++ b/VEX/priv/host-x86/hdefs.h @@ -278,7 +278,7 @@ typedef Xin_FpBinary, /* FP fake binary op */ Xin_FpLdSt, /* FP fake load/store */ Xin_FpI64, /* FP fake to/from 64-bit signed int */ - Xin_FpCMov /* FP fake floating point conditional move */ + Xin_FpCMov /* FP fake floating point (un)conditional move */ } X86InstrTag; diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index b1d1880d3f..146077f491 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -1265,6 +1265,24 @@ static void iselIntExpr64_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) real or virtual; in any case it must not be changed by subsequent code emitted by the caller. */ +/* IEEE 754 formats. From http://www.freesoft.org/CIE/RFC/1832/32.htm: + + Type S (1 bit) E (11 bits) F (52 bits) + ---- --------- ----------- ----------- + signalling NaN u 2047 (max) .0uuuuu---u + (with at least + one 1 bit) + quiet NaN u 2047 (max) .1uuuuu---u + + negative infinity 1 2047 (max) .000000---0 + + positive infinity 0 2047 (max) .000000---0 + + negative zero 1 0 .000000---0 + + positive zero 0 0 .000000---0 +*/ + static HReg iselDblExpr ( ISelEnv* env, IRExpr* e ) { // MatchInfo mi; @@ -1282,8 +1300,23 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e ) vassert(sizeof(u) == 8); vassert(sizeof(u.i64) == 8); vassert(sizeof(u.f64) == 8); - vassert(e->Iex.Const.con->tag == Ico_F64); - u.f64 = e->Iex.Const.con->Ico.F64; + + if (e->Iex.Const.con->tag == Ico_F64) { + u.f64 = e->Iex.Const.con->Ico.F64; + } + else if (e->Iex.Const.con->tag == Ico_NaN64) { + /* QNaN is 0 2047 1 0(51times) + == 0b 11111111111b 1 0(51times) + == 0x7FF8 0000 0000 0000 + */ + /* Since we're running on a little-endian target, and + generating code for one: */ + u.i64[1] = 0x7FF80000; + u.i64[0] = 0x00000000; + } + else + vpanic("iselDblExpr(x86): const"); + addInstr(env, X86Instr_Push(X86RMI_Imm(u.i64[1]))); addInstr(env, X86Instr_Push(X86RMI_Imm(u.i64[0]))); addInstr(env, X86Instr_FpLdSt(True/*load*/, 8, freg, @@ -1349,7 +1382,7 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e ) 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_FpUnary(Xfp_MOV,rX,dst)); addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8))); addInstr(env, X86Instr_FpCMov(Xcc_Z,r0,dst)); return dst; @@ -1444,6 +1477,14 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) X86AMode_IRRS(0, hregX86_EBP(), idx, 0)) ); return; } + if (ty == Ity_I8) { + HReg r = iselIntExpr_R(env, stmt->Ist.Put.expr); + addInstr(env, X86Instr_Store( + 1, + r, + X86AMode_IRRS(0, hregX86_EBP(), idx, 0)) ); + return; + } break; }