Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Smith <dannysmith@users.sourceforge.net>2006-07-03 14:32:58 +0400
committerDanny Smith <dannysmith@users.sourceforge.net>2006-07-03 14:32:58 +0400
commitf34428eb356a001928e1786d51cbfe216ebeef83 (patch)
treed6319e46a0cc4bdaae18f49f4a4ad821677f895e /winsup/mingw/cpu_features.c
parent69d5f3329f4869d6d0e20f610926934fc0044dce (diff)
Support SSE float environment in fenv.h functions.
* cpu_features.c: New file. * cpu_features.h: New file. * crt1.c: Include "cpu_features.h". (__mingw_CRTStartup): Call cpu_features_init(). * Makefile.in (MING_OBJS): Add cpu_features.c. (SRCDIST_FILES): Add cpu_features.c, cpu_features.h. * include/fenv,h ( fenv_t;): Append __mxcsr field. (__MXCSR_EXCEPT_FLAG_SHIFT): New define. (__MXCSR_EXCEPT_MASK_SHIFT): New define. (__MXCSR_ROUND_FLAG_SHIFT): New define. * mingwex/feclearexcept.c: Include "cpu_features.h". Handle SSE environment. * mingwex/fegetenv.c: Likewise. * mingwex/feholdexcept.c: Likewise. * mingwex/fesetenv.c: Likewise. * mingwex/fesetexceptflag.c: Likewise. * mingwex/fesetround.c: Likewise. * mingwex/fetestexcept.c: Likewise. * mingwex/feupdateenv.c: Likewise. * mingwex/fegetround.c: Add comment.
Diffstat (limited to 'winsup/mingw/cpu_features.c')
-rwxr-xr-xwinsup/mingw/cpu_features.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/winsup/mingw/cpu_features.c b/winsup/mingw/cpu_features.c
new file mode 100755
index 000000000..0eccfbfe3
--- /dev/null
+++ b/winsup/mingw/cpu_features.c
@@ -0,0 +1,105 @@
+#include <stdbool.h>
+#include "cpu_features.h"
+
+/* level 1 edx bits */
+#define EDX_CX8 (1 << 8) /* CMPXCHG8B */
+#define EDX_CMOV (1 << 15)
+#define EDX_MMX (1 << 23)
+#define EDX_FXSR (1 << 24) /* FXSAVE and FXRSTOR */
+#define EDX_SSE (1 << 25)
+#define EDX_SSE2 (1 << 26)
+
+/* level 1 ecx bits */
+#define ECX_SSE3 (1 << 0)
+#define ECX_CX16 (1 << 13) /* CMPXCHG16B */
+
+/* extended level 0x80000001 edx bits */
+#define EDX_3DNOW (1 << 31)
+#define EDX_3DNOWP (1 << 30)
+#define EDX_LM (1 << 29) /*LONG MODE */
+
+#define __cpuid(level,a,b,c,d) \
+ __asm__ __volatile__ ("cpuid;" \
+ : "=a" (a), "=b" (b), "=c" (c), "=d" (d)\
+ : "0" (level))
+
+/* Combine the different cpuid flags into a single bitmap. */
+
+unsigned int __cpu_features = 0;
+
+void __cpu_features_init (void)
+{
+ unsigned int eax, ebx, ecx, edx;
+ /* Try to change the value of CPUID bit (bit 21) in EFLAGS.
+ If the bit can be toggled, CPUID is supported. */
+ asm volatile ("pushfl; pushfl; popl %0;"
+ "movl %0,%1; xorl %2,%0;"
+ "pushl %0; popfl; pushfl; popl %0; popfl"
+ : "=&r" (eax), "=&r" (ebx)
+ : "i" (0x00200000));
+
+ if (((eax ^ ebx) & 0x00200000) == 0)
+ return;
+
+ __cpuid (0, eax, ebx, ecx, edx);
+ if (eax == 0)
+ return;
+
+ __cpuid (1, eax, ebx, ecx, edx);
+
+ if (edx & EDX_CX8)
+ __cpu_features |= _CRT_CMPXCHG8B;
+ if (edx & EDX_CMOV)
+ __cpu_features |= _CRT_CMOV;
+
+ if (edx & EDX_MMX)
+ __cpu_features |= _CRT_MMX;
+ if (edx & EDX_FXSR)
+ __cpu_features |= _CRT_FXSR;
+ if (edx & EDX_SSE)
+ __cpu_features |= _CRT_SSE;
+ if (edx & EDX_SSE2)
+ __cpu_features |= _CRT_SSE2;
+
+
+ if (ecx & ECX_SSE3)
+ __cpu_features |= _CRT_SSE3;
+ if (ecx & ECX_CX16)
+ __cpu_features |= _CRT_CMPXCHG16B;
+
+ __cpuid (0x80000000, eax, ebx, ecx, edx);
+ if (eax < 0x80000001)
+ return;
+ __cpuid (0x80000001, eax, ebx, ecx, edx);
+ if (edx & EDX_3DNOW);
+ __cpu_features |= _CRT_3DNOW;
+ if (edx & EDX_3DNOWP)
+ __cpu_features |= _CRT_3DNOWP;
+
+ return;
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+#define report(feature) \
+ if ((feature) & __cpu_features) printf( #feature " found\n")
+
+int main()
+{
+ __cpu_features_init();
+
+ report(_CRT_CMPXCHG8B);
+ report(_CRT_CMOV);
+ report(_CRT_MMX);
+ report(_CRT_FXSR);
+ report(_CRT_SSE);
+ report(_CRT_SSE2);
+ report(_CRT_SSE3);
+ report(_CRT_CMPXCHG16B);
+ report(_CRT_3DNOW);
+ report(_CRT_3DNOWP);
+ return 0;
+}
+
+#endif