diff options
| author | Yi Kong <yikong@google.com> | 2019-03-26 22:01:22 +0000 |
|---|---|---|
| committer | Yi Kong <yikong@google.com> | 2019-03-26 22:01:22 +0000 |
| commit | 2cabea054e40ae2837da959d0ca89ae25cf1b1f1 (patch) | |
| tree | 28e7e891bd6a5b5f3dbb3745db45ea6498c1b36a /compiler-rt/lib/builtins/arm/fp_mode.c | |
| parent | 05495c5d4571b1756369e00a1ca7003d63e204da (diff) | |
| download | bcm5719-llvm-2cabea054e40ae2837da959d0ca89ae25cf1b1f1.tar.gz bcm5719-llvm-2cabea054e40ae2837da959d0ca89ae25cf1b1f1.zip | |
[builtins] Rounding mode support for addxf3/subxf3
Implement rounding mode support for addxf3/subxf3.
On architectures that implemented the support, this will access the
corresponding floating point environment register to apply the
correct rounding. For other architectures, it will keep the current
behaviour and use IEEE-754 default rounding mode (to nearest, ties
to even).
ARM32/AArch64 support implemented in this change. i386 and AMD64
will be added in a follow up change.
Differential Revision: https://reviews.llvm.org/D57143
llvm-svn: 357035
Diffstat (limited to 'compiler-rt/lib/builtins/arm/fp_mode.c')
| -rw-r--r-- | compiler-rt/lib/builtins/arm/fp_mode.c | 59 |
1 files changed, 59 insertions, 0 deletions
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 +} |

