mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-13 19:32:41 +00:00
Revert "Revert "[builtins] Rounding mode support for addxf3/subxf3""
Test failure fixed. This reverts commit e204d244badb2e9765a1020f41c773f63da208f4. llvm-svn: 371003
This commit is contained in:
parent
473d0d7f56
commit
33b8a55329
@ -97,6 +97,7 @@ set(GENERIC_SOURCES
|
||||
floatunsisf.c
|
||||
floatuntidf.c
|
||||
floatuntisf.c
|
||||
fp_mode.c
|
||||
int_util.c
|
||||
lshrdi3.c
|
||||
lshrti3.c
|
||||
@ -306,6 +307,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
|
||||
@ -451,6 +453,7 @@ endif()
|
||||
set(aarch64_SOURCES
|
||||
${GENERIC_TF_SOURCES}
|
||||
${GENERIC_SOURCES}
|
||||
aarch64/fp_mode.c
|
||||
)
|
||||
|
||||
if (MINGW)
|
||||
|
59
compiler-rt/lib/builtins/aarch64/fp_mode.c
Normal file
59
compiler-rt/lib/builtins/aarch64/fp_mode.c
Normal file
@ -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
|
||||
}
|
@ -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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
59
compiler-rt/lib/builtins/arm/fp_mode.c
Normal file
59
compiler-rt/lib/builtins/arm/fp_mode.c
Normal file
@ -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
|
||||
}
|
@ -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);
|
||||
@ -149,9 +150,23 @@ static __inline fp_t __addXf3__(fp_t a, fp_t b) {
|
||||
|
||||
// Perform the 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);
|
||||
}
|
||||
|
24
compiler-rt/lib/builtins/fp_mode.c
Normal file
24
compiler-rt/lib/builtins/fp_mode.c
Normal file
@ -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;
|
||||
}
|
29
compiler-rt/lib/builtins/fp_mode.h
Normal file
29
compiler-rt/lib/builtins/fp_mode.h
Normal file
@ -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
|
@ -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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -11,11 +11,12 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "int_lib.h"
|
||||
#include <fenv.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
|
||||
#include "int_lib.h"
|
||||
#include "fp_test.h"
|
||||
|
||||
// Returns: a + b
|
||||
@ -74,6 +75,36 @@ int main()
|
||||
UINT64_C(0x61e58dd6c51eb77c)))
|
||||
return 1;
|
||||
|
||||
#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP)
|
||||
// Rounding mode tests on supported architectures
|
||||
const long double m = 1234.0L, n = 0.01L;
|
||||
|
||||
fesetround(FE_UPWARD);
|
||||
if (test__addtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d8)))
|
||||
return 1;
|
||||
|
||||
fesetround(FE_DOWNWARD);
|
||||
if (test__addtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
|
||||
|
||||
fesetround(FE_TOWARDZERO);
|
||||
if (test__addtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
|
||||
fesetround(FE_TONEAREST);
|
||||
if (test__addtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#else
|
||||
printf("skipped\n");
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <fenv.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if __LDBL_MANT_DIG__ == 113
|
||||
@ -67,6 +68,35 @@ int main()
|
||||
UINT64_C(0xa44a7bca780a166c)))
|
||||
return 1;
|
||||
|
||||
#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP)
|
||||
// Rounding mode tests on supported architectures
|
||||
const long double m = 1234.02L, n = 0.01L;
|
||||
|
||||
fesetround(FE_UPWARD);
|
||||
if (test__subtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
|
||||
fesetround(FE_DOWNWARD);
|
||||
if (test__subtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d6)))
|
||||
return 1;
|
||||
|
||||
fesetround(FE_TOWARDZERO);
|
||||
if (test__subtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d6)))
|
||||
return 1;
|
||||
|
||||
fesetround(FE_TONEAREST);
|
||||
if (test__subtf3(m, n,
|
||||
UINT64_C(0x40093480a3d70a3d),
|
||||
UINT64_C(0x70a3d70a3d70a3d7)))
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#else
|
||||
printf("skipped\n");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user