aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-10-09 23:40:44 -0400
committerJack Lloyd <[email protected]>2017-10-11 17:08:55 -0400
commit40b3f979723b2b3dfb5c44047d7f786a73fd7f6f (patch)
treebb2ad6b1df281aab32de7bec3e17a806ae95922c /src/lib/utils
parentf60b816469ebc3b46aa64dcba0dcdcdb92e87301 (diff)
Use rol/ror x86 instructions on GCC/Clang
Neither is very good at recognizing rotate sequences. For cases where the rotation value is a constant they do fine, but for variable rotations they do horribly. Using inline asm here improved performance of both CAST-128 and CAST-256 by ~20% on my system with both GCC and Clang.
Diffstat (limited to 'src/lib/utils')
-rw-r--r--src/lib/utils/rotate.h26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/lib/utils/rotate.h b/src/lib/utils/rotate.h
index cb92daf96..6aeb631b3 100644
--- a/src/lib/utils/rotate.h
+++ b/src/lib/utils/rotate.h
@@ -18,7 +18,7 @@ namespace Botan {
* @param rot the number of bits to rotate
* @return input rotated left by rot bits
*/
-template<typename T> inline T rotate_left(T input, size_t rot)
+template<typename T> inline T rotate_left(T input, uint8_t rot)
{
rot %= 8 * sizeof(T);
return (rot == 0) ? input : static_cast<T>((input << rot) | (input >> (8*sizeof(T)-rot)));;
@@ -30,12 +30,34 @@ template<typename T> inline T rotate_left(T input, size_t rot)
* @param rot the number of bits to rotate
* @return input rotated right by rot bits
*/
-template<typename T> inline T rotate_right(T input, size_t rot)
+template<typename T> inline T rotate_right(T input, uint8_t rot)
{
rot %= 8 * sizeof(T);
return (rot == 0) ? input : static_cast<T>((input >> rot) | (input << (8*sizeof(T)-rot)));
}
+#if BOTAN_USE_GCC_INLINE_ASM
+
+#if defined(BOTAN_TARGET_ARCH_IS_X86_64) || defined(BOTAN_TARGET_ARCH_IS_X86_32)
+
+template<>
+inline uint32_t rotate_left(uint32_t input, uint8_t rot)
+ {
+ asm("roll %1,%0" : "+r" (input) : "c" (rot));
+ return input;
+ }
+
+template<>
+inline uint32_t rotate_right(uint32_t input, uint8_t rot)
+ {
+ asm("rorl %1,%0" : "+r" (input) : "c" (rot));
+ return input;
+ }
+
+#endif
+
+#endif
+
}
#endif