鲲鹏社区首页
中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

替换x86 crc32汇编指令

现象描述

编译错误:unknown mnemonic 'crc32q' -- 'crc32q (x3),x2'或operand 1 should be an integer register -- 'crc32b [sp,11],x0'

或unrecognized command line option ‘-msse4.2’。

问题原因

x86使用的是crc32b、crc32w、crc32l、 crc32q汇编指令完成CRC32C校验值计算功能,而ARM64平台使用crc32cb、crc32ch、crc32cw、crc32cx 4个汇编指令完成CRC32C校验值计算功能。

处理步骤

请使用crc32cb、crc32ch、crc32cw、crc32cx取代x86的CRC32系列汇编指令,替换方法如表1所示,并在编译时添加编译参数-march=armv8+crc。

表1 替换方法

指令

输入数据位宽(bit)

备注

crc32cb

8

适用输入数据位宽为8bit,可用于替换x86的crc32b汇编指令。

crc32ch

16

适用输入数据位宽为16bit,可用于替换x86的crc32w汇编指令。

crc32cw

32

适用输入数据位宽为32bit,可用于替换x86的crc32l汇编指令。

crc32cx

64

适用输入数据位宽为64bit,可用于替换x86的crc32q汇编指令。

示例:

  • 在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; 
    } 
  • 在鲲鹏平台下的实现:
    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; 
    }