CRC32

累积 CRC32 值

stableVMJITAOTinstruction

编码

操作码指令Op/En64 位兼容/传统说明
F2 0F 38 F0 /rCRC32 r32, r/m8RM有效有效在r/m8上累积CRC32.
F2 0F 38 F1 /rCRC32 r32, r/m16RM有效有效在r/m16上累积CRC32.
F2 0F 38 F1 /rCRC32 r32, r/m32RM有效有效在r/m32上累积CRC32.
F2 REX.W 0F 38 F0 /rCRC32 r64, r/m8RM有效不可编码在r/m8上累积CRC32.
F2 REX.W 0F 38 F1 /rCRC32 r64, r/m64RM有效不可编码在r/m64上累积CRC32.

操作数编码

每个模式对应上表 Op/En 列的一个取值,说明各操作数按书写顺序分别编码在指令的哪个字段,以及指令对它是读、是写还是两者兼有。

RM

  1. modrm.reg lectura y escrituraModRM 字节的 reg 字段(第 5-3 位)
  2. modrm.rm lecturaModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移

实测开销

正在从 arch-data 加载实测数据...

说明

从第一个操作数(目标操作数)的初始值开始,积累第二个操作数(源操作数)的CRC32(polynomial 11EDC6F41H)值,并将结果存储为目标操作数. 源操作数可以是寄存器或内存位置. 目标操作数必须是r32或r64登记册. 如果目的地是r64寄存器,则32位结果存储在最小的双字中,00000000H则存储在r64寄存器中最显著的双字中.

目标操作数中提供的初始值是存储在r32登记册中的双字整数,或者r64登记册中最小的双字整数. 为了递增积累一个CRC32值,软件保留了目标操作数中之前的CRC32操作的结果,然后用源操作数中的新输入数据再次执行CRC32指令. 源操作数中包含的数据按反射位顺序处理. 这意味着源操作数中最显著的位点,被作为所有源操作数中最不重要的位点,等等. 同样,CRC操作的结果也以反射的位顺序存储在目标操作数中. 这意味着产生的CRC中最显著的位(bit 31)被存储在目标操作数中最小的位(bit 0)等中,用于CRC中的所有位.

行动

Notes:
    BIT_REFLECT64: DST[63-0] = SRC[0-63]
    BIT_REFLECT32: DST[31-0] = SRC[0-31]
    BIT_REFLECT16: DST[15-0] = SRC[0-15]
    BIT_REFLECT8: DST[7-0] = SRC[0-7]
    MOD2: Remainder from Polynomial division modulus 2


CRC32 instruction for 64-bit source operand and 64-bit destination operand:
    TEMP1[63-0] := BIT_REFLECT64 (SRC[63-0])
    TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])
    TEMP3[95-0] := TEMP1[63-0] << 32
    TEMP4[95-0] := TEMP2[31-0] << 64
    TEMP5[95-0] := TEMP3[95-0] XOR TEMP4[95-0]
    TEMP6[31-0] := TEMP5[95-0] MOD2 11EDC6F41H
    DEST[31-0] := BIT_REFLECT (TEMP6[31-0])
    DEST[63-32] := 00000000H

CRC32 instruction for 32-bit source operand and 32-bit destination operand:
    TEMP1[31-0] := BIT_REFLECT32 (SRC[31-0])
    TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])
    TEMP3[63-0] := TEMP1[31-0] << 32
    TEMP4[63-0] := TEMP2[31-0] << 32
    TEMP5[63-0] := TEMP3[63-0] XOR TEMP4[63-0]
    TEMP6[31-0] := TEMP5[63-0] MOD2 11EDC6F41H
    DEST[31-0] := BIT_REFLECT (TEMP6[31-0])

CRC32 instruction for 16-bit source operand and 32-bit destination operand:
    TEMP1[15-0] := BIT_REFLECT16 (SRC[15-0])
    TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])
    TEMP3[47-0] := TEMP1[15-0] << 32
    TEMP4[47-0] := TEMP2[31-0] << 16
    TEMP5[47-0] := TEMP3[47-0] XOR TEMP4[47-0]
    TEMP6[31-0] := TEMP5[47-0] MOD2 11EDC6F41H
    DEST[31-0] := BIT_REFLECT (TEMP6[31-0])

CRC32 instruction for 8-bit source operand and 64-bit destination operand:
    TEMP1[7-0] := BIT_REFLECT8(SRC[7-0])
    TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])
    TEMP3[39-0] := TEMP1[7-0] << 32
    TEMP4[39-0] := TEMP2[31-0] << 8
    TEMP5[39-0] := TEMP3[39-0] XOR TEMP4[39-0]
    TEMP6[31-0] := TEMP5[39-0] MOD2 11EDC6F41H
    DEST[31-0] := BIT_REFLECT (TEMP6[31-0])
    DEST[63-32] := 00000000H

CRC32 instruction for 8-bit source operand and 32-bit destination operand:
    TEMP1[7-0] := BIT_REFLECT8(SRC[7-0])
    TEMP2[31-0] := BIT_REFLECT32 (DEST[31-0])
    TEMP3[39-0] := TEMP1[7-0] << 32
    TEMP4[39-0] := TEMP2[31-0] << 8
    TEMP5[39-0] := TEMP3[39-0] XOR TEMP4[39-0]
    TEMP6[31-0] := TEMP5[39-0] MOD2 11EDC6F41H
    DEST[31-0] := BIT_REFLECT (TEMP6[31-0])

受影响的旗帜

None.

Intel C/C++ 内在编译器

unsigned int _mm_crc32_u8( unsigned int crc, unsigned char data ) unsigned int _mm_crc32_u16( unsigned int crc, unsigned short data ) unsigned int _mm_crc32_u32( unsigned int crc, unsigned int data ) unsigned __int64 _mm_crc32_u64( unsigned __int64 crc, unsigned __int64 data );

SIMD 浮点 例外

None.

异常

保护模式
#GP(0)如果内存操作数的有效地址位于CS,DS,ES,FS或GS部分之外.
#SS(0)如果一个 内存操作数 的有效地址在 SS 段限制之外. #PF (错误码) 对于一个 页面错误.
#AC(0)如果启用了对齐检查,并且在当前特权级别为3时会给出不对齐的内存引用.
#UD如果 CPUID.01H:ECX.SSE4_2[20]=0. 如果使用 LOCK 前缀.
实地址模式
#GP(0)如果操作数的任何部分位于有效地址空间之外,从0到0FFFFH.
#SS(0)如果 内存操作数 的有效地址在 SS 段限制之外。
#UD如果 CPUID.01H: ECX.SSE4_2[20] = 0. 如果使用 LOCK 前缀。虚拟 8086 模式例外
#GP(0)如果操作数的任何部分位于有效地址空间之外,从0到0FFFFH.
#SS(0)如果一个 内存操作数 的有效地址在 SS 段限制之外. #PF (错误码) 对于一个 页面错误.
#AC(0)如果启用对齐检查, 并使用不对齐的内存引用 。
#UD如果 CPUID.01H:ECX.SSE4_2[20]=0. 如果使用 LOCK 前缀.
兼容模式
与保护模式中的例外相同.
64 位模式
#GP(0)如果内存地址是非冠状的.
#SS(0)如果引用SS段的内存地址为非冠状形式. #PF(错误编码) for a 页面错误.
#AC(0)如果启用了对齐检查,并且在当前特权级别为3时会给出不对齐的内存引用.
#UD如果 CPUID.01H:ECX.SSE4_2[20]=0. 如果使用 LOCK 前缀.

来源