X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=sshbn.h;h=6ee97ee65785e70360631e818c6328fdd0677bf1;hb=b6b52269e1085d9a58adf2f0f86f96fd96fa3199;hp=6f5877b00d369b4f691a48d5e0f144c0a7ea2a74;hpb=c2ec13c7e98a2dd0c40161e5d16284bcaf6ec62b;p=PuTTY.git diff --git a/sshbn.h b/sshbn.h index 6f5877b0..6ee97ee6 100644 --- a/sshbn.h +++ b/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 + 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 */