This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2 04/22] 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
-- 
2.1.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]