| Opcode | Encoding | 16-bit | 32-bit | 64-bit | CPUID Feature Flag(s) | Description |
|---|---|---|---|---|---|---|
F2 0F 38 F0 /rCRC32 r32, r/m8 | rm | Valid | Valid | Valid | sse4.2 | Accumulate CRC32 on r/m8 into r32. |
F2 REX 0F 38 F0 /rCRC32 r32, r/m8* | rm | N/E | N/E | Valid | sse4.2 | Accumulate CRC32 on r/m8 into r32. This uses the alterate gpr8 encoding. |
F2 REX.W 0F 38 F0 /rCRC32 r64, r/m8* | rm | N/E | N/E | Valid | sse4.2 | Accumulate CRC32 on r/m8 into r64. This uses the alterate gpr8 encoding. |
F2 0F 38 F1 /rCRC32 r32, r/m16 | rm | Valid | Valid | Valid | sse4.2 | Accumulate CRC32 on r/m16 into r32. |
F2 0F 38 F1 /rCRC32 r32, r/m32 | rm | Valid | Valid | Valid | sse4.2 | Accumulate CRC32 on r/m32 into r32. |
F2 REX.W 0F 38 F1 /rCRC32 r64, r/m64 | rm | N/E | N/E | Valid | sse4.2 | Accumulate CRC32 on r/m64 into r64. |
Encoding
| Encoding | Operand 1 | Operand 2 |
|---|---|---|
mr | ModRM.r/m[rw] | ModRM.reg[r] |
Description
The CRC32 instruction accumulates a CRC32 (with polynomial 0x11EDC6F41) on the source operand into the destination operand.
The polynomial used (0x11EDC6F41) is the "Castagnoli" polynomial. Of note is that this polynomial is not the one used in many places such as Ethernet, SATA, ZIP, PNG, etc. That polynomial (0x04C11DB7) cannot be computed using this instruction.
Operation
// `BitReflect(...)` reverses the bits in the parameter (i.e. `BitReflect(0xAA)` returns `0x55`)
const U40 POLYNOMIAL = 0x11EDC6F41;
public void CRC32(ref U32 dest, U8 src)
{
U40 temp1 = BitReflect(src) << 32;
U40 temp2 = BitReflect(dest) << 8;
U40 temp3 = temp1 ^ temp2;
U32 temp4 = PolynomialDivisionMod2(temp3, POLYNOMIAL);
dest = BitReflect(temp4);
}
public void CRC32(ref U32 dest, U16 src)
{
U48 temp1 = BitReflect(src) << 32;
U48 temp2 = BitReflect(dest) << 16;
U48 temp3 = temp1 ^ temp2;
U32 temp4 = PolynomialDivisionMod2(temp3, POLYNOMIAL);
dest = BitReflect(temp4);
}
public void CRC32(ref U32 dest, U32 src)
{
U64 temp1 = BitReflect(src) << 32;
U64 temp2 = BitReflect(dest) << 32;
U64 temp3 = temp1 ^ temp2;
U32 temp4 = PolynomialDivisionMod2(temp3, POLYNOMIAL);
dest = BitReflect(temp4);
}
public void CRC32(ref U64 dest, U8 src)
{
U40 temp1 = BitReflect(src) << 32;
U40 temp2 = BitReflect((U32)(dest & 0xFFFFFFFFul)) << 8;
U40 temp3 = temp1 ^ temp2;
U32 temp4 = PolynomialDivisionMod2(temp3, POLYNOMIAL);
dest = SignExtend(BitReflect(temp4));
}
public void CRC32(ref U64 dest, U64 src)
{
U96 temp1 = BitReflect(src) << 32;
U96 temp2 = BitReflect((U32)(dest & 0xFFFFFFFFul)) << 64;
U96 temp3 = temp1 ^ temp2;
U32 temp4 = PolynomialDivisionMod2(temp3, POLYNOMIAL);
dest = SignExtend(BitReflect(temp4));
}Flags Affected
None.Intrinsics
uint32_t _mm_crc32_u8(uint32_t crc, uint8_t data)
uint32_t _mm_crc32_u16(uint32_t crc, uint16_t data)
uint32_t _mm_crc32_u32(uint32_t crc, uint32_t data)
uint64_t _mm_crc32_u64(uint64_t crc, uint64_t data)Exceptions
Real-Address Mode
#UD- If the
LOCK- prefix is used.
#SS(0)- If a memory operand using the
SS- segment has an effective address that is outside the
SS- segment's limit.
#GP(0)- If a memory operand (using a segment other than
SS- ) has an effective address that is outside the segment's limit.
Virtual-8086 Mode
#UD- If the
LOCK- prefix is used.
#SS(0)- If a memory operand using the
SS- segment has an effective address that is outside the
SS- segment's limit.
#GP(0)- If a memory operand (using a segment other than
SS- ) has an effective address that is outside the segment's limit.
#PF(fc)- If a page fault occurs.
#AC(0)- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.
Protected Mode
#UD- If the
LOCK- prefix is used.
#SS(0)- If a memory operand using the
SS- segment has an effective address that is outside the
SS- segment's limit.
#GP(0)- If the destination is located in a non-writable segment.
- If a memory operand uses a segment containing a
NULLselector. - If a memory operand (using a segment other than
SS) has an effective address that is outside the segment's limit.
#PF(fc)- If a page fault occurs.
#AC(0)- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.
Compatibility Mode
#UD- If the
LOCK- prefix is used.
#SS(0)- If a memory operand using the
SS- segment has an effective address that is outside the
SS- segment's limit.
#GP(0)- If the destination is located in a non-writable segment.
- If a memory operand uses a segment containing a
NULLselector. - If a memory operand (using a segment other than
SS) has an effective address that is outside the segment's limit.
#PF(fc)- If a page fault occurs.
#AC(0)- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.
Long Mode
#UD- If the
LOCK- prefix is used.
#SS(0)- If a memory operand using the
SSsegment is in non-canonical form. - If a memory operand using the
SSsegment has an effective address that is outside theSSsegment's limit.
#GP(0)- If a memory operand (using a segment other than
SS) is in non-canonical form. - If the destination is located in a non-writable segment.
- If a memory operand uses a segment containing a
NULLselector. - If a memory operand (using a segment other than
SS) has an effective address that is outside the segment's limit.
#PF(fc)- If a page fault occurs.
#AC(0)- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.