Add vec_swap for compilers which do not support std::swap'ing SSE and NEON types

This commit is contained in:
Jeffrey Walton 2016-07-17 21:25:55 -04:00
parent 5ad7bbd0c7
commit 4fd51eb06c
2 changed files with 15 additions and 4 deletions

13
misc.h
View File

@ -423,6 +423,19 @@ inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t co
# define memmove_s CryptoPP::memmove_s
#endif
//! \brief Swaps two variables which are arrays
//! \details C++03 does not provide support for <tt>std::swap(__m128i a, __m128i b)</tt>
//! because <tt>__m128i</tt> is an <tt>unsigned long long[2]</tt>. Most compilers
//! support it out of the box, but Sun Studio C++ compilers 12.2 and 12.3 do not.
//! \sa <A HREF="http://stackoverflow.com/q/38417413">How to swap two __m128i variables
//! in C++03 given its an opaque type and an array?</A> on Stack Overflow.
template <class T>
inline void vec_swap(T& a, T& b)
{
T t;
t=a, a=b, b=t;
}
#endif // __STDC_WANT_SECURE_LIB__
//! \brief Memory block initializer and eraser that attempts to survive optimizations

View File

@ -275,11 +275,9 @@ void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, c
unsigned int i, j;
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120)
// __m128i is an unsigned long long[2], and support for swapping it was not formally added until C++11.
// __m128i is an unsigned long long[2], and support for swapping it was not added until C++11.
// SunCC 12.1 - 12.3 fail to consume the swap; while SunCC 12.4 consumes it without -std=c++11.
__m128i t = *(__m128i *)(rk);
*(__m128i *)(rk) = *(__m128i *)(rk+4*m_rounds);
*(__m128i *)(rk+4*m_rounds) = t;
vec_swap(*(__m128i *)(rk), *(__m128i *)(rk+4*m_rounds));
#else
std::swap(*(__m128i *)(void *)(rk), *(__m128i *)(void *)(rk+4*m_rounds));
#endif