9 #ifndef BOTAN_MP_WORD_MULADD_H__
10 #define BOTAN_MP_WORD_MULADD_H__
12 #include <botan/mp_types.h>
13 #include <botan/mul128.h>
17 #if (BOTAN_MP_WORD_BITS == 8)
18 typedef uint16_t dword;
19 #define BOTAN_HAS_MP_DWORD
20 #elif (BOTAN_MP_WORD_BITS == 16)
21 typedef uint32_t dword;
22 #define BOTAN_HAS_MP_DWORD
23 #elif (BOTAN_MP_WORD_BITS == 32)
24 typedef uint64_t dword;
25 #define BOTAN_HAS_MP_DWORD
26 #elif (BOTAN_MP_WORD_BITS == 64)
27 #if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
29 #define BOTAN_HAS_MP_DWORD
35 #error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64
38 #if defined(BOTAN_TARGET_ARCH_IS_X86_32) && (BOTAN_MP_WORD_BITS == 32)
40 #if defined(BOTAN_USE_GCC_INLINE_ASM)
41 #define BOTAN_MP_USE_X86_32_ASM
42 #define ASM(x) x "\n\t"
43 #elif defined(BOTAN_BUILD_COMPILER_IS_MSVC)
44 #define BOTAN_MP_USE_X86_32_MSVC_ASM
47 #elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && (BOTAN_MP_WORD_BITS == 64) && (BOTAN_USE_GCC_INLINE_ASM)
48 #define BOTAN_MP_USE_X86_64_ASM
49 #define ASM(x) x "\n\t"
52 #if defined(BOTAN_MP_USE_X86_32_ASM) || defined(BOTAN_MP_USE_X86_64_ASM)
53 #define ASM(x) x "\n\t"
61 #if defined(BOTAN_MP_USE_X86_32_ASM)
65 ASM(
"adcl $0,%[carry]")
67 : [a]
"=a"(a), [b]
"=rm"(b), [carry]
"=&d"(*c)
68 :
"0"(a),
"1"(b), [c]
"g"(*c) :
"cc");
72 #elif defined(BOTAN_MP_USE_X86_64_ASM)
76 ASM(
"adcq $0,%[carry]")
78 : [a]
"=a"(a), [b]
"=rm"(b), [carry]
"=&d"(*c)
79 :
"0"(a),
"1"(b), [c]
"g"(*c) :
"cc");
83 #elif defined(BOTAN_HAS_MP_DWORD)
84 const dword s =
static_cast<dword
>(a) * b + *c;
85 *c =
static_cast<word
>(s >> BOTAN_MP_WORD_BITS);
86 return static_cast<word
>(s);
88 static_assert(BOTAN_MP_WORD_BITS == 64,
"Unexpected word size");
107 #if defined(BOTAN_MP_USE_X86_32_ASM)
111 ASM(
"addl %[c],%[a]")
112 ASM(
"adcl $0,%[carry]")
114 ASM(
"addl %[d],%[a]")
115 ASM(
"adcl $0,%[carry]")
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_MP_USE_X86_64_ASM)
126 ASM(
"addq %[c],%[a]")
127 ASM(
"adcq $0,%[carry]")
129 ASM(
"addq %[d],%[a]")
130 ASM(
"adcq $0,%[carry]")
132 : [a]
"=a"(a), [b]
"=rm"(b), [carry]
"=&d"(*d)
133 :
"0"(a),
"1"(b), [c]
"g"(c), [d]
"g"(*d) :
"cc");
137 #elif defined(BOTAN_HAS_MP_DWORD)
138 const dword s =
static_cast<dword
>(a) * b + c + *d;
139 *d =
static_cast<word
>(s >> BOTAN_MP_WORD_BITS);
140 return static_cast<word
>(s);
142 static_assert(BOTAN_MP_WORD_BITS == 64,
"Unexpected word size");
void mul64x64_128(uint64_t a, uint64_t b, uint64_t *lo, uint64_t *hi)
word word_madd3(word a, word b, word c, word *d)
word word_madd2(word a, word b, word *c)