From: Julian Seward Date: Sun, 20 Mar 2005 12:51:39 +0000 (+0000) Subject: The party never stops in x86-land: implement 'fstsw' as cachegrind's X-Git-Tag: svn/VALGRIND_3_0_1^2~276 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=53facf769cd1bce16692d6514f308492c7b648be;p=thirdparty%2Fvalgrind.git The party never stops in x86-land: implement 'fstsw' as cachegrind's regression tests require it. Also tighten up assertion checking in putIReg, and update some copyright notices. git-svn-id: svn://svn.valgrind.org/vex/trunk@1058 --- diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index cb320ccc2b..5ae6ee498c 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -128,20 +128,18 @@ extern void x86g_dirtyhelper_CPUID_sse0 ( VexGuestX86State* ); extern void x86g_dirtyhelper_CPUID_sse1 ( VexGuestX86State* ); extern void x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* ); -extern void x86g_dirtyhelper_FSAVE ( VexGuestX86State*, HWord ); - extern void x86g_dirtyhelper_FINIT ( VexGuestX86State* ); +extern void x86g_dirtyhelper_FXSAVE ( VexGuestX86State*, HWord ); +extern void x86g_dirtyhelper_FSAVE ( VexGuestX86State*, HWord ); +extern void x86g_dirtyhelper_FSTENV ( VexGuestX86State*, HWord ); + extern VexEmWarn x86g_dirtyhelper_FRSTOR ( VexGuestX86State*, HWord ); -extern void x86g_dirtyhelper_FSTENV ( VexGuestX86State*, HWord ); - extern VexEmWarn x86g_dirtyhelper_FLDENV ( VexGuestX86State*, HWord ); -extern void x86g_dirtyhelper_FXSAVE ( VexGuestX86State*, HWord ); - /*---------------------------------------------------------*/ /*--- Condition code stuff ---*/ diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 4bf8464944..fcccc2216a 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -2,7 +2,7 @@ /*---------------------------------------------------------------*/ /*--- ---*/ /*--- This file (guest-x86/ghelpers.c) is ---*/ -/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ +/*--- Copyright (c) OpenWorks LLP. All rights reserved. ---*/ /*--- ---*/ /*---------------------------------------------------------------*/ @@ -10,7 +10,7 @@ This file is part of LibVEX, a library for dynamic binary instrumentation and translation. - Copyright (C) 2004 OpenWorks, LLP. + Copyright (C) 2004-2005 OpenWorks, LLP. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index bc9c14fd7b..937578a5a4 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -2,7 +2,7 @@ /*--------------------------------------------------------------------*/ /*--- ---*/ /*--- This file (guest-x86/toIR.c) is ---*/ -/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ +/*--- Copyright (c) OpenWorks LLP. All rights reserved. ---*/ /*--- ---*/ /*--------------------------------------------------------------------*/ @@ -10,7 +10,7 @@ This file is part of LibVEX, a library for dynamic binary instrumentation and translation. - Copyright (C) 2004 OpenWorks, LLP. + Copyright (C) 2004-2005 OpenWorks, LLP. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -673,9 +673,13 @@ static IRExpr* getIReg ( Int sz, UInt archreg ) static void putIReg ( Int sz, UInt archreg, IRExpr* e ) { IRType ty = typeOfIRExpr(irbb->tyenv, e); - vassert(sz == 1 || sz == 2 || sz == 4); + switch (sz) { + case 1: vassert(ty == Ity_I8); break; + case 2: vassert(ty == Ity_I16); break; + case 4: vassert(ty == Ity_I32); break; + default: vpanic("putIReg(x86)"); + } vassert(archreg < 8); - vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8); stmt( IRStmt_Put(integerGuestRegOffset(sz,archreg), e) ); } @@ -3436,6 +3440,21 @@ static void clear_C2 ( void ) put_C3210( binop(Iop_And32, get_C3210(), mkU32(~X86G_FC_MASK_C2)) ); } +/* Invent a plausible-looking FPU status word value: + ((ftop & 7) << 11) | (c3210 & 0x4700) + */ +static IRExpr* get_FPU_sw ( void ) +{ + return + unop(Iop_32to16, + binop(Iop_Or32, + binop(Iop_Shl32, + binop(Iop_And32, get_ftop(), mkU32(7)), + mkU8(11)), + binop(Iop_And32, get_C3210(), mkU32(0x4700)) + )); +} + /* ------------------------------------------------------- */ /* Given all that stack-mangling junk, we can now go ahead @@ -3726,7 +3745,7 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) fp_pop(); break; - case 4: { /* FLDENV m108 */ + case 4: { /* FLDENV m28 */ /* Uses dirty helper: VexEmWarn x86g_do_FLDENV ( VexGuestX86State*, Addr32 ) */ IRTemp ew = newTemp(Ity_I32); @@ -4666,6 +4685,14 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) break; } + case 7: { /* FNSTSW m16 */ + IRExpr* sw = get_FPU_sw(); + vassert(typeOfIRExpr(irbb->tyenv, sw) == Ity_I16); + storeLE( mkexpr(addr), sw ); + DIP("fnstsw %s\n", dis_buf); + break; + } + default: vex_printf("unhandled opc_aux = 0x%2x\n", gregOfRM(modrm)); vex_printf("first_opcode == 0xDD\n"); @@ -4907,18 +4934,8 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta ) case 0xE0: /* FNSTSW %ax */ DIP("fnstsw %%ax\n"); - /* Invent a plausible-looking FPU status word value and - dump it in %AX: - ((ftop & 7) << 11) | (c3210 & 0x4700) - */ - putIReg(2, R_EAX, - unop(Iop_32to16, - binop(Iop_Or32, - binop(Iop_Shl32, - binop(Iop_And32, get_ftop(), mkU32(7)), - mkU8(11)), - binop(Iop_And32, get_C3210(), mkU32(0x4700)) - ))); + /* Get the FPU status word value and dump it in %AX. */ + putIReg(2, R_EAX, get_FPU_sw()); break; case 0xE8 ... 0xEF: /* FUCOMIP %st(0),%st(?) */