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

Testing on a ci20 dev-board with Debian 5 and GCC 4
pull/765/head
Jeffrey Walton 2018-12-13 04:21:38 -05:00
parent 0bdacf1496
commit 20f4d22055
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
3 changed files with 40 additions and 19 deletions

View File

@ -461,6 +461,13 @@ NAMESPACE_END
#define CRYPTOPP_BOOL_PPC32 1 #define CRYPTOPP_BOOL_PPC32 1
#endif #endif
// And MIPS. TODO: finish these defines
#if defined(__mips64__)
#define CRYPTOPP_BOOL_MIPS64 1
#elif defined(__mips__)
#define CRYPTOPP_BOOL_MIPS32 1
#endif
#if defined(_MSC_VER) || defined(__BORLANDC__) #if defined(_MSC_VER) || defined(__BORLANDC__)
# define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 1 # define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 1
#else #else

View File

@ -66,12 +66,12 @@
# define CRYPTOPP_64BIT 1 # define CRYPTOPP_64BIT 1
#endif #endif
// Some compilers don't handle the code for the arithmetic shifts well. // Some compilers don't handle the code for the arithmetic shifts
// For compilers we know how to support we will issue the asm to sidestep // well. For compilers we know how to support we will issue the asm
// the problem. We also switch to a slightly different pattern. We // to sidestep the problem. We also switch to a slightly different
// believe the pattern preserves the existing properties without a // pattern. We believe the pattern preserves the existing properties
// branch. The ASM uses one intruction, while the C statement use 2 to 6 // without a branch. The ASM uses one intruction, while the C statement
// instructions, depending on the compiler. // use 2 to 6 instructions, depending on the compiler.
#if (__GNUC__ >= 3) || (__SUNPRO_CC >= 0x5100) #if (__GNUC__ >= 3) || (__SUNPRO_CC >= 0x5100)
# define CRYPTOPP_ASR_ASM 1 # define CRYPTOPP_ASR_ASM 1
#endif #endif
@ -92,9 +92,12 @@ using CryptoPP::sword64;
typedef sword64 limb; typedef sword64 limb;
// Added by JW for SunCC. Avoid the bit twiddling hacks. // Added by JW for SunCC. SignExtendShift is just an
// arithmetic shift. Easier said than done in C. Use
// inline ASM when available. Avoid the bit twiddling
// hacks. Also see the comments for CRYPTOPP_ASR_ASM.
template <unsigned int S> template <unsigned int S>
inline int SignExtend(int val) inline int SignExtendShift(int val)
{ {
#if defined(CRYPTOPP_ASR_ASM) && (CRYPTOPP_BOOL_X86) #if defined(CRYPTOPP_ASR_ASM) && (CRYPTOPP_BOOL_X86)
__asm__ __asm__
@ -110,15 +113,21 @@ inline int SignExtend(int val)
: "+r" (val) : "I" (S) : : "+r" (val) : "I" (S) :
); );
return val; return val;
#elif defined(CRYPTOPP_ASR_ASM) && (CRYPTOPP_BOOL_MIPS32)
__asm__
(
"sra %0, %0, %1 \n"
: "+r" (val) : "I" (S) :
);
return val;
#else #else
// GCC and SunCC compile down to a shift and neg. const unsigned int v = ((unsigned int)val >> S);
// Also see the comments for CRYPTOPP_ASR_ASM. return ((signed int)v * -1);
return (val >> S) * -1;
#endif #endif
} }
template <unsigned int S> template <unsigned int S>
inline unsigned int SignExtend(unsigned int val) inline unsigned int SignExtendShift(unsigned int val)
{ {
#if defined(CRYPTOPP_ASR_ASM) && (CRYPTOPP_BOOL_X86) #if defined(CRYPTOPP_ASR_ASM) && (CRYPTOPP_BOOL_X86)
__asm__ __asm__
@ -134,9 +143,14 @@ inline unsigned int SignExtend(unsigned int val)
: "+r" (val) : "I" (S) : : "+r" (val) : "I" (S) :
); );
return val; return val;
#elif defined(CRYPTOPP_ASR_ASM) && (CRYPTOPP_BOOL_MIPS32)
__asm__
(
"sra %0, %0, %1 \n"
: "+r" (val) : "I" (S) :
);
return val;
#else #else
// GCC and SunCC compile down to a shift and neg.
// Also see the comments for CRYPTOPP_ASR_ASM.
const signed int v = (signed int)(val >> S); const signed int v = (signed int)(val >> S);
return (unsigned int)(v * -1); return (unsigned int)(v * -1);
#endif #endif
@ -341,7 +355,7 @@ inline limb div_by_2_26(const limb v)
// Modified for SunCC. See comments for CRYPTOPP_ASR_ASM. // Modified for SunCC. See comments for CRYPTOPP_ASR_ASM.
/* 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 sword32 sign = ((sword32) highword) >> 31; */ /* const sword32 sign = ((sword32) highword) >> 31; */
const word32 sign = SignExtend<31>(highword); const word32 sign = SignExtendShift<31>(highword);
/* Set to 0x3ffffff if v was negative; else set to 0. */ /* Set to 0x3ffffff if v was negative; else set to 0. */
/* const sword32 roundoff = ((word32) sign) >> 6; */ /* const sword32 roundoff = ((word32) sign) >> 6; */
@ -362,7 +376,7 @@ inline limb div_by_2_25(const limb v)
// Modified for SunCC. See comments for CRYPTOPP_ASR_ASM. // Modified for SunCC. See comments for CRYPTOPP_ASR_ASM.
/* 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 sword32 sign = ((sword32) highword) >> 31; */ /* const sword32 sign = ((sword32) highword) >> 31; */
const word32 sign = SignExtend<31>(highword); const word32 sign = SignExtendShift<31>(highword);
/* Set to 0x1ffffff if v was negative; else set to 0. */ /* Set to 0x1ffffff if v was negative; else set to 0. */
/* const sword32 roundoff = ((word32) sign) >> 7; */ /* const sword32 roundoff = ((word32) sign) >> 7; */
@ -558,7 +572,7 @@ sword32 sword32_eq(sword32 a, sword32 b)
a &= a << 2; a &= a << 2;
a &= a << 1; a &= a << 1;
/* return a >> 31; */ /* return a >> 31; */
return (sword32)SignExtend<31>(a); return (sword32)SignExtendShift<31>(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
@ -569,7 +583,7 @@ sword32 sword32_gte(sword32 a, sword32 b)
a -= b; a -= b;
/* a >= 0 iff a >= b. */ /* a >= 0 iff a >= b. */
/* return ~(a >> 31); */ /* return ~(a >> 31); */
return ~(sword32)SignExtend<31>(a); return ~(sword32)SignExtendShift<31>(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