1*86d7f5d3SJohn Marino /* __gmp_invalid_operation -- invalid floating point operation.
2*86d7f5d3SJohn Marino
3*86d7f5d3SJohn Marino THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
4*86d7f5d3SJohn Marino CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
5*86d7f5d3SJohn Marino FUTURE GNU MP RELEASES.
6*86d7f5d3SJohn Marino
7*86d7f5d3SJohn Marino Copyright 2003 Free Software Foundation, Inc.
8*86d7f5d3SJohn Marino
9*86d7f5d3SJohn Marino This file is part of the GNU MP Library.
10*86d7f5d3SJohn Marino
11*86d7f5d3SJohn Marino The GNU MP Library is free software; you can redistribute it and/or modify
12*86d7f5d3SJohn Marino it under the terms of the GNU Lesser General Public License as published by
13*86d7f5d3SJohn Marino the Free Software Foundation; either version 3 of the License, or (at your
14*86d7f5d3SJohn Marino option) any later version.
15*86d7f5d3SJohn Marino
16*86d7f5d3SJohn Marino The GNU MP Library is distributed in the hope that it will be useful, but
17*86d7f5d3SJohn Marino WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18*86d7f5d3SJohn Marino or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
19*86d7f5d3SJohn Marino License for more details.
20*86d7f5d3SJohn Marino
21*86d7f5d3SJohn Marino You should have received a copy of the GNU Lesser General Public License
22*86d7f5d3SJohn Marino along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
23*86d7f5d3SJohn Marino
24*86d7f5d3SJohn Marino #include "config.h"
25*86d7f5d3SJohn Marino
26*86d7f5d3SJohn Marino #include <signal.h>
27*86d7f5d3SJohn Marino #include <stdlib.h>
28*86d7f5d3SJohn Marino
29*86d7f5d3SJohn Marino #if HAVE_UNISTD_H
30*86d7f5d3SJohn Marino #include <unistd.h> /* for getpid */
31*86d7f5d3SJohn Marino #endif
32*86d7f5d3SJohn Marino
33*86d7f5d3SJohn Marino #include "gmp.h"
34*86d7f5d3SJohn Marino #include "gmp-impl.h"
35*86d7f5d3SJohn Marino
36*86d7f5d3SJohn Marino
37*86d7f5d3SJohn Marino /* Incidentally, kill is not available on mingw, but that's ok, it has raise
38*86d7f5d3SJohn Marino and we'll be using that. */
39*86d7f5d3SJohn Marino #if ! HAVE_RAISE
40*86d7f5d3SJohn Marino #define raise(sig) kill (getpid(), sig)
41*86d7f5d3SJohn Marino #endif
42*86d7f5d3SJohn Marino
43*86d7f5d3SJohn Marino
44*86d7f5d3SJohn Marino /* __gmp_invalid_operation is for an invalid floating point operation, like
45*86d7f5d3SJohn Marino mpz_set_d on a NaN or Inf. It's done as a subroutine to minimize code in
46*86d7f5d3SJohn Marino places raising an exception.
47*86d7f5d3SJohn Marino
48*86d7f5d3SJohn Marino feraiseexcept(FE_INVALID) is not used here, since unfortunately on most
49*86d7f5d3SJohn Marino systems it would require libm.
50*86d7f5d3SJohn Marino
51*86d7f5d3SJohn Marino Alternatives:
52*86d7f5d3SJohn Marino
53*86d7f5d3SJohn Marino It might be possible to check whether a hardware "invalid operation" trap
54*86d7f5d3SJohn Marino is enabled or not before raising a signal. This would require all
55*86d7f5d3SJohn Marino callers to be prepared to continue with some bogus result. Bogus returns
56*86d7f5d3SJohn Marino are bad, but presumably an application disabling the trap is prepared for
57*86d7f5d3SJohn Marino that.
58*86d7f5d3SJohn Marino
59*86d7f5d3SJohn Marino On some systems (eg. BSD) the signal handler can find out the reason for
60*86d7f5d3SJohn Marino a SIGFPE (overflow, invalid, div-by-zero, etc). Perhaps we could get
61*86d7f5d3SJohn Marino that into our raise too.
62*86d7f5d3SJohn Marino
63*86d7f5d3SJohn Marino i386 GLIBC implements feraiseexcept(FE_INVALID) with an asm fdiv 0/0.
64*86d7f5d3SJohn Marino That would both respect the exceptions mask and give a reason code in a
65*86d7f5d3SJohn Marino BSD signal. */
66*86d7f5d3SJohn Marino
67*86d7f5d3SJohn Marino void
__gmp_invalid_operation(void)68*86d7f5d3SJohn Marino __gmp_invalid_operation (void)
69*86d7f5d3SJohn Marino {
70*86d7f5d3SJohn Marino raise (SIGFPE);
71*86d7f5d3SJohn Marino abort ();
72*86d7f5d3SJohn Marino }
73