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