commit 4555faba28f41e8588fcdcdb8388bffe221afa4d
parent 0f52219f177675dc84be3d2670755f3461c21fba
Author: André Bargull <andre.bargull@gmail.com>
Date: Fri, 14 Nov 2025 13:38:07 +0000
Bug 1999492 - Part 3: Add back constexpr for Int128 division. r=iain
`constexpr` was removed in bug 1898538 (D211393) for compatibility with GCC,
because it called the non-`constexpr` function `CountLeadingZeroes64`.
Bug 1986593 made `CountLeadingZeroes64` `constexpr`, so we can now add back
`constexpr` for Int128 division.
Differential Revision: https://phabricator.services.mozilla.com/D272138
Diffstat:
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/js/src/vm/Int128.h b/js/src/vm/Int128.h
@@ -64,8 +64,8 @@ class alignas(16) Uint128 final {
* Based on "Unsigned doubleword division from long division" from
* Hacker's Delight, 2nd edition, figure 9-5.
*/
- static std::pair<Uint128, Uint128> udivdi(const Uint128& u,
- const Uint128& v) {
+ static constexpr std::pair<Uint128, Uint128> udivdi(const Uint128& u,
+ const Uint128& v) {
MOZ_ASSERT(v != Uint128{});
// If v < 2**64
@@ -131,8 +131,8 @@ class alignas(16) Uint128 final {
* Based on "Divide long unsigned, using fullword division instructions" from
* Hacker's Delight, 2nd edition, figure 9-3.
*/
- static std::pair<uint64_t, uint64_t> divlu(uint64_t u1, uint64_t u0,
- uint64_t v) {
+ static constexpr std::pair<uint64_t, uint64_t> divlu(uint64_t u1, uint64_t u0,
+ uint64_t v) {
// Number base (32 bits).
constexpr uint64_t base = 4294967296;
@@ -286,16 +286,16 @@ class alignas(16) Uint128 final {
/**
* Return the quotient and remainder of the division.
*/
- std::pair<Uint128, Uint128> divrem(const Uint128& divisor) const {
+ constexpr std::pair<Uint128, Uint128> divrem(const Uint128& divisor) const {
return udivdi(*this, divisor);
}
- Uint128 operator/(const Uint128& other) const {
+ constexpr Uint128 operator/(const Uint128& other) const {
auto [quot, rem] = divrem(other);
return quot;
}
- Uint128 operator%(const Uint128& other) const {
+ constexpr Uint128 operator%(const Uint128& other) const {
auto [quot, rem] = divrem(other);
return rem;
}
@@ -395,12 +395,12 @@ class alignas(16) Uint128 final {
return *this;
}
- Uint128 operator/=(const Uint128& other) {
+ constexpr Uint128 operator/=(const Uint128& other) {
*this = *this / other;
return *this;
}
- Uint128 operator%=(const Uint128& other) {
+ constexpr Uint128 operator%=(const Uint128& other) {
*this = *this % other;
return *this;
}
@@ -453,7 +453,8 @@ class alignas(16) Int128 final {
* Based on "Signed doubleword division from unsigned doubleword division"
* from Hacker's Delight, 2nd edition, figure 9-6.
*/
- static std::pair<Int128, Int128> divdi(const Int128& u, const Int128& v) {
+ static constexpr std::pair<Int128, Int128> divdi(const Int128& u,
+ const Int128& v) {
auto [q, r] = Uint128::udivdi(u.abs(), v.abs());
// If u and v have different signs, negate q.
@@ -484,7 +485,7 @@ class alignas(16) Int128 final {
/**
* Return the quotient and remainder of the division.
*/
- std::pair<Int128, Int128> divrem(const Int128& divisor) const {
+ constexpr std::pair<Int128, Int128> divrem(const Int128& divisor) const {
return divdi(*this, divisor);
}
@@ -552,12 +553,12 @@ class alignas(16) Int128 final {
return Int128{Uint128{*this} * Uint128{other}};
}
- Int128 operator/(const Int128& other) const {
+ constexpr Int128 operator/(const Int128& other) const {
auto [quot, rem] = divrem(other);
return quot;
}
- Int128 operator%(const Int128& other) const {
+ constexpr Int128 operator%(const Int128& other) const {
auto [quot, rem] = divrem(other);
return rem;
}
@@ -641,12 +642,12 @@ class alignas(16) Int128 final {
return *this;
}
- Int128 operator/=(const Int128& other) {
+ constexpr Int128 operator/=(const Int128& other) {
*this = *this / other;
return *this;
}
- Int128 operator%=(const Int128& other) {
+ constexpr Int128 operator%=(const Int128& other) {
*this = *this % other;
return *this;
}