Jacek Caban : ntdll: Store x86 YMM context insyscall dispatcher.

Alexandre Julliard julliard at winehq.org
Tue Mar 2 15:35:59 CST 2021


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Mar  2 18:46:29 2021 +0100

ntdll: Store x86 YMM context insyscall dispatcher.

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

---

 dlls/ntdll/unix/signal_i386.c | 14 ++++++++++++--
 tools/winebuild/import.c      | 18 +++++++++++++++---
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index cc1e1d24e2a..68d532c6f3f 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -468,9 +468,16 @@ struct syscall_xsave
         XSAVE_FORMAT       xsave;
         FLOATING_SAVE_AREA fsave;
     } u;
+    struct
+    {
+        ULONG64 mask;
+        ULONG64 compaction_mask;
+        ULONG64 reserved[6];
+        M128A   ymm_high[8];
+    } xstate;
 };
 
-C_ASSERT( sizeof(struct syscall_xsave) == 0x200 );
+C_ASSERT( sizeof(struct syscall_xsave) == 0x2c0 );
 
 struct syscall_frame
 {
@@ -2551,8 +2558,11 @@ void signal_init_process(void)
 void *signal_init_syscalls(void)
 {
     extern void __wine_syscall_dispatcher_fxsave(void) DECLSPEC_HIDDEN;
+    extern void __wine_syscall_dispatcher_xsave(void) DECLSPEC_HIDDEN;
 
-    if (cpu_info.FeatureSet & CPU_FEATURE_FXSR)
+    if (cpu_info.FeatureSet & CPU_FEATURE_XSAVE)
+        syscall_dispatcher = __wine_syscall_dispatcher_xsave;
+    else if (cpu_info.FeatureSet & CPU_FEATURE_FXSR)
         syscall_dispatcher = __wine_syscall_dispatcher_fxsave;
     else
         syscall_dispatcher = __wine_syscall_dispatcher;
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 53d77a19e23..2905f1a4100 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1425,6 +1425,7 @@ static void output_syscall_dispatcher( int count, const char *variant )
 {
     const unsigned int invalid_param = 0xc000000d; /* STATUS_INVALID_PARAMETER */
     const char *symbol = strmake( "__wine_syscall_dispatcher%s", variant );
+    unsigned int i;
 
     output( "\t.align %d\n", get_alignment(4) );
     output( "\t%s\n", func_declaration(symbol) );
@@ -1456,17 +1457,27 @@ static void output_syscall_dispatcher( int count, const char *variant )
         output( "\tmovl %%ecx,-0x28(%%ebp)\n" ); /* frame->esp */
         output( "\tmovl 4(%%ebp),%%ecx\n" );
         output( "\tmovl %%ecx,-0x2c(%%ebp)\n" ); /* frame->eip */
-        output( "\tsubl $0x200,%%esp\n") ;
+        output( "\tsubl $0x2c0,%%esp\n") ;
         output( "\tandl $~63,%%esp\n" );
         if (!*variant)
         {
             output( "\tfnsave (%%esp)\n" );
             output( "\tfwait\n" );
         }
-        else
+        else if(!strcmp( variant, "_fxsave" ))
         {
             output( "\tfxsave (%%esp)\n" );
         }
+        else
+        {
+            output( "\tmovl %%eax,%%ecx\n ");
+            output( "\tmovl $7,%%eax\n" );
+            output( "\txorl %%edx,%%edx\n" );
+            for (i = 0; i < 6; i++)
+                output( "\tmovl %%edx,0x%x(%%esp)\n", 0x200 + i * 4 );
+            output( "\txsave (%%esp)\n" );
+            output( "\tmovl %%ecx,%%eax\n ");
+        }
         output( "\tleal -0x30(%%ebp),%%ecx\n" );
         output( "\tmovl %%ecx,%%fs:0x1f8\n" );  /* x86_thread_data()->syscall_frame */
         output( "\tcmpl $%u,%%eax\n", count );
@@ -1491,7 +1502,7 @@ static void output_syscall_dispatcher( int count, const char *variant )
         else
             output( "\tcall *.Lsyscall_table(,%%eax,4)\n" );
         output( "2:\tmovl $0,%%fs:0x1f8\n" );
-        output( "\tleal -0x230(%%ebp),%%ebx\n") ;
+        output( "\tleal -0x2f0(%%ebp),%%ebx\n") ;
         output( "\tandl $~63,%%ebx\n" );
         if (!*variant)
         {
@@ -1817,6 +1828,7 @@ void output_syscalls( DLLSPEC *spec )
         {
         case CPU_x86:
             output_syscall_dispatcher( count, "_fxsave" );
+            output_syscall_dispatcher( count, "_xsave" );
             break;
         case CPU_x86_64:
             output_syscall_dispatcher( count, "_xsave" );




More information about the wine-cvs mailing list