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

via libc-commits libc-commits at lists.llvm.org
Thu Feb 15 15:09:45 PST 2024


Author: lntue
Date: 2024-02-15T18:09:40-05:00
New Revision: 2c45bda8029289bbc6b09f349c203059a61609ce

URL: https://github.com/llvm/llvm-project/commit/2c45bda8029289bbc6b09f349c203059a61609ce
DIFF: https://github.com/llvm/llvm-project/commit/2c45bda8029289bbc6b09f349c203059a61609ce.diff

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

Added: 
    libc/src/__support/fixed_point/fx_bits.h
    libc/src/stdfix/CMakeLists.txt
    libc/src/stdfix/abshk.cpp
    libc/src/stdfix/abshk.h
    libc/src/stdfix/abshr.cpp
    libc/src/stdfix/abshr.h
    libc/src/stdfix/absk.cpp
    libc/src/stdfix/absk.h
    libc/src/stdfix/abslk.cpp
    libc/src/stdfix/abslk.h
    libc/src/stdfix/abslr.cpp
    libc/src/stdfix/abslr.h
    libc/src/stdfix/absr.cpp
    libc/src/stdfix/absr.h
    libc/test/src/stdfix/AbsTest.h
    libc/test/src/stdfix/CMakeLists.txt
    libc/test/src/stdfix/abshk_test.cpp
    libc/test/src/stdfix/abshr_test.cpp
    libc/test/src/stdfix/absk_test.cpp
    libc/test/src/stdfix/abslk_test.cpp
    libc/test/src/stdfix/abslr_test.cpp
    libc/test/src/stdfix/absr_test.cpp

Modified: 
    libc/config/linux/x86_64/entrypoints.txt
    libc/docs/math/stdfix.rst
    libc/spec/spec.td
    libc/spec/stdc_ext.td
    libc/src/CMakeLists.txt
    libc/src/__support/fixed_point/CMakeLists.txt
    libc/test/src/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 33f6e97af0e183..69912d3b32f030 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -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

diff  --git a/libc/docs/math/stdfix.rst b/libc/docs/math/stdfix.rst
index 85d721b358f5ec..d05e3fdeabf1c5 100644
--- a/libc/docs/math/stdfix.rst
+++ b/libc/docs/math/stdfix.rst
@@ -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\*        |                |             |               |            |                |             |                |             |               |            |                |             |
 +---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+

diff  --git a/libc/spec/spec.td b/libc/spec/spec.td
index 81a7e2fe5fca7e..90c076580be125 100644
--- a/libc/spec/spec.td
+++ b/libc/spec/spec.td
@@ -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

diff  --git a/libc/spec/stdc_ext.td b/libc/spec/stdc_ext.td
index 4a5b74f7bdc364..dd9f06d1a8cba4 100644
--- a/libc/spec/stdc_ext.td
+++ b/libc/spec/stdc_ext.td
@@ -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">,
       ]
   >;
 

diff  --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 5211db7bc1f993..09b16be1e2d42e 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -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)

diff  --git a/libc/src/__support/fixed_point/CMakeLists.txt b/libc/src/__support/fixed_point/CMakeLists.txt
index 27382f5a7bb80e..4dac9b33325adb 100644
--- a/libc/src/__support/fixed_point/CMakeLists.txt
+++ b/libc/src/__support/fixed_point/CMakeLists.txt
@@ -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
+)

diff  --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
new file mode 100644
index 00000000000000..ad3a6fc97c0a1f
--- /dev/null
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -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

diff  --git a/libc/src/stdfix/CMakeLists.txt b/libc/src/stdfix/CMakeLists.txt
new file mode 100644
index 00000000000000..1eaf64bb82a21b
--- /dev/null
+++ b/libc/src/stdfix/CMakeLists.txt
@@ -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()

diff  --git a/libc/src/stdfix/abshk.cpp b/libc/src/stdfix/abshk.cpp
new file mode 100644
index 00000000000000..d76a5e64e61079
--- /dev/null
+++ b/libc/src/stdfix/abshk.cpp
@@ -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

diff  --git a/libc/src/stdfix/abshk.h b/libc/src/stdfix/abshk.h
new file mode 100644
index 00000000000000..13c9300caab883
--- /dev/null
+++ b/libc/src/stdfix/abshk.h
@@ -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

diff  --git a/libc/src/stdfix/abshr.cpp b/libc/src/stdfix/abshr.cpp
new file mode 100644
index 00000000000000..db887046b662cd
--- /dev/null
+++ b/libc/src/stdfix/abshr.cpp
@@ -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

diff  --git a/libc/src/stdfix/abshr.h b/libc/src/stdfix/abshr.h
new file mode 100644
index 00000000000000..5acd0cfc4a60db
--- /dev/null
+++ b/libc/src/stdfix/abshr.h
@@ -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

diff  --git a/libc/src/stdfix/absk.cpp b/libc/src/stdfix/absk.cpp
new file mode 100644
index 00000000000000..ca231d95a0ab71
--- /dev/null
+++ b/libc/src/stdfix/absk.cpp
@@ -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

diff  --git a/libc/src/stdfix/absk.h b/libc/src/stdfix/absk.h
new file mode 100644
index 00000000000000..73dfcac0ac8e7f
--- /dev/null
+++ b/libc/src/stdfix/absk.h
@@ -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

diff  --git a/libc/src/stdfix/abslk.cpp b/libc/src/stdfix/abslk.cpp
new file mode 100644
index 00000000000000..5e085198ce428e
--- /dev/null
+++ b/libc/src/stdfix/abslk.cpp
@@ -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

diff  --git a/libc/src/stdfix/abslk.h b/libc/src/stdfix/abslk.h
new file mode 100644
index 00000000000000..7de116fa227932
--- /dev/null
+++ b/libc/src/stdfix/abslk.h
@@ -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

diff  --git a/libc/src/stdfix/abslr.cpp b/libc/src/stdfix/abslr.cpp
new file mode 100644
index 00000000000000..0f8969510a5055
--- /dev/null
+++ b/libc/src/stdfix/abslr.cpp
@@ -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

diff  --git a/libc/src/stdfix/abslr.h b/libc/src/stdfix/abslr.h
new file mode 100644
index 00000000000000..bf5b585bbbb669
--- /dev/null
+++ b/libc/src/stdfix/abslr.h
@@ -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

diff  --git a/libc/src/stdfix/absr.cpp b/libc/src/stdfix/absr.cpp
new file mode 100644
index 00000000000000..dbbecb4947da91
--- /dev/null
+++ b/libc/src/stdfix/absr.cpp
@@ -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

diff  --git a/libc/src/stdfix/absr.h b/libc/src/stdfix/absr.h
new file mode 100644
index 00000000000000..b5ead7ce14e2a0
--- /dev/null
+++ b/libc/src/stdfix/absr.h
@@ -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

diff  --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 6c99c6735befff..9ad868551f071c 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -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)

diff  --git a/libc/test/src/stdfix/AbsTest.h b/libc/test/src/stdfix/AbsTest.h
new file mode 100644
index 00000000000000..3d23a475720c25
--- /dev/null
+++ b/libc/test/src/stdfix/AbsTest.h
@@ -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.")

diff  --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt
new file mode 100644
index 00000000000000..3b2ea9e9893126
--- /dev/null
+++ b/libc/test/src/stdfix/CMakeLists.txt
@@ -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()

diff  --git a/libc/test/src/stdfix/abshk_test.cpp b/libc/test/src/stdfix/abshk_test.cpp
new file mode 100644
index 00000000000000..c3f58625ac58ce
--- /dev/null
+++ b/libc/test/src/stdfix/abshk_test.cpp
@@ -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);

diff  --git a/libc/test/src/stdfix/abshr_test.cpp b/libc/test/src/stdfix/abshr_test.cpp
new file mode 100644
index 00000000000000..d7a962ea1f98d3
--- /dev/null
+++ b/libc/test/src/stdfix/abshr_test.cpp
@@ -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);

diff  --git a/libc/test/src/stdfix/absk_test.cpp b/libc/test/src/stdfix/absk_test.cpp
new file mode 100644
index 00000000000000..729cf143a4130a
--- /dev/null
+++ b/libc/test/src/stdfix/absk_test.cpp
@@ -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);

diff  --git a/libc/test/src/stdfix/abslk_test.cpp b/libc/test/src/stdfix/abslk_test.cpp
new file mode 100644
index 00000000000000..93ef3469a225af
--- /dev/null
+++ b/libc/test/src/stdfix/abslk_test.cpp
@@ -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);

diff  --git a/libc/test/src/stdfix/abslr_test.cpp b/libc/test/src/stdfix/abslr_test.cpp
new file mode 100644
index 00000000000000..c50a5587380288
--- /dev/null
+++ b/libc/test/src/stdfix/abslr_test.cpp
@@ -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);

diff  --git a/libc/test/src/stdfix/absr_test.cpp b/libc/test/src/stdfix/absr_test.cpp
new file mode 100644
index 00000000000000..7b811735397935
--- /dev/null
+++ b/libc/test/src/stdfix/absr_test.cpp
@@ -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);


        


More information about the libc-commits mailing list