X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=sshbn.h;h=9366f614ae4cde0cb198626180758db235e4cee1;hb=9f9d72ec58642e91b4f93ee4405a8086ee2fb2f0;hp=3d15b948296172de74e60f2ee324f9c733db4ba9;hpb=2c60070aad2d959a9e7e850523352c23c6aa7009;p=PuTTY.git diff --git a/sshbn.h b/sshbn.h index 3d15b948..9366f614 100644 --- a/sshbn.h +++ b/sshbn.h @@ -20,7 +20,24 @@ * The C variant won't give the right answer, either. */ -#if defined __GNUC__ && defined __i386__ +#if defined __SIZEOF_INT128__ +/* gcc and clang both provide a __uint128_t type on 64-bit targets + * (and, when they do, indicate its presence by the above macro), + * using the same 'two machine registers' kind of code generation that + * 32-bit targets use for 64-bit ints. If we have one of these, we can + * use a 64-bit BignumInt and a 128-bit BignumDblInt. */ +typedef unsigned long long BignumInt; +typedef __uint128_t BignumDblInt; +#define BIGNUM_INT_MASK 0xFFFFFFFFFFFFFFFFULL +#define BIGNUM_TOP_BIT 0x8000000000000000ULL +#define BIGNUM_INT_BITS 64 +#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2) +#define DIVMOD_WORD(q, r, hi, lo, w) do { \ + BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \ + q = n / w; \ + r = n % w; \ +} while (0) +#elif defined __GNUC__ && defined __i386__ typedef unsigned long BignumInt; typedef unsigned long long BignumDblInt; #define BIGNUM_INT_MASK 0xFFFFFFFFUL