Alexandre Julliard : ntdll: Store extended FPU context in NtGetContextThread().
Alexandre Julliard
julliard at winehq.org
Thu Feb 14 16:19:12 CST 2019
Module: wine
Branch: master
Commit: edbdec441b80dbc06f3878b7e4d823735f2888ec
URL: https://source.winehq.org/git/wine.git/?a=commit;h=edbdec441b80dbc06f3878b7e4d823735f2888ec
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Feb 14 19:46:16 2019 +0100
ntdll: Store extended FPU context in NtGetContextThread().
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/signal_i386.c | 37 ++++++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 1b3b10f..3ce10d3 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -427,8 +427,6 @@ static size_t signal_stack_size;
static wine_signal_handler handlers[256];
-static BOOL fpux_support; /* whether the CPU supports extended fpu context */
-
enum i386_trap_code
{
TRAP_x86_UNKNOWN = -1, /* Unknown fault (TRAP_sig not defined) */
@@ -559,6 +557,15 @@ static inline void *get_signal_stack(void)
/***********************************************************************
+ * has_fpux
+ */
+static inline int has_fpux(void)
+{
+ return (cpu_info.FeatureSet & CPU_FEATURE_FXSR);
+}
+
+
+/***********************************************************************
* get_current_teb
*
* Get the current teb based on the stack pointer.
@@ -860,6 +867,26 @@ static inline void save_fpu( CONTEXT *context )
/***********************************************************************
+ * save_fpux
+ *
+ * Save the thread FPU extended context.
+ */
+static inline void save_fpux( CONTEXT *context )
+{
+#ifdef __GNUC__
+ /* we have to enforce alignment by hand */
+ char buffer[sizeof(XMM_SAVE_AREA32) + 16];
+ XMM_SAVE_AREA32 *state = (XMM_SAVE_AREA32 *)(((ULONG_PTR)buffer + 15) & ~15);
+
+ if (!has_fpux()) return;
+ context->ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
+ __asm__ __volatile__( "fxsave %0" : "=m" (*state) );
+ memcpy( context->ExtendedRegisters, state, sizeof(*state) );
+#endif
+}
+
+
+/***********************************************************************
* restore_fpu
*
* Restore the FPU context to a sigcontext.
@@ -985,7 +1012,6 @@ static inline void save_context( CONTEXT *context, const ucontext_t *sigcontext,
{
context->ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
memcpy( context->ExtendedRegisters, fpux, sizeof(*fpux) );
- fpux_support = TRUE;
if (!fpu) fpux_to_fpu( &context->FloatSave, fpux );
}
if (!fpu && !fpux) save_fpu( context );
@@ -1137,7 +1163,7 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
{
DWORD flags = context->ContextFlags & ~CONTEXT_i386;
- if ((flags & CONTEXT_EXTENDED_REGISTERS) && fpux_support) restore_fpux( context );
+ if ((flags & CONTEXT_EXTENDED_REGISTERS) && has_fpux()) restore_fpux( context );
else if (flags & CONTEXT_FLOATING_POINT) restore_fpu( context );
if (flags & CONTEXT_DEBUG_REGISTERS)
@@ -1419,7 +1445,8 @@ NTSTATUS CDECL DECLSPEC_HIDDEN __regs_NtGetContextThread( DWORD edi, DWORD esi,
context->ContextFlags |= CONTEXT_SEGMENTS;
}
if (needed_flags & CONTEXT_FLOATING_POINT) save_fpu( context );
- /* FIXME: extended floating point */
+ if (needed_flags & CONTEXT_EXTENDED_REGISTERS) save_fpux( context );
+ /* FIXME: xstate */
/* update the cached version of the debug registers */
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))
{
More information about the wine-cvs
mailing list