aboutsummaryrefslogtreecommitdiff
path: root/VEX/priv/guest_x86_helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'VEX/priv/guest_x86_helpers.c')
-rw-r--r--VEX/priv/guest_x86_helpers.c126
1 files changed, 120 insertions, 6 deletions
diff --git a/VEX/priv/guest_x86_helpers.c b/VEX/priv/guest_x86_helpers.c
index b4875ee9f..bc5a29eed 100644
--- a/VEX/priv/guest_x86_helpers.c
+++ b/VEX/priv/guest_x86_helpers.c
@@ -7,7 +7,7 @@
This file is part of Valgrind, a dynamic binary instrumentation
framework.
- Copyright (C) 2004-2013 OpenWorks LLP
+ Copyright (C) 2004-2015 OpenWorks LLP
info@open-works.net
This program is free software; you can redistribute it and/or
@@ -724,17 +724,54 @@ UInt LibVEX_GuestX86_get_eflags ( /*IN*/const VexGuestX86State* vex_state )
UInt dflag = vex_state->guest_DFLAG;
vassert(dflag == 1 || dflag == 0xFFFFFFFF);
if (dflag == 0xFFFFFFFF)
- eflags |= (1<<10);
+ eflags |= X86G_CC_MASK_D;
if (vex_state->guest_IDFLAG == 1)
- eflags |= (1<<21);
+ eflags |= X86G_CC_MASK_ID;
if (vex_state->guest_ACFLAG == 1)
- eflags |= (1<<18);
+ eflags |= X86G_CC_MASK_AC;
return eflags;
}
/* VISIBLE TO LIBVEX CLIENT */
void
+LibVEX_GuestX86_put_eflags ( UInt eflags,
+ /*MOD*/VexGuestX86State* vex_state )
+{
+ /* D flag */
+ if (eflags & X86G_CC_MASK_D) {
+ vex_state->guest_DFLAG = 0xFFFFFFFF;
+ eflags &= ~X86G_CC_MASK_D;
+ }
+ else
+ vex_state->guest_DFLAG = 1;
+
+ /* ID flag */
+ if (eflags & X86G_CC_MASK_ID) {
+ vex_state->guest_IDFLAG = 1;
+ eflags &= ~X86G_CC_MASK_ID;
+ }
+ else
+ vex_state->guest_IDFLAG = 0;
+
+ /* AC flag */
+ if (eflags & X86G_CC_MASK_AC) {
+ vex_state->guest_ACFLAG = 1;
+ eflags &= ~X86G_CC_MASK_AC;
+ }
+ else
+ vex_state->guest_ACFLAG = 0;
+
+ UInt cc_mask = X86G_CC_MASK_O | X86G_CC_MASK_S | X86G_CC_MASK_Z |
+ X86G_CC_MASK_A | X86G_CC_MASK_C | X86G_CC_MASK_P;
+ vex_state->guest_CC_OP = X86G_CC_OP_COPY;
+ vex_state->guest_CC_DEP1 = eflags & cc_mask;
+ vex_state->guest_CC_DEP2 = 0;
+ vex_state->guest_CC_NDEP = 0;
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+void
LibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag,
/*MOD*/VexGuestX86State* vex_state )
{
@@ -1800,6 +1837,7 @@ VexEmNote x86g_dirtyhelper_FXRSTOR ( VexGuestX86State* gst, HWord addr )
/* Code that seems to trigger the problem:
for (i = 0; i < 14; i++) tmp.env[i] = 0; */
for (i = 0; i < 7; i++) tmp.env[i+0] = 0;
+ __asm__ __volatile__("" ::: "memory");
for (i = 0; i < 7; i++) tmp.env[i+7] = 0;
for (i = 0; i < 80; i++) tmp.reg[i] = 0;
@@ -1835,7 +1873,7 @@ VexEmNote x86g_dirtyhelper_FXRSTOR ( VexGuestX86State* gst, HWord addr )
warnXMM = (VexEmNote)(w64 >> 32);
- gst->guest_SSEROUND = (UInt)w64;
+ gst->guest_SSEROUND = w64 & 0xFFFFFFFF;
}
/* Prefer an X87 emwarn over an XMM one, if both exist. */
@@ -1880,6 +1918,42 @@ VexEmNote x86g_dirtyhelper_FLDENV ( VexGuestX86State* gst, HWord addr )
return do_put_x87( False/*don't move regs*/, (UChar*)addr, gst);
}
+/* VISIBLE TO LIBVEX CLIENT */
+/* Do x87 save from the supplied VexGuestX86State structure and store the
+ result at the given address which represents a buffer of at least 108
+ bytes. */
+void LibVEX_GuestX86_get_x87 ( /*IN*/VexGuestX86State* vex_state,
+ /*OUT*/UChar* x87_state )
+{
+ do_get_x87 ( vex_state, x87_state );
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+/* Do x87 restore from the supplied address and store read values to the given
+ VexGuestX86State structure. */
+VexEmNote LibVEX_GuestX86_put_x87 ( /*IN*/UChar* x87_state,
+ /*MOD*/VexGuestX86State* vex_state )
+{
+ return do_put_x87 ( True/*moveRegs*/, x87_state, vex_state );
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+/* Return mxcsr from the supplied VexGuestX86State structure. */
+UInt LibVEX_GuestX86_get_mxcsr ( /*IN*/VexGuestX86State* vex_state )
+{
+ return x86g_create_mxcsr ( vex_state->guest_SSEROUND );
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+/* Modify the given VexGuestX86State structure according to the passed mxcsr
+ value. */
+VexEmNote LibVEX_GuestX86_put_mxcsr ( /*IN*/UInt mxcsr,
+ /*MOD*/VexGuestX86State* vex_state)
+{
+ ULong w64 = x86g_check_ldmxcsr( mxcsr );
+ vex_state->guest_SSEROUND = w64 & 0xFFFFFFFF;
+ return (VexEmNote)(w64 >> 32);
+}
/*---------------------------------------------------------------*/
/*--- Misc integer helpers, including rotates and CPUID. ---*/
@@ -2297,6 +2371,46 @@ void x86g_dirtyhelper_CPUID_sse1 ( VexGuestX86State* st )
}
}
+/* Claim to be the following SSE2-capable CPU:
+ vendor_id : GenuineIntel
+ cpu family : 15
+ model : 2
+ model name : Intel(R) Pentium(R) 4 CPU 3.00GHz
+ stepping : 9
+ microcode : 0x17
+ cpu MHz : 2992.577
+ cache size : 512 KB
+ flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov
+ pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe
+ pebs bts cid xtpr
+ clflush size : 64
+ cache_alignment : 128
+ address sizes : 36 bits physical, 32 bits virtual
+*/
+void x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* st )
+{
+ switch (st->guest_EAX) {
+ case 0:
+ st->guest_EAX = 0x00000002;
+ st->guest_EBX = 0x756e6547;
+ st->guest_ECX = 0x6c65746e;
+ st->guest_EDX = 0x49656e69;
+ break;
+ case 1:
+ st->guest_EAX = 0x00000f29;
+ st->guest_EBX = 0x01020809;
+ st->guest_ECX = 0x00004400;
+ st->guest_EDX = 0xbfebfbff;
+ break;
+ default:
+ st->guest_EAX = 0x03020101;
+ st->guest_EBX = 0x00000000;
+ st->guest_ECX = 0x00000000;
+ st->guest_EDX = 0x0c040883;
+ break;
+ }
+}
+
/* Claim to be the following SSSE3-capable CPU (2 x ...):
vendor_id : GenuineIntel
cpu family : 6
@@ -2324,7 +2438,7 @@ void x86g_dirtyhelper_CPUID_sse1 ( VexGuestX86State* st )
address sizes : 36 bits physical, 48 bits virtual
power management:
*/
-void x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* st )
+void x86g_dirtyhelper_CPUID_sse3 ( VexGuestX86State* st )
{
# define SET_ABCD(_a,_b,_c,_d) \
do { st->guest_EAX = (UInt)(_a); \