1 /* $NetBSD: except.c,v 1.10 2006/05/10 19:07:22 mrg Exp $ */
4 * Copyright (c) 1995 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
37 void sigfpe(int, siginfo_t
*, void *);
38 volatile sig_atomic_t signal_caught
;
45 #define FPTYPE long double
50 static volatile const FPTYPE one
= 1.0;
51 static volatile const FPTYPE zero
= 0.0;
53 static volatile const float huge
= FLT_MAX
;
54 static volatile const float tiny
= FLT_MIN
;
57 static volatile const long double huge
= LDBL_MAX
;
58 static volatile const long double tiny
= LDBL_MIN
;
60 static volatile const double huge
= DBL_MAX
;
61 static volatile const double tiny
= DBL_MIN
;
64 static volatile FPTYPE x
;
66 /* trip divide by zero */
74 /* trip invalid operation */
103 { dz
, FP_X_DZ
, FPE_FLTDIV
},
104 { inv
, FP_X_INV
, FPE_FLTINV
},
105 { ofl
, FP_X_OFL
, FPE_FLTOVF
},
106 { ufl
, FP_X_UFL
, FPE_FLTUND
}
118 * check to make sure that all exceptions are masked and
119 * that the accumulated exception status is clear.
121 assert(fpgetmask() == 0);
122 assert(fpgetsticky() == 0);
124 /* set up signal handler */
125 sa
.sa_sigaction
= sigfpe
;
126 sigemptyset(&sa
.sa_mask
);
127 sa
.sa_flags
= SA_SIGINFO
;
128 sigaction(SIGFPE
, &sa
, 0);
132 * exceptions masked, check whether "sticky" bits are set correctly
134 for (i
= 0; i
< sizeof(ops
)/sizeof(ops
[0]); i
++) {
137 assert(ex1
& ops
[i
].mask
);
138 assert(signal_caught
== 0);
139 /* check correct fpsetsticky() behaviour */
140 ex2
= fpsetsticky(0);
141 assert(fpgetsticky() == 0);
145 /* force delayed exceptions to be delivered */
146 #define BARRIER() fpsetmask(0); x = one * one
148 * exception unmasked, check SIGFPE delivery and correct siginfo
150 for (i
= 0; i
< sizeof(ops
)/sizeof(ops
[0]); i
++) {
151 fpsetmask(ops
[i
].mask
);
157 assert(signal_caught
== 1);
158 assert(sicode
== ops
[i
].sicode
);
166 sigfpe(int s
, siginfo_t
*si
, void *c
)
169 sicode
= si
->si_code
;