Skip to content

Commit 7fe2e8f

Browse files
authored
Merge pull request #725 from cppalliance/128
Remove u128 x64 intrinsic pessimzations
2 parents 693907f + c995e23 commit 7fe2e8f

File tree

1 file changed

+22
-68
lines changed

1 file changed

+22
-68
lines changed

include/boost/decimal/detail/emulated128.hpp

Lines changed: 22 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -757,31 +757,15 @@ constexpr auto uint128::operator+=(std::uint64_t n) noexcept -> uint128&
757757

758758
constexpr auto operator+(uint128 lhs, uint128 rhs) noexcept -> uint128
759759
{
760-
#if (defined(BOOST_DECIMAL_HAS_X64_INTRINSICS) || defined(BOOST_DECIMAL_HAS_MSVC_64BIT_INTRINSICS)) && !defined(BOOST_DECIMAL_NO_CONSTEVAL_DETECTION)
761-
if (!BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs.low))
762-
{
763-
// Branchless version can be executed on x64 machines when available
764-
unsigned long long low {};
765-
unsigned long long high {};
766-
767-
const auto carry {BOOST_DECIMAL_ADD_CARRY(0, lhs.low, rhs.low, &low)};
768-
BOOST_DECIMAL_ADD_CARRY(carry, lhs.high, rhs.high, &high);
760+
uint128 temp {lhs.high + rhs.high, lhs.low + rhs.low};
769761

770-
return uint128{high, low};
771-
}
772-
else
773-
#endif
762+
// Need to carry a bit into rhs
763+
if (temp.low < lhs.low)
774764
{
775-
uint128 temp {lhs.high + rhs.high, lhs.low + rhs.low};
776-
777-
// Need to carry a bit into rhs
778-
if (temp.low < lhs.low)
779-
{
780-
++temp.high;
781-
}
782-
783-
return temp;
765+
++temp.high;
784766
}
767+
768+
return temp;
785769
}
786770

787771
constexpr auto uint128::operator+=(uint128 v) noexcept -> uint128&
@@ -807,31 +791,15 @@ constexpr auto uint128::operator++(int) noexcept -> uint128
807791

808792
constexpr auto operator-(uint128 lhs, uint128 rhs) noexcept -> uint128
809793
{
810-
#if (defined(BOOST_DECIMAL_HAS_X64_INTRINSICS) || defined(BOOST_DECIMAL_HAS_MSVC_64BIT_INTRINSICS)) && !defined(BOOST_DECIMAL_NO_CONSTEVAL_DETECTION)
811-
if (!BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs.low))
812-
{
813-
// Branchless version can be executed on x64 machines when available
814-
unsigned long long low {};
815-
unsigned long long high {};
816-
817-
const auto carry {_subborrow_u64(0, lhs.low, rhs.low, &low)};
818-
_subborrow_u64(carry, lhs.high, rhs.high, &high);
794+
uint128 temp {lhs.high - rhs.high, lhs.low - rhs.low};
819795

820-
return uint128{high, low};
821-
}
822-
else
823-
#endif
796+
// Check for carry
797+
if (lhs.low < rhs.low)
824798
{
825-
uint128 temp {lhs.high - rhs.high, lhs.low - rhs.low};
826-
827-
// Check for carry
828-
if (lhs.low < rhs.low)
829-
{
830-
--temp.high;
831-
}
832-
833-
return temp;
799+
--temp.high;
834800
}
801+
802+
return temp;
835803
}
836804

837805
constexpr auto uint128::operator-=(uint128 v) noexcept -> uint128&
@@ -1328,35 +1296,21 @@ constexpr auto int128::operator>(int rhs) const noexcept -> bool
13281296

13291297
constexpr auto operator+(const int128& lhs, const int128& rhs) noexcept -> int128
13301298
{
1331-
#if (defined(BOOST_DECIMAL_HAS_X64_INTRINSICS) || defined(BOOST_DECIMAL_HAS_MSVC_64BIT_INTRINSICS)) && !defined(BOOST_DECIMAL_NO_CONSTEVAL_DETECTION)
1332-
if (!BOOST_DECIMAL_IS_CONSTANT_EVALUATED(lhs.low))
1333-
{
1334-
unsigned long long low {};
1335-
unsigned long long high {};
1336-
1337-
const auto carry {BOOST_DECIMAL_ADD_CARRY(0, lhs.low, rhs.low, &low)};
1338-
BOOST_DECIMAL_ADD_CARRY(carry, static_cast<std::uint64_t>(lhs.high), static_cast<std::uint64_t>(rhs.high), &high);
1339-
1340-
return {static_cast<std::int64_t>(high), low};
1341-
}
1342-
#endif
1343-
{
1344-
#ifdef BOOST_DECIMAL_HAS_INT128
1299+
#ifdef BOOST_DECIMAL_HAS_INT128
13451300

1346-
const auto lhs_full {(static_cast<__uint128_t>(lhs.high) << 64) | lhs.low};
1347-
const auto rhs_full {(static_cast<__uint128_t>(rhs.high) << 64) | rhs.low};
1348-
const auto result {lhs_full + rhs_full};
1301+
const auto lhs_full {(static_cast<__uint128_t>(lhs.high) << 64) | lhs.low};
1302+
const auto rhs_full {(static_cast<__uint128_t>(rhs.high) << 64) | rhs.low};
1303+
const auto result {lhs_full + rhs_full};
13491304

1350-
return {static_cast<std::int64_t>(result >> 64), static_cast<std::uint64_t>(result)};
1305+
return {static_cast<std::int64_t>(result >> 64), static_cast<std::uint64_t>(result)};
13511306

1352-
#else
1307+
#else
13531308

1354-
const auto new_low {lhs.low + rhs.low};
1355-
const auto new_high {lhs.high + rhs.high + static_cast<std::int64_t>(new_low < lhs.low)};
1356-
return int128{new_high, new_low};
1309+
const auto new_low {lhs.low + rhs.low};
1310+
const auto new_high {lhs.high + rhs.high + static_cast<std::int64_t>(new_low < lhs.low)};
1311+
return int128{new_high, new_low};
13571312

1358-
#endif
1359-
}
1313+
#endif
13601314
}
13611315

13621316
constexpr auto operator-(const int128& lhs, const int128& rhs) noexcept -> int128

0 commit comments

Comments
 (0)