Opcode | Encoding | 16-bit | 32-bit | 64-bit | CPUID Feature Flag(s) | Description |
---|---|---|---|---|---|---|
F2 0F 38 F0 /r CRC32 r32, r/m8 | rm | Valid | Valid | Valid | sse4.2 | Accumulate CRC32 on r/m8 into r32. |
F2 REX 0F 38 F0 /r CRC32 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 /r CRC32 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 /r CRC32 r32, r/m16 | rm | Valid | Valid | Valid | sse4.2 | Accumulate CRC32 on r/m16 into r32. |
F2 0F 38 F1 /r CRC32 r32, r/m32 | rm | Valid | Valid | Valid | sse4.2 | Accumulate CRC32 on r/m32 into r32. |
F2 REX.W 0F 38 F1 /r CRC32 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
NULL
selector. - 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
NULL
selector. - 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
SS
segment is in non-canonical form. - If a memory operand using the
SS
segment has an effective address that is outside theSS
segment'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
NULL
selector. - 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.