Add some appropriate bignum typedefs for generic 64-bit systems,
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 18 Feb 2011 08:25:36 +0000 (08:25 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 18 Feb 2011 08:25:36 +0000 (08:25 +0000)
setting BignumInt to 32 bits. gcc defines _LP64 on x86-64 and
presumably on other 64-bit architectures, so I've conditioned my
defines on that in the hope that they won't need redoing for the next
few such architectures.

I've also added a set for _LLP64, but it's untested as yet.

git-svn-id: svn://svn.tartarus.org/sgt/putty@9092 cda61777-01e9-0310-a592-d414129be87e

sshbn.c

diff --git a/sshbn.c b/sshbn.c
index ba3d5b6..c0ae528 100644 (file)
--- a/sshbn.c
+++ b/sshbn.c
@@ -51,7 +51,34 @@ typedef unsigned __int64 BignumDblInt;
     __asm mov r, edx \
     __asm mov q, eax \
 } while(0)
+#elif defined _LP64
+/* 64-bit architectures can do 32x32->64 chunks at a time */
+typedef unsigned int BignumInt;
+typedef unsigned long BignumDblInt;
+#define BIGNUM_INT_MASK  0xFFFFFFFFU
+#define BIGNUM_TOP_BIT   0x80000000U
+#define BIGNUM_INT_BITS  32
+#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 _LLP64
+/* 64-bit architectures in which unsigned long is 32 bits, not 64 */
+typedef unsigned long BignumInt;
+typedef unsigned long long BignumDblInt;
+#define BIGNUM_INT_MASK  0xFFFFFFFFUL
+#define BIGNUM_TOP_BIT   0x80000000UL
+#define BIGNUM_INT_BITS  32
+#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)
 #else
+/* Fallback for all other cases */
 typedef unsigned short BignumInt;
 typedef unsigned long BignumDblInt;
 #define BIGNUM_INT_MASK  0xFFFFU