summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2014-03-22 12:28:21 +0000
committerandrew <andrew@FreeBSD.org>2014-03-22 12:28:21 +0000
commit3bc7f167e052261843a975e4e487fa9da3647a87 (patch)
treeb93b5176b69fb606e82737c847bcfca39736e0f9
parentde9a58cc91e99b4be038d6eb2da9a8f634274d6e (diff)
downloadFreeBSD-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.c24
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 */
}
OpenPOWER on IntegriCloud