ntdll: Store extended FPU context in NtGetContextThread().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5ecea50170
commit
edbdec441b
|
@ -427,8 +427,6 @@ static size_t signal_stack_size;
|
||||||
|
|
||||||
static wine_signal_handler handlers[256];
|
static wine_signal_handler handlers[256];
|
||||||
|
|
||||||
static BOOL fpux_support; /* whether the CPU supports extended fpu context */
|
|
||||||
|
|
||||||
enum i386_trap_code
|
enum i386_trap_code
|
||||||
{
|
{
|
||||||
TRAP_x86_UNKNOWN = -1, /* Unknown fault (TRAP_sig not defined) */
|
TRAP_x86_UNKNOWN = -1, /* Unknown fault (TRAP_sig not defined) */
|
||||||
|
@ -558,6 +556,15 @@ static inline void *get_signal_stack(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* has_fpux
|
||||||
|
*/
|
||||||
|
static inline int has_fpux(void)
|
||||||
|
{
|
||||||
|
return (cpu_info.FeatureSet & CPU_FEATURE_FXSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* get_current_teb
|
* get_current_teb
|
||||||
*
|
*
|
||||||
|
@ -859,6 +866,26 @@ static inline void save_fpu( CONTEXT *context )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* save_fpux
|
||||||
|
*
|
||||||
|
* Save the thread FPU extended context.
|
||||||
|
*/
|
||||||
|
static inline void save_fpux( CONTEXT *context )
|
||||||
|
{
|
||||||
|
#ifdef __GNUC__
|
||||||
|
/* we have to enforce alignment by hand */
|
||||||
|
char buffer[sizeof(XMM_SAVE_AREA32) + 16];
|
||||||
|
XMM_SAVE_AREA32 *state = (XMM_SAVE_AREA32 *)(((ULONG_PTR)buffer + 15) & ~15);
|
||||||
|
|
||||||
|
if (!has_fpux()) return;
|
||||||
|
context->ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
|
||||||
|
__asm__ __volatile__( "fxsave %0" : "=m" (*state) );
|
||||||
|
memcpy( context->ExtendedRegisters, state, sizeof(*state) );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* restore_fpu
|
* restore_fpu
|
||||||
*
|
*
|
||||||
|
@ -985,7 +1012,6 @@ static inline void save_context( CONTEXT *context, const ucontext_t *sigcontext,
|
||||||
{
|
{
|
||||||
context->ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
|
context->ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
|
||||||
memcpy( context->ExtendedRegisters, fpux, sizeof(*fpux) );
|
memcpy( context->ExtendedRegisters, fpux, sizeof(*fpux) );
|
||||||
fpux_support = TRUE;
|
|
||||||
if (!fpu) fpux_to_fpu( &context->FloatSave, fpux );
|
if (!fpu) fpux_to_fpu( &context->FloatSave, fpux );
|
||||||
}
|
}
|
||||||
if (!fpu && !fpux) save_fpu( context );
|
if (!fpu && !fpux) save_fpu( context );
|
||||||
|
@ -1137,7 +1163,7 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
|
||||||
{
|
{
|
||||||
DWORD flags = context->ContextFlags & ~CONTEXT_i386;
|
DWORD flags = context->ContextFlags & ~CONTEXT_i386;
|
||||||
|
|
||||||
if ((flags & CONTEXT_EXTENDED_REGISTERS) && fpux_support) restore_fpux( context );
|
if ((flags & CONTEXT_EXTENDED_REGISTERS) && has_fpux()) restore_fpux( context );
|
||||||
else if (flags & CONTEXT_FLOATING_POINT) restore_fpu( context );
|
else if (flags & CONTEXT_FLOATING_POINT) restore_fpu( context );
|
||||||
|
|
||||||
if (flags & CONTEXT_DEBUG_REGISTERS)
|
if (flags & CONTEXT_DEBUG_REGISTERS)
|
||||||
|
@ -1419,7 +1445,8 @@ NTSTATUS CDECL DECLSPEC_HIDDEN __regs_NtGetContextThread( DWORD edi, DWORD esi,
|
||||||
context->ContextFlags |= CONTEXT_SEGMENTS;
|
context->ContextFlags |= CONTEXT_SEGMENTS;
|
||||||
}
|
}
|
||||||
if (needed_flags & CONTEXT_FLOATING_POINT) save_fpu( context );
|
if (needed_flags & CONTEXT_FLOATING_POINT) save_fpu( context );
|
||||||
/* FIXME: extended floating point */
|
if (needed_flags & CONTEXT_EXTENDED_REGISTERS) save_fpux( context );
|
||||||
|
/* FIXME: xstate */
|
||||||
/* update the cached version of the debug registers */
|
/* update the cached version of the debug registers */
|
||||||
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))
|
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue