diff options
author | Palmer Dabbelt <palmer.dabbelt@eecs.berkeley.edu> | 2015-07-04 20:10:39 -0700 |
---|---|---|
committer | Palmer Dabbelt <palmer.dabbelt@eecs.berkeley.edu> | 2015-07-05 09:59:19 -0700 |
commit | 394782ac1a2b67e922be4752c223c2d188754e0d (patch) | |
tree | 62164493fb3dfdf1e261e041be662136c4c98a5d /glibc | |
parent | c0e50a3913830d9a200a790fa8584427f85d41fe (diff) | |
download | riscv-gnu-toolchain-394782ac1a2b67e922be4752c223c2d188754e0d.zip riscv-gnu-toolchain-394782ac1a2b67e922be4752c223c2d188754e0d.tar.gz riscv-gnu-toolchain-394782ac1a2b67e922be4752c223c2d188754e0d.tar.bz2 |
Fix some glibc FP routines for non-F
Some glibc floating point routines use inline assembly. This changes
them to use regular C code to do this when compiled without hardware
floatint-point support. The change just uses regular C to perform
these operations when compiled on ABIs without hardware floating
point.
Diffstat (limited to 'glibc')
-rw-r--r-- | glibc/sysdeps/riscv/fpu/s_fdim.c | 5 | ||||
-rw-r--r-- | glibc/sysdeps/riscv/fpu/s_fdimf.c | 5 | ||||
-rw-r--r-- | glibc/sysdeps/riscv/fpu/s_fmax.c | 8 | ||||
-rw-r--r-- | glibc/sysdeps/riscv/fpu/s_fmaxf.c | 8 | ||||
-rw-r--r-- | glibc/sysdeps/riscv/fpu/s_fmin.c | 8 | ||||
-rw-r--r-- | glibc/sysdeps/riscv/fpu/s_fminf.c | 8 | ||||
-rw-r--r-- | glibc/sysdeps/riscv/fpu_control.h | 8 |
7 files changed, 48 insertions, 2 deletions
diff --git a/glibc/sysdeps/riscv/fpu/s_fdim.c b/glibc/sysdeps/riscv/fpu/s_fdim.c index 9835f59..96c6199 100644 --- a/glibc/sysdeps/riscv/fpu/s_fdim.c +++ b/glibc/sysdeps/riscv/fpu/s_fdim.c @@ -9,8 +9,13 @@ double __fdim (double x, double y) if (x <= y) return 0.0; +#ifdef __riscv_soft_float + if (isinf(diff)) + errno = ERANGE; +#else if (__builtin_expect(_FCLASS(diff) & _FCLASS_INF, 0)) errno = ERANGE; +#endif return diff; } diff --git a/glibc/sysdeps/riscv/fpu/s_fdimf.c b/glibc/sysdeps/riscv/fpu/s_fdimf.c index 480136c..893132a 100644 --- a/glibc/sysdeps/riscv/fpu/s_fdimf.c +++ b/glibc/sysdeps/riscv/fpu/s_fdimf.c @@ -9,8 +9,13 @@ float __fdimf (float x, float y) if (x <= y) return 0.0f; +#ifdef __riscv_soft_float + if (isinf(diff)) + errno = ERANGE; +#else if (__builtin_expect(_FCLASS(diff) & _FCLASS_INF, 0)) errno = ERANGE; +#endif return diff; } diff --git a/glibc/sysdeps/riscv/fpu/s_fmax.c b/glibc/sysdeps/riscv/fpu/s_fmax.c index 8d2e662..e133c67 100644 --- a/glibc/sysdeps/riscv/fpu/s_fmax.c +++ b/glibc/sysdeps/riscv/fpu/s_fmax.c @@ -2,8 +2,16 @@ double __fmax (double x, double y) { +#ifdef __riscv_soft_float + if (isnan(x)) + return y; + if (isnan(y)) + return x; + return (x > y) ? x : y; +#else double res; asm ("fmax.d %0, %1, %2" : "=f"(res) : "f"(x), "f"(y)); return res; +#endif } weak_alias (__fmax, fmax) diff --git a/glibc/sysdeps/riscv/fpu/s_fmaxf.c b/glibc/sysdeps/riscv/fpu/s_fmaxf.c index aa62172..6ec578c 100644 --- a/glibc/sysdeps/riscv/fpu/s_fmaxf.c +++ b/glibc/sysdeps/riscv/fpu/s_fmaxf.c @@ -2,8 +2,16 @@ float __fmaxf (float x, float y) { +#ifdef __riscv_soft_float + if (isnan(x)) + return y; + if (isnan(y)) + return x; + return (x > y) ? x : y; +#else float res; asm ("fmax.s %0, %1, %2" : "=f"(res) : "f"(x), "f"(y)); return res; +#endif } weak_alias (__fmaxf, fmaxf) diff --git a/glibc/sysdeps/riscv/fpu/s_fmin.c b/glibc/sysdeps/riscv/fpu/s_fmin.c index e4e37df..8330620 100644 --- a/glibc/sysdeps/riscv/fpu/s_fmin.c +++ b/glibc/sysdeps/riscv/fpu/s_fmin.c @@ -2,8 +2,16 @@ double __fmin (double x, double y) { +#ifdef __riscv_soft_float + if (isnan(x)) + return y; + if (isnan(y)) + return x; + return (x < y) ? x : y; +#else double res; asm ("fmin.d %0, %1, %2" : "=f"(res) : "f"(x), "f"(y)); return res; +#endif } weak_alias (__fmin, fmin) diff --git a/glibc/sysdeps/riscv/fpu/s_fminf.c b/glibc/sysdeps/riscv/fpu/s_fminf.c index 5d25bc2..00dcb6c 100644 --- a/glibc/sysdeps/riscv/fpu/s_fminf.c +++ b/glibc/sysdeps/riscv/fpu/s_fminf.c @@ -2,8 +2,16 @@ float __fminf (float x, float y) { +#ifdef __riscv_soft_float + if (isnan(x)) + return y; + if (isnan(y)) + return x; + return (x < y) ? x : y; +#else float res; asm ("fmin.s %0, %1, %2" : "=f"(res) : "f"(x), "f"(y)); return res; +#endif } weak_alias (__fminf, fminf) diff --git a/glibc/sysdeps/riscv/fpu_control.h b/glibc/sysdeps/riscv/fpu_control.h index c47d03b..cd52ff9 100644 --- a/glibc/sysdeps/riscv/fpu_control.h +++ b/glibc/sysdeps/riscv/fpu_control.h @@ -30,10 +30,14 @@ #define _FPU_DEFAULT 0x00000000 typedef unsigned int fpu_control_t; #define _FPU_GETCW(cw) (cw) = 0 +#define _FPU_GETROUND(cw) (cw) = 0 +#define _FPU_GETFLAGS(cw) (cw) = 0 #define _FPU_SETCW(cw) do { } while (0) +#define _FPU_SETROUND(cw) do { } while (0) +#define _FPU_SETFLAGS(cw) do { } while (0) extern fpu_control_t __fpu_control; -#else /* __mips_soft_float */ +#else /* __riscv_soft_float */ /* rounding control */ #define _FPU_RC_NEAREST 0x0 @@ -87,6 +91,6 @@ extern fpu_control_t __fpu_control; #define _FCLASS_INF (_FCLASS_MINF | _FCLASS_PINF) #define _FCLASS_NAN (_FCLASS_SNAN | _FCLASS_QNAN) -#endif /* __mips_soft_float */ +#endif /* __riscv_soft_float */ #endif /* fpu_control.h */ |