Fix compile on 32-bit SunCC (GH #761)

pull/765/head
Jeffrey Walton 2018-12-12 09:05:56 -05:00
parent 80c551121f
commit 3d98320b1e
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
1 changed files with 63 additions and 10 deletions

View File

@ -54,6 +54,7 @@
#include "config.h" #include "config.h"
#include "donna.h" #include "donna.h"
#include "stdcpp.h" #include "stdcpp.h"
#include "cpu.h"
// This macro is not in a header like config.h because // This macro is not in a header like config.h because
// we don't want it exposed to user code. We also need // we don't want it exposed to user code. We also need
@ -82,6 +83,44 @@ using CryptoPP::sword64;
typedef sword64 limb; 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 element representation:
* *
* Field elements are written as an array of signed, 64-bit limbs, least * 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]; output[0] += output[10];
} }
#if (-1 & 3) != 3 // Modified for SunCC. See comments for SignExtexnd function.
#error "This code only works on a two's complement system" // #if (-1 & 3) != 3
#endif // #error "This code only works on a two's complement system"
// #endif
/* return v / 2^26, using only shifts and adds. /* 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. */ /* High word of v; no shift needed. */
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); 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. */ /* 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. */ /* Set to 0x3ffffff if v was negative; else set to 0. */
const int32_t roundoff = ((uint32_t) sign) >> 6; const int32_t roundoff = ((uint32_t) sign) >> 6;
/* Should return v / (1<<26) */ /* 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*/ /* High word of v; no shift needed*/
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); 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. */ /* 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. */ /* Set to 0x1ffffff if v was negative; else set to 0. */
const int32_t roundoff = ((uint32_t) sign) >> 7; const int32_t roundoff = ((uint32_t) sign) >> 7;
/* Should return v / (1<<25) */ /* Should return v / (1<<25) */
@ -469,29 +517,34 @@ void fexpand(limb *output, const byte *input)
#undef F #undef F
} }
#if (-32 >> 1) != -16 // Modified for SunCC. See comments for SignExtexnd function.
#error "This code only works when >> does sign-extension on negative numbers" // #if (-32 >> 1) != -16
#endif // #error "This code only works when >> does sign-extension on negative numbers"
// #endif
/* sword32_eq returns 0xffffffff iff a == b and zero otherwise. */ /* sword32_eq returns 0xffffffff iff a == b and zero otherwise. */
sword32 sword32_eq(sword32 a, sword32 b) sword32 sword32_eq(sword32 a, sword32 b)
{ {
// Modified for SunCC. See comments for SignExtexnd function.
a = ~(a ^ b); a = ~(a ^ b);
a &= a << 16; a &= a << 16;
a &= a << 8; a &= a << 8;
a &= a << 4; a &= a << 4;
a &= a << 2; a &= a << 2;
a &= a << 1; 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 /* sword32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are
* both non-negative. */ * both non-negative. */
sword32 sword32_gte(sword32 a, sword32 b) sword32 sword32_gte(sword32 a, sword32 b)
{ {
// Modified for SunCC. See comments for SignExtexnd function.
a -= b; a -= b;
/* a >= 0 iff 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 /* Take a fully reduced polynomial form number and contract it into a