From 9d2455a69949356713cdbb8e34d20063e19cd457 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sat, 20 May 2017 18:03:53 -0400 Subject: [PATCH] Add inline ASM for missing CRC intrinsics (Issue 428) --- crc.cpp | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/crc.cpp b/crc.cpp index 1add0d84..18babbb7 100644 --- a/crc.cpp +++ b/crc.cpp @@ -13,6 +13,33 @@ NAMESPACE_BEGIN(CryptoPP) # undef CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE #endif + +// Use inline ASM to provide the instructions when the user omits -march=native +#if (CRYPTOPP_GCC_VERSION >= 40300 || CRYPTOPP_LLVM_CLANG_VERSION >= 30200 || CRYPTOPP_APPLE_CLANG_VERSION >= 30200) && !defined(__SSE4_2__) +GCC_INLINE unsigned int GCC_INLINE_ATTRIB +MM_CRC32_U8(unsigned int crc, unsigned char val) +{ + asm ("crc32 %1, %0" : "+r"(crc) : "r"(val)); + return crc; +} +GCC_INLINE unsigned int GCC_INLINE_ATTRIB +MM_CRC32_U16(unsigned int crc, unsigned short val) +{ + asm ("crc32 %1, %0" : "+r"(crc) : "r"(val)); + return crc; +} +GCC_INLINE unsigned int GCC_INLINE_ATTRIB +MM_CRC32_U32(unsigned int crc, unsigned int val) +{ + asm ("crc32 %1, %0" : "+r"(crc) : "r"(val)); + return crc; +} +#else + #define MM_CRC32_U8(a,b) _mm_crc32_u8(a,b) + #define MM_CRC32_U16(a,b) _mm_crc32_u16(a,b) + #define MM_CRC32_U32(a,b) _mm_crc32_u32(a,b) +#endif + /* Table of CRC-32's of all single byte values (made by makecrc.c) */ const word32 CRC32::m_tab[] = { #ifdef IS_LITTLE_ENDIAN @@ -303,13 +330,13 @@ void CRC32C::Update(const byte *s, size_t n) if (HasSSE4()) { for(; !IsAligned(s) && n > 0; s++, n--) - m_crc = _mm_crc32_u8(m_crc, *s); + m_crc = MM_CRC32_U8(m_crc, *s); for(; n > 4; s+=4, n-=4) - m_crc = _mm_crc32_u32(m_crc, *(const word32 *)(void*)s); + m_crc = MM_CRC32_U32(m_crc, *(const word32 *)(void*)s); for(; n > 0; s++, n--) - m_crc = _mm_crc32_u8(m_crc, *s); + m_crc = MM_CRC32_U8(m_crc, *s); return; }