Replacing the x86 crc32 Assembly Instructions
Symptom
Error:
- "unknown mnemonic 'crc32q' -- 'crc32q (x3),x2'", "operand 1 should be an integer register -- 'crc32b [sp,11],x0'", or
- unrecognized command line option '-msse4.2'
Cause
The x86 platform uses the crc32b, crc32w, crc32l, and crc32q assembly instructions to calculate CRC32C check values, while the ARM64 platform uses the crc32cb, crc32ch, crc32cw, and crc32cx assembly instructions to calculate CRC32C check values.
Procedure
Replace the CRC32 series assembly instructions of the x86 with the CRC32CB, CRC32CH, CRC32CW, and CRC32CX assembly instructions. Table 1 describes the replacement method. You need to add the -march=armv8+crc parameter during compilation.
Instruction |
Input Data Bit Width (Bit) |
Remarks |
|---|---|---|
CRC32CB |
8 |
Applies to 8-bit input data and replaces the x86 CRC32B assembly instruction. |
CRC32CH |
16 |
Applies to 16-bit input data and replaces the x86 CRC32W assembly instruction. |
CRC32CW |
32 |
Applies to 32-bit input data and replaces the x86 CRC32I assembly instruction. |
CRC32CX |
64 |
Applies to 64-bit input data and replaces the x86 CRC32Q assembly instruction. |
Example:
- Code on x86:
static inline uint32_t crc32_u8(uint32_t crc, uint8_t v) { __asm__("crc32b %1, %0" : "+r"(crc) : "rm"(v)); return crc; } static inline uint32_t crc32_u16(uint32_t crc, uint16_t v) { __asm__("crc32w %1, %0" : "+r"(crc) : "rm"(v)); return crc; } static inline uint32_t crc32_u32(uint32_t crc, uint32_t v) { __asm__("crc32l %1, %0" : "+r"(crc) : "rm"(v)); return crc; } static inline uint32_t crc32_u64(uint32_t crc, uint64_t v) { uint64_t result = crc; __asm__("crc32q %1, %0" : "+r"(result) : "rm"(v)); return result; } - Code on the Kunpeng platform:
static inline uint32_t crc32_u8(uint32_t crc, uint8_t value) { __asm__("crc32cb %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)); return crc; } static inline uint32_t crc32_u16(uint32_t crc, uint16_t value) { __asm__("crc32ch %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)); return crc; } static inline uint32_t crc32_u32(uint32_t crc, uint32_t value) { __asm__("crc32cw %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)); return crc; } static inline uint32_t crc32_u64(uint32_t crc, uint64_t value) { __asm__("crc32cx %w[c], %w[c], %x[v]":[c]"+r"(crc):[v]"r"(value)); return crc; }