Brendan Shanks : wow64: Copy floating point and extended registers in copy_context_64to32.
Alexandre Julliard
julliard at winehq.org
Wed Aug 3 15:31:40 CDT 2022
Module: wine
Branch: master
Commit: 2599042221d7bcbafd2646178b47801fb080c1ae
URL: https://gitlab.winehq.org/wine/wine/-/commit/2599042221d7bcbafd2646178b47801fb080c1ae
Author: Brendan Shanks <bshanks at codeweavers.com>
Date: Tue Aug 2 10:40:09 2022 -0700
wow64: Copy floating point and extended registers in copy_context_64to32.
---
dlls/wow64cpu/cpu.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/dlls/wow64cpu/cpu.c b/dlls/wow64cpu/cpu.c
index 34c3f3ad493..fa1c22aafc6 100644
--- a/dlls/wow64cpu/cpu.c
+++ b/dlls/wow64cpu/cpu.c
@@ -53,6 +53,51 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved )
return TRUE;
}
+/***********************************************************************
+ * fpux_to_fpu
+ *
+ * Build a standard i386 FPU context from an extended one.
+ */
+static void fpux_to_fpu( I386_FLOATING_SAVE_AREA *fpu, const XMM_SAVE_AREA32 *fpux )
+{
+ unsigned int i, tag, stack_top;
+
+ fpu->ControlWord = fpux->ControlWord;
+ fpu->StatusWord = fpux->StatusWord;
+ 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);
+ }
+}
+
/**********************************************************************
* copy_context_64to32
*
@@ -97,7 +142,15 @@ static void copy_context_64to32( I386_CONTEXT *ctx32, DWORD flags, AMD64_CONTEXT
ctx32->Dr6 = ctx64->Dr6;
ctx32->Dr7 = ctx64->Dr7;
}
- /* FIXME: floating point + xstate */
+ if (flags & CONTEXT_I386_FLOATING_POINT)
+ {
+ fpux_to_fpu( &ctx32->FloatSave, &ctx64->FltSave );
+ }
+ if (flags & CONTEXT_I386_EXTENDED_REGISTERS)
+ {
+ *(XSAVE_FORMAT *)ctx32->ExtendedRegisters = ctx64->FltSave;
+ }
+ /* FIXME: xstate */
}
More information about the wine-cvs
mailing list