@@ -18,6 +18,8 @@ inline std::ostream &binary(std::ostream &out, uint64_t input, int count) {
1818 return out;
1919}
2020
21+
22+
2123template <int NB, typename B>
2224std::ostream &operator <<(std::ostream &out, zoo::swar::SWAR<NB, B> s) {
2325 using S = zoo::swar::SWAR<NB, B>;
@@ -44,6 +46,14 @@ std::ostream &operator<<(std::ostream &out, zoo::swar::SWAR<NB, B> s) {
4446
4547namespace zoo ::swar {
4648
49+ template <int NBits, typename T>
50+ constexpr static auto consumeMSB (SWAR<NBits, T> s) noexcept {
51+ using S = SWAR<NBits, T>;
52+ auto msbCleared = s & ~S{S::MostSignificantBit};
53+ return S{static_cast <T>(msbCleared.value () << 1 )};
54+ }
55+
56+
4757template <typename S>
4858constexpr auto parallelSuffix (S input) {
4959 auto
@@ -509,7 +519,7 @@ wideningMultiplication(SWAR<NB, T> multiplicand, SWAR<NB, T> multiplier) {
509519
510520template <int NB, typename T>
511521constexpr
512- auto saturatedMultiplication (SWAR<NB, T> multiplicand, SWAR<NB, T> multiplier) {
522+ auto saturatingMultiplication (SWAR<NB, T> multiplicand, SWAR<NB, T> multiplier) {
513523 using S = SWAR<NB, T>;
514524 constexpr auto One = S{S::LeastSignificantBit};
515525 auto [result, overflow] = wideningMultiplication (multiplicand, multiplier);
@@ -519,22 +529,21 @@ auto saturatedMultiplication(SWAR<NB, T> multiplicand, SWAR<NB, T> multiplier) {
519529 return S{saturated};
520530}
521531
522-
523- // TODO(Jamie): Add tests from other PR.
524- template <int NB, typename T>
525- constexpr auto saturatingExponentiation (
532+ template <int NB, typename T, typename MultiplicationFn>
533+ constexpr auto exponentiation (
526534 SWAR<NB, T> x,
527- SWAR<NB, T> exponent
535+ SWAR<NB, T> exponent,
536+ MultiplicationFn&& multiplicationFn
528537) {
529538 using S = SWAR<NB, T>;
530539 constexpr auto NumBitsPerLane = S::NBits;
531540 constexpr auto
532541 MSB = S{S::MostSignificantBit},
533542 LSB = S{S::LeastSignificantBit};
534543
535- auto operation = [](auto left, auto right, auto counts) {
544+ auto operation = [&multiplicationFn ](auto left, auto right, auto counts) {
536545 auto mask = makeLaneMaskFromMSB (counts);
537- auto product = saturatedMultiplication (left, right);
546+ auto product = multiplicationFn (left, right);
538547 return (product & mask) | (left & ~mask);
539548 };
540549
@@ -553,6 +562,30 @@ constexpr auto saturatingExponentiation(
553562 );
554563}
555564
565+ template <int NB, typename T>
566+ constexpr auto saturatingExponentation (
567+ SWAR<NB, T> x,
568+ SWAR<NB, T> exponent
569+ ) {
570+ return exponentiation (
571+ x,
572+ exponent,
573+ saturatingMultiplication<NB, T>
574+ );
575+ }
576+
577+ template <int NB, typename T>
578+ constexpr auto exponentiation_OverflowUnsafe (
579+ SWAR<NB, T> x,
580+ SWAR<NB, T> exponent
581+ ) {
582+ return exponentiation (
583+ x,
584+ exponent,
585+ multiplication_OverflowUnsafe<NB, T>
586+ );
587+ }
588+
556589}
557590
558591#endif
0 commit comments