diff --git a/misc.h b/misc.h index 689b5ed3..5ff4105c 100644 --- a/misc.h +++ b/misc.h @@ -1293,6 +1293,33 @@ CRYPTOPP_DLL void CRYPTOPP_API UnalignedDeallocate(void *ptr); // ************** rotate functions *************** //! \brief Performs a left rotate +//! \tparam T the word type +//! \tparam Y the number of bit positions to rotate the value +//! \param x the value to rotate +//! \details This is a portable C/C++ implementation which attempts to take advantage of the +//! constexpr-ness of a template parameter in hopes of achieving better code +//! generation under Clang and VC++. If a specialization is not available, then +//! rotlImmediate simply calls rotlFixed. +template inline T rotlImmediate(T x) +{ + return rotlFixed(x, Y); +} + +//! \brief Performs a right rotate +//! \tparam T the word type +//! \tparam Y the number of bit positions to rotate the value +//! \param x the value to rotate +//! \details This is a portable C/C++ implementation which attempts to take advantage of the +//! constexpr-ness of a template parameter in hopes of achieving better code +//! generation under Clang and VC++. If a specialization is not available, then +//! rotrImmediate simply calls rotlFixed. +template inline T rotrFixed(T x) +{ + return rotrFixed(x, Y); +} + +//! \brief Performs a left rotate +//! \tparam T the word type //! \param x the value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits. @@ -1314,6 +1341,7 @@ template inline T rotlFixed(T x, unsigned int y) } //! \brief Performs a right rotate +//! \tparam T the word type //! \param x the value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits. @@ -1335,6 +1363,7 @@ template inline T rotrFixed(T x, unsigned int y) } //! \brief Performs a left rotate +//! \tparam T the word type //! \param x the value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits. @@ -1352,6 +1381,7 @@ template inline T rotlVariable(T x, unsigned int y) } //! \brief Performs a right rotate +//! \tparam T the word type //! \param x the value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits. @@ -1369,6 +1399,7 @@ template inline T rotrVariable(T x, unsigned int y) } //! \brief Performs a left rotate +//! \tparam T the word type //! \param x the value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits. @@ -1382,6 +1413,7 @@ template inline T rotlMod(T x, unsigned int y) } //! \brief Performs a right rotate +//! \tparam T the word type //! \param x the value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a portable C/C++ implementation. The value x to be rotated can be 8 to 64-bits. @@ -1394,9 +1426,39 @@ template inline T rotrMod(T x, unsigned int y) return T((x>>(y&MASK))|(x<<(-y&MASK))); } +#if defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32) && 0 +template +inline word32 rotlImmediate(word32 x) +{ + __asm__ ("roll %1, %0" : "+mq" (x) : "I" ((unsigned char)Y)); + return x; +} +template +inline T rotlImmediate(word32 x) +{ + __asm__ ("rorl %1, %0" : "+mq" (x) : "I" ((unsigned char)Y)); + return x; +} +# if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32) +template <> +inline word64 rotlImmediate(word64 x) +{ + __asm__ ("rolq %1, %0" : "+mq" (x) : "J" ((unsigned char)Y)); + return x; +} +template <> +inline T rotlImmediate(word64 x) +{ + __asm__ ("rorq %1, %0" : "+mq" (x) : "J" ((unsigned char)Y)); + return x; +} +# endif +#endif + #ifdef _MSC_VER //! \brief Performs a left rotate +//! \tparam T the word type //! \param x the 32-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotl provided by @@ -1411,6 +1473,7 @@ template<> inline word32 rotlFixed(word32 x, unsigned int y) } //! \brief Performs a right rotate +//! \tparam T the word type //! \param x the 32-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotr provided by @@ -1425,6 +1488,7 @@ template<> inline word32 rotrFixed(word32 x, unsigned int y) } //! \brief Performs a left rotate +//! \tparam T the word type //! \param x the 32-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotl provided by @@ -1438,6 +1502,7 @@ template<> inline word32 rotlVariable(word32 x, unsigned int y) } //! \brief Performs a right rotate +//! \tparam T the word type //! \param x the 32-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotr provided by @@ -1451,6 +1516,7 @@ template<> inline word32 rotrVariable(word32 x, unsigned int y) } //! \brief Performs a left rotate +//! \tparam T the word type //! \param x the 32-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotl provided by @@ -1463,6 +1529,7 @@ template<> inline word32 rotlMod(word32 x, unsigned int y) } //! \brief Performs a right rotate +//! \tparam T the word type //! \param x the 32-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotr provided by @@ -1480,6 +1547,7 @@ template<> inline word32 rotrMod(word32 x, unsigned int y) // Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions //! \brief Performs a left rotate +//! \tparam T the word type //! \param x the 64-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotl provided by @@ -1494,6 +1562,7 @@ template<> inline word64 rotlFixed(word64 x, unsigned int y) } //! \brief Performs a right rotate +//! \tparam T the word type //! \param x the 64-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotr provided by @@ -1508,6 +1577,7 @@ template<> inline word64 rotrFixed(word64 x, unsigned int y) } //! \brief Performs a left rotate +//! \tparam T the word type //! \param x the 64-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotl provided by @@ -1521,6 +1591,7 @@ template<> inline word64 rotlVariable(word64 x, unsigned int y) } //! \brief Performs a right rotate +//! \tparam T the word type //! \param x the 64-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotr provided by @@ -1534,6 +1605,7 @@ template<> inline word64 rotrVariable(word64 x, unsigned int y) } //! \brief Performs a left rotate +//! \tparam T the word type //! \param x the 64-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotl provided by @@ -1546,6 +1618,7 @@ template<> inline word64 rotlMod(word64 x, unsigned int y) } //! \brief Performs a right rotate +//! \tparam T the word type //! \param x the 64-bit value to rotate //! \param y the number of bit positions to rotate the value //! \details This is a Microsoft specific implementation using _lrotr provided by