1 #ifndef SECP256K1_INT128_STRUCT_IMPL_H
2 #define SECP256K1_INT128_STRUCT_IMPL_H
6 #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
8 # if defined(_M_ARM64) || defined(SECP256K1_MSVC_MULH_TEST_OVERRIDE)
12 # if defined(SECP256K1_MSVC_MULH_TEST_OVERRIDE)
13 # pragma message(__FILE__ ": SECP256K1_MSVC_MULH_TEST_OVERRIDE is defined, forcing use of __(u)mulh.")
22 return (uint64_t)a * (uint64_t)b;
26 # define secp256k1_umul128 _umul128
27 # define secp256k1_mul128 _mul128
32 uint64_t ll = (uint64_t)(uint32_t)a * (uint32_t)b;
33 uint64_t lh = (uint32_t)a * (b >> 32);
34 uint64_t hl = (a >> 32) * (uint32_t)b;
35 uint64_t hh = (a >> 32) * (b >> 32);
36 uint64_t mid34 = (ll >> 32) + (uint32_t)lh + (uint32_t)hl;
37 *hi = hh + (lh >> 32) + (hl >> 32) + (mid34 >> 32);
38 return (mid34 << 32) + (uint32_t)ll;
42 uint64_t ll = (uint64_t)(uint32_t)a * (uint32_t)b;
43 int64_t lh = (uint32_t)a * (b >> 32);
44 int64_t hl = (a >> 32) * (uint32_t)b;
45 int64_t hh = (a >> 32) * (b >> 32);
46 uint64_t mid34 = (ll >> 32) + (uint32_t)lh + (uint32_t)hl;
47 *hi = hh + (lh >> 32) + (hl >> 32) + (mid34 >> 32);
48 return (mid34 << 32) + (uint32_t)ll;
65 r->
hi += hi + (r->
lo < lo);
79 r->
lo = r->
hi >> (n-64);
82 r->
lo = ((1U * r->
hi) << (64-n)) | r->
lo >> n;
102 return n >= 64 ? r->
hi >> (n - 64) == 0
103 : r->
hi == 0 && r->
lo >> n == 0;
114 r->hi = (uint64_t)hi;
127 VERIFY_CHECK((r->hi <= 0x7fffffffffffffffu && (uint64_t)hi <= 0x7fffffffffffffffu) <= (r->hi + (uint64_t)hi <= 0x7fffffffffffffffu));
132 VERIFY_CHECK((r->hi > 0x7fffffffffffffffu && (uint64_t)hi > 0x7fffffffffffffffu) <= (r->hi + (uint64_t)hi > 0x7fffffffffffffffu));
144 VERIFY_CHECK((r->hi <= 0x7fffffffffffffffu && (uint64_t)hi > 0x7fffffffffffffffu) <= (r->hi - (uint64_t)hi <= 0x7fffffffffffffffu));
149 VERIFY_CHECK((r->hi > 0x7fffffffffffffffu && (uint64_t)hi <= 0x7fffffffffffffffu) <= (r->hi - (uint64_t)hi > 0x7fffffffffffffffu));
165 r->lo = (uint64_t)((int64_t)(r->hi) >> (n-64));
166 r->hi = (uint64_t)((int64_t)(r->hi) >> 63);
168 r->lo = ((1U * r->hi) << (64-n)) | r->lo >> n;
169 r->hi = (uint64_t)((int64_t)(r->hi) >> n);
184 r->hi = (uint64_t)(a >> 63);
189 return a->hi == b->hi && a->lo == b->lo;
195 return n >= 64 ? r->hi == (uint64_t)sign << (n - 64) && r->lo == 0
196 : r->hi == (uint64_t)(sign >> 1) && r->lo == (uint64_t)sign << n;
int128_t secp256k1_int128
static SECP256K1_INLINE void secp256k1_i128_load(secp256k1_int128 *r, int64_t hi, uint64_t lo)
static SECP256K1_INLINE void secp256k1_i128_det(secp256k1_int128 *r, int64_t a, int64_t b, int64_t c, int64_t d)
static SECP256K1_INLINE int secp256k1_u128_check_bits(const secp256k1_uint128 *r, unsigned int n)
static SECP256K1_INLINE void secp256k1_i128_rshift(secp256k1_int128 *r, unsigned int n)
static SECP256K1_INLINE uint64_t secp256k1_u128_hi_u64(const secp256k1_uint128 *a)
static SECP256K1_INLINE uint64_t secp256k1_i128_to_u64(const secp256k1_int128 *a)
static SECP256K1_INLINE void secp256k1_i128_from_i64(secp256k1_int128 *r, int64_t a)
static SECP256K1_INLINE void secp256k1_u128_from_u64(secp256k1_uint128 *r, uint64_t a)
static SECP256K1_INLINE int secp256k1_i128_eq_var(const secp256k1_int128 *a, const secp256k1_int128 *b)
static SECP256K1_INLINE int64_t secp256k1_i128_to_i64(const secp256k1_int128 *a)
static SECP256K1_INLINE void secp256k1_i128_mul(secp256k1_int128 *r, int64_t a, int64_t b)
static SECP256K1_INLINE int64_t secp256k1_mul128(int64_t a, int64_t b, int64_t *hi)
static SECP256K1_INLINE uint64_t secp256k1_umul128(uint64_t a, uint64_t b, uint64_t *hi)
static SECP256K1_INLINE void secp256k1_u128_rshift(secp256k1_uint128 *r, unsigned int n)
static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r, unsigned int n, int sign)
static SECP256K1_INLINE void secp256k1_u128_accum_u64(secp256k1_uint128 *r, uint64_t a)
static SECP256K1_INLINE void secp256k1_i128_dissip_mul(secp256k1_int128 *r, int64_t a, int64_t b)
static SECP256K1_INLINE void secp256k1_i128_accum_mul(secp256k1_int128 *r, int64_t a, int64_t b)
static SECP256K1_INLINE void secp256k1_u128_accum_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b)
static SECP256K1_INLINE void secp256k1_u128_load(secp256k1_uint128 *r, uint64_t hi, uint64_t lo)
static SECP256K1_INLINE void secp256k1_u128_mul(secp256k1_uint128 *r, uint64_t a, uint64_t b)
static SECP256K1_INLINE uint64_t secp256k1_u128_to_u64(const secp256k1_uint128 *a)
#define VERIFY_CHECK(cond)