7#if defined(_MSC_VER) && !defined(__clang__)
9inline std::uint64_t
add64(std::uint64_t a, std::uint64_t b,
unsigned char& carry) {
11 carry = _addcarry_u64(carry, a, b, &out);
15inline std::uint64_t
sub64(std::uint64_t a, std::uint64_t b,
unsigned char& borrow) {
17 borrow = _subborrow_u64(borrow, a, b, &out);
23#ifdef SECP256K1_NO_INT128
25inline std::uint64_t
add64(std::uint64_t a, std::uint64_t b,
unsigned char& carry) {
26 std::uint64_t result = a + b;
27 unsigned char new_carry = (result < a) ? 1 : 0;
29 std::uint64_t temp = result + 1;
30 new_carry |= (temp < result) ? 1 : 0;
37inline std::uint64_t
sub64(std::uint64_t a, std::uint64_t b,
unsigned char& borrow) {
38 std::uint64_t temp = a - borrow;
39 unsigned char const borrow1 = (a < borrow);
40 std::uint64_t result = temp - b;
41 unsigned char const borrow2 = (temp < b);
42 borrow = borrow1 | borrow2;
49#pragma GCC diagnostic push
50#pragma GCC diagnostic ignored "-Wpedantic"
53inline std::uint64_t
add64(std::uint64_t a, std::uint64_t b,
unsigned char& carry) {
54 unsigned __int128
const sum =
static_cast<unsigned __int128
>(a) + b + carry;
55 carry =
static_cast<unsigned char>(sum >> 64);
56 return static_cast<std::uint64_t
>(sum);
60#pragma GCC diagnostic pop
63inline std::uint64_t
sub64(std::uint64_t a, std::uint64_t b,
unsigned char& borrow) {
64 std::uint64_t
const temp = a - borrow;
65 unsigned char const borrow1 = (a < borrow);
66 std::uint64_t
const result = temp - b;
67 unsigned char const borrow2 = (temp < b);
68 borrow = borrow1 | borrow2;
81#if defined(_MSC_VER) && !defined(__clang__)
83inline std::uint64_t mulhi64(std::uint64_t a, std::uint64_t b)
noexcept {
88#elif defined(__SIZEOF_INT128__)
90#pragma GCC diagnostic push
91#pragma GCC diagnostic ignored "-Wpedantic"
93inline std::uint64_t mulhi64(std::uint64_t a, std::uint64_t b)
noexcept {
94 return static_cast<std::uint64_t
>(
95 (
static_cast<unsigned __int128
>(a) * b) >> 64);
98#pragma GCC diagnostic pop
102inline std::uint64_t
mulhi64(std::uint64_t a, std::uint64_t b)
noexcept {
103 std::uint32_t
const ah =
static_cast<std::uint32_t
>(a >> 32);
104 std::uint32_t
const al =
static_cast<std::uint32_t
>(a);
105 std::uint32_t
const bh =
static_cast<std::uint32_t
>(b >> 32);
106 std::uint32_t
const bl =
static_cast<std::uint32_t
>(b);
107 std::uint64_t
const mid =
static_cast<std::uint64_t
>(al) * bh +
108 (
static_cast<std::uint64_t
>(ah) * bl) +
109 (
static_cast<std::uint64_t
>(al) * bl >> 32);
110 return static_cast<std::uint64_t
>(ah) * bh + (mid >> 32);
std::uint64_t add64(std::uint64_t a, std::uint64_t b, unsigned char &carry)
std::uint64_t sub64(std::uint64_t a, std::uint64_t b, unsigned char &borrow)
std::uint64_t mulhi64(std::uint64_t a, std::uint64_t b) noexcept