site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com On 9 mei 2007, at 01:29, Kristoffer Eriksen wrote: Jonas #include <stdio.h> #include <stdlib.h> #include <math.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> #define FPU_NoMask 0x00 #define FPU_Invalid 0x01 #define FPU_Denormal 0x02 #define FPU_DivisionByZero 0x04 #define FPU_Overflow 0x08 #define FPU_Underflow 0x10 #define FPU_Inexact 0x20 #define FPU_ExceptionMask 0xff unsigned short fpucw; unsigned int mxcsr; int setfpumask(int fpmask) { int oldmask; asm volatile ("fstcw _fpucw"); oldmask = fpucw & 0xffc0; fpucw = fpucw | (fpmask & FPU_ExceptionMask); asm volatile ("fldcw _fpucw"); asm volatile("fwait"); // the sse masking flags are the same as the 80x87 flags, just // shifted left 7 asm volatile("stmxcsr _mxcsr"); mxcsr = (mxcsr & 0xffffe07f) | ((fpmask & FPU_ExceptionMask) << 7); asm volatile("ldmxcsr _mxcsr"); return oldmask; } void dosqrtsse() { double x; pid_t pid; pid = getpid(); x = sqrt(-1.0/(double)pid); printf("sse: %d %f\n",pid,x); } void dosqrtx87() { long double x; pid_t pid; pid = getpid(); x = sqrt(-1.0/(long double)pid); printf("x87: %d %f\n",pid,x); } int main(int argc, char *argv[]){ printf("Default mask\n"); dosqrtsse(); dosqrtx87(); // both inexact and invalid need to be masked in this case printf("Only inexact and invalid exceptions masked\n"); setfpumask(FPU_Inexact|FPU_Invalid); dosqrtsse(); dosqrtx87(); printf("No exceptions masked\n"); setfpumask(FPU_NoMask); dosqrtsse(); // not reached dosqrtx87(); // not reached exit(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... To summarize, I'm using the feraiseexcept() function from fenv.h, which I had hoped would enable floating point exceptions for the requested flags. I figured you'd have to do something like this, but it doesn't work either: retval = fegetexceptflag(&flags, FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW ); flags |= (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW); retval = fesetexceptflag(&flags, FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW ); It's quite annoying that none of the man pages for those functions available on the Internet contain any example code (and that there aren't even any man pages for them in Mac OS X) Anyway, the following does work (based on code from the Free Pascal runtime library), but with a some caveats: a) I don't know how to write PIC inline assembler code in gcc (nor how to address local variables in inline gcc assembler, nor how to force local variables to be in memory), so this code will not work inside a dynamic library (because it directly accesses a global variable from assembler code) b) do not write GUI programs with fpu exceptions turned on, because there are parts of CoreGraphics which trigger such exceptions (at least on ppc) Float and double are handled using sse by default on Mac OS X, while long double is handled using the 80x87. This means you need to set both the sse and 80x87 fpu masks. You can force all code to use the 80x87 by compiling with -mfpmath=387 (not recommended, since slower). This email sent to site_archiver@lists.apple.com