Advertisement
zhangsongcui

hwCrc32c

Jun 15th, 2018
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.50 KB | None | 0 0
  1. #ifdef __ARM_FEATURE_CRC32
  2. #include <arm_acle.h>
  3. #define _mm_crc32_u8 __crc32cb
  4. #define _mm_crc32_u16 __crc32ch
  5. #define _mm_crc32_u32 __crc32cw
  6. #define _mm_crc32_u64 __crc32cd
  7. #else
  8. #include <nmmintrin.h>
  9. #endif
  10. #include <stdio.h>
  11. #include <stdint.h>
  12. #include <stddef.h>
  13.  
  14. /**
  15.  * Calculates CRC-32C using hardware support
  16.  *
  17.  * @param initialCrc The initial CRC to use for the operation
  18.  * @param buf The buffer that stores the data whose CRC is to be calculated
  19.  * @param len The size of the buffer
  20.  * @return The CRC-32C of the data in the buffer
  21.  */
  22. uint32_t hwCrc32c(uint32_t initialCrc, const char *buf, size_t len) {
  23.     uint32_t crc = initialCrc;
  24.  
  25.     // XOR the initial CRC with INT_MAX
  26.     crc ^= 0xFFFFFFFF;
  27.  
  28.     if (len >= 8) {
  29.         // Align the input to the word boundary
  30.         const auto offset = (intptr_t)buf & 0b111;
  31.         switch (offset) {
  32.             case 7:
  33.                 crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
  34.                 break;
  35.             case 6:
  36.                 crc = _mm_crc32_u16(crc, *(uint16_t *)buf);
  37.                 break;
  38.             case 5:
  39.                 crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
  40.                 crc = _mm_crc32_u16(crc, *(uint16_t *)(buf + 1));
  41.                 break;
  42.             case 4:
  43.                 crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
  44.                 break;
  45.             case 3:
  46.                 crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
  47.                 crc = _mm_crc32_u32(crc, *(uint32_t *)(buf + 1));
  48.                 break;
  49.             case 2:
  50.                 crc = _mm_crc32_u16(crc, *(uint16_t *)buf);
  51.                 crc = _mm_crc32_u32(crc, *(uint32_t *)(buf + 2));
  52.                 break;
  53.             case 1:
  54.                 crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
  55.                 crc = _mm_crc32_u16(crc, *(uint16_t *)(buf + 2));
  56.                 crc = _mm_crc32_u32(crc, *(uint32_t *)(buf + 4));
  57.                 break;
  58.         }
  59.        
  60.         buf += offset;
  61.         len -= offset;
  62.        
  63.         for (; len >= 8; len -= 8) {
  64.             crc = (uint32_t)_mm_crc32_u64(crc, *(uint64_t *)buf);
  65.             buf += 8;
  66.         }
  67.     }
  68.    
  69.     switch (len) {
  70.         case 1:
  71.             crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
  72.             break;
  73.         case 2:
  74.             crc = _mm_crc32_u16(crc, *(uint16_t *)buf);
  75.             break;
  76.         case 3:
  77.             crc = _mm_crc32_u16(crc, *(uint16_t *)buf);
  78.             crc = _mm_crc32_u8(crc, *(uint8_t *)(buf + 2));
  79.             break;
  80.         case 4:
  81.             crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
  82.             break;
  83.         case 5:
  84.             crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
  85.             crc = _mm_crc32_u8(crc, *(uint8_t *)(buf + 4));
  86.             break;
  87.         case 6:
  88.             crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
  89.             crc = _mm_crc32_u16(crc, *(uint16_t *)(buf + 4));
  90.             break;
  91.         case 7:
  92.             crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
  93.             crc = _mm_crc32_u16(crc, *(uint16_t *)(buf + 4));
  94.             crc = _mm_crc32_u8(crc, *(uint8_t *)(buf + 6));
  95.             break;
  96.     }
  97.  
  98.     // XOR again with INT_MAX
  99.     crc ^= 0xFFFFFFFF;
  100.     return crc;
  101. }
  102.  
  103. #include <string_view>
  104.  
  105. using namespace std;
  106.  
  107. uint32_t hwCrc32c(std::string_view sv) {
  108.     return hwCrc32c(0, sv.data(), sv.length());
  109. }
  110.  
  111. int main() {
  112.     std::printf("%08X\n", hwCrc32c("input"sv));
  113.     std::printf("%08X\n", hwCrc32c("123"sv));
  114.     std::printf("%08X\n", hwCrc32c("12345678901234567890"));
  115. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement