我要评分
获取效率
正确性
完整性
易理解

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.

Table 1 Replacement method

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; 
    }