[libc][stdfix] Add abs functions for signed fixed point types. (#81823)

This commit is contained in:
lntue 2024-02-15 18:09:40 -05:00 committed by GitHub
parent 340b1ab9dc
commit 2c45bda802
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 473 additions and 2 deletions

View File

@ -442,6 +442,18 @@ if(LIBC_COMPILER_HAS_FLOAT128)
)
endif()
if(LIBC_COMPILER_HAS_FIXED_POINT)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# stdfix.h _Fract and _Accum entrypoints
libc.src.stdfix.abshk
libc.src.stdfix.abshr
libc.src.stdfix.absk
libc.src.stdfix.absr
libc.src.stdfix.abslk
libc.src.stdfix.abslr
)
endif()
if(LLVM_LIBC_FULL_BUILD)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# assert.h entrypoints

View File

@ -60,7 +60,7 @@ Fixed-point Arithmetics
| +----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| | unsigned (uhr) | signed (hr) | unsigned (ur) | signed (r) | unsigned (ulr) | signed (lr) | unsigned (uhk) | signed (hk) | unsigned (uk) | signed (k) | unsigned (ulk) | signed (lk) |
+===============+================+=============+===============+============+================+=============+================+=============+===============+============+================+=============+
| abs | | | | | | | | | | | | |
| abs | | |check| | | |check| | | |check| | | |check| | | |check| | | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| bits\* | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+

View File

@ -52,7 +52,6 @@ def CharType : NamedType<"char">;
def UnsignedCharType : NamedType<"unsigned char">;
def UnsignedShortType : NamedType<"unsigned short">;
// TODO: Add compatibility layer to use C23 type _Float128 if possible.
def Float128Type : NamedType<"float128">;
// Common types

View File

@ -1,3 +1,20 @@
// Fixed point types.
// From ISO/IEC TR 18037:2008 standard:
// https://standards.iso.org/ittf/PubliclyAvailableStandards/c051126_ISO_IEC_TR_18037_2008.zip
def ShortFractType : NamedType<"short fract">;
def FractType : NamedType<"fract">;
def LongFractType : NamedType<"long fract">;
def UnsignedShortFractType : NamedType<"unsigned short fract">;
def UnsignedFractType : NamedType<"unsigned fract">;
def UnsignedLongFractType : NamedType<"unsigned long fract">;
def ShortAccumType : NamedType<"short accum">;
def AccumType : NamedType<"accum">;
def LongAccumType : NamedType<"long accum">;
def UnsignedShortAccumType : NamedType<"unsigned short accum">;
def UnsignedAccumType : NamedType<"unsigned accum">;
def UnsignedLongAccumType : NamedType<"unsigned long accum">;
def StdcExt : StandardSpec<"stdc_ext"> {
// From ISO/IEC TR 18037:2008 standard:
// https://standards.iso.org/ittf/PubliclyAvailableStandards/c051126_ISO_IEC_TR_18037_2008.zip
@ -7,6 +24,13 @@ def StdcExt : StandardSpec<"stdc_ext"> {
[], // types
[], // enums
[ // functions
GuardedFunctionSpec<"abshr", RetValSpec<ShortFractType>, [ArgSpec<ShortFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"absr", RetValSpec<FractType>, [ArgSpec<FractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"abslr", RetValSpec<LongFractType>, [ArgSpec<LongFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"abshk", RetValSpec<ShortAccumType>, [ArgSpec<ShortAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"absk", RetValSpec<AccumType>, [ArgSpec<AccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"abslk", RetValSpec<LongAccumType>, [ArgSpec<LongAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
]
>;

View File

@ -6,6 +6,7 @@ add_subdirectory(fenv)
add_subdirectory(inttypes)
add_subdirectory(math)
add_subdirectory(stdbit)
add_subdirectory(stdfix)
add_subdirectory(stdio)
add_subdirectory(stdlib)
add_subdirectory(string)

View File

@ -7,3 +7,14 @@ add_header_library(
libc.src.__support.macros.attributes
libc.src.__support.CPP.type_traits
)
add_header_library(
fx_bits
HDRS
fx_bits.h
DEPENDS
.fx_rep
libc.include.llvm-libc-macros.stdfix_macros
libc.src.__support.macros.attributes
libc.src.__support.macros.optimization
)

View File

@ -0,0 +1,37 @@
//===-- Utility class to manipulate fixed point numbers. --*- 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_FIXEDPOINT_FXBITS_H
#define LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_FXBITS_H
#include "include/llvm-libc-macros/stdfix-macros.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "fx_rep.h"
#ifdef LIBC_COMPILER_HAS_FIXED_POINT
namespace LIBC_NAMESPACE::fixed_point {
template <typename T> LIBC_INLINE constexpr T abs(T x) {
using FXRep = FXRep<T>;
if constexpr (FXRep::SIGN_LEN == 0)
return x;
else {
if (LIBC_UNLIKELY(x == FXRep::MIN()))
return FXRep::MAX();
return (x < FXRep::ZERO() ? -x : x);
}
}
} // namespace LIBC_NAMESPACE::fixed_point
#endif // LIBC_COMPILER_HAS_FIXED_POINT
#endif // LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_FXBITS_H

View File

@ -0,0 +1,18 @@
if(NOT LIBC_COMPILER_HAS_FIXED_POINT)
return()
endif()
foreach(suffix IN ITEMS hr r lr hk k lk)
add_entrypoint_object(
abs${suffix}
HDRS
abs${suffix}.h
SRCS
abs${suffix}.cpp
COMPILE_OPTIONS
-O3
-ffixed-point
DEPENDS
libc.src.__support.fixed_point.fx_bits
)
endforeach()

19
libc/src/stdfix/abshk.cpp Normal file
View File

@ -0,0 +1,19 @@
//===-- Implementation of abshk function ----------------------------------===//
//
// 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 "abshk.h"
#include "src/__support/common.h"
#include "src/__support/fixed_point/fx_bits.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(short accum, abshk, (short accum x)) {
return fixed_point::abs(x);
}
} // namespace LIBC_NAMESPACE

20
libc/src/stdfix/abshk.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for abshk -------------------------*- 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_STDFIX_ABSHK_H
#define LLVM_LIBC_SRC_STDFIX_ABSHK_H
#include "include/llvm-libc-macros/stdfix-macros.h"
namespace LIBC_NAMESPACE {
short accum abshk(short accum x);
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC_STDFIX_ABSHK_H

19
libc/src/stdfix/abshr.cpp Normal file
View File

@ -0,0 +1,19 @@
//===-- Implementation of abshr function ----------------------------------===//
//
// 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 "abshr.h"
#include "src/__support/common.h"
#include "src/__support/fixed_point/fx_bits.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(short fract, abshr, (short fract x)) {
return fixed_point::abs(x);
}
} // namespace LIBC_NAMESPACE

20
libc/src/stdfix/abshr.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for abshr -------------------------*- 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_STDFIX_ABSHR_H
#define LLVM_LIBC_SRC_STDFIX_ABSHR_H
#include "include/llvm-libc-macros/stdfix-macros.h"
namespace LIBC_NAMESPACE {
short fract abshr(short fract x);
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC_STDFIX_ABSHR_H

17
libc/src/stdfix/absk.cpp Normal file
View File

@ -0,0 +1,17 @@
//===-- Implementation of absk function -----------------------------------===//
//
// 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 "absk.h"
#include "src/__support/common.h"
#include "src/__support/fixed_point/fx_bits.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(accum, absk, (accum x)) { return fixed_point::abs(x); }
} // namespace LIBC_NAMESPACE

20
libc/src/stdfix/absk.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for absk --------------------------*- 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_STDFIX_ABSK_H
#define LLVM_LIBC_SRC_STDFIX_ABSK_H
#include "include/llvm-libc-macros/stdfix-macros.h"
namespace LIBC_NAMESPACE {
accum absk(accum x);
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC_STDFIX_ABSK_H

19
libc/src/stdfix/abslk.cpp Normal file
View File

@ -0,0 +1,19 @@
//===-- Implementation of abslk function ----------------------------------===//
//
// 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 "abslk.h"
#include "src/__support/common.h"
#include "src/__support/fixed_point/fx_bits.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(long accum, abslk, (long accum x)) {
return fixed_point::abs(x);
}
} // namespace LIBC_NAMESPACE

20
libc/src/stdfix/abslk.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for abslk -------------------------*- 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_STDFIX_ABSLK_H
#define LLVM_LIBC_SRC_STDFIX_ABSLK_H
#include "include/llvm-libc-macros/stdfix-macros.h"
namespace LIBC_NAMESPACE {
long accum abslk(long accum x);
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC_STDFIX_ABSLK_H

19
libc/src/stdfix/abslr.cpp Normal file
View File

@ -0,0 +1,19 @@
//===-- Implementation of abslr function ----------------------------------===//
//
// 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 "abslr.h"
#include "src/__support/common.h"
#include "src/__support/fixed_point/fx_bits.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(long fract, abslr, (long fract x)) {
return fixed_point::abs(x);
}
} // namespace LIBC_NAMESPACE

20
libc/src/stdfix/abslr.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for abslr -------------------------*- 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_STDFIX_ABSLR_H
#define LLVM_LIBC_SRC_STDFIX_ABSLR_H
#include "include/llvm-libc-macros/stdfix-macros.h"
namespace LIBC_NAMESPACE {
long fract abslr(long fract x);
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC_STDFIX_ABSLR_H

17
libc/src/stdfix/absr.cpp Normal file
View File

@ -0,0 +1,17 @@
//===-- Implementation of absr function -----------------------------------===//
//
// 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 "absr.h"
#include "src/__support/common.h"
#include "src/__support/fixed_point/fx_bits.h"
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(fract, absr, (fract x)) { return fixed_point::abs(x); }
} // namespace LIBC_NAMESPACE

20
libc/src/stdfix/absr.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for absr --------------------------*- 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_STDFIX_ABSR_H
#define LLVM_LIBC_SRC_STDFIX_ABSR_H
#include "include/llvm-libc-macros/stdfix-macros.h"
namespace LIBC_NAMESPACE {
fract absr(fract x);
} // namespace LIBC_NAMESPACE
#endif // LLVM_LIBC_SRC_STDFIX_ABSR_H

View File

@ -44,6 +44,7 @@ add_subdirectory(inttypes)
add_subdirectory(math)
add_subdirectory(search)
add_subdirectory(stdbit)
add_subdirectory(stdfix)
add_subdirectory(stdio)
add_subdirectory(stdlib)
add_subdirectory(string)

View File

@ -0,0 +1,37 @@
//===-- Utility class to test fixed-point abs -------------------*- 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 "test/UnitTest/Test.h"
#include "src/__support/fixed_point/fx_rep.h"
template <typename T> class AbsTest : public LIBC_NAMESPACE::testing::Test {
using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
static constexpr T zero = FXRep::ZERO();
static constexpr T min = FXRep::MIN();
static constexpr T max = FXRep::MAX();
static constexpr T half = static_cast<T>(0.5);
static constexpr T neg_half = static_cast<T>(-0.5);
public:
typedef T (*AbsFunc)(T);
void testSpecialNumbers(AbsFunc func) {
EXPECT_EQ(zero, func(zero));
EXPECT_EQ(max, func(min));
EXPECT_EQ(max, func(max));
EXPECT_EQ(half, func(half));
EXPECT_EQ(half, func(neg_half));
}
};
#define LIST_ABS_TESTS(T, func) \
using LlvmLibcAbsTest = AbsTest<T>; \
TEST_F(LlvmLibcAbsTest, SpecialNumbers) { testSpecialNumbers(&func); } \
static_assert(true, "Require semicolon.")

View File

@ -0,0 +1,23 @@
if(NOT LIBC_COMPILER_HAS_FIXED_POINT)
return()
endif()
add_custom_target(libc-stdfix-tests)
foreach(suffix IN ITEMS hr r lr hk k lk)
add_libc_test(
abs${suffix}_test
SUITE
libc-stdfix-tests
HDRS
AbsTest.h
SRCS
abs${suffix}_test.cpp
COMPILE_OPTIONS
-O3
-ffixed-point
DEPENDS
libc.src.stdfix.abs${suffix}
libc.src.__support.fixed_point.fx_bits
)
endforeach()

View File

@ -0,0 +1,13 @@
//===-- Unittests for abshk -----------------------------------------------===//
//
// 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 "AbsTest.h"
#include "src/stdfix/abshk.h"
LIST_ABS_TESTS(short accum, LIBC_NAMESPACE::abshk);

View File

@ -0,0 +1,13 @@
//===-- Unittests for abshr -----------------------------------------------===//
//
// 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 "AbsTest.h"
#include "src/stdfix/abshr.h"
LIST_ABS_TESTS(short fract, LIBC_NAMESPACE::abshr);

View File

@ -0,0 +1,13 @@
//===-- Unittests for absk ------------------------------------------------===//
//
// 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 "AbsTest.h"
#include "src/stdfix/absk.h"
LIST_ABS_TESTS(accum, LIBC_NAMESPACE::absk);

View File

@ -0,0 +1,13 @@
//===-- Unittests for abslk -----------------------------------------------===//
//
// 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 "AbsTest.h"
#include "src/stdfix/abslk.h"
LIST_ABS_TESTS(long accum, LIBC_NAMESPACE::abslk);

View File

@ -0,0 +1,13 @@
//===-- Unittests for abslr -----------------------------------------------===//
//
// 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 "AbsTest.h"
#include "src/stdfix/abslr.h"
LIST_ABS_TESTS(long fract, LIBC_NAMESPACE::abslr);

View File

@ -0,0 +1,13 @@
//===-- Unittests for absr ------------------------------------------------===//
//
// 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 "AbsTest.h"
#include "src/stdfix/absr.h"
LIST_ABS_TESTS(fract, LIBC_NAMESPACE::absr);