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