diff options
author | Kaz Kojima <kkojima@rr.iij4u.or.jp> | 2012-04-05 11:53:49 +0900 |
---|---|---|
committer | Kaz Kojima <kkojima@rr.iij4u.or.jp> | 2012-04-05 11:53:49 +0900 |
commit | 8a53f50f2a8ab4e1166afa0e9a8d4abc62b0ed4e (patch) | |
tree | fa72b2abad1cead529a3fcd7efc03df3dcac9a3a /sysdeps/sh/sh4 | |
parent | 15a946b57a1e7f4ba95b63572062860ca1a5e58f (diff) | |
download | glibc-8a53f50f2a8ab4e1166afa0e9a8d4abc62b0ed4e.tar.gz |
Fix SH4 fraiseexcpt so to generate exceptions appropriately.
Diffstat (limited to 'sysdeps/sh/sh4')
-rw-r--r-- | sysdeps/sh/sh4/fpu/fraiseexcpt.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/sysdeps/sh/sh4/fpu/fraiseexcpt.c b/sysdeps/sh/sh4/fpu/fraiseexcpt.c index 0bed3a5297..a555b10885 100644 --- a/sysdeps/sh/sh4/fpu/fraiseexcpt.c +++ b/sysdeps/sh/sh4/fpu/fraiseexcpt.c @@ -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 @@ -17,18 +18,47 @@ <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; } |