[compiler-rt][builtins] libc-backed floating-point extend/trunct builtins (#209984)

Add libc-backed floating-point extend/truncate builtins

Part of #197824
This commit is contained in:
hulxv 2026-07-31 03:50:13 +03:00 committed by GitHub
parent 53e16d7708
commit 0879c1092c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 994 additions and 21 deletions

View file

@ -243,6 +243,27 @@ set(GENERIC_TF_SOURCES
trunctfsf2.c
)
# Implement extended-precision builtins, assuming long double is 80 bits.
# long double is not 80 bits on Android or MSVC.
set(x86_80_BIT_SOURCES
divxc3.c
extendhfxf2.c
extendxftf2.c
fixxfdi.c
fixxfti.c
fixunsxfdi.c
fixunsxfsi.c
fixunsxfti.c
floatdixf.c
floattixf.c
floatundixf.c
floatuntixf.c
mulxc3.c
powixf2.c
trunctfxf2.c
truncxfhf2.c
)
option(COMPILER_RT_USE_LIBC_MATH
"Use LLVM libc math routines for floating-point builtins" OFF)
@ -270,6 +291,10 @@ if(COMPILER_RT_USE_LIBC_MATH)
use_libc_builtin(GENERIC_SOURCES divdf3)
use_libc_builtin(GENERIC_SOURCES divsf3)
use_libc_builtin(GENERIC_TF_SOURCES divtf3)
use_libc_builtin(GENERIC_TF_SOURCES extenddftf2)
use_libc_builtin(GENERIC_SOURCES extendsfdf2)
use_libc_builtin(GENERIC_TF_SOURCES extendsftf2)
use_libc_builtin(x86_80_BIT_SOURCES extendxftf2)
use_libc_builtin(GENERIC_SOURCES muldf3)
use_libc_builtin(GENERIC_SOURCES mulsf3)
use_libc_builtin(GENERIC_TF_SOURCES multf3)
@ -278,6 +303,10 @@ if(COMPILER_RT_USE_LIBC_MATH)
use_libc_builtin(GENERIC_SOURCES subdf3)
use_libc_builtin(GENERIC_SOURCES subsf3)
use_libc_builtin(GENERIC_TF_SOURCES subtf3)
use_libc_builtin(GENERIC_SOURCES truncdfsf2)
use_libc_builtin(GENERIC_TF_SOURCES trunctfdf2)
use_libc_builtin(GENERIC_TF_SOURCES trunctfsf2)
use_libc_builtin(x86_80_BIT_SOURCES trunctfxf2)
endif()
option(COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN
@ -349,27 +378,6 @@ if (NOT MSVC)
)
endif ()
# Implement extended-precision builtins, assuming long double is 80 bits.
# long double is not 80 bits on Android or MSVC.
set(x86_80_BIT_SOURCES
divxc3.c
extendhfxf2.c
extendxftf2.c
fixxfdi.c
fixxfti.c
fixunsxfdi.c
fixunsxfsi.c
fixunsxfti.c
floatdixf.c
floattixf.c
floatundixf.c
floatuntixf.c
mulxc3.c
powixf2.c
trunctfxf2.c
truncxfhf2.c
)
if (NOT MSVC)
set(x86_64_SOURCES
${GENERIC_SOURCES}

View file

@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements compiler-rt's __extenddftf2, extend double to float128,
/// on top of LLVM-libc's shared::extenddftf2.
///
//===----------------------------------------------------------------------===//
#define QUAD_PRECISION
#include "fp_lib.h"
#include "fp_libc_config.h"
#include "shared/builtins/extenddftf2.h"
#ifdef CRT_HAS_TF_MODE
extern "C" COMPILER_RT_ABI tf_float __extenddftf2(double a) {
return LIBC_NAMESPACE::shared::extenddftf2(a);
}
#endif

View file

@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements compiler-rt's __extendsfdf2, extend float to double, on
/// top of LLVM-libc's shared::extendsfdf2.
///
//===----------------------------------------------------------------------===//
#include "shared/builtins/extendsfdf2.h"
#include "fp_libc_config.h"
#include "int_lib.h"
extern "C" COMPILER_RT_ABI double __extendsfdf2(float a) {
return LIBC_NAMESPACE::shared::extendsfdf2(a);
}

View file

@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements compiler-rt's __extendsftf2, extend float to float128,
/// on top of LLVM-libc's shared::extendsftf2.
///
//===----------------------------------------------------------------------===//
#define QUAD_PRECISION
#include "fp_lib.h"
#include "fp_libc_config.h"
#include "shared/builtins/extendsftf2.h"
#ifdef CRT_HAS_TF_MODE
extern "C" COMPILER_RT_ABI tf_float __extendsftf2(float a) {
return LIBC_NAMESPACE::shared::extendsftf2(a);
}
#endif

View file

@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements compiler-rt's __extendxftf2, extend long double to
/// float128, on top of LLVM-libc's shared::extendxftf2.
///
//===----------------------------------------------------------------------===//
#define QUAD_PRECISION
#include "fp_lib.h"
#include "fp_libc_config.h"
#include "shared/builtins/extendxftf2.h"
#if defined(CRT_HAS_TF_MODE) && __LDBL_MANT_DIG__ == 64 && defined(__x86_64__)
extern "C" COMPILER_RT_ABI tf_float __extendxftf2(xf_float a) {
return LIBC_NAMESPACE::shared::extendxftf2(a);
}
#endif

View file

@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements compiler-rt's __truncdfsf2, truncate double to float,
/// on top of LLVM-libc's shared::truncdfsf2.
///
//===----------------------------------------------------------------------===//
#include "shared/builtins/truncdfsf2.h"
#include "fp_libc_config.h"
#include "int_lib.h"
extern "C" COMPILER_RT_ABI float __truncdfsf2(double a) {
return LIBC_NAMESPACE::shared::truncdfsf2(a);
}

View file

@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements compiler-rt's __trunctfdf2, truncate float128 to
/// double, on top of LLVM-libc's shared::trunctfdf2.
///
//===----------------------------------------------------------------------===//
#define QUAD_PRECISION
#include "fp_lib.h"
#include "fp_libc_config.h"
#include "shared/builtins/trunctfdf2.h"
#ifdef CRT_HAS_TF_MODE
extern "C" COMPILER_RT_ABI double __trunctfdf2(tf_float a) {
return LIBC_NAMESPACE::shared::trunctfdf2(a);
}
#endif

View file

@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements compiler-rt's __trunctfsf2, truncate float128 to float,
/// on top of LLVM-libc's shared::trunctfsf2.
///
//===----------------------------------------------------------------------===//
#define QUAD_PRECISION
#include "fp_lib.h"
#include "fp_libc_config.h"
#include "shared/builtins/trunctfsf2.h"
#ifdef CRT_HAS_TF_MODE
extern "C" COMPILER_RT_ABI float __trunctfsf2(tf_float a) {
return LIBC_NAMESPACE::shared::trunctfsf2(a);
}
#endif

View file

@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements compiler-rt's __trunctfxf2, truncate float128 to long
/// double, on top of LLVM-libc's shared::trunctfxf2.
///
//===----------------------------------------------------------------------===//
#define QUAD_PRECISION
#include "fp_lib.h"
#include "fp_libc_config.h"
#include "shared/builtins/trunctfxf2.h"
#if defined(CRT_HAS_TF_MODE) && __LDBL_MANT_DIG__ == 64 && defined(__x86_64__)
extern "C" COMPILER_RT_ABI xf_float __trunctfxf2(tf_float a) {
return LIBC_NAMESPACE::shared::trunctfxf2(a);
}
#endif

View file

@ -23,6 +23,10 @@
#include "builtins/divdf3.h"
#include "builtins/divsf3.h"
#include "builtins/divtf3.h"
#include "builtins/extenddftf2.h"
#include "builtins/extendsfdf2.h"
#include "builtins/extendsftf2.h"
#include "builtins/extendxftf2.h"
#include "builtins/muldf3.h"
#include "builtins/mulsf3.h"
#include "builtins/multf3.h"
@ -31,5 +35,9 @@
#include "builtins/subdf3.h"
#include "builtins/subsf3.h"
#include "builtins/subtf3.h"
#include "builtins/truncdfsf2.h"
#include "builtins/trunctfdf2.h"
#include "builtins/trunctfsf2.h"
#include "builtins/trunctfxf2.h"
#endif // LLVM_LIBC_SHARED_BUILTINS_H

View file

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __extenddftf2 implementation as
/// shared::extenddftf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDDFTF2_H
#define LLVM_LIBC_SHARED_BUILTINS_EXTENDDFTF2_H
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/builtins/extenddftf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::extenddftf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128
#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDDFTF2_H

View file

@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __extendsfdf2 implementation as
/// shared::extendsfdf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDSFDF2_H
#define LLVM_LIBC_SHARED_BUILTINS_EXTENDSFDF2_H
#include "shared/libc_common.h"
#include "src/__support/builtins/extendsfdf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::extendsfdf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDSFDF2_H

View file

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __extendsftf2 implementation as
/// shared::extendsftf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDSFTF2_H
#define LLVM_LIBC_SHARED_BUILTINS_EXTENDSFTF2_H
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/builtins/extendsftf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::extendsftf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128
#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDSFTF2_H

View file

@ -0,0 +1,37 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __extendxftf2 implementation as
/// shared::extendxftf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDXFTF2_H
#define LLVM_LIBC_SHARED_BUILTINS_EXTENDXFTF2_H
#include "include/llvm-libc-types/float128.h"
#include "src/__support/macros/properties/types.h"
#if defined(LIBC_TYPES_HAS_FLOAT128) && \
defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
#include "shared/libc_common.h"
#include "src/__support/builtins/extendxftf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::extendxftf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDXFTF2_H

View file

@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __truncdfsf2 implementation as
/// shared::truncdfsf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCDFSF2_H
#define LLVM_LIBC_SHARED_BUILTINS_TRUNCDFSF2_H
#include "shared/libc_common.h"
#include "src/__support/builtins/truncdfsf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::truncdfsf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCDFSF2_H

View file

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __trunctfdf2 implementation as
/// shared::trunctfdf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCTFDF2_H
#define LLVM_LIBC_SHARED_BUILTINS_TRUNCTFDF2_H
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/builtins/trunctfdf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::trunctfdf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128
#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCTFDF2_H

View file

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __trunctfsf2 implementation as
/// shared::trunctfsf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCTFSF2_H
#define LLVM_LIBC_SHARED_BUILTINS_TRUNCTFSF2_H
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/builtins/trunctfsf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::trunctfsf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128
#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCTFSF2_H

View file

@ -0,0 +1,37 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __trunctfxf2 implementation as
/// shared::trunctfxf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCTFXF2_H
#define LLVM_LIBC_SHARED_BUILTINS_TRUNCTFXF2_H
#include "include/llvm-libc-types/float128.h"
#include "src/__support/macros/properties/types.h"
#if defined(LIBC_TYPES_HAS_FLOAT128) && \
defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
#include "shared/libc_common.h"
#include "src/__support/builtins/trunctfxf2.h"
namespace LIBC_NAMESPACE_DECL {
namespace shared {
using builtins::trunctfxf2;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCTFXF2_H

View file

@ -1,3 +1,19 @@
add_header_library(
fpconvert_helper
HDRS
fpconvert_helper.h
DEPENDS
libc.hdr.fenv_macros
libc.src.__support.CPP.algorithm
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.macros.attributes
libc.src.__support.macros.config
)
add_header_library(
addtf3
HDRS
@ -127,3 +143,83 @@ add_header_library(
libc.src.__support.FPUtil.generic.div
libc.src.__support.macros.config
)
add_header_library(
extendsftf2
HDRS
extendsftf2.h
DEPENDS
libc.include.llvm-libc-types.float128
libc.src.__support.builtins.fpconvert_helper
libc.src.__support.macros.config
)
add_header_library(
extenddftf2
HDRS
extenddftf2.h
DEPENDS
libc.include.llvm-libc-types.float128
libc.src.__support.builtins.fpconvert_helper
libc.src.__support.macros.config
)
add_header_library(
extendxftf2
HDRS
extendxftf2.h
DEPENDS
libc.include.llvm-libc-types.float128
libc.src.__support.builtins.fpconvert_helper
libc.src.__support.macros.config
libc.src.__support.macros.properties.types
)
add_header_library(
trunctfdf2
HDRS
trunctfdf2.h
DEPENDS
libc.include.llvm-libc-types.float128
libc.src.__support.builtins.fpconvert_helper
libc.src.__support.macros.config
)
add_header_library(
trunctfsf2
HDRS
trunctfsf2.h
DEPENDS
libc.include.llvm-libc-types.float128
libc.src.__support.builtins.fpconvert_helper
libc.src.__support.macros.config
)
add_header_library(
trunctfxf2
HDRS
trunctfxf2.h
DEPENDS
libc.include.llvm-libc-types.float128
libc.src.__support.builtins.fpconvert_helper
libc.src.__support.macros.config
libc.src.__support.macros.properties.types
)
add_header_library(
extendsfdf2
HDRS
extendsfdf2.h
DEPENDS
libc.src.__support.builtins.fpconvert_helper
libc.src.__support.macros.config
)
add_header_library(
truncdfsf2
HDRS
truncdfsf2.h
DEPENDS
libc.src.__support.builtins.fpconvert_helper
libc.src.__support.macros.config
)

View file

@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __extenddftf2 implementation as
/// builtins::extenddftf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDDFTF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDDFTF2_H
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT128
#include "src/__support/builtins/fpconvert_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Extend double to float128; mirrors compiler-rt's __extenddftf2.
LIBC_INLINE float128 extenddftf2(double x) { return fpconvert<float128>(x); }
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDDFTF2_H

View file

@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __extendsfdf2 implementation as
/// builtins::extendsfdf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFDF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFDF2_H
#include "src/__support/builtins/fpconvert_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Extend float to double; mirrors compiler-rt's __extendsfdf2.
LIBC_INLINE double extendsfdf2(float x) { return fpconvert<double>(x); }
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFDF2_H

View file

@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __extendsftf2 implementation as
/// builtins::extendsftf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFTF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFTF2_H
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT128
#include "src/__support/builtins/fpconvert_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Extend float to float128; mirrors compiler-rt's __extendsftf2.
LIBC_INLINE float128 extendsftf2(float x) { return fpconvert<float128>(x); }
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFTF2_H

View file

@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __extendxftf2 implementation as
/// builtins::extendxftf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDXFTF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDXFTF2_H
#include "include/llvm-libc-types/float128.h"
#include "src/__support/macros/properties/types.h"
#if defined(LIBC_TYPES_HAS_FLOAT128) && \
defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
#include "src/__support/builtins/fpconvert_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Extend long double to float128; mirrors compiler-rt's __extendxftf2.
LIBC_INLINE float128 extendxftf2(long double x) {
return fpconvert<float128>(x);
}
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDXFTF2_H

View file

@ -0,0 +1,83 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Shared float-to-float extend/truncate conversions, rounding to nearest
/// (ties to even) when narrowing. These mirror compiler-rt's __extend<a><b>2 /
/// __trunc<a><b>2 builtins, so they can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FPCONVERT_HELPER_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FPCONVERT_HELPER_H
#include "hdr/fenv_macros.h"
#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// TODO: use fputil::cast after adding Float128/64/32/16 classes currently, we
// are using this helper to avoid an infinity loop that happens because
// fputil::cast is calling the builtins if the target doesn't have FPU.
//
// assembly (each body below compiles to a self-call):
// // double f(float128 x) { return cast<double>(x); }
// trunc_tf_df: callq __trunctfdf2@PLT
// // float128 g(double x) { return cast<float128>(x); }
// ext_df_tf: jmp __extenddftf2@PLT // TAILCALL
// Convert the floating-point value x from From to To (extend or truncate).
// Narrowing rounds to nearest, ties to even; mirrors compiler-rt __extend* /
// __trunc*.
template <typename To, typename From>
LIBC_INLINE constexpr To fpconvert(From x) {
using FromBits = fputil::FPBits<From>;
using ToBits = fputil::FPBits<To>;
using ToStorageType = typename ToBits::StorageType;
FromBits x_bits(x);
if constexpr (cpp::is_same_v<To, From>)
return x;
if (x_bits.is_nan()) {
typename FromBits::StorageType x_frac = x_bits.get_mantissa();
if constexpr (ToBits::FRACTION_LEN >= FromBits::FRACTION_LEN) {
ToStorageType to_frac =
static_cast<ToStorageType>(x_frac)
<< (ToBits::FRACTION_LEN - FromBits::FRACTION_LEN);
return ToBits::signaling_nan(x_bits.sign(), to_frac).get_val();
}
ToStorageType to_frac = static_cast<ToStorageType>(
x_frac >> (FromBits::FRACTION_LEN - ToBits::FRACTION_LEN));
return ToBits::quiet_nan(x_bits.sign(), to_frac).get_val();
}
if (x_bits.is_inf())
return ToBits::inf(x_bits.sign()).get_val();
// Zero and subnormals fall through: DyadicFloat(x) gives a zero mantissa for
// zero, which as<To>() maps back to a correctly-signed zero.
constexpr size_t MAX_FRACTION_LEN =
cpp::max(ToBits::FRACTION_LEN, FromBits::FRACTION_LEN);
fputil::DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x);
return xd.template as<To, /*ShouldSignalExceptions=*/true>();
}
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FPCONVERT_HELPER_H

View file

@ -0,0 +1,30 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __truncdfsf2 implementation as
/// builtins::truncdfsf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFSF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFSF2_H
#include "src/__support/builtins/fpconvert_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Truncate double to float; mirrors compiler-rt's __truncdfsf2.
LIBC_INLINE float truncdfsf2(double x) { return fpconvert<float>(x); }
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFSF2_H

View file

@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __trunctfdf2 implementation as
/// builtins::trunctfdf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFDF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFDF2_H
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT128
#include "src/__support/builtins/fpconvert_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Truncate float128 to double; mirrors compiler-rt's __trunctfdf2.
LIBC_INLINE double trunctfdf2(float128 x) { return fpconvert<double>(x); }
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFDF2_H

View file

@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __trunctfsf2 implementation as
/// builtins::trunctfsf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFSF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFSF2_H
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT128
#include "src/__support/builtins/fpconvert_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Truncate float128 to float; mirrors compiler-rt's __trunctfsf2.
LIBC_INLINE float trunctfsf2(float128 x) { return fpconvert<float>(x); }
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFSF2_H

View file

@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This header exposes LLVM-libc's __trunctfxf2 implementation as
/// builtins::trunctfxf2 so that it can be reused by compiler-rt's builtins.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFXF2_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFXF2_H
#include "include/llvm-libc-types/float128.h"
#include "src/__support/macros/properties/types.h"
#if defined(LIBC_TYPES_HAS_FLOAT128) && \
defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
#include "src/__support/builtins/fpconvert_helper.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace builtins {
// Truncate float128 to long double; mirrors compiler-rt's __trunctfxf2.
LIBC_INLINE long double trunctfxf2(float128 x) {
return fpconvert<long double>(x);
}
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT128 && LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFXF2_H

View file

@ -834,6 +834,10 @@ add_fp_unittest(
libc.src.__support.builtins.divdf3
libc.src.__support.builtins.divsf3
libc.src.__support.builtins.divtf3
libc.src.__support.builtins.extenddftf2
libc.src.__support.builtins.extendsfdf2
libc.src.__support.builtins.extendsftf2
libc.src.__support.builtins.extendxftf2
libc.src.__support.builtins.muldf3
libc.src.__support.builtins.mulsf3
libc.src.__support.builtins.multf3
@ -842,6 +846,10 @@ add_fp_unittest(
libc.src.__support.builtins.subdf3
libc.src.__support.builtins.subsf3
libc.src.__support.builtins.subtf3
libc.src.__support.builtins.truncdfsf2
libc.src.__support.builtins.trunctfdf2
libc.src.__support.builtins.trunctfsf2
libc.src.__support.builtins.trunctfxf2
)
add_fp_unittest(

View file

@ -38,3 +38,25 @@ TEST(LlvmLibcSharedBuiltinsTest, QuadPrecisionArithmtic) {
}
#endif // LIBC_TYPES_HAS_FLOAT128
TEST(LlvmLibcSharedBuiltinsTest, ExtendConversion) {
EXPECT_FP_EQ(1.5, shared::extendsfdf2(1.5f));
#ifdef LIBC_TYPES_HAS_FLOAT128
EXPECT_FP_EQ(float128(1.5), shared::extenddftf2(1.5));
EXPECT_FP_EQ(float128(1.5), shared::extendsftf2(1.5f));
#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
EXPECT_FP_EQ(float128(1.5), shared::extendxftf2(1.5L));
#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#endif // LIBC_TYPES_HAS_FLOAT128
}
TEST(LlvmLibcSharedBuiltinsTest, TruncateConversion) {
EXPECT_FP_EQ(1.5f, shared::truncdfsf2(1.5));
#ifdef LIBC_TYPES_HAS_FLOAT128
EXPECT_FP_EQ(1.5, shared::trunctfdf2(float128(1.5)));
EXPECT_FP_EQ(1.5f, shared::trunctfsf2(float128(1.5)));
#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
EXPECT_FP_EQ(1.5L, shared::trunctfxf2(float128(1.5)));
#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#endif // LIBC_TYPES_HAS_FLOAT128
}