From 3d98320b1ef27f9cc3ede627df502ce5ff2a7110 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Wed, 12 Dec 2018 09:05:56 -0500 Subject: [PATCH] Fix compile on 32-bit SunCC (GH #761) --- donna_32.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/donna_32.cpp b/donna_32.cpp index 69c7e2f8..04412e34 100644 --- a/donna_32.cpp +++ b/donna_32.cpp @@ -54,6 +54,7 @@ #include "config.h" #include "donna.h" #include "stdcpp.h" +#include "cpu.h" // This macro is not in a header like config.h because // we don't want it exposed to user code. We also need @@ -82,6 +83,44 @@ using CryptoPP::sword64; typedef sword64 limb; +// Added by JW for SunCC. Avoid the bit twiddling hacks. +inline int SignExtend(int val) +{ +#if (__GNUC__ >= 3) || (__SUNPRO_CC >= 0x5100) +# if CRYPTOPP_BOOL_X86 + __asm__ + ( + "sar $31, %0 \n" + : "+g" (val) : : "cc" + ); + return val; +# endif +// TODO: ARM +#endif + + // GCC and SunCC compile down to a shift and neg. + return (val >> 31) * -1; +} + +// Added by JW for SunCC. Avoid the bit twiddling hacks. +inline unsigned int SignExtend(unsigned int val) +{ +#if (__GNUC__ >= 3) || (__SUNPRO_CC >= 0x5100) +# if CRYPTOPP_BOOL_X86 + __asm__ + ( + "sar $31, %0 \n" + : "+g" (val) : : "cc" + ); + return val; +# endif +// TODO: ARM +#endif + + // GCC and SunCC compile down to a shift and neg. + return (unsigned int)(((signed int)(val >> 31)) * -1); +} + /* Field element representation: * * Field elements are written as an array of signed, 64-bit limbs, least @@ -265,9 +304,10 @@ void freduce_degree(limb *output) output[0] += output[10]; } -#if (-1 & 3) != 3 -#error "This code only works on a two's complement system" -#endif +// Modified for SunCC. See comments for SignExtexnd function. +// #if (-1 & 3) != 3 +// #error "This code only works on a two's complement system" +// #endif /* return v / 2^26, using only shifts and adds. * @@ -276,8 +316,12 @@ inline limb div_by_2_26(const limb v) { /* High word of v; no shift needed. */ const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); + + // Modified for SunCC. See comments for SignExtexnd function. /* Set to all 1s if v was negative; else set to 0s. */ - const int32_t sign = ((int32_t) highword) >> 31; + /* const int32_t sign = ((int32_t) highword) >> 31; */ + const int32_t sign = SignExtend(highword); + /* Set to 0x3ffffff if v was negative; else set to 0. */ const int32_t roundoff = ((uint32_t) sign) >> 6; /* Should return v / (1<<26) */ @@ -291,8 +335,12 @@ inline limb div_by_2_25(const limb v) { /* High word of v; no shift needed*/ const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); + + // Modified for SunCC. See comments for SignExtexnd function. /* Set to all 1s if v was negative; else set to 0s. */ - const int32_t sign = ((int32_t) highword) >> 31; + /* const int32_t sign = ((int32_t) highword) >> 31; */ + const int32_t sign = SignExtend(highword); + /* Set to 0x1ffffff if v was negative; else set to 0. */ const int32_t roundoff = ((uint32_t) sign) >> 7; /* Should return v / (1<<25) */ @@ -469,29 +517,34 @@ void fexpand(limb *output, const byte *input) #undef F } -#if (-32 >> 1) != -16 -#error "This code only works when >> does sign-extension on negative numbers" -#endif +// Modified for SunCC. See comments for SignExtexnd function. +// #if (-32 >> 1) != -16 +// #error "This code only works when >> does sign-extension on negative numbers" +// #endif /* sword32_eq returns 0xffffffff iff a == b and zero otherwise. */ sword32 sword32_eq(sword32 a, sword32 b) { + // Modified for SunCC. See comments for SignExtexnd function. a = ~(a ^ b); a &= a << 16; a &= a << 8; a &= a << 4; a &= a << 2; a &= a << 1; - return a >> 31; + /* return a >> 31; */ + return (sword32)SignExtend(a); } /* sword32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are * both non-negative. */ sword32 sword32_gte(sword32 a, sword32 b) { + // Modified for SunCC. See comments for SignExtexnd function. a -= b; /* a >= 0 iff a >= b. */ - return ~(a >> 31); + /* return ~(a >> 31); */ + return ~(sword32)SignExtend(a); } /* Take a fully reduced polynomial form number and contract it into a