James Eder : ntdll: Add detection for PF_SSE_DAZ_MODE_AVAILABLE.
Alexandre Julliard
julliard at winehq.org
Mon Oct 22 13:42:44 CDT 2012
Module: wine
Branch: master
Commit: a6eec2cf6a6285cd44408f051ef33f463ea1c0fb
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a6eec2cf6a6285cd44408f051ef33f463ea1c0fb
Author: James Eder <jimportal at gmail.com>
Date: Sat Oct 20 18:40:47 2012 -0600
ntdll: Add detection for PF_SSE_DAZ_MODE_AVAILABLE.
---
dlls/ntdll/nt.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index c1cf38b..3f8e772 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -866,6 +866,49 @@ static inline int have_cpuid(void)
#endif
}
+/* Detect if a SSE2 processor is capable of Denormals Are Zero (DAZ) mode.
+ *
+ * This function assumes you have already checked for SSE2/FXSAVE support. */
+static inline int have_sse_daz_mode(void)
+{
+#ifdef __i386__
+ typedef struct DECLSPEC_ALIGN(16) _M128A {
+ ULONGLONG Low;
+ LONGLONG High;
+ } M128A;
+
+ typedef struct _XMM_SAVE_AREA32 {
+ WORD ControlWord;
+ WORD StatusWord;
+ BYTE TagWord;
+ BYTE Reserved1;
+ WORD ErrorOpcode;
+ DWORD ErrorOffset;
+ WORD ErrorSelector;
+ WORD Reserved2;
+ DWORD DataOffset;
+ WORD DataSelector;
+ WORD Reserved3;
+ DWORD MxCsr;
+ DWORD MxCsr_Mask;
+ M128A FloatRegisters[8];
+ M128A XmmRegisters[16];
+ BYTE Reserved4[96];
+ } XMM_SAVE_AREA32;
+
+ /* Intel says we need a zeroed 16-byte aligned buffer */
+ char buffer[512 + 16];
+ XMM_SAVE_AREA32 *state = (XMM_SAVE_AREA32 *)(((ULONG_PTR)buffer + 15) & ~15);
+ memset(buffer, 0, sizeof(buffer));
+
+ __asm__ __volatile__( "fxsave %0" : "=m" (*state) : "m" (*state) );
+
+ return (state->MxCsr_Mask & (1 << 6)) >> 6;
+#else /* all x86_64 processors include SSE2 with DAZ mode */
+ return 1;
+#endif
+}
+
static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
{
unsigned int regs[4], regs2[4];
@@ -904,6 +947,9 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
user_shared_data->ProcessorFeatures[PF_XSAVE_ENABLED] = (regs2[2] & (1 << 27)) >> 27;
user_shared_data->ProcessorFeatures[PF_COMPARE_EXCHANGE128] = (regs2[2] & (1 << 13)) >> 13;
+ if((regs2[3] & (1 << 26)) && (regs2[3] & (1 << 24))) /* has SSE2 and FXSAVE/FXRSTOR */
+ user_shared_data->ProcessorFeatures[PF_SSE_DAZ_MODE_AVAILABLE] = have_sse_daz_mode();
+
if (regs[1] == AUTH && regs[3] == ENTI && regs[2] == CAMD)
{
info->Level = (regs2[0] >> 8) & 0xf; /* family */
More information about the wine-cvs
mailing list