9#ifndef BOTAN_MP_WORD_MULADD_H_
10#define BOTAN_MP_WORD_MULADD_H_
12#include <botan/types.h>
13#include <botan/mul128.h>
17#if (BOTAN_MP_WORD_BITS == 32)
18 typedef uint64_t dword;
19 #define BOTAN_HAS_MP_DWORD
21#elif (BOTAN_MP_WORD_BITS == 64)
22 #if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
23 typedef uint128_t dword;
24 #define BOTAN_HAS_MP_DWORD
30 #error BOTAN_MP_WORD_BITS must be 32 or 64
33#if defined(BOTAN_USE_GCC_INLINE_ASM)
35 #if defined(BOTAN_TARGET_ARCH_IS_X86_32) && (BOTAN_MP_WORD_BITS == 32)
36 #define BOTAN_MP_USE_X86_32_ASM
37 #elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && (BOTAN_MP_WORD_BITS == 64)
38 #define BOTAN_MP_USE_X86_64_ASM
48#if defined(BOTAN_MP_USE_X86_32_ASM)
54 : [a]"=a"(a), [b]
"=rm"(b), [
carry]
"=&d"(*c)
55 :
"0"(a),
"1"(b), [c]
"g"(*c) :
"cc");
59#elif defined(BOTAN_MP_USE_X86_64_ASM)
65 : [a]"=a"(a), [b]
"=rm"(b), [
carry]
"=&d"(*c)
66 :
"0"(a),
"1"(b), [c]
"g"(*c) :
"cc");
70#elif defined(BOTAN_HAS_MP_DWORD)
71 const dword s =
static_cast<dword
>(a) * b + *c;
72 *c =
static_cast<word
>(s >> BOTAN_MP_WORD_BITS);
73 return static_cast<word
>(s);
75 static_assert(BOTAN_MP_WORD_BITS == 64,
"Unexpected word size");
94#if defined(BOTAN_MP_USE_X86_32_ASM)
104 : [a]"=a"(a), [b]
"=rm"(b), [
carry]
"=&d"(*d)
105 :
"0"(a),
"1"(b), [c]
"g"(c), [d]
"g"(*d) :
"cc");
109#elif defined(BOTAN_MP_USE_X86_64_ASM)
117 : [a]"=a"(a), [b]
"=rm"(b), [
carry]
"=&d"(*d)
118 :
"0"(a),
"1"(b), [c]
"g"(c), [d]
"g"(*d) :
"cc");
122#elif defined(BOTAN_HAS_MP_DWORD)
123 const dword s =
static_cast<dword
>(a) * b + c + *d;
124 *d =
static_cast<word
>(s >> BOTAN_MP_WORD_BITS);
125 return static_cast<word
>(s);
127 static_assert(BOTAN_MP_WORD_BITS == 64,
"Unexpected word size");
void carry(int64_t &h0, int64_t &h1)
word word_madd3(word a, word b, word c, word *d)
word word_madd2(word a, word b, word *c)
void mul64x64_128(uint64_t a, uint64_t b, uint64_t *lo, uint64_t *hi)