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