vendor/bela/src/bela/numbers.cc
inline std::pair<uint64_t, uint64_t> Mul32(std::pair<uint64_t, uint64_t> num, uint32_t mul) {
  uint64_t bits0_31 = num.second & 0xFFFFFFFF;
  uint64_t bits32_63 = num.second >> 32;
  uint64_t bits64_95 = num.first & 0xFFFFFFFF;
  uint64_t bits96_127 = num.first >> 32;

  // The picture so far: each of these 64-bit values has only the lower 32 bits
  // filled in.
  // bits96_127:          [ 00000000 xxxxxxxx ]
  // bits64_95:                    [ 00000000 xxxxxxxx ]
  // bits32_63:                             [ 00000000 xxxxxxxx ]
  // bits0_31:                                       [ 00000000 xxxxxxxx ]

  bits0_31 *= mul;
  bits32_63 *= mul;
  bits64_95 *= mul;
  bits96_127 *= mul;

  // Now the top halves may also have value, though all 64 of their bits will
  // never be set at the same time, since they are a result of a 32x32 bit
  // multiply.  This makes the carry calculation slightly easier.
  // bits96_127:          [ mmmmmmmm | mmmmmmmm ]
  // bits64_95:                    [ | mmmmmmmm mmmmmmmm | ]
  // bits32_63:                      |        [ mmmmmmmm | mmmmmmmm ]
  // bits0_31:                       |                 [ | mmmmmmmm mmmmmmmm ]
  // eventually:        [ bits128_up | ...bits64_127.... | ..bits0_63... ]

  uint64_t bits0_63 = bits0_31 + (bits32_63 << 32);
  uint64_t bits64_127 = bits64_95 + (bits96_127 << 32) + (bits32_63 >> 32) + (bits0_63 < bits0_31);
  uint64_t bits128_up = (bits96_127 >> 32) + (bits64_127 < bits64_95);
  if (bits128_up == 0)
    return {bits64_127, bits0_63};

  int shift = 64 - std::countl_zero(bits128_up);
  uint64_t lo = (bits0_63 >> shift) + (bits64_127 << (64 - shift));
  uint64_t hi = (bits64_127 >> shift) + (bits128_up << (64 - shift));
  return {hi, lo};
}
// Given a 128-bit number expressed as a pair of uint64_t, high half first,
// return that number multiplied by the given 32-bit value.  If the result is
// too large to fit in a 128-bit number, divide it by 2 until it fits.
Given a 128-bit number expressed as a pair of uint64_t, high half first,
return that number multiplied by the given 32-bit value.  If the result is
too large to fit in a 128-bit number, divide it by 2 until it fits.
Given a 128 - bit number expressed as a pair of uint64_t high half first return that number multiplied by the given 32 - bit value . If the result is too large to fit in a 128 - bit number divide it by 2 until it fits .
inline std::pair<uint64_t, uint64_t> Mul32(std::pair<uint64_t, uint64_t> num, uint32_t mul) {
  uint64_t bits0_31 = num.second & 0xFFFFFFFF;
  uint64_t bits32_63 = num.second >> 32;
  uint64_t bits64_95 = num.first & 0xFFFFFFFF;
  uint64_t bits96_127 = num.first >> 32;
  bits0_31 *= mul;
  bits32_63 *= mul;
  bits64_95 *= mul;
  bits96_127 *= mul;
  uint64_t bits0_63 = bits0_31 + (bits32_63 << 32);
  uint64_t bits64_127 = bits64_95 + (bits96_127 << 32) + (bits32_63 >> 32) + (bits0_63 < bits0_31);
  uint64_t bits128_up = (bits96_127 >> 32) + (bits64_127 < bits64_95);
  if (bits128_up == 0)
    return {bits64_127, bits0_63};
  int shift = 64 - std::countl_zero(bits128_up);
  uint64_t lo = (bits0_63 >> shift) + (bits64_127 << (64 - shift));
  uint64_t hi = (bits64_127 >> shift) + (bits128_up << (64 - shift));
  return {hi, lo};
}
inline std :: pair < uint64_t , uint64_t > Mul32 ( std :: pair < uint64_t , uint64_t > num , uint32_t mul ) { uint64_t bits0_31 = num . second & 0xFFFFFFFF ; uint64_t bits32_63 = num . second >> 32 ; uint64_t bits64_95 = num . first & 0xFFFFFFFF ; uint64_t bits96_127 = num . first >> 32 ; bits0_31 *= mul ; bits32_63 *= mul ; bits64_95 *= mul ; bits96_127 *= mul ; uint64_t bits0_63 = bits0_31 + ( bits32_63 << 32 ) ; uint64_t bits64_127 = bits64_95 + ( bits96_127 << 32 ) + ( bits32_63 >> 32 ) + ( bits0_63 < bits0_31 ) ; uint64_t bits128_up = ( bits96_127 >> 32 ) + ( bits64_127 < bits64_95 ) ; if ( bits128_up == 0 ) return { bits64_127 , bits0_63 } ; int shift = 64 - std :: countl_zero ( bits128_up ) ; uint64_t lo = ( bits0_63 >> shift ) + ( bits64_127 << ( 64 - shift ) ) ; uint64_t hi = ( bits64_127 >> shift ) + ( bits128_up << ( 64 - shift ) ) ; return { hi , lo } ; }
Given a 128-bit number expressed as a pair of uint64_t, high half first,
return that number multiplied by the given 32-bit value.
Given a 128 - bit number expressed as a pair of uint64_t high half first return that number multiplied by the given 32 - bit value .
// The picture so far: each of these 64-bit values has only the lower 32 bits // filled in. // bits96_127:          [ 00000000 xxxxxxxx ] // bits64_95:                    [ 00000000 xxxxxxxx ] // bits32_63:                             [ 00000000 xxxxxxxx ] // bits0_31:                                       [ 00000000 xxxxxxxx ] // Now the top halves may also have value, though all 64 of their bits will // never be set at the same time, since they are a result of a 32x32 bit // multiply.  This makes the carry calculation slightly easier. // bits96_127:          [ mmmmmmmm | mmmmmmmm ] // bits64_95:                    [ | mmmmmmmm mmmmmmmm | ] // bits32_63:                      |        [ mmmmmmmm | mmmmmmmm ] // bits0_31:                       |                 [ | mmmmmmmm mmmmmmmm ] // eventually:        [ bits128_up | ...bits64_127.... | ..bits0_63... ]