Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc] Add nearest integer instructions to fputil.
Add round to nearest integer instructions to fputil. This will be used in sinf implementation https://reviews.llvm.org/D123154 Reviewed By: michaelrj Differential Revision: https://reviews.llvm.org/D129776
- Loading branch information
Showing
5 changed files
with
148 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
//===--- Round floating point to nearest integer on aarch64 -----*- 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_NEAREST_INTEGER_H | ||
#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_NEAREST_INTEGER_H | ||
|
||
#include "src/__support/architectures.h" | ||
|
||
#if !defined(LLVM_LIBC_ARCH_AARCH64) | ||
#error "Invalid include" | ||
#endif | ||
|
||
namespace __llvm_libc { | ||
namespace fputil { | ||
|
||
static inline double nearest_integer(double x) { | ||
double result; | ||
__asm__ __volatile__("frintn %d0, %d1\n\t" : "=w"(result) : "w"(x)); | ||
return result; | ||
} | ||
|
||
} // namespace fputil | ||
} // namespace __llvm_libc | ||
|
||
#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_NEAREST_INTEGER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
//===-- Fast rounding to nearest integer for floating point -----*- 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_NEAREST_INTEGER_H | ||
#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_NEAREST_INTEGER_H | ||
|
||
#include "src/__support/architectures.h" | ||
#include "src/__support/common.h" | ||
|
||
#if (defined(LLVM_LIBC_ARCH_X86_64) && defined(__SSE4_2__)) | ||
#include "x86_64/nearest_integer.h" | ||
#elif defined(LLVM_LIBC_ARCH_AARCH64) | ||
#include "aarch64/nearest_integer.h" | ||
#else | ||
|
||
namespace __llvm_libc { | ||
namespace fputil { | ||
|
||
// This is a fast implementation for rounding to a nearest integer that, in case | ||
// of a tie, might pick a random one among 2 closest integers when the rounding | ||
// mode is not FE_TONEAREST. | ||
// | ||
// Notice that for AARCH64 and x86-64 with SSE4.2 support, we will use their | ||
// corresponding rounding instruction instead. And in those cases, the results | ||
// are rounded to the nearest integer, tie-to-even. | ||
static inline double nearest_integer(double x) { | ||
if (x < 0x1p53 && x > -0x1p53) { | ||
double r = x < 0 ? (x - 0x1.0p52) + 0x1.0p52 : (x + 0x1.0p52) - 0x1.0p52; | ||
double diff = x - r; | ||
// The expression above is correct for the default rounding mode, round-to- | ||
// nearest, tie-to-even. For other rounding modes, it might be off by 1, | ||
// which is corrected below. | ||
if (unlikely(diff > 0.5)) | ||
return r + 1.0; | ||
if (unlikely(diff < -0.5)) | ||
return r - 1.0; | ||
return r; | ||
} | ||
return x; | ||
} | ||
|
||
} // namespace fputil | ||
} // namespace __llvm_libc | ||
|
||
#endif | ||
#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_NEAREST_INTEGER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
//===--- Round floating point to nearest integer on x86-64 ------*- 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_X86_64_NEAREST_INTEGER_H | ||
#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_X86_64_NEAREST_INTEGER_H | ||
|
||
#include "src/__support/architectures.h" | ||
|
||
#if !defined(LLVM_LIBC_ARCH_X86_64) | ||
#error "Invalid include" | ||
#endif | ||
|
||
#if !defined(__SSE4_2__) | ||
#error "SSE4.2 instruction set is not supported" | ||
#endif | ||
|
||
#include <immintrin.h> | ||
|
||
namespace __llvm_libc { | ||
namespace fputil { | ||
|
||
static inline double nearest_integer(double x) { | ||
__m128d xmm = _mm_set_sd(x); // NOLINT | ||
__m128d ymm = | ||
_mm_round_sd(xmm, xmm, _MM_ROUND_NEAREST | _MM_FROUND_NO_EXC); // NOLINT | ||
return ymm[0]; | ||
} | ||
|
||
} // namespace fputil | ||
} // namespace __llvm_libc | ||
|
||
#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_X86_64_NEAREST_INTEGER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters