]>
Commit | Line | Data |
---|---|---|
84e1099f | 1 | /* Raise given exceptions. |
dff8da6b | 2 | Copyright (C) 1997-2024 Free Software Foundation, Inc. |
84e1099f | 3 | This file is part of the GNU C Library. |
84e1099f UD |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or | |
3214b89b AJ |
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. | |
84e1099f UD |
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 | |
3214b89b | 13 | Lesser General Public License for more details. |
84e1099f | 14 | |
3214b89b | 15 | You should have received a copy of the GNU Lesser General Public |
ab84e3ff | 16 | License along with the GNU C Library. If not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
84e1099f UD |
18 | |
19 | #include <fenv.h> | |
e8fcfc26 | 20 | #include <float.h> |
84e1099f UD |
21 | #include <math.h> |
22 | ||
5556231d | 23 | /* Please see section 10, |
2da72a51 UD |
24 | page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */ |
25 | ||
84e1099f | 26 | int |
0747f818 | 27 | __feraiseexcept (int excepts) |
84e1099f UD |
28 | { |
29 | /* Raise exceptions represented by EXCEPTS. But we must raise only one | |
30 | signal at a time. It is important that if the overflow/underflow | |
31 | exception and the divide by zero exception are given at the same | |
32 | time, the overflow/underflow exception follows the divide by zero | |
33 | exception. */ | |
34 | ||
35 | /* We do these bits in assembly to be certain GCC doesn't optimize | |
36 | away something important, and so we can force delayed traps to | |
2da72a51 | 37 | occur. */ |
84e1099f | 38 | |
2da72a51 | 39 | /* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */ |
5556231d | 40 | |
2da72a51 | 41 | /* First: Invalid exception. */ |
84e1099f UD |
42 | if (excepts & FE_INVALID) |
43 | { | |
c0c3f78a | 44 | /* One example of an invalid operation is 0 * Infinity. */ |
84e1099f | 45 | double d = HUGE_VAL; |
2da72a51 UD |
46 | __asm__ __volatile__ ( |
47 | " fcpy,dbl %%fr0,%%fr22\n" | |
48 | " fmpy,dbl %0,%%fr22,%0\n" | |
49 | " fldd 0(%%sr0,%%sp),%0" | |
50 | : "+f" (d) : : "%fr22" ); | |
84e1099f UD |
51 | } |
52 | ||
2da72a51 | 53 | /* Second: Division by zero. */ |
84e1099f UD |
54 | if (excepts & FE_DIVBYZERO) |
55 | { | |
56 | double d = 1.0; | |
2da72a51 UD |
57 | __asm__ __volatile__ ( |
58 | " fcpy,dbl %%fr0,%%fr22\n" | |
59 | " fdiv,dbl %0,%%fr22,%0\n" | |
60 | " fldd 0(%%sr0,%%sp),%0" | |
61 | : "+f" (d) : : "%fr22" ); | |
84e1099f UD |
62 | } |
63 | ||
2da72a51 | 64 | /* Third: Overflow. */ |
84e1099f UD |
65 | if (excepts & FE_OVERFLOW) |
66 | { | |
67 | double d = DBL_MAX; | |
2da72a51 UD |
68 | __asm__ __volatile__ ( |
69 | " fadd,dbl %0,%0,%0\n" | |
70 | " fldd 0(%%sr0,%%sp),%0" | |
71 | : "+f" (d) ); | |
84e1099f UD |
72 | } |
73 | ||
2da72a51 | 74 | /* Fourth: Underflow. */ |
84e1099f UD |
75 | if (excepts & FE_UNDERFLOW) |
76 | { | |
77 | double d = DBL_MIN; | |
2da72a51 UD |
78 | double e = 3.0; |
79 | __asm__ __volatile__ ( | |
80 | " fdiv,dbl %0,%1,%0\n" | |
81 | " fldd 0(%%sr0,%%sp),%0" | |
82 | : "+f" (d) : "f" (e) ); | |
84e1099f UD |
83 | } |
84 | ||
2da72a51 | 85 | /* Fifth: Inexact */ |
84e1099f UD |
86 | if (excepts & FE_INEXACT) |
87 | { | |
2da72a51 UD |
88 | double d = M_PI; |
89 | double e = 69.69; | |
90 | __asm__ __volatile__ ( | |
91 | " fdiv,dbl %0,%1,%%fr22\n" | |
92 | " fcnvfxt,dbl,sgl %%fr22,%%fr22L\n" | |
93 | " fldd 0(%%sr0,%%sp),%%fr22" | |
94 | : : "f" (d), "f" (e) : "%fr22" ); | |
84e1099f UD |
95 | } |
96 | ||
97 | /* Success. */ | |
98 | return 0; | |
99 | } | |
0747f818 JM |
100 | libm_hidden_def (__feraiseexcept) |
101 | weak_alias (__feraiseexcept, feraiseexcept) | |
102 | libm_hidden_weak (feraiseexcept) |