| http://yann.poupet.free.fr/ep93xx/ |
| Add support for the Maverick Crunch FPU on Cirrus EP93XX processor series |
| |
| diff -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/bits/endian.h glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/bits/endian.h |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/bits/endian.h 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/bits/endian.h 2009-11-13 00:51:22.000000000 +0100 |
| @@ -12,7 +12,7 @@ |
| /* FPA floating point units are always big-endian, irrespective of the |
| CPU endianness. VFP floating point units use the same endianness |
| as the rest of the system. */ |
| -#ifdef __VFP_FP__ |
| +#if defined __VFP_FP__ || defined __MAVERICK__ |
| #define __FLOAT_WORD_ORDER __BYTE_ORDER |
| #else |
| #define __FLOAT_WORD_ORDER __BIG_ENDIAN |
| diff -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/__longjmp.S glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/__longjmp.S |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/__longjmp.S 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/__longjmp.S 2009-11-13 00:51:22.000000000 +0100 |
| @@ -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 -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/bits/fenv.h glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/bits/fenv.h |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/bits/fenv.h 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/bits/fenv.h 2009-11-13 00:51:22.000000000 +0100 |
| @@ -20,6 +20,45 @@ |
| # error "Never use <bits/fenv.h> directly; include <fenv.h> 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 |
| { |
| @@ -44,6 +83,8 @@ |
| modes exist, but you have to encode them in the actual instruction. */ |
| #define FE_TONEAREST 0 |
| |
| +#endif |
| + |
| /* Type representing exception flags. */ |
| typedef unsigned long int fexcept_t; |
| |
| diff -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/bits/setjmp.h glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/bits/setjmp.h |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/bits/setjmp.h 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/bits/setjmp.h 2009-11-13 00:51:22.000000000 +0100 |
| @@ -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 -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/fegetround.c glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/fegetround.c |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/fegetround.c 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/fegetround.c 2009-11-13 00:51:22.000000000 +0100 |
| @@ -18,9 +18,21 @@ |
| 02111-1307 USA. */ |
| |
| #include <fenv.h> |
| +#include <fpu_control.h> |
| |
| 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 -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/fesetround.c glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/fesetround.c |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/fesetround.c 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/fesetround.c 2009-11-13 00:51:22.000000000 +0100 |
| @@ -18,12 +18,28 @@ |
| 02111-1307 USA. */ |
| |
| #include <fenv.h> |
| +#include <fpu_control.h> |
| |
| 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 -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/fpu_control.h glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/fpu_control.h |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/fpu_control.h 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/fpu_control.h 2009-11-13 00:51:22.000000000 +0100 |
| @@ -1,5 +1,6 @@ |
| /* FPU control word definitions. ARM version. |
| - Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc. |
| + Copyright (C) 1996, 1997, 1998, 2000, 2005 |
| + Free Software Foundation, Inc. |
| This file is part of the GNU C Library. |
| |
| The GNU C Library is free software; you can redistribute it and/or |
| @@ -20,6 +21,79 @@ |
| #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 +173,6 @@ |
| /* Default control word set at startup. */ |
| extern fpu_control_t __fpu_control; |
| |
| +#endif |
| + |
| #endif /* _FPU_CONTROL_H */ |
| diff -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/jmpbuf-offsets.h glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/jmpbuf-offsets.h |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/jmpbuf-offsets.h 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/jmpbuf-offsets.h 2009-11-13 00:51:22.000000000 +0100 |
| @@ -17,4 +17,8 @@ |
| Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 02111-1307 USA. */ |
| |
| +#ifdef __MAVERICK__ |
| +#define __JMP_BUF_SP 32 |
| +#else |
| #define __JMP_BUF_SP 20 |
| +#endif |
| diff -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/setjmp.S glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/setjmp.S |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/fpu/setjmp.S 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/fpu/setjmp.S 2009-11-13 00:51:22.000000000 +0100 |
| @@ -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)) |
| diff -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/gccframe.h glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/gccframe.h |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/gccframe.h 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/gccframe.h 2009-11-13 00:51:22.000000000 +0100 |
| @@ -17,6 +17,10 @@ |
| Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 02111-1307 USA. */ |
| |
| +#ifdef __MAVERICK__ |
| +#define FIRST_PSEUDO_REGISTER 43 |
| +#else |
| #define FIRST_PSEUDO_REGISTER 27 |
| +#endif |
| |
| #include <sysdeps/generic/gccframe.h> |
| diff -durN glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/gmp-mparam.h glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/gmp-mparam.h |
| --- glibc-2.12.1.orig/glibc-ports-2.12.1/sysdeps/arm/gmp-mparam.h 2009-05-16 10:36:20.000000000 +0200 |
| +++ glibc-2.12.1/glibc-ports-2.12.1/sysdeps/arm/gmp-mparam.h 2009-11-13 00:51:22.000000000 +0100 |
| @@ -29,7 +29,7 @@ |
| #if defined(__ARMEB__) |
| # define IEEE_DOUBLE_MIXED_ENDIAN 0 |
| # define IEEE_DOUBLE_BIG_ENDIAN 1 |
| -#elif defined(__VFP_FP__) |
| +#elif defined(__VFP_FP__) || defined(__MAVERICK__) |
| # define IEEE_DOUBLE_MIXED_ENDIAN 0 |
| # define IEEE_DOUBLE_BIG_ENDIAN 0 |
| #else |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/bits/endian.h glibc-2.12.1/ports/sysdeps/arm/bits/endian.h |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/fpu/__longjmp.S glibc-2.12.1/ports/sysdeps/arm/fpu/__longjmp.S |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/fpu/bits/fenv.h glibc-2.12.1/ports/sysdeps/arm/fpu/bits/fenv.h |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/fpu/bits/setjmp.h glibc-2.12.1/ports/sysdeps/arm/fpu/bits/setjmp.h |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/fpu/fegetround.c glibc-2.12.1/ports/sysdeps/arm/fpu/fegetround.c |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/fpu/fesetround.c glibc-2.12.1/ports/sysdeps/arm/fpu/fesetround.c |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/fpu/fpu_control.h glibc-2.12.1/ports/sysdeps/arm/fpu/fpu_control.h |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/fpu/jmpbuf-offsets.h glibc-2.12.1/ports/sysdeps/arm/fpu/jmpbuf-offsets.h |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/fpu/setjmp.S glibc-2.12.1/ports/sysdeps/arm/fpu/setjmp.S |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/gccframe.h glibc-2.12.1/ports/sysdeps/arm/gccframe.h |
| diff -durN glibc-2.12.1.orig/ports/sysdeps/arm/gmp-mparam.h glibc-2.12.1/ports/sysdeps/arm/gmp-mparam.h |