Jacek Caban : ntdll: Use syscall frame for FPU and XMM contexts in NtSetContextThread.

Alexandre Julliard julliard at winehq.org
Mon Mar 1 15:54:05 CST 2021


Module: wine
Branch: master
Commit: 6e03330a2124dfcdd631d43672f5ead46ce9f334
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6e03330a2124dfcdd631d43672f5ead46ce9f334

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Mar  1 16:52:15 2021 +0100

ntdll: Use syscall frame for FPU and XMM contexts in NtSetContextThread.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/signal_i386.c | 73 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 54 insertions(+), 19 deletions(-)

diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index cec2a89c7bf..cc1e1d24e2a 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -770,23 +770,6 @@ static inline void restore_fpu( const CONTEXT *context )
 }
 
 
-/***********************************************************************
- *           restore_fpux
- *
- * Restore the FPU extended context
- */
-static inline void restore_fpux( const CONTEXT *context )
-{
-    /* we have to enforce alignment by hand */
-    char buffer[sizeof(XSAVE_FORMAT) + 16];
-    XSAVE_FORMAT *state = (XSAVE_FORMAT *)(((ULONG_PTR)buffer + 15) & ~15);
-
-    memcpy( state, context->ExtendedRegisters, sizeof(*state) );
-    /* reset the current interrupt status */
-    state->StatusWord &= state->ControlWord | 0xff80;
-    __asm__ __volatile__( "fxrstor %0" : : "m" (*state) );
-}
-
 /***********************************************************************
  *           restore_xstate
  *
@@ -867,6 +850,32 @@ static void fpux_to_fpu( FLOATING_SAVE_AREA *fpu, const XSAVE_FORMAT *fpux )
 }
 
 
+/***********************************************************************
+ *           fpu_to_fpux
+ *
+ * Fill extended FPU context from standard one.
+ */
+static void fpu_to_fpux( XSAVE_FORMAT *fpux, const FLOATING_SAVE_AREA *fpu )
+{
+    unsigned int i;
+
+    fpux->ControlWord   = fpu->ControlWord;
+    fpux->StatusWord    = fpu->StatusWord;
+    fpux->ErrorOffset   = fpu->ErrorOffset;
+    fpux->ErrorSelector = fpu->ErrorSelector;
+    fpux->ErrorOpcode   = fpu->ErrorSelector >> 16;
+    fpux->DataOffset    = fpu->DataOffset;
+    fpux->DataSelector  = fpu->DataSelector;
+    fpux->TagWord       = 0;
+    for (i = 0; i < 8; i++)
+    {
+        if (((fpu->TagWord >> (i * 2)) & 3) != 3)
+            fpux->TagWord |= 1 << i;
+        memcpy( &fpux->FloatRegisters[i], &fpu->RegisterArea[10 * i], 10 );
+    }
+}
+
+
 /***********************************************************************
  *           save_context
  *
@@ -1041,6 +1050,16 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
  */
 void signal_restore_full_cpu_context(void)
 {
+    struct syscall_xsave *xsave = get_syscall_xsave( get_syscall_frame() );
+
+    if (cpu_info.FeatureSet & CPU_FEATURE_FXSR)
+    {
+        __asm__ volatile( "fxrstor %0" : : "m"(xsave->u.xsave) );
+    }
+    else
+    {
+        __asm__ volatile( "frstor %0; fwait" : : "m" (xsave->u.fsave) );
+    }
     set_full_cpu_context();
 }
 
@@ -1272,8 +1291,24 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
         frame->fs = context->SegFs;
         frame->gs = context->SegGs;
     }
-    if (flags & CONTEXT_EXTENDED_REGISTERS) restore_fpux( context );
-    else if (flags & CONTEXT_FLOATING_POINT) restore_fpu( context );
+    if (flags & CONTEXT_EXTENDED_REGISTERS)
+    {
+        struct syscall_xsave *xsave = get_syscall_xsave( frame );
+        memcpy( &xsave->u.xsave, context->ExtendedRegisters, sizeof(xsave->u.xsave) );
+        /* reset the current interrupt status */
+        xsave->u.xsave.StatusWord &= xsave->u.xsave.ControlWord | 0xff80;
+    }
+    else if (flags & CONTEXT_FLOATING_POINT)
+    {
+        if (cpu_info.FeatureSet & CPU_FEATURE_FXSR)
+        {
+            fpu_to_fpux( &get_syscall_xsave( frame )->u.xsave, &context->FloatSave );
+        }
+        else
+        {
+            get_syscall_xsave( frame )->u.fsave = context->FloatSave;
+        }
+    }
 
     restore_xstate( context );
 




More information about the wine-cvs mailing list