mirror of
https://github.com/crosstool-ng/crosstool-ng.git
synced 2024-12-21 13:47:48 +00:00
98bc4decde
Signed-off-by: Alexey Neyman <stilor@att.net>
367 lines
8.7 KiB
Diff
367 lines
8.7 KiB
Diff
http://yann.poupet.free.fr/ep93xx/
|
|
Add support for the Maverick Crunch FPU on Cirrus EP93XX processor series
|
|
|
|
---
|
|
sysdeps/arm/bits/endian.h | 2 -
|
|
sysdeps/arm/fpu/__longjmp.S | 26 +++++++++++++
|
|
sysdeps/arm/fpu/bits/fenv.h | 41 ++++++++++++++++++++
|
|
sysdeps/arm/fpu/bits/setjmp.h | 4 ++
|
|
sysdeps/arm/fpu/fegetround.c | 12 ++++++
|
|
sysdeps/arm/fpu/fesetround.c | 16 ++++++++
|
|
sysdeps/arm/fpu/fpu_control.h | 78 ++++++++++++++++++++++++++++++++++++++-
|
|
sysdeps/arm/fpu/jmpbuf-offsets.h | 4 ++
|
|
sysdeps/arm/fpu/setjmp.S | 30 +++++++++++++++
|
|
sysdeps/arm/gccframe.h | 4 ++
|
|
sysdeps/arm/gmp-mparam.h | 2 -
|
|
11 files changed, 216 insertions(+), 3 deletions(-)
|
|
|
|
--- a/sysdeps/arm/bits/endian.h
|
|
+++ b/sysdeps/arm/bits/endian.h
|
|
@@ -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
|
|
--- a/sysdeps/arm/fpu/__longjmp.S
|
|
+++ b/sysdeps/arm/fpu/__longjmp.S
|
|
@@ -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)
|
|
--- a/sysdeps/arm/fpu/bits/fenv.h
|
|
+++ b/sysdeps/arm/fpu/bits/fenv.h
|
|
@@ -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;
|
|
|
|
--- a/sysdeps/arm/fpu/bits/setjmp.h
|
|
+++ b/sysdeps/arm/fpu/bits/setjmp.h
|
|
@@ -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
|
|
--- a/sysdeps/arm/fpu/fegetround.c
|
|
+++ b/sysdeps/arm/fpu/fegetround.c
|
|
@@ -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
|
|
}
|
|
--- a/sysdeps/arm/fpu/fesetround.c
|
|
+++ b/sysdeps/arm/fpu/fesetround.c
|
|
@@ -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)
|
|
--- a/sysdeps/arm/fpu/fpu_control.h
|
|
+++ b/sysdeps/arm/fpu/fpu_control.h
|
|
@@ -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 */
|
|
--- a/sysdeps/arm/fpu/jmpbuf-offsets.h
|
|
+++ b/sysdeps/arm/fpu/jmpbuf-offsets.h
|
|
@@ -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
|
|
--- a/sysdeps/arm/fpu/setjmp.S
|
|
+++ b/sysdeps/arm/fpu/setjmp.S
|
|
@@ -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))
|
|
--- a/sysdeps/arm/gccframe.h
|
|
+++ b/sysdeps/arm/gccframe.h
|
|
@@ -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>
|
|
--- a/sysdeps/arm/gmp-mparam.h
|
|
+++ b/sysdeps/arm/gmp-mparam.h
|
|
@@ -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
|