Jacek Caban : ntdll: Use xsavec in x86_64 syscall dispatcher.

Alexandre Julliard julliard at winehq.org
Mon Feb 22 15:43:22 CST 2021


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Feb 22 18:04:31 2021 +0100

ntdll: Use xsavec in x86_64 syscall dispatcher.

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

---

 dlls/ntdll/unix/signal_x86_64.c |  5 ++++-
 dlls/ntdll/unix/system.c        |  6 ++++++
 include/winternl.h              |  1 +
 tools/winebuild/import.c        | 13 ++++++++++++-
 4 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 88e5eace003..df83094750e 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2814,9 +2814,12 @@ void *signal_init_syscalls(void)
     void *ptr, *syscall_dispatcher;
 
     extern void __wine_syscall_dispatcher_xsave(void) DECLSPEC_HIDDEN;
+    extern void __wine_syscall_dispatcher_xsavec(void) DECLSPEC_HIDDEN;
 
     NtQuerySystemInformation( SystemCpuInformation, &cpu_info, sizeof(cpu_info), NULL );
-    if (cpu_info.FeatureSet & CPU_FEATURE_XSAVE)
+    if (cpu_info.FeatureSet & CPU_FEATURE_XSAVEC)
+        syscall_dispatcher = __wine_syscall_dispatcher_xsavec;
+    else if (cpu_info.FeatureSet & CPU_FEATURE_XSAVE)
         syscall_dispatcher = __wine_syscall_dispatcher_xsave;
     else
         syscall_dispatcher = __wine_syscall_dispatcher;
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index 6cf044d496f..27ecfae365f 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -305,6 +305,12 @@ static void get_cpuinfo( SYSTEM_CPU_INFORMATION *info )
             if (regs3[1] & (1 << 5)) info->FeatureSet |= CPU_FEATURE_AVX2;
         }
 
+        if (info->FeatureSet & CPU_FEATURE_XSAVE)
+        {
+            do_cpuid( 0x0000000d, regs3 ); /* get XSAVE details */
+            if (regs3[0] & 2) info->FeatureSet |= CPU_FEATURE_XSAVEC;
+        }
+
         if (regs[1] == AUTH && regs[3] == ENTI && regs[2] == CAMD)
         {
             info->Level = (regs2[0] >> 8) & 0xf; /* family */
diff --git a/include/winternl.h b/include/winternl.h
index 76feca83596..3beecf10ff6 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1754,6 +1754,7 @@ typedef struct _SYSTEM_CPU_INFORMATION {
 
 /* FIXME: following values are made up, actual flags are unknown */
 #define CPU_FEATURE_SSSE3         0x00008000   /* SSSE3 instructions */
+#define CPU_FEATURE_XSAVEC        0x00400000   /* XSAVEC instructions */
 #define CPU_FEATURE_SSE41         0x01000000   /* SSE41 instructions */
 #define CPU_FEATURE_SSE42         0x02000000   /* SSE42 instructions */
 #define CPU_FEATURE_AVX           0x40000000   /* AVX instructions */
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index a01694ffb9c..2fa9d3d430b 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1534,7 +1534,17 @@ static void output_syscall_dispatcher( int count, const char *variant )
             output( "\tmovq %%rdx,0x200(%%r12)\n" );
             output( "\tmovq %%rdx,0x208(%%r12)\n" );
             output( "\tmovq %%rdx,0x210(%%r12)\n" );
-            output( "\txsave64 (%%r12)\n" );
+            if (!strcmp( variant, "_xsavec" ))
+            {
+                output( "\tmovq %%rdx,0x218(%%r12)\n" );
+                output( "\tmovq %%rdx,0x220(%%r12)\n" );
+                output( "\tmovq %%rdx,0x228(%%r12)\n" );
+                output( "\tmovq %%rdx,0x230(%%r12)\n" );
+                output( "\tmovq %%rdx,0x238(%%r12)\n" );
+                output( "\txsavec64 (%%r12)\n" );
+            }
+            else
+                output( "\txsave64 (%%r12)\n" );
             output( "\tmovq %%rsi,%%rdx\n" );
         }
         output( "\tmovq %%gs:0x30,%%rcx\n" );
@@ -1740,6 +1750,7 @@ void output_syscalls( DLLSPEC *spec )
         {
         case CPU_x86_64:
             output_syscall_dispatcher( count, "_xsave" );
+            output_syscall_dispatcher( count, "_xsavec" );
             break;
         default:
             break;




More information about the wine-cvs mailing list