ntdll: Store x86 YMM context insyscall dispatcher.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-03-02 18:46:29 +01:00 committed by Alexandre Julliard
parent 0712b6b1a0
commit 5d228d6fc9
2 changed files with 27 additions and 5 deletions

View File

@ -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;

View File

@ -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" );