riscv: Fix feenvupdate with FE_DFL_ENV (BZ 31022)
[glibc.git] / sysdeps / x86 / fpu / test-fenv-sse.c
blob46ec963f5518607287a4db7b34bac8fca6bb189a
1 /* Test floating-point environment includes SSE state (bug 16064).
2 Copyright (C) 2014-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
19 #include <cpuid.h>
20 #include <fenv.h>
21 #include <float.h>
22 #include <stdbool.h>
23 #include <stdio.h>
25 static bool
26 have_sse2 (void)
28 unsigned int eax, ebx, ecx, edx;
30 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
31 return false;
33 return (edx & bit_SSE2) != 0;
36 static __attribute__ ((noinline)) int
37 sse_tests (void)
39 int ret = 0;
40 fenv_t base_env;
41 if (fegetenv (&base_env) != 0)
43 puts ("fegetenv (&base_env) failed");
44 return 1;
46 if (fesetround (FE_UPWARD) != 0)
48 puts ("fesetround (FE_UPWARD) failed");
49 return 1;
51 if (fesetenv (&base_env) != 0)
53 puts ("fesetenv (&base_env) failed");
54 return 1;
56 volatile float a = 1.0f, b = FLT_MIN, c;
57 c = a + b;
58 if (c != 1.0f)
60 puts ("fesetenv did not restore rounding mode");
61 ret = 1;
63 if (fesetround (FE_DOWNWARD) != 0)
65 puts ("fesetround (FE_DOWNWARD) failed");
66 return 1;
68 if (feupdateenv (&base_env) != 0)
70 puts ("feupdateenv (&base_env) failed");
71 return 1;
73 volatile float d = -FLT_MIN, e;
74 e = a + d;
75 if (e != 1.0f)
77 puts ("feupdateenv did not restore rounding mode");
78 ret = 1;
80 if (fesetround (FE_UPWARD) != 0)
82 puts ("fesetround (FE_UPWARD) failed");
83 return 1;
85 fenv_t upward_env;
86 if (feholdexcept (&upward_env) != 0)
88 puts ("feholdexcept (&upward_env) failed");
89 return 1;
91 if (fesetround (FE_DOWNWARD) != 0)
93 puts ("fesetround (FE_DOWNWARD) failed");
94 return 1;
96 if (fesetenv (&upward_env) != 0)
98 puts ("fesetenv (&upward_env) failed");
99 return 1;
101 e = a + d;
102 if (e != 1.0f)
104 puts ("fesetenv did not restore rounding mode from feholdexcept");
105 ret = 1;
107 if (fesetround (FE_UPWARD) != 0)
109 puts ("fesetround (FE_UPWARD) failed");
110 return 1;
112 if (fesetenv (FE_DFL_ENV) != 0)
114 puts ("fesetenv (FE_DFL_ENV) failed");
115 return 1;
117 c = a + b;
118 if (c != 1.0f)
120 puts ("fesetenv (FE_DFL_ENV) did not restore rounding mode");
121 ret = 1;
123 return ret;
126 static int
127 do_test (void)
129 if (!have_sse2 ())
131 puts ("CPU does not support SSE2, cannot test");
132 return 0;
134 return sse_tests ();
137 #define TEST_FUNCTION do_test ()
138 #include <test-skeleton.c>