]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/x86/fpu/test-fenv-sse-2.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / x86 / fpu / test-fenv-sse-2.c
1 /* Test x86-specific floating-point environment (bug 16068): SSE part.
2 Copyright (C) 2015-2020 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <cpuid.h>
20 #include <fenv.h>
21 #include <float.h>
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <stdio.h>
25
26 static bool
27 have_sse2 (void)
28 {
29 unsigned int eax, ebx, ecx, edx;
30
31 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
32 return false;
33
34 return (edx & bit_SSE2) != 0;
35 }
36
37 static uint32_t
38 get_sse_mxcsr (void)
39 {
40 uint32_t temp;
41 __asm__ __volatile__ ("stmxcsr %0" : "=m" (temp));
42 return temp;
43 }
44
45 static void
46 set_sse_mxcsr (uint32_t val)
47 {
48 __asm__ __volatile__ ("ldmxcsr %0" : : "m" (val));
49 }
50
51 static void
52 set_sse_mxcsr_bits (uint32_t mask, uint32_t bits)
53 {
54 uint32_t mxcsr = get_sse_mxcsr ();
55 mxcsr = (mxcsr & ~mask) | bits;
56 set_sse_mxcsr (mxcsr);
57 }
58
59 static int
60 test_sse_mxcsr_bits (const char *test, uint32_t mask, uint32_t bits)
61 {
62 uint32_t mxcsr = get_sse_mxcsr ();
63 printf ("Testing %s: mxcsr = %x\n", test, mxcsr);
64 if ((mxcsr & mask) == bits)
65 {
66 printf ("PASS: %s\n", test);
67 return 0;
68 }
69 else
70 {
71 printf ("FAIL: %s\n", test);
72 return 1;
73 }
74 }
75
76 #define MXCSR_FZ 0x8000
77 #define MXCSR_DAZ 0x40
78 #define MXCSR_DE 0x2
79 #define MXCSR_DM 0x100
80
81 static __attribute__ ((noinline)) int
82 sse_tests (void)
83 {
84 int result = 0;
85 fenv_t env1, env2;
86 /* Test FZ bit. */
87 fegetenv (&env1);
88 set_sse_mxcsr_bits (MXCSR_FZ, MXCSR_FZ);
89 fegetenv (&env2);
90 fesetenv (&env1);
91 result |= test_sse_mxcsr_bits ("fesetenv FZ restoration",
92 MXCSR_FZ, 0);
93 set_sse_mxcsr_bits (MXCSR_FZ, 0);
94 fesetenv (&env2);
95 result |= test_sse_mxcsr_bits ("fesetenv FZ restoration 2",
96 MXCSR_FZ, MXCSR_FZ);
97 set_sse_mxcsr_bits (MXCSR_FZ, MXCSR_FZ);
98 fesetenv (FE_NOMASK_ENV);
99 result |= test_sse_mxcsr_bits ("fesetenv (FE_NOMASK_ENV) FZ restoration",
100 MXCSR_FZ, 0);
101 set_sse_mxcsr_bits (MXCSR_FZ, MXCSR_FZ);
102 fesetenv (FE_DFL_ENV);
103 result |= test_sse_mxcsr_bits ("fesetenv (FE_DFL_ENV) FZ restoration",
104 MXCSR_FZ, 0);
105 /* Test DAZ bit. */
106 set_sse_mxcsr_bits (MXCSR_DAZ, MXCSR_DAZ);
107 fegetenv (&env2);
108 fesetenv (&env1);
109 result |= test_sse_mxcsr_bits ("fesetenv DAZ restoration",
110 MXCSR_DAZ, 0);
111 set_sse_mxcsr_bits (MXCSR_DAZ, 0);
112 fesetenv (&env2);
113 result |= test_sse_mxcsr_bits ("fesetenv DAZ restoration 2",
114 MXCSR_DAZ, MXCSR_DAZ);
115 set_sse_mxcsr_bits (MXCSR_DAZ, MXCSR_DAZ);
116 fesetenv (FE_NOMASK_ENV);
117 result |= test_sse_mxcsr_bits ("fesetenv (FE_NOMASK_ENV) DAZ restoration",
118 MXCSR_DAZ, 0);
119 set_sse_mxcsr_bits (MXCSR_DAZ, MXCSR_DAZ);
120 fesetenv (FE_DFL_ENV);
121 result |= test_sse_mxcsr_bits ("fesetenv (FE_DFL_ENV) DAZ restoration",
122 MXCSR_DAZ, 0);
123 /* Test DM bit. */
124 set_sse_mxcsr_bits (MXCSR_DM, 0);
125 fegetenv (&env2);
126 fesetenv (&env1);
127 result |= test_sse_mxcsr_bits ("fesetenv DM restoration",
128 MXCSR_DM, MXCSR_DM);
129 set_sse_mxcsr_bits (MXCSR_DM, MXCSR_DM);
130 fesetenv (&env2);
131 result |= test_sse_mxcsr_bits ("fesetenv DM restoration 2",
132 MXCSR_DM, 0);
133 set_sse_mxcsr_bits (MXCSR_DM, 0);
134 /* Presume FE_NOMASK_ENV should leave the "denormal operand"
135 exception masked, as not a standard exception. */
136 fesetenv (FE_NOMASK_ENV);
137 result |= test_sse_mxcsr_bits ("fesetenv (FE_NOMASK_ENV) DM restoration",
138 MXCSR_DM, MXCSR_DM);
139 set_sse_mxcsr_bits (MXCSR_DM, 0);
140 fesetenv (FE_DFL_ENV);
141 result |= test_sse_mxcsr_bits ("fesetenv (FE_DFL_ENV) DM restoration",
142 MXCSR_DM, MXCSR_DM);
143 /* Test DE bit. */
144 set_sse_mxcsr_bits (MXCSR_DE, MXCSR_DE);
145 fegetenv (&env2);
146 fesetenv (&env1);
147 result |= test_sse_mxcsr_bits ("fesetenv DE restoration",
148 MXCSR_DE, 0);
149 set_sse_mxcsr_bits (MXCSR_DE, 0);
150 fesetenv (&env2);
151 result |= test_sse_mxcsr_bits ("fesetenv DE restoration 2",
152 MXCSR_DE, MXCSR_DE);
153 set_sse_mxcsr_bits (MXCSR_DE, MXCSR_DE);
154 fesetenv (FE_NOMASK_ENV);
155 result |= test_sse_mxcsr_bits ("fesetenv (FE_NOMASK_ENV) DE restoration",
156 MXCSR_DE, 0);
157 set_sse_mxcsr_bits (MXCSR_DE, MXCSR_DE);
158 fesetenv (FE_DFL_ENV);
159 result |= test_sse_mxcsr_bits ("fesetenv (FE_DFL_ENV) DE restoration",
160 MXCSR_DE, 0);
161 return result;
162 }
163
164 static int
165 do_test (void)
166 {
167 if (!have_sse2 ())
168 {
169 puts ("CPU does not support SSE2, cannot test");
170 return 0;
171 }
172 return sse_tests ();
173 }
174
175 #define TEST_FUNCTION do_test ()
176 #include <test-skeleton.c>