diff -urN glibc-2.5/ports/sysdeps/arm/fpu/bits/fenv.h glibc-2.5/ports/sysdeps/arm/fpu/bits/fenv.h --- glibc-2.5/ports/sysdeps/arm/fpu/bits/fenv.h 2001-07-06 14:55:48.000000000 +1000 +++ glibc-2.5/ports/sysdeps/arm/fpu/bits/fenv.h 2007-05-18 08:44:33.000000000 +1000 @@ -20,6 +20,45 @@ # error "Never use directly; include instead." #endif +#if defined(__MAVERICK__) + +/* Define bits representing exceptions in the FPU status word. */ +enum + { + FE_INVALID = 1, +#define FE_INVALID FE_INVALID + FE_OVERFLOW = 4, +#define FE_OVERFLOW FE_OVERFLOW + FE_UNDERFLOW = 8, +#define FE_UNDERFLOW FE_UNDERFLOW + FE_INEXACT = 16, +#define FE_INEXACT FE_INEXACT + }; + +/* Amount to shift by to convert an exception to a mask bit. */ +#define FE_EXCEPT_SHIFT 5 + +/* All supported exceptions. */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +/* IEEE rounding modes. */ +enum + { + FE_TONEAREST = 0, +#define FE_TONEAREST FE_TONEAREST + FE_TOWARDZERO = 0x400, +#define FE_TOWARDZERO FE_TOWARDZERO + FE_DOWNWARD = 0x800, +#define FE_DOWNWARD FE_DOWNWARD + FE_UPWARD = 0xc00, +#define FE_UPWARD FE_UPWARD + }; + +#define FE_ROUND_MASK (FE_UPWARD) + +#else /* FPA */ + /* Define bits representing exceptions in the FPU status word. */ enum { @@ -31,6 +70,7 @@ #define FE_OVERFLOW FE_OVERFLOW FE_UNDERFLOW = 8, #define FE_UNDERFLOW FE_UNDERFLOW + }; /* Amount to shift by to convert an exception to a mask bit. */ @@ -44,6 +84,8 @@ modes exist, but you have to encode them in the actual instruction. */ #define FE_TONEAREST 0 +#endif /* FPA */ + /* Type representing exception flags. */ typedef unsigned long int fexcept_t; diff -urN glibc-2.5/ports/sysdeps/arm/fpu/bits/setjmp.h glibc-2.5/ports/sysdeps/arm/fpu/bits/setjmp.h --- glibc-2.5/ports/sysdeps/arm/fpu/bits/setjmp.h 2006-01-10 19:22:16.000000000 +1000 +++ glibc-2.5/ports/sysdeps/arm/fpu/bits/setjmp.h 2007-05-18 08:45:22.000000000 +1000 @@ -28,7 +28,11 @@ #ifndef _ASM /* Jump buffer contains v1-v6, sl, fp, sp and pc. Other registers are not saved. */ +#ifdef __MAVERICK__ +typedef int __jmp_buf[34]; +#else typedef int __jmp_buf[22]; #endif +#endif #endif diff -urN glibc-2.5/ports/sysdeps/arm/fpu/fegetround.c glibc-2.5/ports/sysdeps/arm/fpu/fegetround.c --- glibc-2.5/ports/sysdeps/arm/fpu/fegetround.c 2001-07-06 14:55:48.000000000 +1000 +++ glibc-2.5/ports/sysdeps/arm/fpu/fegetround.c 2007-05-18 08:47:52.000000000 +1000 @@ -18,9 +18,21 @@ 02111-1307 USA. */ #include +#include int fegetround (void) { +#if defined(__MAVERICK__) + + unsigned long temp; + + _FPU_GETCW (temp); + return temp & FE_ROUND_MASK; + +#else /* FPA */ + return FE_TONEAREST; /* Easy. :-) */ + +#endif } diff -urN glibc-2.5/ports/sysdeps/arm/fpu/fesetround.c glibc-2.5/ports/sysdeps/arm/fpu/fesetround.c --- glibc-2.5/ports/sysdeps/arm/fpu/fesetround.c 2005-10-11 01:29:32.000000000 +1000 +++ glibc-2.5/ports/sysdeps/arm/fpu/fesetround.c 2007-05-18 08:48:32.000000000 +1000 @@ -20,10 +20,26 @@ #include +#include int fesetround (int round) { +#if defined(__MAVERICK__) + unsigned long temp; + + if (round & ~FE_ROUND_MASK) + return 1; + + _FPU_GETCW (temp); + temp = (temp & ~FE_ROUND_MASK) | round; + _FPU_SETCW (temp); + return 0; + +#else /* FPA */ + /* We only support FE_TONEAREST, so there is no need for any work. */ return (round == FE_TONEAREST)?0:1; + +#endif } libm_hidden_def (fesetround) diff -urN glibc-2.5/ports/sysdeps/arm/fpu/fpu_control.h glibc-2.5/ports/sysdeps/arm/fpu/fpu_control.h --- glibc-2.5/ports/sysdeps/arm/fpu/fpu_control.h 2001-07-06 14:55:48.000000000 +1000 +++ glibc-2.5/ports/sysdeps/arm/fpu/fpu_control.h 2007-05-18 08:50:28.000000000 +1000 @@ -20,6 +20,81 @@ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H +#if defined(__MAVERICK__) + +/* DSPSC register: (from EP9312 User's Guide) + * + * bits 31..29 - DAID + * bits 28..26 - HVID + * bits 25..24 - RSVD + * bit 23 - ISAT + * bit 22 - UI + * bit 21 - INT + * bit 20 - AEXC + * bits 19..18 - SAT + * bits 17..16 - FCC + * bit 15 - V + * bit 14 - FWDEN + * bit 13 - Invalid + * bit 12 - Denorm + * bits 11..10 - RM + * bits 9..5 - IXE, UFE, OFE, RSVD, IOE + * bits 4..0 - IX, UF, OF, RSVD, IO + */ + +/* masking of interrupts */ +#define _FPU_MASK_IM (1 << 5) /* invalid operation */ +#define _FPU_MASK_ZM 0 /* divide by zero */ +#define _FPU_MASK_OM (1 << 7) /* overflow */ +#define _FPU_MASK_UM (1 << 8) /* underflow */ +#define _FPU_MASK_PM (1 << 9) /* inexact */ +#define _FPU_MASK_DM 0 /* denormalized operation */ + +#define _FPU_RESERVED 0xfffff000 /* These bits are reserved. */ + +#define _FPU_DEFAULT 0x00b00000 /* Default value. */ +#define _FPU_IEEE 0x00b003a0 /* Default + exceptions enabled. */ + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Macros for accessing the hardware control word. */ +#define _FPU_GETCW(cw) ({ \ + register int __t1, __t2; \ + \ + __asm__ volatile ( \ + "cfmvr64l %1, mvdx0\n\t" \ + "cfmvr64h %2, mvdx0\n\t" \ + "cfmv32sc mvdx0, dspsc\n\t" \ + "cfmvr64l %0, mvdx0\n\t" \ + "cfmv64lr mvdx0, %1\n\t" \ + "cfmv64hr mvdx0, %2" \ + : "=r" (cw), "=r" (__t1), "=r" (__t2) \ + ); \ +}) + +#define _FPU_SETCW(cw) ({ \ + register int __t0, __t1, __t2; \ + \ + __asm__ volatile ( \ + "cfmvr64l %1, mvdx0\n\t" \ + "cfmvr64h %2, mvdx0\n\t" \ + "cfmv64lr mvdx0, %0\n\t" \ + "cfmvsc32 dspsc, mvdx0\n\t" \ + "cfmv64lr mvdx0, %1\n\t" \ + "cfmv64hr mvdx0, %2" \ + : "=r" (__t0), "=r" (__t1), "=r" (__t2) \ + : "0" (cw) \ + ); \ +}) + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#else /* FPA */ + + + /* We have a slight terminology confusion here. On the ARM, the register * we're interested in is actually the FPU status word - the FPU control * word is something different (which is implementation-defined and only @@ -99,4 +174,6 @@ /* Default control word set at startup. */ extern fpu_control_t __fpu_control; +#endif /* FPA */ + #endif /* _FPU_CONTROL_H */ diff -urN glibc-2.5/ports/sysdeps/arm/fpu/__longjmp.S glibc-2.5/ports/sysdeps/arm/fpu/__longjmp.S --- glibc-2.5/ports/sysdeps/arm/fpu/__longjmp.S 2001-07-06 14:55:48.000000000 +1000 +++ glibc-2.5/ports/sysdeps/arm/fpu/__longjmp.S 2007-05-18 08:51:36.000000000 +1000 @@ -30,7 +30,33 @@ movs r0, r1 /* get the return value in place */ moveq r0, #1 /* can't let setjmp() return zero! */ +#ifdef __MAVERICK__ + cfldrd mvd4, [ip], #8 + nop + cfldrd mvd5, [ip], #8 + nop + cfldrd mvd6, [ip], #8 + nop + cfldrd mvd7, [ip], #8 + nop + cfldrd mvd8, [ip], #8 + nop + cfldrd mvd9, [ip], #8 + nop + cfldrd mvd10, [ip], #8 + nop + cfldrd mvd11, [ip], #8 + nop + cfldrd mvd12, [ip], #8 + nop + cfldrd mvd13, [ip], #8 + nop + cfldrd mvd14, [ip], #8 + nop + cfldrd mvd15, [ip], #8 +#else lfmfd f4, 4, [ip] ! /* load the floating point regs */ +#endif LOADREGS(ia, ip, {v1-v6, sl, fp, sp, pc}) END (__longjmp) diff -urN glibc-2.5/ports/sysdeps/arm/fpu/setjmp.S glibc-2.5/ports/sysdeps/arm/fpu/setjmp.S --- glibc-2.5/ports/sysdeps/arm/fpu/setjmp.S 2001-07-06 14:55:48.000000000 +1000 +++ glibc-2.5/ports/sysdeps/arm/fpu/setjmp.S 2007-05-18 08:53:00.000000000 +1000 @@ -24,11 +24,41 @@ ENTRY (__sigsetjmp) /* Save registers */ +#ifdef __MAVERICK__ + cfstrd mvd4, [r0], #8 + nop + cfstrd mvd5, [r0], #8 + nop + cfstrd mvd6, [r0], #8 + nop + cfstrd mvd7, [r0], #8 + nop + cfstrd mvd8, [r0], #8 + nop + cfstrd mvd9, [r0], #8 + nop + cfstrd mvd10, [r0], #8 + nop + cfstrd mvd11, [r0], #8 + nop + cfstrd mvd12, [r0], #8 + nop + cfstrd mvd13, [r0], #8 + nop + cfstrd mvd14, [r0], #8 + nop + cfstrd mvd15, [r0], #8 +#else sfmea f4, 4, [r0]! +#endif stmia r0, {v1-v6, sl, fp, sp, lr} /* Restore pointer to jmp_buf */ +#ifdef __MAVERICK__ + sub r0, r0, #96 +#else sub r0, r0, #48 +#endif /* Make a tail call to __sigjmp_save; it takes the same args. */ B PLTJMP(C_SYMBOL_NAME(__sigjmp_save))