Accumulate CRC32 Value

Encoding

EncodingOperand 1Operand 2
mrModRM.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

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 the SS 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.