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:
parent
0712b6b1a0
commit
5d228d6fc9
|
@ -468,9 +468,16 @@ struct syscall_xsave
|
||||||
XSAVE_FORMAT xsave;
|
XSAVE_FORMAT xsave;
|
||||||
FLOATING_SAVE_AREA fsave;
|
FLOATING_SAVE_AREA fsave;
|
||||||
} u;
|
} 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
|
struct syscall_frame
|
||||||
{
|
{
|
||||||
|
@ -2551,8 +2558,11 @@ void signal_init_process(void)
|
||||||
void *signal_init_syscalls(void)
|
void *signal_init_syscalls(void)
|
||||||
{
|
{
|
||||||
extern void __wine_syscall_dispatcher_fxsave(void) DECLSPEC_HIDDEN;
|
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;
|
syscall_dispatcher = __wine_syscall_dispatcher_fxsave;
|
||||||
else
|
else
|
||||||
syscall_dispatcher = __wine_syscall_dispatcher;
|
syscall_dispatcher = __wine_syscall_dispatcher;
|
||||||
|
|
|
@ -1425,6 +1425,7 @@ static void output_syscall_dispatcher( int count, const char *variant )
|
||||||
{
|
{
|
||||||
const unsigned int invalid_param = 0xc000000d; /* STATUS_INVALID_PARAMETER */
|
const unsigned int invalid_param = 0xc000000d; /* STATUS_INVALID_PARAMETER */
|
||||||
const char *symbol = strmake( "__wine_syscall_dispatcher%s", variant );
|
const char *symbol = strmake( "__wine_syscall_dispatcher%s", variant );
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
output( "\t.align %d\n", get_alignment(4) );
|
output( "\t.align %d\n", get_alignment(4) );
|
||||||
output( "\t%s\n", func_declaration(symbol) );
|
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 %%ecx,-0x28(%%ebp)\n" ); /* frame->esp */
|
||||||
output( "\tmovl 4(%%ebp),%%ecx\n" );
|
output( "\tmovl 4(%%ebp),%%ecx\n" );
|
||||||
output( "\tmovl %%ecx,-0x2c(%%ebp)\n" ); /* frame->eip */
|
output( "\tmovl %%ecx,-0x2c(%%ebp)\n" ); /* frame->eip */
|
||||||
output( "\tsubl $0x200,%%esp\n") ;
|
output( "\tsubl $0x2c0,%%esp\n") ;
|
||||||
output( "\tandl $~63,%%esp\n" );
|
output( "\tandl $~63,%%esp\n" );
|
||||||
if (!*variant)
|
if (!*variant)
|
||||||
{
|
{
|
||||||
output( "\tfnsave (%%esp)\n" );
|
output( "\tfnsave (%%esp)\n" );
|
||||||
output( "\tfwait\n" );
|
output( "\tfwait\n" );
|
||||||
}
|
}
|
||||||
else
|
else if(!strcmp( variant, "_fxsave" ))
|
||||||
{
|
{
|
||||||
output( "\tfxsave (%%esp)\n" );
|
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( "\tleal -0x30(%%ebp),%%ecx\n" );
|
||||||
output( "\tmovl %%ecx,%%fs:0x1f8\n" ); /* x86_thread_data()->syscall_frame */
|
output( "\tmovl %%ecx,%%fs:0x1f8\n" ); /* x86_thread_data()->syscall_frame */
|
||||||
output( "\tcmpl $%u,%%eax\n", count );
|
output( "\tcmpl $%u,%%eax\n", count );
|
||||||
|
@ -1491,7 +1502,7 @@ static void output_syscall_dispatcher( int count, const char *variant )
|
||||||
else
|
else
|
||||||
output( "\tcall *.Lsyscall_table(,%%eax,4)\n" );
|
output( "\tcall *.Lsyscall_table(,%%eax,4)\n" );
|
||||||
output( "2:\tmovl $0,%%fs:0x1f8\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" );
|
output( "\tandl $~63,%%ebx\n" );
|
||||||
if (!*variant)
|
if (!*variant)
|
||||||
{
|
{
|
||||||
|
@ -1817,6 +1828,7 @@ void output_syscalls( DLLSPEC *spec )
|
||||||
{
|
{
|
||||||
case CPU_x86:
|
case CPU_x86:
|
||||||
output_syscall_dispatcher( count, "_fxsave" );
|
output_syscall_dispatcher( count, "_fxsave" );
|
||||||
|
output_syscall_dispatcher( count, "_xsave" );
|
||||||
break;
|
break;
|
||||||
case CPU_x86_64:
|
case CPU_x86_64:
|
||||||
output_syscall_dispatcher( count, "_xsave" );
|
output_syscall_dispatcher( count, "_xsave" );
|
||||||
|
|
Loading…
Reference in New Issue