1/* Set given exception flags. i386 version.
2 Copyright (C) 2016-2024 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 <fenv.h>
20#include <ldsodefs.h>
21
22int
23fesetexcept (int excepts)
24{
25 /* The flags can be set in the 387 unit or in the SSE unit. To set a flag,
26 it is sufficient to do it in the SSE unit, because that is guaranteed to
27 not trap. However, on i386 CPUs that have only a 387 unit, set the flags
28 in the 387, as long as this cannot trap. */
29
30 excepts &= FE_ALL_EXCEPT;
31
32 if (CPU_FEATURE_USABLE (SSE))
33 {
34 /* Get the control word of the SSE unit. */
35 unsigned int mxcsr;
36 __asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
37
38 /* Set relevant flags. */
39 mxcsr |= excepts;
40
41 /* Put the new data in effect. */
42 __asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
43 }
44 else
45 {
46 fenv_t temp;
47
48 /* Note: fnstenv masks all floating-point exceptions until the fldenv
49 or fldcw below. */
50 __asm__ ("fnstenv %0" : "=m" (*&temp));
51
52 /* Set relevant flags. */
53 temp.__status_word |= excepts;
54
55 if ((~temp.__control_word) & excepts)
56 {
57 /* Setting the exception flags may trigger a trap (at the next
58 floating-point instruction, but that does not matter).
59 ISO C23 (7.6.4.4) does not allow it. */
60 __asm__ volatile ("fldcw %0" : : "m" (*&temp.__control_word));
61 return -1;
62 }
63
64 /* Store the new status word (along with the rest of the environment). */
65 __asm__ ("fldenv %0" : : "m" (*&temp));
66 }
67
68 return 0;
69}
70

source code of glibc/sysdeps/i386/fpu/fesetexcept.c