From cc0c9bba3607db7e841c35d8f48bd4128a378968 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sat, 22 Mar 2014 12:28:21 +0000 Subject: [PATCH] Implement __flt_rounds for ARMv6 hard-float. The fpscr register stores the current rounding mode used by the VFP unit. --- lib/libc/arm/gen/flt_rounds.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/libc/arm/gen/flt_rounds.c b/lib/libc/arm/gen/flt_rounds.c index 81ab08b34c74..86509d233231 100644 --- a/lib/libc/arm/gen/flt_rounds.c +++ b/lib/libc/arm/gen/flt_rounds.c @@ -30,20 +30,32 @@ __FBSDID("$FreeBSD$"); #include #include +#ifndef __ARM_PCS_VFP #include "softfloat-for-gcc.h" #include "milieu.h" #include "softfloat.h" +#endif int __flt_rounds(void) { + int mode; -#ifndef ARM_HARD_FLOAT +#ifndef __ARM_PCS_VFP /* * Translate our rounding modes to the unnamed * manifest constants required by C99 et. al. */ - switch (__softfloat_float_rounding_mode) { + mode = __softfloat_float_rounding_mode; +#else /* __ARM_PCS_VFP */ + /* + * Read the floating-point status and control register + */ + __asm __volatile("vmrs %0, fpscr" : "=&r"(mode)); + mode &= _ROUND_MASK; +#endif /* __ARM_PCS_VFP */ + + switch (mode) { case FE_TOWARDZERO: return (0); case FE_TONEAREST: @@ -54,12 +66,4 @@ __flt_rounds(void) return (3); } return (-1); -#else /* ARM_HARD_FLOAT */ - /* - * Apparently, the rounding mode is specified as part of the - * instruction format on ARM, so the dynamic rounding mode is - * indeterminate. Some FPUs may differ. - */ - return (-1); -#endif /* ARM_HARD_FLOAT */ }