diff options
Diffstat (limited to 'compiler-rt/lib/builtins')
| -rw-r--r-- | compiler-rt/lib/builtins/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/aarch64/fp_mode.c | 59 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/adddf3.c | 3 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/addsf3.c | 3 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/addtf3.c | 3 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/arm/fp_mode.c | 59 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/fp_add_impl.inc | 19 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/fp_mode.c | 24 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/fp_mode.h | 29 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/subdf3.c | 3 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/subsf3.c | 3 | ||||
| -rw-r--r-- | compiler-rt/lib/builtins/subtf3.c | 3 |
12 files changed, 198 insertions, 15 deletions
diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 1669ea8586e..0662b1ae23e 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -94,6 +94,7 @@ set(GENERIC_SOURCES floatunsisf.c floatuntidf.c floatuntisf.c + fp_mode.c int_util.c lshrdi3.c lshrti3.c @@ -290,6 +291,7 @@ set(i386_SOURCES ${i386_SOURCES} ${x86_ARCH_SOURCES}) set(i686_SOURCES ${i686_SOURCES} ${x86_ARCH_SOURCES}) set(arm_SOURCES + arm/fp_mode.c arm/bswapdi2.S arm/bswapsi2.S arm/clzdi2.S @@ -441,7 +443,8 @@ endif() set(aarch64_SOURCES ${GENERIC_TF_SOURCES} - ${GENERIC_SOURCES}) + ${GENERIC_SOURCES} + aarch64/fp_mode.c) if (MINGW) set(aarch64_SOURCES diff --git a/compiler-rt/lib/builtins/aarch64/fp_mode.c b/compiler-rt/lib/builtins/aarch64/fp_mode.c new file mode 100644 index 00000000000..5a413689d2c --- /dev/null +++ b/compiler-rt/lib/builtins/aarch64/fp_mode.c @@ -0,0 +1,59 @@ +//===----- 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. +FE_ROUND_MODE __attribute__((weak)) __aarch64_fe_default_rmode = FE_TONEAREST; +#endif + +FE_ROUND_MODE __fe_getround() { +#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 FE_UPWARD; + case AARCH64_DOWNWARD: + return FE_DOWNWARD; + case AARCH64_TOWARDZERO: + return FE_TOWARDZERO; + case AARCH64_TONEAREST: + default: + return FE_TONEAREST; + } +#else + return __aarch64_fe_default_rmode; +#endif +} + +int __fe_raise_inexact() { +#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 +} diff --git a/compiler-rt/lib/builtins/adddf3.c b/compiler-rt/lib/builtins/adddf3.c index 73ad6150096..d5c5e980b6d 100644 --- a/compiler-rt/lib/builtins/adddf3.c +++ b/compiler-rt/lib/builtins/adddf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements double-precision soft-float addition with the IEEE-754 -// default rounding (to nearest, ties to even). +// This file implements double-precision soft-float addition. // //===----------------------------------------------------------------------===// diff --git a/compiler-rt/lib/builtins/addsf3.c b/compiler-rt/lib/builtins/addsf3.c index a48d537236a..95985b104eb 100644 --- a/compiler-rt/lib/builtins/addsf3.c +++ b/compiler-rt/lib/builtins/addsf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements single-precision soft-float addition with the IEEE-754 -// default rounding (to nearest, ties to even). +// This file implements single-precision soft-float addition. // //===----------------------------------------------------------------------===// diff --git a/compiler-rt/lib/builtins/addtf3.c b/compiler-rt/lib/builtins/addtf3.c index 1dc303b70d7..156c251a067 100644 --- a/compiler-rt/lib/builtins/addtf3.c +++ b/compiler-rt/lib/builtins/addtf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements quad-precision soft-float addition with the IEEE-754 -// default rounding (to nearest, ties to even). +// This file implements quad-precision soft-float addition. // //===----------------------------------------------------------------------===// diff --git a/compiler-rt/lib/builtins/arm/fp_mode.c b/compiler-rt/lib/builtins/arm/fp_mode.c new file mode 100644 index 00000000000..300b71935ad --- /dev/null +++ b/compiler-rt/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 +} diff --git a/compiler-rt/lib/builtins/fp_add_impl.inc b/compiler-rt/lib/builtins/fp_add_impl.inc index f9a32ce6733..828efea9fa4 100644 --- a/compiler-rt/lib/builtins/fp_add_impl.inc +++ b/compiler-rt/lib/builtins/fp_add_impl.inc @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "fp_lib.h" +#include "fp_mode.h" static __inline fp_t __addXf3__(fp_t a, fp_t b) { rep_t aRep = toRep(a); @@ -137,7 +138,21 @@ static __inline fp_t __addXf3__(fp_t a, fp_t b) { // Final rounding. The result may overflow to infinity, but that is the // correct result in that case. - if (roundGuardSticky > 0x4) result++; - if (roundGuardSticky == 0x4) result += result & 1; + switch (__fe_getround()){ + case FE_TONEAREST: + if (roundGuardSticky > 0x4) result++; + if (roundGuardSticky == 0x4) result += result & 1; + break; + case FE_DOWNWARD: + if (resultSign && roundGuardSticky) result++; + break; + case FE_UPWARD: + if (!resultSign && roundGuardSticky) result++; + break; + case FE_TOWARDZERO: + break; + } + if (roundGuardSticky) + __fe_raise_inexact(); return fromRep(result); } diff --git a/compiler-rt/lib/builtins/fp_mode.c b/compiler-rt/lib/builtins/fp_mode.c new file mode 100644 index 00000000000..c1b6c1f6b8a --- /dev/null +++ b/compiler-rt/lib/builtins/fp_mode.c @@ -0,0 +1,24 @@ +//===----- lib/fp_mode.c - Floaing-point environment 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 +// +//===----------------------------------------------------------------------===// +// +// This file provides a default implementation of fp_mode.h for architectures +// that does not support or does not have an implementation of floating point +// environment mode. +// +//===----------------------------------------------------------------------===// + +#include "fp_mode.h" + +// IEEE-754 default rounding (to nearest, ties to even). +FE_ROUND_MODE __fe_getround() { + return FE_TONEAREST; +} + +int __fe_raise_inexact() { + return 0; +} diff --git a/compiler-rt/lib/builtins/fp_mode.h b/compiler-rt/lib/builtins/fp_mode.h new file mode 100644 index 00000000000..51bec0431a4 --- /dev/null +++ b/compiler-rt/lib/builtins/fp_mode.h @@ -0,0 +1,29 @@ +//===----- lib/fp_mode.h - Floaing-point environment 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 +// +//===----------------------------------------------------------------------===// +// +// This file is not part of the interface of this library. +// +// This file defines an interface for accessing hardware floating point +// environment mode. +// +//===----------------------------------------------------------------------===// + +#ifndef FP_MODE +#define FP_MODE + +typedef enum { + FE_TONEAREST, + FE_DOWNWARD, + FE_UPWARD, + FE_TOWARDZERO +} FE_ROUND_MODE; + +FE_ROUND_MODE __fe_getround(); +int __fe_raise_inexact(); + +#endif // FP_MODE_H diff --git a/compiler-rt/lib/builtins/subdf3.c b/compiler-rt/lib/builtins/subdf3.c index 013c60e9c84..292aec6d1e8 100644 --- a/compiler-rt/lib/builtins/subdf3.c +++ b/compiler-rt/lib/builtins/subdf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements double-precision soft-float subtraction with the -// IEEE-754 default rounding (to nearest, ties to even). +// This file implements double-precision soft-float subtraction. // //===----------------------------------------------------------------------===// diff --git a/compiler-rt/lib/builtins/subsf3.c b/compiler-rt/lib/builtins/subsf3.c index 90b0e11f3eb..760db366ee4 100644 --- a/compiler-rt/lib/builtins/subsf3.c +++ b/compiler-rt/lib/builtins/subsf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements single-precision soft-float subtraction with the -// IEEE-754 default rounding (to nearest, ties to even). +// This file implements single-precision soft-float subtraction. // //===----------------------------------------------------------------------===// diff --git a/compiler-rt/lib/builtins/subtf3.c b/compiler-rt/lib/builtins/subtf3.c index 871cf86b89f..f1b3e293516 100644 --- a/compiler-rt/lib/builtins/subtf3.c +++ b/compiler-rt/lib/builtins/subtf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements quad-precision soft-float subtraction with the -// IEEE-754 default rounding (to nearest, ties to even). +// This file implements quad-precision soft-float subtraction. // //===----------------------------------------------------------------------===// |

