diff options
author | Jack Lloyd <[email protected]> | 2017-10-09 23:40:44 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-10-11 17:08:55 -0400 |
commit | 40b3f979723b2b3dfb5c44047d7f786a73fd7f6f (patch) | |
tree | bb2ad6b1df281aab32de7bec3e17a806ae95922c /src/lib/utils | |
parent | f60b816469ebc3b46aa64dcba0dcdcdb92e87301 (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.h | 26 |
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 |