aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/builtins/aarch64/fp_mode.c
diff options
context:
space:
mode:
authorMaxim Yurchuk <maxim-yurchuk@ydb.tech>2024-10-18 20:31:38 +0300
committerGitHub <noreply@github.com>2024-10-18 20:31:38 +0300
commit2a74bac2d2d3bccb4e10120f1ead805640ec9dd0 (patch)
tree047e4818ced5aaf73f58517629e5260b5291f9f0 /contrib/libs/cxxsupp/builtins/aarch64/fp_mode.c
parent2d9656823e9521d8c29ea4c9a1d0eab78391abfc (diff)
parent3d834a1923bbf9403cd4a448e7f32b670aa4124f (diff)
downloadydb-2a74bac2d2d3bccb4e10120f1ead805640ec9dd0.tar.gz
Merge pull request #10502 from ydb-platform/mergelibs-241016-1210
Library import 241016-1210
Diffstat (limited to 'contrib/libs/cxxsupp/builtins/aarch64/fp_mode.c')
-rw-r--r--contrib/libs/cxxsupp/builtins/aarch64/fp_mode.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/contrib/libs/cxxsupp/builtins/aarch64/fp_mode.c b/contrib/libs/cxxsupp/builtins/aarch64/fp_mode.c
new file mode 100644
index 0000000000..03d75cd8be
--- /dev/null
+++ b/contrib/libs/cxxsupp/builtins/aarch64/fp_mode.c
@@ -0,0 +1,60 @@
+//===----- lib/aarch64/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 AARCH64_TONEAREST 0x0
+#define AARCH64_UPWARD 0x1
+#define AARCH64_DOWNWARD 0x2
+#define AARCH64_TOWARDZERO 0x3
+#define AARCH64_RMODE_MASK (AARCH64_TONEAREST | AARCH64_UPWARD | \
+ AARCH64_DOWNWARD | AARCH64_TOWARDZERO)
+#define AARCH64_RMODE_SHIFT 22
+
+#define AARCH64_INEXACT 0x10
+
+#ifndef __ARM_FP
+// For soft float targets, allow changing rounding mode by overriding the weak
+// __aarch64_fe_default_rmode symbol.
+CRT_FE_ROUND_MODE __attribute__((weak)) __aarch64_fe_default_rmode =
+ CRT_FE_TONEAREST;
+#endif
+
+CRT_FE_ROUND_MODE __fe_getround(void) {
+#ifdef __ARM_FP
+ uint64_t fpcr;
+ __asm__ __volatile__("mrs %0, fpcr" : "=r" (fpcr));
+ fpcr = fpcr >> AARCH64_RMODE_SHIFT & AARCH64_RMODE_MASK;
+ switch (fpcr) {
+ case AARCH64_UPWARD:
+ return CRT_FE_UPWARD;
+ case AARCH64_DOWNWARD:
+ return CRT_FE_DOWNWARD;
+ case AARCH64_TOWARDZERO:
+ return CRT_FE_TOWARDZERO;
+ case AARCH64_TONEAREST:
+ default:
+ return CRT_FE_TONEAREST;
+ }
+#else
+ return __aarch64_fe_default_rmode;
+#endif
+}
+
+int __fe_raise_inexact(void) {
+#ifdef __ARM_FP
+ uint64_t fpsr;
+ __asm__ __volatile__("mrs %0, fpsr" : "=r" (fpsr));
+ __asm__ __volatile__("msr fpsr, %0" : : "ri" (fpsr | AARCH64_INEXACT));
+ return 0;
+#else
+ return 0;
+#endif
+}