mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 20:18:28 +00:00
ntdll: Store extended FPU context in NtGetContextThread().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5ecea50170
commit
edbdec441b
1 changed files with 32 additions and 5 deletions
|
@ -427,8 +427,6 @@ static size_t signal_stack_size;
|
|||
|
||||
static wine_signal_handler handlers[256];
|
||||
|
||||
static BOOL fpux_support; /* whether the CPU supports extended fpu context */
|
||||
|
||||
enum i386_trap_code
|
||||
{
|
||||
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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -985,7 +1012,6 @@ static inline void save_context( CONTEXT *context, const ucontext_t *sigcontext,
|
|||
{
|
||||
context->ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
|
||||
memcpy( context->ExtendedRegisters, fpux, sizeof(*fpux) );
|
||||
fpux_support = TRUE;
|
||||
if (!fpu) fpux_to_fpu( &context->FloatSave, fpux );
|
||||
}
|
||||
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;
|
||||
|
||||
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 );
|
||||
|
||||
if (flags & CONTEXT_DEBUG_REGISTERS)
|
||||
|
@ -1419,7 +1445,8 @@ NTSTATUS CDECL DECLSPEC_HIDDEN __regs_NtGetContextThread( DWORD edi, DWORD esi,
|
|||
context->ContextFlags |= CONTEXT_SEGMENTS;
|
||||
}
|
||||
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 */
|
||||
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue