зеркало из https://github.com/github/putty.git
Add a case to sshbn.h for 64-bit Visual Studio.
This commit fulfills the promise of the previous one: now one of the branches of sshbn.h's big ifdef _doesn't_ define a BignumDblInt, and instead provides implementations of the primitive arithmetic macros in terms of Visual Studio's x86-64 compiler intrinsics. So now, when this codebase is compiled with 64-bit VS, it can use a 64-bit BignumInt and everything still seems to work.
This commit is contained in:
Родитель
c2ec13c7e9
Коммит
84cd309295
47
sshbn.h
47
sshbn.h
|
@ -67,6 +67,53 @@
|
|||
#define BIGNUM_INT_BITS 64
|
||||
#define DEFINE_BIGNUMDBLINT typedef __uint128_t BignumDblInt
|
||||
|
||||
#elif defined _MSC_VER && defined _M_AMD64
|
||||
|
||||
/*
|
||||
* 64-bit BignumInt, using Visual Studio x86-64 compiler intrinsics.
|
||||
*
|
||||
* 64-bit Visual Studio doesn't provide very much in the way of help
|
||||
* here: there's no int128 type, and also no inline assembler giving
|
||||
* us direct access to the x86-64 MUL or ADC instructions. However,
|
||||
* there are compiler intrinsics giving us that access, so we can
|
||||
* use those - though it turns out we have to be a little careful,
|
||||
* since they seem to generate wrong code if their pointer-typed
|
||||
* output parameters alias their inputs. Hence all the internal temp
|
||||
* variables inside the macros.
|
||||
*/
|
||||
|
||||
#include <intrin.h>
|
||||
typedef unsigned char BignumCarry; /* the type _addcarry_u64 likes to use */
|
||||
typedef unsigned __int64 BignumInt;
|
||||
#define BIGNUM_INT_BITS 64
|
||||
#define BignumADC(ret, retc, a, b, c) do \
|
||||
{ \
|
||||
BignumInt ADC_tmp; \
|
||||
(retc) = _addcarry_u64(c, a, b, &ADC_tmp); \
|
||||
(ret) = ADC_tmp; \
|
||||
} while (0)
|
||||
#define BignumMUL(rh, rl, a, b) do \
|
||||
{ \
|
||||
BignumInt MULADD_hi; \
|
||||
(rl) = _umul128(a, b, &MULADD_hi); \
|
||||
(rh) = MULADD_hi; \
|
||||
} while (0)
|
||||
#define BignumMULADD(rh, rl, a, b, addend) do \
|
||||
{ \
|
||||
BignumInt MULADD_lo, MULADD_hi; \
|
||||
MULADD_lo = _umul128(a, b, &MULADD_hi); \
|
||||
MULADD_hi += _addcarry_u64(0, MULADD_lo, (addend), &(rl)); \
|
||||
(rh) = MULADD_hi; \
|
||||
} while (0)
|
||||
#define BignumMULADD2(rh, rl, a, b, addend1, addend2) do \
|
||||
{ \
|
||||
BignumInt MULADD_lo1, MULADD_lo2, MULADD_hi; \
|
||||
MULADD_lo1 = _umul128(a, b, &MULADD_hi); \
|
||||
MULADD_hi += _addcarry_u64(0, MULADD_lo1, (addend1), &MULADD_lo2); \
|
||||
MULADD_hi += _addcarry_u64(0, MULADD_lo2, (addend2), &(rl)); \
|
||||
(rh) = MULADD_hi; \
|
||||
} while (0)
|
||||
|
||||
#elif defined __GNUC__ || defined _LLP64 || __STDC__ >= 199901L
|
||||
|
||||
/* 32-bit BignumInt, using C99 unsigned long long as BignumDblInt */
|
||||
|
|
Загрузка…
Ссылка в новой задаче