mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-25 01:02:24 +00:00
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:
parent
c2ec13c7e9
commit
84cd309295
47
sshbn.h
47
sshbn.h
@ -67,6 +67,53 @@
|
|||||||
#define BIGNUM_INT_BITS 64
|
#define BIGNUM_INT_BITS 64
|
||||||
#define DEFINE_BIGNUMDBLINT typedef __uint128_t BignumDblInt
|
#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
|
#elif defined __GNUC__ || defined _LLP64 || __STDC__ >= 199901L
|
||||||
|
|
||||||
/* 32-bit BignumInt, using C99 unsigned long long as BignumDblInt */
|
/* 32-bit BignumInt, using C99 unsigned long long as BignumDblInt */
|
||||||
|
Loading…
Reference in New Issue
Block a user