<?xml-stylesheet type="text/xsl" encoding="UTF-8" href="iform.xsl" version="1.0"?>
<!DOCTYPE instructionsection PUBLIC "-//ARM//DTD instructionsection //EN" "iform-p.dtd">
<!-- Copyright (c) 2010-2025 Arm Limited or its affiliates. All rights reserved. -->
<!-- This document is Non-Confidential. This document may only be used and distributed in accordance with the terms of the agreement entered into by Arm and the party that Arm delivered this document to. -->
<instructionsection id="CRC32_a32" title="CRC32 -- AArch32" type="instruction">
  <docvars>
    <docvar key="instr-class" value="general"/>
  </docvars>
  <heading>CRC32</heading>
  <desc>
    <brief>
      <para>CRC32</para>
    </brief>
    <authored>
      <para><instruction>CRC32</instruction> performs a cyclic redundancy check (CRC) calculation on a
value held in a general-purpose register. It takes an input CRC
value in the first source operand, performs a CRC on the input value
in the second source operand, and returns the output CRC value. The
second source operand can be 8, 16, or 32 bits. To align with common
usage, the bit order of the values is reversed as part of the
operation, and the polynomial <hexnumber>0x04C11DB7</hexnumber> is used for
the CRC calculation.</para>
      <para>In an Armv8.0 implementation, this is an <arm-defined-word>OPTIONAL</arm-defined-word> instruction.
From Armv8.1, it is mandatory for all implementations to implement this instruction.</para>
      <note>
        <para><xref linkend="ARMARM_AArch32.id_isar5">ID_ISAR5</xref>.CRC32
indicates whether this instruction is supported in the T32 and A32
instruction sets.</para>
      </note>
    </authored>
    <encodingnotes>
      <para>For more information about the <arm-defined-word>CONSTRAINED UNPREDICTABLE</arm-defined-word> behavior, see <xref linkend="ARMARM_CJAEGDJC">Architectural Constraints on UNPREDICTABLE behaviors</xref>.</para>
    </encodingnotes>
  </desc>
  <operationalnotes>
    <operationalnote>
      <operationalnote_content>
        <para>This instruction is a data-independent-time instruction as described in <xref linkend="ARMARM_BEIIDCEG">About the DIT bit</xref>.</para>
      </operationalnote_content>
    </operationalnote>
  </operationalnotes>
  <alias_list howmany="0"/>
  <classes>
    <classesintro count="2">
      <txt>It has encodings from the following instruction sets:</txt>
      <txt> A32 (</txt>
      <a href="#iclass_a1">A1</a>
      <txt>)</txt>
      <txt> and </txt>
      <txt> T32 (</txt>
      <a href="#iclass_t1">T1</a>
      <txt>)</txt>
      <txt>.</txt>
    </classesintro>
    <iclass name="A1" oneof="2" id="iclass_a1" no_encodings="3" isa="A32">
      <docvars>
        <docvar key="armarmheading" value="A1"/>
        <docvar key="instr-class" value="general"/>
        <docvar key="isa" value="A32"/>
      </docvars>
      <iclassintro count="3"/>
      <arch_variants>
        <arch_variant feature="FEAT_CRC32" name="v8Ap0"/>
      </arch_variants>
      <regdiagram form="32" psname="A32.dp.dpmisc.crc32.CRC32B_A1" tworows="1">
        <box hibit="31" width="4" name="cond" usename="1" settings="4" constraint="!= 1111">
          <c colspan="4">!= 1111</c>
        </box>
        <box hibit="27" width="5" settings="5">
          <c>0</c>
          <c>0</c>
          <c>0</c>
          <c>1</c>
          <c>0</c>
        </box>
        <box hibit="22" width="2" name="sz" usename="1">
          <c colspan="2"/>
        </box>
        <box hibit="20" width="1" settings="1">
          <c>0</c>
        </box>
        <box hibit="19" width="4" name="Rn" usename="1">
          <c colspan="4"/>
        </box>
        <box hibit="15" width="4" name="Rd" usename="1">
          <c colspan="4"/>
        </box>
        <box hibit="11" width="2" settings="2">
          <c>(0)</c>
          <c>(0)</c>
        </box>
        <box hibit="9" name="C" usename="1" settings="1" psbits="x">
          <c>0</c>
        </box>
        <box hibit="8" width="5" settings="5">
          <c>(0)</c>
          <c>0</c>
          <c>1</c>
          <c>0</c>
          <c>0</c>
        </box>
        <box hibit="3" width="4" name="Rm" usename="1">
          <c colspan="4"/>
        </box>
      </regdiagram>
      <encoding name="CRC32B_A1" oneofinclass="3" oneof="6" label="CRC32B" bitdiffs="sz == 00">
        <docvars>
          <docvar key="armarmheading" value="A1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A32"/>
          <docvar key="mnemonic" value="CRC32B"/>
        </docvars>
        <box hibit="22" width="2" name="sz">
          <c>0</c>
          <c>0</c>
        </box>
        <asmtemplate><text>CRC32B{</text><a hover="See x[Standard assembler syntax fields](Babbefhf). A CRC32 instruction must be unconditional." link="qw_option__2">&lt;q&gt;</a><text>}  </text><a hover="Is the general-purpose accumulator output register, encoded in the &quot;Rd&quot; field." link="Rd__18">&lt;Rd&gt;</a><text>, </text><a hover="Is the general-purpose accumulator input register, encoded in the &quot;Rn&quot; field." link="Rn__6">&lt;Rn&gt;</a><text>, </text><a hover="Is the general-purpose data source register, encoded in the &quot;Rm&quot; field." link="Rm__11">&lt;Rm&gt;</a></asmtemplate>
      </encoding>
      <encoding name="CRC32H_A1" oneofinclass="3" oneof="6" label="CRC32H" bitdiffs="sz == 01">
        <docvars>
          <docvar key="armarmheading" value="A1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A32"/>
          <docvar key="mnemonic" value="CRC32H"/>
        </docvars>
        <box hibit="22" width="2" name="sz">
          <c>0</c>
          <c>1</c>
        </box>
        <asmtemplate><text>CRC32H{</text><a hover="See x[Standard assembler syntax fields](Babbefhf). A CRC32 instruction must be unconditional." link="qw_option__2">&lt;q&gt;</a><text>}  </text><a hover="Is the general-purpose accumulator output register, encoded in the &quot;Rd&quot; field." link="Rd__18">&lt;Rd&gt;</a><text>, </text><a hover="Is the general-purpose accumulator input register, encoded in the &quot;Rn&quot; field." link="Rn__6">&lt;Rn&gt;</a><text>, </text><a hover="Is the general-purpose data source register, encoded in the &quot;Rm&quot; field." link="Rm__11">&lt;Rm&gt;</a></asmtemplate>
      </encoding>
      <encoding name="CRC32W_A1" oneofinclass="3" oneof="6" label="CRC32W" bitdiffs="sz == 10">
        <docvars>
          <docvar key="armarmheading" value="A1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A32"/>
          <docvar key="mnemonic" value="CRC32W"/>
        </docvars>
        <box hibit="22" width="2" name="sz">
          <c>1</c>
          <c>0</c>
        </box>
        <asmtemplate><text>CRC32W{</text><a hover="See x[Standard assembler syntax fields](Babbefhf). A CRC32 instruction must be unconditional." link="qw_option__2">&lt;q&gt;</a><text>}  </text><a hover="Is the general-purpose accumulator output register, encoded in the &quot;Rd&quot; field." link="Rd__18">&lt;Rd&gt;</a><text>, </text><a hover="Is the general-purpose accumulator input register, encoded in the &quot;Rn&quot; field." link="Rn__6">&lt;Rn&gt;</a><text>, </text><a hover="Is the general-purpose data source register, encoded in the &quot;Rm&quot; field." link="Rm__11">&lt;Rm&gt;</a></asmtemplate>
      </encoding>
      <ps_section howmany="1">
        <ps name="A32.dp.dpmisc.crc32.CRC32B_A1" sections="1" secttype="noheading">
          <pstext mayhavelinks="1" section="Decode" rep_section="decode">if !IsFeatureImplemented(FEAT_CRC32) then Undefined(); end;
let d : integer = UInt(Rd);
let n : integer = UInt(Rn);
let m : integer = UInt(Rm);
let size : integer{} = 8 &lt;&lt; UInt(sz);
let crc32c : boolean = (C == '1');
if d == 15 || n == 15 || m == 15 then UnpredictableProcedure(); end;
if size == 64 then UnpredictableProcedure(); end;
if cond != '1110' then UnpredictableProcedure(); end;</pstext></ps>
      </ps_section>
      <constrained_unpredictables encoding="A1" ps_block="Decode">
        <cu_case>
          <cu_cause>
            <pstext mayhavelinks="1">size == 64</pstext></cu_cause>
          <cu_type constraint="Constraint_UNDEF"/>
          <cu_type constraint="Constraint_NOP"/>
          <cu_type constraint="Constraint_ADDITIONAL_DECODE">
            <cu_type_variable name="pseudocode" value="size = 32;"/>
          </cu_type>
        </cu_case>
        <cu_case>
          <cu_cause>
            <pstext mayhavelinks="1">cond != '1110'</pstext></cu_cause>
          <cu_type constraint="Constraint_UNDEF"/>
          <cu_type constraint="Constraint_NOP"/>
          <cu_type constraint="Constraint_UNCOND"/>
          <cu_type constraint="Constraint_COND"/>
        </cu_case>
      </constrained_unpredictables>
    </iclass>
    <iclass name="T1" oneof="2" id="iclass_t1" no_encodings="3" isa="T32">
      <docvars>
        <docvar key="armarmheading" value="T1"/>
        <docvar key="instr-class" value="general"/>
        <docvar key="isa" value="T32"/>
      </docvars>
      <iclassintro count="3"/>
      <arch_variants>
        <arch_variant feature="FEAT_CRC32" name="v8Ap0"/>
      </arch_variants>
      <regdiagram form="16x2" psname="T32.w.reg.dpint_2r.CRC32B_T1" tworows="1">
        <box hibit="31" width="11" settings="11">
          <c>1</c>
          <c>1</c>
          <c>1</c>
          <c>1</c>
          <c>1</c>
          <c>0</c>
          <c>1</c>
          <c>0</c>
          <c>1</c>
          <c>1</c>
          <c>0</c>
        </box>
        <box hibit="20" name="C" usename="1" settings="1" psbits="x">
          <c>0</c>
        </box>
        <box hibit="19" width="4" name="Rn" usename="1">
          <c colspan="4"/>
        </box>
        <box hibit="15" width="4" settings="4">
          <c>1</c>
          <c>1</c>
          <c>1</c>
          <c>1</c>
        </box>
        <box hibit="11" width="4" name="Rd" usename="1">
          <c colspan="4"/>
        </box>
        <box hibit="7" width="2" settings="2">
          <c>1</c>
          <c>0</c>
        </box>
        <box hibit="5" width="2" name="sz" usename="1">
          <c colspan="2"/>
        </box>
        <box hibit="3" width="4" name="Rm" usename="1">
          <c colspan="4"/>
        </box>
      </regdiagram>
      <encoding name="CRC32B_T1" oneofinclass="3" oneof="6" label="CRC32B" bitdiffs="sz == 00">
        <docvars>
          <docvar key="armarmheading" value="T1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="T32"/>
          <docvar key="mnemonic" value="CRC32B"/>
        </docvars>
        <box hibit="5" width="2" name="sz">
          <c>0</c>
          <c>0</c>
        </box>
        <asmtemplate><text>CRC32B{</text><a hover="See x[Standard assembler syntax fields](Babbefhf). A CRC32 instruction must be unconditional." link="qw_option__2">&lt;q&gt;</a><text>}  </text><a hover="Is the general-purpose accumulator output register, encoded in the &quot;Rd&quot; field." link="Rd__18">&lt;Rd&gt;</a><text>, </text><a hover="Is the general-purpose accumulator input register, encoded in the &quot;Rn&quot; field." link="Rn__6">&lt;Rn&gt;</a><text>, </text><a hover="Is the general-purpose data source register, encoded in the &quot;Rm&quot; field." link="Rm__11">&lt;Rm&gt;</a></asmtemplate>
      </encoding>
      <encoding name="CRC32H_T1" oneofinclass="3" oneof="6" label="CRC32H" bitdiffs="sz == 01">
        <docvars>
          <docvar key="armarmheading" value="T1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="T32"/>
          <docvar key="mnemonic" value="CRC32H"/>
        </docvars>
        <box hibit="5" width="2" name="sz">
          <c>0</c>
          <c>1</c>
        </box>
        <asmtemplate><text>CRC32H{</text><a hover="See x[Standard assembler syntax fields](Babbefhf). A CRC32 instruction must be unconditional." link="qw_option__2">&lt;q&gt;</a><text>}  </text><a hover="Is the general-purpose accumulator output register, encoded in the &quot;Rd&quot; field." link="Rd__18">&lt;Rd&gt;</a><text>, </text><a hover="Is the general-purpose accumulator input register, encoded in the &quot;Rn&quot; field." link="Rn__6">&lt;Rn&gt;</a><text>, </text><a hover="Is the general-purpose data source register, encoded in the &quot;Rm&quot; field." link="Rm__11">&lt;Rm&gt;</a></asmtemplate>
      </encoding>
      <encoding name="CRC32W_T1" oneofinclass="3" oneof="6" label="CRC32W" bitdiffs="sz == 10">
        <docvars>
          <docvar key="armarmheading" value="T1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="T32"/>
          <docvar key="mnemonic" value="CRC32W"/>
        </docvars>
        <box hibit="5" width="2" name="sz">
          <c>1</c>
          <c>0</c>
        </box>
        <asmtemplate><text>CRC32W{</text><a hover="See x[Standard assembler syntax fields](Babbefhf). A CRC32 instruction must be unconditional." link="qw_option__2">&lt;q&gt;</a><text>}  </text><a hover="Is the general-purpose accumulator output register, encoded in the &quot;Rd&quot; field." link="Rd__18">&lt;Rd&gt;</a><text>, </text><a hover="Is the general-purpose accumulator input register, encoded in the &quot;Rn&quot; field." link="Rn__6">&lt;Rn&gt;</a><text>, </text><a hover="Is the general-purpose data source register, encoded in the &quot;Rm&quot; field." link="Rm__11">&lt;Rm&gt;</a></asmtemplate>
      </encoding>
      <ps_section howmany="1">
        <ps name="T32.w.reg.dpint_2r.CRC32B_T1" sections="1" secttype="noheading">
          <pstext mayhavelinks="1" section="Decode" rep_section="decode">if InITBlock() then UnpredictableProcedure(); end;
if !IsFeatureImplemented(FEAT_CRC32) then Undefined(); end;
let d : integer = UInt(Rd);
let n : integer = UInt(Rn);
let m : integer = UInt(Rm);
let size : integer{} = 8 &lt;&lt; UInt(sz);
let crc32c : boolean = (C == '1');
if d == 15 || n == 15 || m == 15 then UnpredictableProcedure(); end;
if size == 64 then UnpredictableProcedure(); end;</pstext></ps>
      </ps_section>
      <constrained_unpredictables encoding="T1" ps_block="Decode">
        <cu_case>
          <cu_cause>
            <pstext mayhavelinks="1">size == 64</pstext></cu_cause>
          <cu_type constraint="Constraint_UNDEF"/>
          <cu_type constraint="Constraint_NOP"/>
          <cu_type constraint="Constraint_ADDITIONAL_DECODE">
            <cu_type_variable name="pseudocode" value="size = 32;"/>
          </cu_type>
        </cu_case>
      </constrained_unpredictables>
    </iclass>
  </classes>
  <explanations scope="all">
    <explanation enclist="CRC32B_A1, CRC32H_A1, CRC32W_A1, CRC32B_T1, CRC32H_T1, CRC32W_T1" symboldefcount="1">
      <symbol link="qw_option__2">&lt;q&gt;</symbol>
      <account encodedin="">
        <intro>
          <para>See <xref linkend="Babbefhf">Standard assembler syntax fields</xref>. A <instruction>CRC32</instruction> instruction must be unconditional.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="CRC32B_A1, CRC32H_A1, CRC32W_A1, CRC32B_T1, CRC32H_T1, CRC32W_T1" symboldefcount="1">
      <symbol link="Rd__18">&lt;Rd&gt;</symbol>
      <account encodedin="Rd">
        <intro>
          <para>Is the general-purpose accumulator output register, encoded in the "Rd" field.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="CRC32B_A1, CRC32H_A1, CRC32W_A1, CRC32B_T1, CRC32H_T1, CRC32W_T1" symboldefcount="1">
      <symbol link="Rn__6">&lt;Rn&gt;</symbol>
      <account encodedin="Rn">
        <intro>
          <para>Is the general-purpose accumulator input register, encoded in the "Rn" field.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="CRC32B_A1, CRC32H_A1, CRC32W_A1, CRC32B_T1, CRC32H_T1, CRC32W_T1" symboldefcount="1">
      <symbol link="Rm__11">&lt;Rm&gt;</symbol>
      <account encodedin="Rm">
        <intro>
          <para>Is the general-purpose data source register, encoded in the "Rm" field.</para>
        </intro>
      </account>
    </explanation>
  </explanations>
  <ps_section howmany="1">
    <ps name="A32.dp.dpmisc.crc32.CRC32B_A1" sections="1" secttype="Operation">
      <pstext mayhavelinks="1" section="Execute" rep_section="execute">if ConditionPassed() then
    EncodingSpecificOperations();

    let acc : bits(32) = R(n);             // accumulator
    let val : bits(size) = R(m)[size-1:0]; // input value
    let poly : bits(32) = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)[31:0];
    let tempacc : bits(32+size) = BitReverse{32}(acc)::Zeros{size};
    let tempval : bits(32+size) = BitReverse{size}(val)::Zeros{32};
    // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation
    R(d) = BitReverse{32}(Poly32Mod2{32+size}(tempacc XOR tempval, poly));
end;</pstext></ps>
  </ps_section>
  <timestamp>2026-03-12 12:23:09</timestamp>
  <commit_id>2025-09_rel_asl1</commit_id>
</instructionsection>
