diff --git a/CppProperties.json b/CppProperties.json new file mode 100644 index 0000000000000..659bf4ea9068f --- /dev/null +++ b/CppProperties.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "inheritEnvironments": [ + "msvc_x86" + ], + "name": "x86-Debug", + "includePath": [ + "${env.INCLUDE}", + "${workspaceRoot}\\**" + ], + "defines": [ + "WIN32", + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "intelliSenseMode": "windows-msvc-x86" + } + ] +} \ No newline at end of file diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h index 00c6119b4f353..b7b7de1dfade0 100644 --- a/libc/src/__support/fixed_point/fx_bits.h +++ b/libc/src/__support/fixed_point/fx_bits.h @@ -195,6 +195,26 @@ countls(T f) { return cpp::countl_zero(value_bits) - FXRep::SIGN_LEN; } +// Multiply an integer with a fixed-point value and return an integer. +// Overflow behavior is undefined, per ISO 8037. +template +LIBC_INLINE constexpr cpp::enable_if_t && cpp::is_integral_v, IntT > +muli(FixedPointT f, IntT i) { + + using FXRep = FXRep; + using BitType = typename FXRep::StorageType; + BitType fixed_bits = FXBits(f).get_bits(); + + // Safely promote types to unsigned for multiplication to avoid signed overflow + using UnsignedIntT = cpp::make_unsigned_t; + using UnsignedFixedT = cpp::make_unsigned_t; + + auto product = static_cast(i) * static_cast(fixed_bits); + + // Shift back to remove fractional bits + return static_cast(product >> FXRep::FRAC_LEN); +} + // fixed-point to integer conversion template LIBC_INLINE constexpr cpp::enable_if_t, XType> diff --git a/libc/src/stdfix/CMakeLists.txt b/libc/src/stdfix/CMakeLists.txt index 843111e3f80b1..60a4eb1282adc 100644 --- a/libc/src/stdfix/CMakeLists.txt +++ b/libc/src/stdfix/CMakeLists.txt @@ -87,6 +87,18 @@ foreach(suffix IN ITEMS r lr k lk ur ulr uk ulk) DEPENDS libc.src.__support.fixed_point.fx_bits ) + + add_entrypoint_object( + muli${suffix} + HDRS + muli${suffix}.h + SRCS + muli${suffix}.cpp + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.fixed_point.fx_bits + ) endforeach() add_entrypoint_object( diff --git a/libc/src/stdfix/mulik.cpp b/libc/src/stdfix/mulik.cpp new file mode 100644 index 0000000000000..172eb18a9ad72 --- /dev/null +++ b/libc/src/stdfix/mulik.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of mulik 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 "mulik.h" +#include "include/llvm-libc-macros/stdfix-macros.h" // accum +#include "src/__support/common.h" // LLVM_LIBC_FUNCTION +#include "src/__support/fixed_point/fx_bits.h" // fixed_point +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, mulik, (accum f, int i)) { + return fixed_point::muli(f, i); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdfix/mulik.h b/libc/src/stdfix/mulik.h new file mode 100644 index 0000000000000..58d6cdfdf8acb --- /dev/null +++ b/libc/src/stdfix/mulik.h @@ -0,0 +1,21 @@ +//===-- Implementation header for mulik ------------------------*- 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_MULIK_H +#define LLVM_LIBC_SRC_STDFIX_MULIK_H + +#include "include/llvm-libc-macros/stdfix-macros.h" // accum +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +int mulik(accum f, int i); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDFIX_MULIK_H diff --git a/libc/src/stdfix/mulilk.cpp b/libc/src/stdfix/mulilk.cpp new file mode 100644 index 0000000000000..f91f617101a75 --- /dev/null +++ b/libc/src/stdfix/mulilk.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of mulilk 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 "mulilk.h" +#include "include/llvm-libc-macros/stdfix-macros.h" // long accum +#include "src/__support/common.h" // LLVM_LIBC_FUNCTION +#include "src/__support/fixed_point/fx_bits.h" // fixed_point +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(long int, mulilk, (long accum f, long int i)) { + return fixed_point::muli(f, i); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdfix/mulilk.h b/libc/src/stdfix/mulilk.h new file mode 100644 index 0000000000000..78501d3fa9113 --- /dev/null +++ b/libc/src/stdfix/mulilk.h @@ -0,0 +1,21 @@ +//===-- Implementation header for mulilk ------------------------*- 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_MULILK_H +#define LLVM_LIBC_SRC_STDFIX_MULILK_H + +#include "include/llvm-libc-macros/stdfix-macros.h" // accum +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +long int mulilk(long accum f, long int i); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDFIX_MULILK_H diff --git a/libc/src/stdfix/mulilr.cpp b/libc/src/stdfix/mulilr.cpp new file mode 100644 index 0000000000000..f20a270d56d90 --- /dev/null +++ b/libc/src/stdfix/mulilr.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of mulilr 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 "mulilr.h" +#include "include/llvm-libc-macros/stdfix-macros.h" // fract +#include "src/__support/common.h" // LLVM_LIBC_FUNCTION +#include "src/__support/fixed_point/fx_bits.h" // fixed_point +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(long int, mulilr, (long fract f, long int i)) { + return fixed_point::muli(f, i); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdfix/mulilr.h b/libc/src/stdfix/mulilr.h new file mode 100644 index 0000000000000..3be913f950cea --- /dev/null +++ b/libc/src/stdfix/mulilr.h @@ -0,0 +1,21 @@ +//===-- Implementation header for mulilr -----------------------*- 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_MULILR_H +#define LLVM_LIBC_SRC_STDFIX_MULILR_H + +#include "include/llvm-libc-macros/stdfix-macros.h" // long fract +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +long int mulilr(long fract f, long int i); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDFIX_MULILR_H diff --git a/libc/src/stdfix/mulir.cpp b/libc/src/stdfix/mulir.cpp new file mode 100644 index 0000000000000..fe9907a2bfc8a --- /dev/null +++ b/libc/src/stdfix/mulir.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of mulir 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 "mulir.h" +#include "include/llvm-libc-macros/stdfix-macros.h" // fract +#include "src/__support/common.h" // LLVM_LIBC_FUNCTION +#include "src/__support/fixed_point/fx_bits.h" // fixed_point +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, mulir, (fract f, int i)) { + return fixed_point::muli(f, i); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdfix/mulir.h b/libc/src/stdfix/mulir.h new file mode 100644 index 0000000000000..7046bb7b507a4 --- /dev/null +++ b/libc/src/stdfix/mulir.h @@ -0,0 +1,21 @@ +//===-- Implementation header for mulir -----------------------*- 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_MULIR_H +#define LLVM_LIBC_SRC_STDFIX_MULIR_H + +#include "include/llvm-libc-macros/stdfix-macros.h" // long fract +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +int mulir(fract f, int i); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDFIX_MULIR_H diff --git a/libc/src/stdfix/muliuk.cpp b/libc/src/stdfix/muliuk.cpp new file mode 100644 index 0000000000000..f42d5e42543fc --- /dev/null +++ b/libc/src/stdfix/muliuk.cpp @@ -0,0 +1,21 @@ +//===-- Implementation header for muliuk ------------------------*- 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_MULIUK_H +#define LLVM_LIBC_SRC_STDFIX_MULIUK_H + +#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned accum +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +unsigned int muliuk(unsigned accum f, unsigned int i); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDFIX_MULIUK_H diff --git a/libc/src/stdfix/muliuk.h b/libc/src/stdfix/muliuk.h new file mode 100644 index 0000000000000..1f0f7bdb6cb48 --- /dev/null +++ b/libc/src/stdfix/muliuk.h @@ -0,0 +1,21 @@ +//===-- Implementation header for muliuk -----------------------*- 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_MULIUK_H +#define LLVM_LIBC_SRC_STDFIX_MULIUK_H + +#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned accum +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +unsigned int muliuk(unsigned accum f, unsigned int i); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDFIX_MULIUK_H diff --git a/libc/src/stdfix/muliulk.cpp b/libc/src/stdfix/muliulk.cpp new file mode 100644 index 0000000000000..4c8140e49ffc2 --- /dev/null +++ b/libc/src/stdfix/muliulk.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of muliulk 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 "muliulk.h" +#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long accum +#include "src/__support/common.h" // LLVM_LIBC_FUNCTION +#include "src/__support/fixed_point/fx_bits.h" // fixed_point +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(unsigned long int, muliulk, (unsigned long accum f, unsigned long int i)) { + return fixed_point::muli(f, i); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdfix/muliulk.h b/libc/src/stdfix/muliulk.h new file mode 100644 index 0000000000000..1eda755798689 --- /dev/null +++ b/libc/src/stdfix/muliulk.h @@ -0,0 +1,21 @@ +//===-- Implementation header for muliulk -----------------------*- 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_MULIULK_H +#define LLVM_LIBC_SRC_STDFIX_MULIULK_H + +#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned accum +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +unsigned long int muliulk(unsigned long accum f, unsigned long int i); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDFIX_MULIULK_H diff --git a/libc/src/stdfix/muliulr.cpp b/libc/src/stdfix/muliulr.cpp new file mode 100644 index 0000000000000..d61e27653f615 --- /dev/null +++ b/libc/src/stdfix/muliulr.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of muliulr 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 "muliulr.h" +#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long fract +#include "src/__support/common.h" // LLVM_LIBC_FUNCTION +#include "src/__support/fixed_point/fx_bits.h" // fixed_point +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(unsigned long int, muliulr, (unsigned long fract f, unsigned long int i)) { + return fixed_point::muli(f, i); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdfix/muliulr.h b/libc/src/stdfix/muliulr.h new file mode 100644 index 0000000000000..4d54aa8b561fe --- /dev/null +++ b/libc/src/stdfix/muliulr.h @@ -0,0 +1,21 @@ +//===-- Implementation header for muliulr -----------------------*- 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_MULIULR_H +#define LLVM_LIBC_SRC_STDFIX_MULIULR_H + +#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned fract +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +unsigned long int muliulr(unsigned long fract f, unsigned long int i); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDFIX_MULIULR_H diff --git a/libc/src/stdfix/muliur.cpp b/libc/src/stdfix/muliur.cpp new file mode 100644 index 0000000000000..aa2a5d11a3550 --- /dev/null +++ b/libc/src/stdfix/muliur.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of muliur 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 "muliur.h" +#include "include/llvm-libc-macros/stdfix-macros.h" // fract +#include "src/__support/common.h" // LLVM_LIBC_FUNCTION +#include "src/__support/fixed_point/fx_bits.h" // fixed_point +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(unsigned int, muliur, (unsigned fract f, unsigned int i)) { + return fixed_point::muli(f, i); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdfix/muliur.h b/libc/src/stdfix/muliur.h new file mode 100644 index 0000000000000..1a5afb6dfad6b --- /dev/null +++ b/libc/src/stdfix/muliur.h @@ -0,0 +1,21 @@ +//===-- Implementation header for muliur -----------------------*- 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_MULIUR_H +#define LLVM_LIBC_SRC_STDFIX_MULIUR_H + +#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned fract +#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL + +namespace LIBC_NAMESPACE_DECL { + +unsigned int muliur(unsigned fract f, unsigned int i); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDFIX_MULIUR_H