From: Julian Seward Date: Mon, 6 Sep 2004 23:19:03 +0000 (+0000) Subject: Add a few more FP insns, and fix some bugs. X-Git-Tag: svn/VALGRIND_3_0_1^2~1103 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4fa0aa6dca36fd73aa59f603541ca0c5710054cd;p=thirdparty%2Fvalgrind.git Add a few more FP insns, and fix some bugs. git-svn-id: svn://svn.valgrind.org/vex/trunk@231 --- diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 32d858f731..4683f5c20b 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -3131,7 +3131,7 @@ static void put_ST_TAG ( Int i, IRExpr* value ) } /* Given i, generate an expression yielding 'ST_TAG(i)'. This will be - zero to indicate "Empty" and nonzero and indicate "NonEmpty". */ + zero to indicate "Empty" and nonzero to indicate "NonEmpty". */ static IRExpr* get_ST_TAG ( Int i ) { @@ -3169,6 +3169,7 @@ The previous state of the register is not checked. */ static void put_ST_UNCHECKED ( Int i, IRExpr* value ) { + vassert(typeOfIRExpr(irbb->tyenv, value) == Ity_F64); stmt( IRStmt_PutI( off_ST(i), value, OFFB_F0, OFFB_F7+8-1 ) ); /* Mark the register as in-use. */ put_ST_TAG(i, mkU8(1)); @@ -3182,11 +3183,11 @@ static void put_ST_UNCHECKED ( Int i, IRExpr* value ) static void put_ST ( Int i, IRExpr* value ) { put_ST_UNCHECKED( i, - IRExpr_Mux0X(get_ST_TAG(i), - /* 0 means empty */ - value, - /* non-0 means full */ - mkNaN64() + IRExpr_Mux0X( get_ST_TAG(i), + /* 0 means empty */ + value, + /* non-0 means full */ + mkNaN64() ) ); } @@ -3231,7 +3232,7 @@ static void fp_push ( void ) static void fp_pop ( void ) { - put_ST_TAG(0, mkU8(1)); + put_ST_TAG(0, mkU8(0)); put_ftop( binop(Iop_And32, binop(Iop_Add32, get_ftop(), mkU32(1)), @@ -3260,6 +3261,20 @@ void fp_do_op_mem_ST_0 ( IRTemp addr, UChar* op_txt, UChar* dis_buf, } +/* ST(dst) = ST(dst) `op` ST(src). + Check dst and src tags when reading but not on write. +*/ +static +void fp_do_op_ST_ST ( UChar* op_txt, IROp op, UInt st_src, UInt st_dst ) +{ + DIP("f%s st(%d), st(%d)\n", op_txt, st_src, st_dst ); + put_ST_UNCHECKED( + st_dst, + binop(op, get_ST(st_dst), get_ST(st_src) ) + ); +} + + static UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) { @@ -3276,7 +3291,18 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) /* -+-+-+-+-+-+-+-+-+-+-+-+ 0xD8 opcodes +-+-+-+-+-+-+-+ */ if (first_opcode == 0xD8) { - goto decode_fail; + if (modrm < 0xC0) { + goto decode_fail; + } else { + delta++; + switch (modrm) { + case 0xC0 ... 0xC7: /* FADD %st(?),%st(0) */ + fp_do_op_ST_ST ( "add", Iop_AddF64, modrm - 0xC0, 0 ); + break; + default: + goto decode_fail; + } + } } /* -+-+-+-+-+-+-+-+-+-+-+-+ 0xD9 opcodes +-+-+-+-+-+-+-+ */ @@ -3297,11 +3323,23 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) break; case 0xE8: /* FLD1 */ - DIP("fldz"); + DIP("fld1"); fp_push(); put_ST(0, IRExpr_Const(IRConst_F64(1.0))); break; + case 0xEC: /* FLDLG2 */ + DIP("fldlg2"); + fp_push(); + put_ST(0, IRExpr_Const(IRConst_F64(0.301029995663981143))); + break; + + case 0xED: /* FLDLN2 */ + DIP("fldln2"); + fp_push(); + put_ST(0, IRExpr_Const(IRConst_F64(0.69314718055994530942))); + break; + case 0xEE: /* FLDZ */ DIP("fldz"); fp_push(); @@ -3327,6 +3365,11 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) delta += len; switch (gregOfRM(modrm)) { + case 0: /* FIADD m32int */ /* ST(0) += m32int */ + DIP("fiaddl %s", dis_buf); + fop = Iop_AddF64; + goto do_fop_m32; + case 1: /* FIMUL m32int */ /* ST(0) *= m32int */ DIP("fimull %s", dis_buf); fop = Iop_MulF64;