1 /* Raise given exceptions.
2 Copyright (C) 2001-2014 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 <http://www.gnu.org/licenses/>. */
23 __feraiseexcept (int excepts
)
25 /* Raise exceptions represented by EXPECTS. But we must raise only
26 one signal at a time. It is important that if the overflow/underflow
27 exception and the inexact exception are given at the same time,
28 the overflow/underflow exception follows the inexact exception. */
30 /* First: invalid exception. */
31 if ((FE_INVALID
& excepts
) != 0)
33 /* One example of an invalid operation is 0.0 / 0.0. */
36 __asm__
__volatile__ ("divss %0, %0 " : : "x" (f
));
40 /* Next: division by zero. */
41 if ((FE_DIVBYZERO
& excepts
) != 0)
46 __asm__
__volatile__ ("divss %1, %0" : : "x" (f
), "x" (g
));
51 if ((FE_OVERFLOW
& excepts
) != 0)
53 /* XXX: Is it ok to only set the x87 FPU? */
54 /* There is no way to raise only the overflow flag. Do it the
58 /* Bah, we have to clear selected exceptions. Since there is no
59 `fldsw' instruction we have to do it the hard way. */
60 __asm__
__volatile__ ("fnstenv %0" : "=m" (*&temp
));
62 /* Set the relevant bits. */
63 temp
.__status_word
|= FE_OVERFLOW
;
65 /* Put the new data in effect. */
66 __asm__
__volatile__ ("fldenv %0" : : "m" (*&temp
));
68 /* And raise the exception. */
69 __asm__
__volatile__ ("fwait");
72 /* Next: underflow. */
73 if ((FE_UNDERFLOW
& excepts
) != 0)
75 /* XXX: Is it ok to only set the x87 FPU? */
76 /* There is no way to raise only the underflow flag. Do it the
80 /* Bah, we have to clear selected exceptions. Since there is no
81 `fldsw' instruction we have to do it the hard way. */
82 __asm__
__volatile__ ("fnstenv %0" : "=m" (*&temp
));
84 /* Set the relevant bits. */
85 temp
.__status_word
|= FE_UNDERFLOW
;
87 /* Put the new data in effect. */
88 __asm__
__volatile__ ("fldenv %0" : : "m" (*&temp
));
90 /* And raise the exception. */
91 __asm__
__volatile__ ("fwait");
95 if ((FE_INEXACT
& excepts
) != 0)
97 /* XXX: Is it ok to only set the x87 FPU? */
98 /* There is no way to raise only the inexact flag. Do it the
102 /* Bah, we have to clear selected exceptions. Since there is no
103 `fldsw' instruction we have to do it the hard way. */
104 __asm__
__volatile__ ("fnstenv %0" : "=m" (*&temp
));
106 /* Set the relevant bits. */
107 temp
.__status_word
|= FE_INEXACT
;
109 /* Put the new data in effect. */
110 __asm__
__volatile__ ("fldenv %0" : : "m" (*&temp
));
112 /* And raise the exception. */
113 __asm__
__volatile__ ("fwait");
119 strong_alias (__feraiseexcept
, feraiseexcept
)
120 libm_hidden_def (feraiseexcept
)