diff options
author | andrew <andrew@FreeBSD.org> | 2014-03-22 12:28:21 +0000 |
---|---|---|
committer | andrew <andrew@FreeBSD.org> | 2014-03-22 12:28:21 +0000 |
commit | 3bc7f167e052261843a975e4e487fa9da3647a87 (patch) | |
tree | b93b5176b69fb606e82737c847bcfca39736e0f9 | |
parent | de9a58cc91e99b4be038d6eb2da9a8f634274d6e (diff) | |
download | FreeBSD-src-3bc7f167e052261843a975e4e487fa9da3647a87.zip FreeBSD-src-3bc7f167e052261843a975e4e487fa9da3647a87.tar.gz |
Implement __flt_rounds for ARMv6 hard-float. The fpscr register stores the
current rounding mode used by the VFP unit.
-rw-r--r-- | lib/libc/arm/gen/flt_rounds.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/lib/libc/arm/gen/flt_rounds.c b/lib/libc/arm/gen/flt_rounds.c index 81ab08b..86509d2 100644 --- a/lib/libc/arm/gen/flt_rounds.c +++ b/lib/libc/arm/gen/flt_rounds.c @@ -30,20 +30,32 @@ __FBSDID("$FreeBSD$"); #include <fenv.h> #include <float.h> +#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 */ } |