Fix SH4 fraiseexcpt so to generate exceptions appropriately.
authorKaz Kojima <kkojima@rr.iij4u.or.jp>
Thu, 5 Apr 2012 02:53:49 +0000 (11:53 +0900)
committerKaz Kojima <kkojima@rr.iij4u.or.jp>
Thu, 5 Apr 2012 02:53:49 +0000 (11:53 +0900)
ChangeLog
sysdeps/sh/sh4/fpu/fraiseexcpt.c

index dd4a520..092756e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2012-04-05  Nobuhiro Iwamatsu  <iwamatsu@nigauri.org>
+
+       * sysdeps/sh/sh4/fpu/fraiseexcpt.c (feraiseexcept): Produce
+       an exception using FPU order intentionally.
+
+2012-04-05  Nobuhiro Iwamatsu  <iwamatsu@nigauri.org>
+
+       * sysdeps/sh/sh4/fpu/fedisblxcpt.c: New file.
+       * sysdeps/sh/sh4/fpu/feenablxcpt.c: New file.
+       * sysdeps/sh/sh4/fpu/fegetexcept.c: New file.
+       * sysdeps/sh/sh4/fpu/feupdateenv.c: New file.
+
 2012-04-05  Simon Josefsson  <simon@josefsson.org>
 
        [BZ #12340]
index 0bed3a5..a555b10 100644 (file)
@@ -1,6 +1,7 @@
 /* Raise given exceptions.
-   Copyright (C) 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2000, 2002, 2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
+   Contributed by Nobuhiro Iwamatsu <iwamatsu@nigauri.org>, 2012.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    <http://www.gnu.org/licenses/>.  */
 
 #include <fenv.h>
+#include <float.h>
 #include <fpu_control.h>
 #include <math.h>
 
 int
 feraiseexcept (int excepts)
 {
+  if (excepts == 0)
+    return 0;
+
   /* Raise exceptions represented by EXPECTS.  */
-  fexcept_t temp;
-  _FPU_GETCW (temp);
-  temp |= (excepts & FE_ALL_EXCEPT);
-  temp |= (excepts & FE_ALL_EXCEPT) << 5;
-  _FPU_SETCW (temp);
+
+  if (excepts & FE_INEXACT)
+  {
+    double d = 1.0, x = 3.0;
+    __asm__ __volatile__ ("fdiv %1, %0" : "+d" (d) : "d" (x));
+  }
+
+  if (excepts & FE_UNDERFLOW)
+  {
+    long double d = LDBL_MIN, x = 10;
+    __asm__ __volatile__ ("fdiv %1, %0" : "+d" (d) : "d" (x));
+  }
+
+  if (excepts & FE_OVERFLOW)
+  {
+    long double d = LDBL_MAX;
+    __asm__ __volatile__ ("fmul %0, %0" : "+d" (d) : "d" (d));
+  }
+
+  if (excepts & FE_DIVBYZERO)
+  {
+    double d = 1.0, x = 0.0;
+    __asm__ __volatile__ ("fdiv %1, %0" : "+d" (d) : "d" (x));
+  }
+
+  if (excepts & FE_INVALID)
+  {
+    double d = HUGE_VAL, x = 0.0;
+    __asm__ __volatile__ ("fmul %1, %0" : "+d" (d) : "d" (x));
+  }
 
   return 0;
 }