1 /*
2  $Id$
3  */
4 #if (defined(__ppc__) || defined(__ppc64__))
5 /* from http://developer.apple.com/documentation/Performance/Conceptual/Mac_OSX_Numerics/Mac_OSX_Numerics.pdf */
6 #define fegetenvd(x) asm volatile("mffs %0" : "=f" (x));
7 #define fesetenvd(x) asm volatile("mtfsf 255,%0" : : "f" (x));
8 enum {
9   FE_ENABLE_INEXACT = 0x00000008,
10   FE_ENABLE_DIVBYZERO = 0x00000010,
11   FE_ENABLE_UNDERFLOW = 0x00000020,
12   FE_ENABLE_OVERFLOW = 0x00000040,
13   FE_ENABLE_INVALID = 0x00000080,
14   FE_ENABLE_ALL_EXCEPT = 0x000000F8 };
15 typedef union {
16   struct {
17     unsigned long hi;
18         unsigned long lo;
19   } i;
20   double d;
21 } hexdouble;
22 
macx_trapfpe_(void)23 void macx_trapfpe_(void) {
24   hexdouble t;
25   fegetenvd(t.d);
26   /* Enable hardware trapping for all exceptions */
27   //  t.i.lo |= FE_ENABLE_ALL_EXCEPT;
28   t.i.lo = FE_ENABLE_OVERFLOW | FE_ENABLE_DIVBYZERO|FE_ENABLE_INVALID;
29   fesetenvd(t.d);
30  }
31 #elif (defined (__i386__) || defined( __x86_64__ ))
32 #include <fenv.h>
33 #include <stdio.h>
34 
35 #define _FPU_MASK_IM  0x01
36 #define _FPU_MASK_ZM  0x04
37 #define _FPU_MASK_OM  0x08
38 #define _FPU_RESERVED 0xF0C0
39 
40 #ifndef _FE_DIVBYZERO
41 #define _FE_DIVBYZERO FE_DIVBYZERO
42 #endif
43 #ifndef _FE_OVERFLOW
44 #define _FE_OVERFLOW  FE_OVERFLOW
45 #endif
46 #ifndef _FE_INVALID
47 #define _FE_INVALID FE_INVALID
48 #endif
49 typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
50 extern fpu_control_t __fpu_control;
51 
52 #define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw))
53 #define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw))
54 #define _FPU_GETMXCSR(cw_sse) asm volatile ("stmxcsr %0" : "=m" (cw_sse))
55 #define _FPU_SETMXCSR(cw_sse) asm volatile ("ldmxcsr %0" : : "m" (cw_sse))
56 
macx_trapfpe_()57 int macx_trapfpe_()
58 {
59   fpu_control_t mode, mode_sse;
60 
61   _FPU_GETCW (mode) ;
62   mode &= (_FPU_RESERVED | _FE_DIVBYZERO |  _FE_OVERFLOW |  _FE_INVALID) ;
63   _FPU_SETCW (mode) ;
64 
65   _FPU_GETMXCSR (mode_sse) ;
66   mode_sse &= (0xFFFF0000 | (_FPU_RESERVED | _FE_DIVBYZERO | _FE_OVERFLOW | _FE_INVALID) <<7);
67   _FPU_SETMXCSR (mode_sse) ;
68 
69   return 1 ;
70 }
71 #else
72 #error arch not ready
73 #endif
74