xref: /dflybsd-src/contrib/gmp/invalid.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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