Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef __ARM_FEATURE_CRC32
- #include <arm_acle.h>
- #define _mm_crc32_u8 __crc32cb
- #define _mm_crc32_u16 __crc32ch
- #define _mm_crc32_u32 __crc32cw
- #define _mm_crc32_u64 __crc32cd
- #else
- #include <nmmintrin.h>
- #endif
- #include <stdio.h>
- #include <stdint.h>
- #include <stddef.h>
- /**
- * Calculates CRC-32C using hardware support
- *
- * @param initialCrc The initial CRC to use for the operation
- * @param buf The buffer that stores the data whose CRC is to be calculated
- * @param len The size of the buffer
- * @return The CRC-32C of the data in the buffer
- */
- uint32_t hwCrc32c(uint32_t initialCrc, const char *buf, size_t len) {
- uint32_t crc = initialCrc;
- // XOR the initial CRC with INT_MAX
- crc ^= 0xFFFFFFFF;
- if (len >= 8) {
- // Align the input to the word boundary
- const auto offset = (intptr_t)buf & 0b111;
- switch (offset) {
- case 7:
- crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
- break;
- case 6:
- crc = _mm_crc32_u16(crc, *(uint16_t *)buf);
- break;
- case 5:
- crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
- crc = _mm_crc32_u16(crc, *(uint16_t *)(buf + 1));
- break;
- case 4:
- crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
- break;
- case 3:
- crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
- crc = _mm_crc32_u32(crc, *(uint32_t *)(buf + 1));
- break;
- case 2:
- crc = _mm_crc32_u16(crc, *(uint16_t *)buf);
- crc = _mm_crc32_u32(crc, *(uint32_t *)(buf + 2));
- break;
- case 1:
- crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
- crc = _mm_crc32_u16(crc, *(uint16_t *)(buf + 2));
- crc = _mm_crc32_u32(crc, *(uint32_t *)(buf + 4));
- break;
- }
- buf += offset;
- len -= offset;
- for (; len >= 8; len -= 8) {
- crc = (uint32_t)_mm_crc32_u64(crc, *(uint64_t *)buf);
- buf += 8;
- }
- }
- switch (len) {
- case 1:
- crc = _mm_crc32_u8(crc, *(uint8_t *)buf);
- break;
- case 2:
- crc = _mm_crc32_u16(crc, *(uint16_t *)buf);
- break;
- case 3:
- crc = _mm_crc32_u16(crc, *(uint16_t *)buf);
- crc = _mm_crc32_u8(crc, *(uint8_t *)(buf + 2));
- break;
- case 4:
- crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
- break;
- case 5:
- crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
- crc = _mm_crc32_u8(crc, *(uint8_t *)(buf + 4));
- break;
- case 6:
- crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
- crc = _mm_crc32_u16(crc, *(uint16_t *)(buf + 4));
- break;
- case 7:
- crc = _mm_crc32_u32(crc, *(uint32_t *)buf);
- crc = _mm_crc32_u16(crc, *(uint16_t *)(buf + 4));
- crc = _mm_crc32_u8(crc, *(uint8_t *)(buf + 6));
- break;
- }
- // XOR again with INT_MAX
- crc ^= 0xFFFFFFFF;
- return crc;
- }
- #include <string_view>
- using namespace std;
- uint32_t hwCrc32c(std::string_view sv) {
- return hwCrc32c(0, sv.data(), sv.length());
- }
- int main() {
- std::printf("%08X\n", hwCrc32c("input"sv));
- std::printf("%08X\n", hwCrc32c("123"sv));
- std::printf("%08X\n", hwCrc32c("12345678901234567890"));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement