Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b974968
feat: implement generic idivfx
krishna2803 Mar 25, 2025
f9b0de4
feat: implement idivr
krishna2803 Mar 25, 2025
ec355df
chore: update CMakeLists.txt
krishna2803 Mar 25, 2025
fc30ed0
chore: update entrypoints
krishna2803 Mar 25, 2025
6a3c052
chore: implement sanity check tests for idivr
krishna2803 Mar 25, 2025
6bcec01
fix: SIGFPE
krishna2803 Mar 25, 2025
078e558
fix: update test
krishna2803 Mar 25, 2025
7b54572
feat: implement idivlr
krishna2803 Mar 25, 2025
65eb2ea
feat: implement idivk
krishna2803 Mar 25, 2025
693ce40
feat: implement idivlk
krishna2803 Mar 25, 2025
e59067d
chore: update entrypoints
krishna2803 Mar 25, 2025
05ba8d3
chore: add more tests
krishna2803 Mar 25, 2025
c245ea5
fix: idivlk typo
krishna2803 Mar 25, 2025
85ee5ed
fix: idivlr typo
krishna2803 Mar 25, 2025
aebbcc7
feat: implement idivu{r,lr,k,lk}
krishna2803 Mar 25, 2025
276793b
chore: update entrypoints
krishna2803 Mar 25, 2025
3e3c403
fix: idivulk typo
krishna2803 Mar 25, 2025
b1145cf
fix: add cast to tests
krishna2803 Mar 25, 2025
d30de69
chore: add idiv{ur,uk,ulk,ulr} tests
krishna2803 Mar 25, 2025
cce1821
refactor: rename fixed_point::idivfx to fixed_point::idiv
krishna2803 Mar 25, 2025
dc7713c
chore: add type generic macros
krishna2803 Mar 25, 2025
c31a661
fix: fixed_point::div function for negative values
krishna2803 Mar 25, 2025
2d341ee
feat: improve and add more tests
krishna2803 Mar 25, 2025
44bb098
docs: update idivfx
krishna2803 Mar 25, 2025
01cacf5
revert: "chore: add type generic macros"
krishna2803 Mar 27, 2025
26baea9
chore: add gaurd for zero denominator
krishna2803 Mar 28, 2025
832669c
chore: update tests
krishna2803 Mar 28, 2025
04c1742
refactor: use proxy headers for signals
krishna2803 Apr 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions libc/config/baremetal/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,14 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
libc.src.stdfix.idivr
libc.src.stdfix.idivlr
libc.src.stdfix.idivk
libc.src.stdfix.idivlk
libc.src.stdfix.idivur
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
)
endif()

Expand Down
8 changes: 8 additions & 0 deletions libc/config/baremetal/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,14 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
libc.src.stdfix.idivr
libc.src.stdfix.idivlr
libc.src.stdfix.idivk
libc.src.stdfix.idivlk
libc.src.stdfix.idivur
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
)
endif()

Expand Down
8 changes: 8 additions & 0 deletions libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,14 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
libc.src.stdfix.idivr
libc.src.stdfix.idivlr
libc.src.stdfix.idivk
libc.src.stdfix.idivulk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks duplicated, I think you mean libc.src.stdfix.idivlk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for the bug! i'll put up a patch

libc.src.stdfix.idivur
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
)
endif()

Expand Down
8 changes: 8 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,14 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
libc.src.stdfix.idivr
libc.src.stdfix.idivlr
libc.src.stdfix.idivk
libc.src.stdfix.idivlk
libc.src.stdfix.idivur
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
)
endif()

Expand Down
2 changes: 1 addition & 1 deletion libc/docs/headers/stdfix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ The following functions are included in the ISO/IEC TR 18037:2008 standard.
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| divi\* | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| idiv\* | | | | | | | | | | | | |
| idiv\* | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| muli | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
Expand Down
11 changes: 11 additions & 0 deletions libc/include/llvm-libc-macros/stdfix-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,17 @@
unsigned short accum: rounduhk, \
unsigned long accum: roundulk)(x, y)

#define idivfx(x, y) \
_Generic((x), \
fract: idivr, \
long fract: idivlr, \
accum: idivk, \
long accum: idivlk, \
unsigned fract: idivur, \
unsigned long fract: idivulr, \
unsigned accum: idivuk, \
unsigned long accum: idivulk)(x, y)

#endif // LIBC_COMPILER_HAS_FIXED_POINT

#endif // LLVM_LIBC_MACROS_STDFIX_MACROS_H
64 changes: 64 additions & 0 deletions libc/include/stdfix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,70 @@ functions:
arguments:
- type: unsigned long accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivr
standards:
- stdc_ext
return_type: int
arguments:
- type: fract
- type: fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivlr
standards:
- stdc_ext
return_type: long int
arguments:
- type: long fract
- type: long fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivk
standards:
- stdc_ext
return_type: int
arguments:
- type: accum
- type: accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivlk
standards:
- stdc_ext
return_type: long int
arguments:
- type: long accum
- type: long accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivur
standards:
- stdc_ext
return_type: unsigned int
arguments:
- type: unsigned fract
- type: unsigned fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivulr
standards:
- stdc_ext
return_type: unsigned long int
arguments:
- type: unsigned long fract
- type: unsigned long fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivuk
standards:
- stdc_ext
return_type: unsigned int
arguments:
- type: unsigned accum
- type: unsigned accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivulk
standards:
- stdc_ext
return_type: unsigned long int
arguments:
- type: unsigned long accum
- type: unsigned long accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: roundhk
standards:
- stdc_ext
Expand Down
24 changes: 24 additions & 0 deletions libc/src/__support/fixed_point/fx_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,30 @@ bitsfx(T f) {
return cpp::bit_cast<XType, T>(f);
}

// divide the two fixed-point types and return an integer result
template <typename T, typename XType>
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, XType>
idiv(T x, T y) {
using FXBits = FXBits<T>;
using FXRep = FXRep<T>;
using CompType = typename FXRep::CompType;

if (y == FXRep::ZERO()) {
// If the value of the second operand of the / operator is zero, the
// behavior is undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
return static_cast<XType>(0);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's UB, I'm wondering if we could just omit this check and instead have a debug assert.

Thoughts @lntue?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably we can have some optional hardening macro/option for division by 0 similar to https://github.com/llvm/llvm-project/blob/main/libc/src/__support/macros/null_check.h?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we do something like:

#if defined(LIBC_ADD_FIXED_POINT_CHECKS)
#define LIBC_CRASH_ON_ZERO_DENOM(den, zero)                                    \
  do {                                                                         \
    if (LIBC_UNLIKELY((den) == (zero)))                                        \
      __builtin_trap();                                                        \
  } while (0)
#endif

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LIBC_CRASH_ON_VALUE(var, value) sounds a bit more generic.


CompType x_comp = static_cast<CompType>(FXBits(x).get_bits());
CompType y_comp = static_cast<CompType>(FXBits(y).get_bits());

// If an integer result of one of these functions overflows, the behavior is
// undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
CompType result = x_comp / y_comp;

return static_cast<XType>(result);
}

} // namespace fixed_point
} // namespace LIBC_NAMESPACE_DECL

Expand Down
14 changes: 14 additions & 0 deletions libc/src/stdfix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
)
endforeach()

foreach(suffix IN ITEMS r lr k lk ur ulr uk ulk)
add_entrypoint_object(
idiv${suffix}
HDRS
idiv${suffix}.h
SRCS
idiv${suffix}.cpp
COMPILE_OPTIONS
${libc_opt_high_flag}
DEPENDS
libc.src.__support.fixed_point.fx_bits
)
endforeach()

add_entrypoint_object(
uhksqrtus
HDRS
Expand Down
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation of idivk 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 "idivk.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, idivk, (accum x, accum y)) {
return fixed_point::idiv<accum, int>(x, y);
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for idivk ------------------------*- 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_IDIVK_H
#define LLVM_LIBC_SRC_STDFIX_IDIVK_H

#include "include/llvm-libc-macros/stdfix-macros.h" // accum
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

int idivk(accum x, accum y);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_IDIVK_H
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivlk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation of idivlk 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 "idivlk.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, idivlk, (long accum x, long accum y)) {
return fixed_point::idiv<long accum, long int>(x, y);
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivlk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for idivlk -----------------------*- 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_IDIVLK_H
#define LLVM_LIBC_SRC_STDFIX_IDIVLK_H

#include "include/llvm-libc-macros/stdfix-macros.h" // long accum
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

long int idivlk(long accum x, long accum y);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_IDIVLK_H
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivlr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation of idivlr 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 "idivlr.h"
#include "include/llvm-libc-macros/stdfix-macros.h" // 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(long int, idivlr, (long fract x, long fract y)) {
return fixed_point::idiv<long fract, long int>(x, y);
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivlr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for idivlr -----------------------*- 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_IDIVLR_H
#define LLVM_LIBC_SRC_STDFIX_IDIVLR_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 idivlr(long fract x, long fract y);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_IDIVLR_H
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation of idivr 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 "idivr.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, idivr, (fract x, fract y)) {
return fixed_point::idiv<fract, int>(x, y);
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for idivr ------------------------*- 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_IDIVR_H
#define LLVM_LIBC_SRC_STDFIX_IDIVR_H

#include "include/llvm-libc-macros/stdfix-macros.h" // fract
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

int idivr(fract x, fract y);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_IDIVR_H
Loading
Loading