]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/pa/sfp-exceptions.c
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / pa / sfp-exceptions.c
CommitLineData
db89d474 1/*
a945c346 2 * Copyright (C) 1997-2024 Free Software Foundation, Inc.
db89d474
JDA
3 *
4 * This file is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 3, or (at your option) any
7 * later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * Under Section 7 of GPL version 3, you are granted additional
15 * permissions described in the GCC Runtime Library Exception, version
16 * 3.1, as published by the Free Software Foundation.
17 *
18 * You should have received a copy of the GNU General Public License and
19 * a copy of the GCC Runtime Library Exception along with this program;
20 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
21 * <http://www.gnu.org/licenses/>.
22 */
23
24
25#include "sfp-machine.h"
26
27#define HUGE_VAL (__builtin_huge_val ())
28
29/* Please see section 10,
30 page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */
31
32void
33__sfp_handle_exceptions (int _fex)
34{
35 /* Raise exceptions represented by _FEX. But we must raise only one
36 signal at a time. It is important that if the overflow/underflow
37 exception and the divide by zero exception are given at the same
38 time, the overflow/underflow exception follows the divide by zero
39 exception. */
40
41 /* We do these bits in assembly to be certain GCC doesn't optimize
42 away something important, and so we can force delayed traps to
43 occur. */
44
45 /* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */
46
47 /* First: Invalid exception. */
48 if (_fex & FP_EX_INVALID)
49 {
50 /* One example of an invalid operation is 0 * Infinity. */
51 double d = HUGE_VAL;
52 __asm__ __volatile__ (
53 " fcpy,dbl %%fr0,%%fr22\n"
54 " fmpy,dbl %0,%%fr22,%0\n"
55 " fldd 0(%%sr0,%%sp),%0"
56 : "+f" (d) : : "%fr22" );
57 }
58
59 /* Second: Division by zero. */
60 if (_fex & FP_EX_DIVZERO)
61 {
62 double d = 1.0;
63 __asm__ __volatile__ (
64 " fcpy,dbl %%fr0,%%fr22\n"
65 " fdiv,dbl %0,%%fr22,%0\n"
66 " fldd 0(%%sr0,%%sp),%0"
67 : "+f" (d) : : "%fr22" );
68 }
69
70 /* Third: Overflow. */
71 if (_fex & FP_EX_OVERFLOW)
72 {
73 double d = __DBL_MAX__;
74 __asm__ __volatile__ (
75 " fadd,dbl %0,%0,%0\n"
76 " fldd 0(%%sr0,%%sp),%0"
77 : "+f" (d) );
78 }
79
80 /* Fourth: Underflow. */
81 if (_fex & FP_EX_UNDERFLOW)
82 {
83 double d = __DBL_MIN__;
84 double e = 3.0;
85 __asm__ __volatile__ (
86 " fdiv,dbl %0,%1,%0\n"
87 " fldd 0(%%sr0,%%sp),%0"
88 : "+f" (d) : "f" (e) );
89 }
90
91 /* Fifth: Inexact */
92 if (_fex & FP_EX_INEXACT)
93 {
94 double d = 3.14159265358979323846;
95 double e = 69.69;
96 __asm__ __volatile__ (
97 " fdiv,dbl %0,%1,%%fr22\n"
98 " fcnvfxt,dbl,sgl %%fr22,%%fr22L\n"
99 " fldd 0(%%sr0,%%sp),%%fr22"
100 : : "f" (d), "f" (e) : "%fr22" );
101 }
102}