Alexandre Julliard : ntdll: Mac OS support for saving and restoring the extended FPU context on exceptions .
Alexandre Julliard
julliard at winehq.org
Wed Jan 16 07:09:31 CST 2008
Module: wine
Branch: master
Commit: 992de9f487abf009e027ce51c51f94961573bf34
URL: http://source.winehq.org/git/wine.git/?a=commit;h=992de9f487abf009e027ce51c51f94961573bf34
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Jan 15 20:27:14 2008 +0100
ntdll: Mac OS support for saving and restoring the extended FPU context on exceptions.
---
dlls/ntdll/signal_i386.c | 57 +++++++++++++++++++++++++++++++++++++++++----
1 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index b07715c..03729ed 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -304,6 +304,8 @@ typedef ucontext_t SIGCONTEXT;
#define ESP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->__ss.__esp))
#define TRAP_sig(context) ((context)->uc_mcontext->__es.__trapno)
#define ERROR_sig(context) ((context)->uc_mcontext->__es.__err)
+#define FPU_sig(context) NULL
+#define FPUX_sig(context) ((XMM_SAVE_AREA32 *)&(context)->uc_mcontext->__fs.__fpu_fcw)
#else
#define EAX_sig(context) ((context)->uc_mcontext->ss.eax)
#define EBX_sig(context) ((context)->uc_mcontext->ss.ebx)
@@ -323,11 +325,10 @@ typedef ucontext_t SIGCONTEXT;
#define ESP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->ss.esp))
#define TRAP_sig(context) ((context)->uc_mcontext->es.trapno)
#define ERROR_sig(context) ((context)->uc_mcontext->es.err)
+#define FPU_sig(context) NULL
+#define FPUX_sig(context) ((XMM_SAVE_AREA32 *)&(context)->uc_mcontext->fs.fpu_fcw)
#endif
-#define FPU_sig(context) NULL /* FIXME */
-#define FPUX_sig(context) NULL /* FIXME */
-
#endif /* __APPLE__ */
WINE_DEFAULT_DEBUG_CHANNEL(seh);
@@ -703,6 +704,52 @@ static inline void restore_fpux( const CONTEXT *context )
/***********************************************************************
+ * fpux_to_fpu
+ *
+ * Build a standard FPU context from an extended one.
+ */
+static void fpux_to_fpu( FLOATING_SAVE_AREA *fpu, const XMM_SAVE_AREA32 *fpux )
+{
+ unsigned int i, tag, stack_top;
+
+ fpu->ControlWord = fpux->ControlWord | 0xffff0000;
+ fpu->StatusWord = fpux->StatusWord | 0xffff0000;
+ fpu->ErrorOffset = fpux->ErrorOffset;
+ fpu->ErrorSelector = fpux->ErrorSelector | (fpux->ErrorOpcode << 16);
+ fpu->DataOffset = fpux->DataOffset;
+ fpu->DataSelector = fpux->DataSelector;
+ fpu->Cr0NpxState = fpux->StatusWord | 0xffff0000;
+
+ stack_top = (fpux->StatusWord >> 11) & 7;
+ fpu->TagWord = 0xffff0000;
+ for (i = 0; i < 8; i++)
+ {
+ memcpy( &fpu->RegisterArea[10 * i], &fpux->FloatRegisters[i], 10 );
+ if (!(fpux->TagWord & (1 << i))) tag = 3; /* empty */
+ else
+ {
+ const M128A *reg = &fpux->FloatRegisters[(i - stack_top) & 7];
+ if ((reg->High & 0x7fff) == 0x7fff) /* exponent all ones */
+ {
+ tag = 2; /* special */
+ }
+ else if (!(reg->High & 0x7fff)) /* exponent all zeroes */
+ {
+ if (reg->Low) tag = 2; /* special */
+ else tag = 1; /* zero */
+ }
+ else
+ {
+ if (reg->Low >> 63) tag = 0; /* valid */
+ else tag = 2; /* special */
+ }
+ }
+ fpu->TagWord |= tag << (2 * i);
+ }
+}
+
+
+/***********************************************************************
* save_context
*
* Build a context structure from the signal info.
@@ -746,10 +793,10 @@ static inline void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext,
if (fpux)
{
save_fpux( context );
- context->ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
+ context->ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
memcpy( context->ExtendedRegisters, fpux, sizeof(*fpux) );
fpux_support = 1;
- /* FIXME: convert fpux to fpu */
+ if (!fpu) fpux_to_fpu( &context->FloatSave, fpux );
}
if (!fpu && !fpux) save_fpu( context );
}
More information about the wine-cvs
mailing list