I have a long standing patch for FPU emulator to fix a segmentation fault in pow() library function. Here is a test program to reproduce it. main() { union { double d; struct { #ifdef __MIPSEB unsigned int high, low; #else unsigned int low, high; #endif } i; } x, y, z; x.i.low = 0x00000000; x.i.high = 0xfff00001; y.i.low = 0x80000000; y.i.high = 0xcff00000; z.d = pow(x.d, y.d); printf("%x %x\n", z.i.high, z.i.low); return 0; } If you run this program, you will get segmentation fault (unless your FPU does not raise Unimplemented exception for NaN operands). The segmentation fault is caused by endless recursion in __ieee754_pow(). It looks glibc's pow() assume unary '-' operation for any number (including NaN) always invert its sign bit. Here is a revised (just added a few comments) patch. Please review. Thank you. diff -u linux-mips/arch/mips/math-emu/dp_simple.c linux/arch/mips/math-emu/dp_simple.c --- linux-mips/arch/mips/math-emu/dp_simple.c 2005-01-31 11:05:18.000000000 +0900 +++ linux/arch/mips/math-emu/dp_simple.c 2005-04-20 17:02:02.613112541 +0900 @@ -48,16 +48,22 @@ CLEARCX; FLUSHXDP; + /* + * Invert the sign ALWAYS to prevent an endless recursion on + * pow() in libc. + */ + /* quick fix up */ + DPSIGN(x) ^= 1; + if (xc == IEEE754_CLASS_SNAN) { + ieee754dp y = ieee754dp_indef(); SETCX(IEEE754_INVALID_OPERATION); - return ieee754dp_nanxcpt(ieee754dp_indef(), "neg"); + DPSIGN(y) = DPSIGN(x); + return ieee754dp_nanxcpt(y, "neg"); } if (ieee754dp_isnan(x)) /* but not infinity */ return ieee754dp_nanxcpt(x, "neg", x); - - /* quick fix up */ - DPSIGN(x) ^= 1; return x; } diff -u linux-mips/arch/mips/math-emu/sp_simple.c linux/arch/mips/math-emu/sp_simple.c --- linux-mips/arch/mips/math-emu/sp_simple.c 2005-01-31 11:05:18.000000000 +0900 +++ linux/arch/mips/math-emu/sp_simple.c 2005-04-20 17:02:13.678391113 +0900 @@ -48,16 +48,22 @@ CLEARCX; FLUSHXSP; + /* + * Invert the sign ALWAYS to prevent an endless recursion on + * pow() in libc. + */ + /* quick fix up */ + SPSIGN(x) ^= 1; + if (xc == IEEE754_CLASS_SNAN) { + ieee754sp y = ieee754sp_indef(); SETCX(IEEE754_INVALID_OPERATION); - return ieee754sp_nanxcpt(ieee754sp_indef(), "neg"); + SPSIGN(y) = SPSIGN(x); + return ieee754sp_nanxcpt(y, "neg"); } if (ieee754sp_isnan(x)) /* but not infinity */ return ieee754sp_nanxcpt(x, "neg", x); - - /* quick fix up */ - SPSIGN(x) ^= 1; return x; } --- Atsushi Nemoto