Floating-point exception handling
site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com Organization: University of Michigan User-agent: Thunderbird 2.0.0.23 (Macintosh/20090812) I am part of an ad hoc group working on a Forth language standard for IEEE 754 (2008) floating point, and I'm trying to do an example implementation of alternate handling for floating- point exceptions with gcc/Darwin, for one of the C-based Forths. It's my first attempt at writing a signal handler, but I was able to get it working pretty well on my PowerPC G4, with the sample code quoted below as a guide. The sample code is apparently an update of Listing 7-1 in the 2004 version of "PowerPC Numerics". My question is, what's the analogous magic for OS X intel? AFAIU, there are two issues, enabling nondefault exception handling, and dealing with state in the handler. The sample code deals with state only by restoring it when the handler returns. I might be able to figure out the intel analog for the ppc assembly language functions used for enabling, fegetenvd() and fesetenvd() quoted below; but I wouldn't mind a little hand holding on that. I didn't find any documentation on what's going on with state restoration in myHandler(), and so don't have a clue how to change that for intel. Thanks for any suggestions. -- David ----------- /* The following sample code is slightly modified to get it to compile with gcc version 4.0.1 (Apple Inc. build 5493) under OS X 10.5.8 and ppc. The original is here: http://lists.apple.com/archives/unix-porting/2003/May/msg00026.html See also Listing 7-1 in "PowerPC Numerics", 2004: http://developer.apple.com/documentation/Performance/Conceptual/Mac_OSX_Nume... -- David N. Williams, 15-Sep-09 */ #include <stdio.h> #include <math.h> #include <fenv.h> #include <signal.h> #include <ucontext.h> #include <mach/thread_status.h> #include <stdlib.h> // for exit() #define fegetenvd(x) asm volatile("mffs %0" : "=f" (x)); #define fesetenvd(x) asm volatile("mtfsf 255,%0" : : "f" (x)); enum { FE_ENABLE_INEXACT = 0x00000008, FE_ENABLE_DIVBYZERO = 0x00000010, FE_ENABLE_UNDERFLOW = 0x00000020, FE_ENABLE_OVERFLOW = 0x00000040, FE_ENABLE_INVALID = 0x00000080, FE_ENABLE_ALL_EXCEPT = 0x000000F8 }; typedef union { struct { unsigned long hi; unsigned long lo; } i; double d; } hexdouble; // void myHandler(int sig, siginfo_t *sip, struct ucontext *scp) void myHandler(int sig, siginfo_t *sip, ucontext_t *scp) { hexdouble t; // superfluous in this example ppc_float_state_t *fs; ppc_thread_state_t *ss; // fs = &scp->uc_mcontext->fs; fs = &scp->uc_mcontext->__fs; // ss = &scp->uc_mcontext->ss; ss = &scp->uc_mcontext->__ss; fprintf(stdout, "SIGFPE at 0x%x invokes myHandler, fpscr = %08X\n", // sip->si_addr, fs->fpscr); sip->si_addr, fs->__fpscr); // fs->fpscr &= FE_ENABLE_ALL_EXCEPT; fs->__fpscr &= FE_ENABLE_ALL_EXCEPT; // Re-arms interrupts when this state is restored // ss->srr0 += 4; // Advances the PC when this state is restored ss->__srr0 += 4; // Advances the PC when this state is restored // fprintf(stdout, "fpscr = %08X\n", fs->fpscr); fprintf(stdout, "fpscr = %08X\n", fs->__fpscr); fflush(stdout); } // static struct sigaction act = { myHandler, (sigset_t)0, SA_SIGINFO }; static struct sigaction act = { (void (*))myHandler, (sigset_t)0, SA_SIGINFO }; int main( int argc, char **argv) { float s; hexdouble t; fegetenvd(t.d); t.i.lo |= FE_ENABLE_ALL_EXCEPT; // Enable hardware trapping for all exceptions fesetenvd(t.d); if (sigaction(SIGFPE, &act, (struct sigaction *)0) != 0) { // Set handler perror("Yikes"); exit(-1); } fegetenvd(t.d); s = HUGE_VALF * HUGE_VALF; // Overflow folded out by compiler s = s / (1.0 + s); // Inf/Inf raises invalid operation fegetenvd(t.d); fprintf(stdout, "In main(1), s computed as: %e , fpscr = %08X\n", s, t.i.lo); // keep the compiler honest ... s = HUGE_VALF * HUGE_VALF; // Overflow folded out by compiler s = s / (2.0 + s); // Inf/Inf raises invalid operation fegetenvd(t.d); fprintf(stdout, "In main(2), s computed as: %e , fpscr = %08X\n", s, t.i.lo); // keep the compiler honest ... return 0; } _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... This email sent to site_archiver@lists.apple.com
participants (1)
-
David N. Williams