From 5d228d6fc977d0b7927f78d28f712e88954599e5 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 2 Mar 2021 18:46:29 +0100 Subject: [PATCH] ntdll: Store x86 YMM context insyscall dispatcher. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- 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" );