summaryrefslogtreecommitdiff
path: root/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch
diff options
context:
space:
mode:
Diffstat (limited to 'tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch')
-rw-r--r--tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch241
1 files changed, 241 insertions, 0 deletions
diff --git a/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch b/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch
new file mode 100644
index 0000000..2ca90f6
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch
@@ -0,0 +1,241 @@
+From 7002592cb4072303c6a286e1c6479df99ae151b3 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri@gaisler.se>
+Date: Thu, 19 Feb 2015 22:14:36 +0100
+Subject: [PATCH 04/23] sim/erc32: Use fenv.h for host FPU access
+
+ * float.c (get_accex, clear_accex, set_fsr) Use functions from fenv.h
+ instead of custom assembly.
+---
+ sim/erc32/float.c | 191 +++++++++---------------------------------------------
+ 1 file changed, 30 insertions(+), 161 deletions(-)
+
+diff --git a/sim/erc32/float.c b/sim/erc32/float.c
+index 598b7cc..40c133b 100644
+--- a/sim/erc32/float.c
++++ b/sim/erc32/float.c
+@@ -28,53 +28,38 @@
+ * 4. Clear host exception bits
+ *
+ *
+- * This can also be done using ieee_flags() library routine on sun.
+ */
+
+ #include "config.h"
+ #include "sis.h"
++#include <fenv.h>
+
+-/* Forward declarations */
+-
+-extern uint32 _get_sw (void);
+-extern uint32 _get_cw (void);
+-static void __setfpucw (unsigned short fpu_control);
+-
+-/* This host dependent routine should return the accrued exceptions */
++/* This routine should return the accrued exceptions */
+ int
+ get_accex()
+ {
+-#ifdef sparc
+- return ((_get_fsr_raw() >> 5) & 0x1F);
+-#elif i386
+- uint32 accx;
+-
+- accx = _get_sw() & 0x3f;
+- accx = ((accx & 1) << 4) | ((accx & 2) >> 1) | ((accx & 4) >> 1) |
+- (accx & 8) | ((accx & 16) >> 2) | ((accx & 32) >> 5);
++ int fexc, accx;
++
++ fexc = fetestexcept(FE_ALL_EXCEPT);
++ accx = 0;
++ if (fexc & FE_INEXACT)
++ accx |= 1;
++ if (fexc & FE_DIVBYZERO)
++ accx |= 2;
++ if (fexc & FE_UNDERFLOW)
++ accx |= 4;
++ if (fexc & FE_OVERFLOW)
++ accx |= 8;
++ if (fexc & FE_INVALID)
++ accx |= 0x10;
+ return(accx);
+-#else
+- return(0);
+-#warning no fpu trap support for this target
+-#endif
+-
+ }
+
+ /* How to clear the accrued exceptions */
+ void
+ clear_accex()
+ {
+-#ifdef sparc
+- set_fsr((_get_fsr_raw() & ~0x3e0));
+-#elif i386
+- asm("\n"
+-".text\n"
+-" fnclex\n"
+-"\n"
+-" ");
+-#else
+-#warning no fpu trap support for this target
+-#endif
++ feclearexcept(FE_ALL_EXCEPT);
+ }
+
+ /* How to map SPARC FSR onto the host */
+@@ -82,138 +67,22 @@ void
+ set_fsr(fsr)
+ uint32 fsr;
+ {
+-#ifdef sparc
+- _set_fsr_raw(fsr & ~0x0f800000);
+-#elif i386
+- void __setfpucw(unsigned short fpu_control);
+- uint32 rawfsr;
++ int fround;
+
+- fsr >>= 30;
+- switch (fsr) {
++ fsr >>= 30;
++ switch (fsr) {
+ case 0:
+- case 2:
+- break;
+-
++ fround = FE_TONEAREST;
++ break;
+ case 1:
+- fsr = 3;
+- break;
+-
++ fround = FE_TOWARDZERO;
++ break;
++ case 2:
++ fround = FE_UPWARD;
++ break;
+ case 3:
+- fsr = 1;
+- break;
++ fround = FE_DOWNWARD;
++ break;
+ }
+- rawfsr = _get_cw();
+- rawfsr |= (fsr << 10) | 0x3ff;
+- __setfpucw(rawfsr);
+-#else
+-#warning no fpu trap support for this target
+-#endif
+-}
+-
+-
+-/* Host dependent support functions */
+-
+-#ifdef sparc
+-
+- asm("\n"
+-"\n"
+-".text\n"
+-" .align 4\n"
+-" .global __set_fsr_raw,_set_fsr_raw\n"
+-"__set_fsr_raw:\n"
+-"_set_fsr_raw:\n"
+-" save %sp,-104,%sp\n"
+-" st %i0,[%fp+68]\n"
+-" ld [%fp+68], %fsr\n"
+-" mov 0,%i0\n"
+-" ret\n"
+-" restore\n"
+-"\n"
+-" .align 4\n"
+-" .global __get_fsr_raw\n"
+-" .global _get_fsr_raw\n"
+-"__get_fsr_raw:\n"
+-"_get_fsr_raw:\n"
+-" save %sp,-104,%sp\n"
+-" st %fsr,[%fp+68]\n"
+-" ld [%fp+68], %i0\n"
+-" ret\n"
+-" restore\n"
+-"\n"
+-" ");
+-
+-#elif i386
+-
+- asm("\n"
+-"\n"
+-".text\n"
+-" .align 8\n"
+-".globl _get_sw,__get_sw\n"
+-"__get_sw:\n"
+-"_get_sw:\n"
+-" pushl %ebp\n"
+-" movl %esp,%ebp\n"
+-" movl $0,%eax\n"
+-" fnstsw %ax\n"
+-" movl %ebp,%esp\n"
+-" popl %ebp\n"
+-" ret\n"
+-"\n"
+-" .align 8\n"
+-".globl _get_cw,__get_cw\n"
+-"__get_cw:\n"
+-"_get_cw:\n"
+-" pushl %ebp\n"
+-" movl %esp,%ebp\n"
+-" subw $2,%esp\n"
+-" fnstcw -2(%ebp)\n"
+-" movw -2(%ebp),%eax\n"
+-" movl %ebp,%esp\n"
+-" popl %ebp\n"
+-" ret\n"
+-"\n"
+-"\n"
+-" ");
+-
+-
+-#else
+-#warning no fpu trap support for this target
+-#endif
+-
+-#if i386
+-/* #if defined _WIN32 || defined __GO32__ */
+-/* This is so floating exception handling works on NT
+- These definitions are from the linux fpu_control.h, which
+- doesn't exist on NT.
+-
+- default to:
+- - extended precision
+- - rounding to nearest
+- - exceptions on overflow, zero divide and NaN
+-*/
+-#define _FPU_DEFAULT 0x1372
+-#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */
+-
+-static void
+-__setfpucw(unsigned short fpu_control)
+-{
+- volatile unsigned short cw;
+-
+- /* If user supplied _fpu_control, use it ! */
+- if (!fpu_control)
+- {
+- /* use defaults */
+- fpu_control = _FPU_DEFAULT;
+- }
+- /* Get Control Word */
+- __asm__ volatile ("fnstcw %0" : "=m" (cw) : );
+-
+- /* mask in */
+- cw &= _FPU_RESERVED;
+- cw = cw | (fpu_control & ~_FPU_RESERVED);
+-
+- /* set cw */
+- __asm__ volatile ("fldcw %0" :: "m" (cw));
++ fesetround(fround);
+ }
+-/* #endif */
+-#endif
+--
+1.9.1
+