aboutsummaryrefslogtreecommitdiffstats
path: root/lib/builtins/arm/fp_mode.c
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-10-23 17:52:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-10-23 17:52:22 +0000
commit3a1720af1d7f43edc5b214cde0be11bfb94d077e (patch)
tree029e0ff2d5e3c0eaf2405fd8e669555fdf5e1297 /lib/builtins/arm/fp_mode.c
parent8f3cadc28cb2bb9e8f9d69eeaaea1f57f2f7b2ab (diff)
downloadsrc-vendor/compiler-rt.tar.gz
src-vendor/compiler-rt.zip
Vendor import of stripped compiler-rt trunk r375505, the last commitvendor/compiler-rt/compiler-rt-trunk-r375505vendor/compiler-rt
before the upstream Subversion repository was made read-only, and the LLVM project migrated to GitHub: https://llvm.org/svn/llvm-project/compiler-rt/trunk@375505
Notes
Notes: svn path=/vendor/compiler-rt/dist/; revision=353944 svn path=/vendor/compiler-rt/compiler-rt-r375505/; revision=353945; tag=vendor/compiler-rt/compiler-rt-trunk-r375505
Diffstat (limited to 'lib/builtins/arm/fp_mode.c')
-rw-r--r--lib/builtins/arm/fp_mode.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/lib/builtins/arm/fp_mode.c b/lib/builtins/arm/fp_mode.c
new file mode 100644
index 000000000000..300b71935ad4
--- /dev/null
+++ b/lib/builtins/arm/fp_mode.c
@@ -0,0 +1,59 @@
+//===----- lib/arm/fp_mode.c - Floaing-point mode utilities -------*- C -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+
+#include "../fp_mode.h"
+
+#define ARM_TONEAREST 0x0
+#define ARM_UPWARD 0x1
+#define ARM_DOWNWARD 0x2
+#define ARM_TOWARDZERO 0x3
+#define ARM_RMODE_MASK (ARM_TONEAREST | ARM_UPWARD | \
+ ARM_DOWNWARD | ARM_TOWARDZERO)
+#define ARM_RMODE_SHIFT 22
+
+#define ARM_INEXACT 0x1000
+
+#ifndef __ARM_FP
+// For soft float targets, allow changing rounding mode by overriding the weak
+// __arm_fe_default_rmode symbol.
+FE_ROUND_MODE __attribute__((weak)) __arm_fe_default_rmode = FE_TONEAREST;
+#endif
+
+FE_ROUND_MODE __fe_getround() {
+#ifdef __ARM_FP
+ uint32_t fpscr;
+ __asm__ __volatile__("vmrs %0, fpscr" : "=r" (fpscr));
+ fpscr = fpscr >> ARM_RMODE_SHIFT & ARM_RMODE_MASK;
+ switch (fpscr) {
+ case ARM_UPWARD:
+ return FE_UPWARD;
+ case ARM_DOWNWARD:
+ return FE_DOWNWARD;
+ case ARM_TOWARDZERO:
+ return FE_TOWARDZERO;
+ case ARM_TONEAREST:
+ default:
+ return FE_TONEAREST;
+ }
+#else
+ return __arm_fe_default_rmode;
+#endif
+}
+
+int __fe_raise_inexact() {
+#ifdef __ARM_FP
+ uint32_t fpscr;
+ __asm__ __volatile__("vmrs %0, fpscr" : "=r" (fpscr));
+ __asm__ __volatile__("vmsr fpscr, %0" : : "ri" (fpscr | ARM_INEXACT));
+ return 0;
+#else
+ return 0;
+#endif
+}