<?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="SETPT" title="SETPT, SETMT, SETET -- A64" type="instruction">
  <docvars>
    <docvar key="instr-class" value="general"/>
    <docvar key="isa" value="A64"/>
  </docvars>
  <heading>SETPT, SETMT, SETET</heading>
  <desc>
    <brief>
      <para>Memory set, unprivileged</para>
    </brief>
    <authored>
      <para>These instructions set a required number of bytes in memory to the value in the least significant
byte of the source data register. The prologue, main, and epilogue instructions are expected to
be run in succession and to appear consecutively in memory: SETPT, then SETMT,
and then SETET.</para>
      <para>SETPT performs some preconditioning of the arguments suitable for using the
SETMT instruction, and sets an <arm-defined-word>IMPLEMENTATION DEFINED</arm-defined-word> portion of the requested number
of bytes. SETMT sets a further <arm-defined-word>IMPLEMENTATION DEFINED</arm-defined-word> portion of the remaining bytes.
SETET sets any final remaining bytes.</para>
      <note>
        <para>The ability to set an <arm-defined-word>IMPLEMENTATION DEFINED</arm-defined-word> number of bytes allows an implementation to
optimize how the bytes being set are divided between the different instructions.</para>
      </note>
      <para>For more information on exceptions specific to memory set instructions,
see <xref linkend="ARMARM_MDSec.memcpy_and_memset_exceptions">Memory Copy and Memory Set exceptions</xref>.</para>
      <para>The architecture supports two algorithms for the memory set: option A and option B. Which
algorithm is used is <arm-defined-word>IMPLEMENTATION DEFINED</arm-defined-word>.</para>
      <note>
        <para>Portable software should not assume that the choice of algorithm is constant.</para>
      </note>
      <para>For SETPT:</para>
      <list type="unordered">
        <listitem>
          <content>If Xn[63] == '1', the set size is saturated to <hexnumber>0x7FFFFFFFFFFFFFFF</hexnumber>.</content>
        </listitem>
      </list>
      <para>On completion of SETPT, option A:</para>
      <list type="unordered">
        <listitem>
          <content>Xn holds -1 times the number of bytes in the saturated set size remaining to be set.</content>
        </listitem>
        <listitem>
          <content>Xd holds the original Xd + saturated set size.</content>
        </listitem>
        <listitem>
          <content>PSTATE.{N,Z,C,V} are set to {0,0,0,0}.</content>
        </listitem>
      </list>
      <para>On completion of SETPT, option B:</para>
      <list type="unordered">
        <listitem>
          <content>Xn holds the number of bytes in the saturated set size remaining to be set.</content>
        </listitem>
        <listitem>
          <content>Xd holds the lowest address that has not been set.</content>
        </listitem>
        <listitem>
          <content>PSTATE.{N,Z,C,V} are set to {0,0,1,0}.</content>
        </listitem>
      </list>
      <para>For SETMT, option A, when PSTATE.C = '0':</para>
      <list type="unordered">
        <listitem>
          <content>Xn holds a signed 64-bit integer.</content>
        </listitem>
        <listitem>
          <content>Xn holds -1 times the number of bytes remaining to be set.</content>
        </listitem>
        <listitem>
          <content>Xd holds the lowest address to be set - Xn.</content>
        </listitem>
        <listitem>
          <content>On completion of the instruction, Xn holds -1 times the number of bytes remaining to be set.</content>
        </listitem>
      </list>
      <para>For SETMT, option B, when PSTATE.C = '1':</para>
      <list type="unordered">
        <listitem>
          <content>Xn holds the number of bytes remaining to be set.</content>
        </listitem>
        <listitem>
          <content>Xd holds the lowest address to be set.</content>
        </listitem>
        <listitem>
          <content>On completion of the instruction:<list type="unordered">
              <listitem>
                <content>Xn holds the number of bytes remaining to be set.</content>
              </listitem>
              <listitem>
                <content>Xd holds the lowest address that has not been set.</content>
              </listitem>
            </list>
          </content>
        </listitem>
      </list>
      <para>For SETET, option A, when PSTATE.C = '0':</para>
      <list type="unordered">
        <listitem>
          <content>Xn holds a signed 64-bit integer.</content>
        </listitem>
        <listitem>
          <content>Xn holds -1 times the number of bytes remaining to be set.</content>
        </listitem>
        <listitem>
          <content>Xd holds the lowest address to be set - Xn.</content>
        </listitem>
        <listitem>
          <content>On completion of the instruction, Xn holds 0.</content>
        </listitem>
      </list>
      <para>For SETET, option B, when PSTATE.C = '1':</para>
      <list type="unordered">
        <listitem>
          <content>Xn holds the number of bytes remaining to be set.</content>
        </listitem>
        <listitem>
          <content>Xd holds the lowest address to be set.</content>
        </listitem>
        <listitem>
          <content>On completion of the instruction:<list type="unordered">
              <listitem>
                <content>Xn holds 0.</content>
              </listitem>
              <listitem>
                <content>Xd holds the lowest address that has not been set.</content>
              </listitem>
            </list>
          </content>
        </listitem>
      </list>
      <para>Explicit Memory Write  effects produced by the instruction behave as if the instruction was
  executed at EL0 if the <xref linkend="ARMARM_Effective_value">Effective value</xref> of
  PSTATE.UAO is 0 and either:</para>
      <list type="unordered">
        <listitem>
          <content>The instruction is executed at EL1.</content>
        </listitem>
        <listitem>
          <content>The instruction is executed at EL2 when the <xref linkend="ARMARM_Effective_value">Effective value</xref>
  of <register_link id="AArch64-hcr_el2.xml" state="AArch64">HCR_EL2()</register_link>.{E2H, TGE} is '11'.</content>
        </listitem>
      </list>
      <para>Otherwise, the Explicit Memory Write  effects operate with the restrictions determined by
  the Exception level at which the instruction is executed.</para>
    </authored>
    <encodingnotes>
      <para>For information about the <arm-defined-word>CONSTRAINED UNPREDICTABLE</arm-defined-word> behavior of this instruction, see <xref linkend="CJAEGDJC">Architectural Constraints on UNPREDICTABLE behaviors</xref>, and particularly <xref linkend="CEGDGDDAG2">Memory Copy and Memory Set SET*</xref> and <xref linkend="ARMARM_CEGCCGAE">Crossing a page boundary with different memory types or Shareability attributes</xref>.</para>
    </encodingnotes>
  </desc>
  <alias_list howmany="0"/>
  <classes>
    <iclass name="Integer" oneof="1" id="iclass_integer" no_encodings="3" isa="A64">
      <docvars>
        <docvar key="instr-class" value="general"/>
        <docvar key="isa" value="A64"/>
      </docvars>
      <iclassintro count="3"/>
      <arch_variants>
        <arch_variant feature="FEAT_MOPS" name="v8Ap8"/>
      </arch_variants>
      <regdiagram form="32" psname="A64.ldst.memcms.SETPT_SET_memcms" tworows="1">
        <box hibit="31" width="2" name="sz" usename="1">
          <c colspan="2"/>
        </box>
        <box hibit="29" width="3" settings="3">
          <c>0</c>
          <c>1</c>
          <c>1</c>
        </box>
        <box hibit="26" name="o0" usename="1" settings="1" psbits="x">
          <c>0</c>
        </box>
        <box hibit="25" width="2" settings="2">
          <c>0</c>
          <c>1</c>
        </box>
        <box hibit="23" width="2" name="op1" usename="1" settings="2" psbits="xx">
          <c>1</c>
          <c>1</c>
        </box>
        <box hibit="21" width="1" settings="1">
          <c>0</c>
        </box>
        <box hibit="20" width="5" name="Rs" usename="1">
          <c colspan="5"/>
        </box>
        <box hibit="15" width="4" name="op2" usename="1" settings="2" psbits="xxxx">
          <c>x</c>
          <c>x</c>
          <c>0</c>
          <c>1</c>
        </box>
        <box hibit="11" width="2" settings="2">
          <c>0</c>
          <c>1</c>
        </box>
        <box hibit="9" width="5" name="Rn" usename="1">
          <c colspan="5"/>
        </box>
        <box hibit="4" width="5" name="Rd" usename="1">
          <c colspan="5"/>
        </box>
      </regdiagram>
      <encoding name="SETPT_SET_memcms" oneofinclass="3" oneof="3" label="Prologue" bitdiffs="op2 == 0001">
        <docvars>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A64"/>
          <docvar key="pme" value="pme-prologue"/>
          <docvar key="mnemonic" value="SETPT"/>
        </docvars>
        <box hibit="15" width="4" name="op2">
          <c>0</c>
          <c>0</c>
          <c/>
          <c/>
        </box>
        <asmtemplate><text>SETPT  [</text><a hover="For the &quot;Prologue&quot; variant: is the 64-bit name of the general-purpose register that holds the destination address and is updated by the instruction, encoded in the &quot;Rd&quot; field." link="XdOrXZR">&lt;Xd&gt;</a><text>]!, </text><a hover="For the &quot;Prologue&quot; variant: is the 64-bit name of the general-purpose register that holds the number of bytes to be set and is updated by the instruction, encoded in the &quot;Rn&quot; field." link="XnOrXZR__5">&lt;Xn&gt;</a><text>!, </text><a hover="Is the 64-bit name of the general-purpose register that holds the source data, encoded in the &quot;Rs&quot; field." link="XsOrXZR__7">&lt;Xs&gt;</a></asmtemplate>
      </encoding>
      <encoding name="SETMT_SET_memcms" oneofinclass="3" oneof="3" label="Main" bitdiffs="op2 == 0101">
        <docvars>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A64"/>
          <docvar key="pme" value="pme-main"/>
          <docvar key="mnemonic" value="SETMT"/>
        </docvars>
        <box hibit="15" width="4" name="op2">
          <c>0</c>
          <c>1</c>
          <c/>
          <c/>
        </box>
        <asmtemplate><text>SETMT  [</text><a hover="For the &quot;Epilogue&quot; and &quot;Main&quot; variants: is the 64-bit name of the general-purpose register that holds an encoding of the destination address and for option B is updated by the instruction, encoded in the &quot;Rd&quot; field." link="XdOrXZR__3">&lt;Xd&gt;</a><text>]!, </text><a hover="For the &quot;Main&quot; variant: is the 64-bit name of the general-purpose register that holds an encoding of the number of bytes to be set and is updated by the instruction, encoded in the &quot;Rn&quot; field." link="XnOrXZR__6">&lt;Xn&gt;</a><text>!, </text><a hover="Is the 64-bit name of the general-purpose register that holds the source data, encoded in the &quot;Rs&quot; field." link="XsOrXZR__7">&lt;Xs&gt;</a></asmtemplate>
      </encoding>
      <encoding name="SETET_SET_memcms" oneofinclass="3" oneof="3" label="Epilogue" bitdiffs="op2 == 1001">
        <docvars>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A64"/>
          <docvar key="pme" value="pme-epilogue"/>
          <docvar key="mnemonic" value="SETET"/>
        </docvars>
        <box hibit="15" width="4" name="op2">
          <c>1</c>
          <c>0</c>
          <c/>
          <c/>
        </box>
        <asmtemplate><text>SETET  [</text><a hover="For the &quot;Epilogue&quot; and &quot;Main&quot; variants: is the 64-bit name of the general-purpose register that holds an encoding of the destination address and for option B is updated by the instruction, encoded in the &quot;Rd&quot; field." link="XdOrXZR__3">&lt;Xd&gt;</a><text>]!, </text><a hover="For the &quot;Epilogue&quot; variant: is the 64-bit name of the general-purpose register that holds the number of bytes to be set and is set to zero on completion of the instruction, encoded in the &quot;Rn&quot; field." link="XnOrXZR__7">&lt;Xn&gt;</a><text>!, </text><a hover="Is the 64-bit name of the general-purpose register that holds the source data, encoded in the &quot;Rs&quot; field." link="XsOrXZR__7">&lt;Xs&gt;</a></asmtemplate>
      </encoding>
      <ps_section howmany="1">
        <ps name="A64.ldst.memcms.SETPT_SET_memcms" sections="1" secttype="noheading">
          <pstext mayhavelinks="1" section="Decode" rep_section="decode">if !IsFeatureImplemented(FEAT_MOPS) || sz != '00' then EndOfDecode(Decode_UNDEF); end;

var memset : SETParams;
memset.d = UInt(Rd);
memset.s = UInt(Rs);
memset.n = UInt(Rn);
let options : bits(2) = op2[1:0];
let nontemporal : boolean = options[1] == '1';

case op2[3:2] of
    when '00' =&gt; memset.stage = MOPSStage_Prologue;
    when '01' =&gt; memset.stage = MOPSStage_Main;
    when '10' =&gt; memset.stage = MOPSStage_Epilogue;
    otherwise =&gt; EndOfDecode(Decode_UNDEF);
end;</pstext></ps>
      </ps_section>
    </iclass>
  </classes>
  <explanations scope="all">
    <explanation enclist="SETPT_SET_memcms" symboldefcount="1">
      <symbol link="XdOrXZR">&lt;Xd&gt;</symbol>
      <account encodedin="Rd">
        <intro>
          <para>For the "Prologue" variant: is the 64-bit name of the general-purpose register that holds the destination address and is updated by the instruction, encoded in the "Rd" field.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SETMT_SET_memcms, SETET_SET_memcms" symboldefcount="2">
      <symbol link="XdOrXZR__3">&lt;Xd&gt;</symbol>
      <account encodedin="Rd">
        <intro>
          <para>For the "Epilogue" and "Main" variants: is the 64-bit name of the general-purpose register that holds an encoding of the destination address and for option B is updated by the instruction, encoded in the "Rd" field.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SETPT_SET_memcms" symboldefcount="1">
      <symbol link="XnOrXZR__5">&lt;Xn&gt;</symbol>
      <account encodedin="Rn">
        <intro>
          <para>For the "Prologue" variant: is the 64-bit name of the general-purpose register that holds the number of bytes to be set and is updated by the instruction, encoded in the "Rn" field.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SETMT_SET_memcms" symboldefcount="2">
      <symbol link="XnOrXZR__6">&lt;Xn&gt;</symbol>
      <account encodedin="Rn">
        <intro>
          <para>For the "Main" variant: is the 64-bit name of the general-purpose register that holds an encoding of the number of bytes to be set and is updated by the instruction, encoded in the "Rn" field.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SETET_SET_memcms" symboldefcount="3">
      <symbol link="XnOrXZR__7">&lt;Xn&gt;</symbol>
      <account encodedin="Rn">
        <intro>
          <para>For the "Epilogue" variant: is the 64-bit name of the general-purpose register that holds the number of bytes to be set and is set to zero on completion of the instruction, encoded in the "Rn" field.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SETPT_SET_memcms, SETMT_SET_memcms, SETET_SET_memcms" symboldefcount="1">
      <symbol link="XsOrXZR__7">&lt;Xs&gt;</symbol>
      <account encodedin="Rs">
        <intro>
          <para>Is the 64-bit name of the general-purpose register that holds the source data, encoded in the "Rs" field.</para>
        </intro>
      </account>
    </explanation>
  </explanations>
  <ps_section howmany="1">
    <ps name="A64.ldst.memcms.SETPT_SET_memcms" sections="1" secttype="Operation">
      <pstext mayhavelinks="1" section="Execute" rep_section="execute">CheckMOPSEnabled();

CheckSETConstrainedUnpredictable(memset.n, memset.d, memset.s);

let data : bits(8) = X{}(memset.s);
var B : <a link="MOPSBlockSize" file="shared_pseudocode.xml" hover="type MOPSBlockSize">MOPSBlockSize</a> = 0;

memset.is_setg = FALSE;
memset.nzcv = PSTATE.[N,Z,C,V];
memset.toaddress = X{64}(memset.d);
if memset.stage == MOPSStage_Prologue then
    memset.setsize = UInt(X{64}(memset.n));
else
    memset.setsize = SInt(X{64}(memset.n));
end;
memset.implements_option_a = SETOptionA();

let privileged : boolean = (if options[0] == '1' then AArch64_IsUnprivAccessPriv()
                               else PSTATE.EL != EL0);

let accdesc : AccessDescriptor = CreateAccDescMOPS(MemOp_STORE, privileged, nontemporal);

if memset.stage == MOPSStage_Prologue then
    if memset.setsize &gt; ArchMaxMOPSBlockSize then
        memset.setsize = ArchMaxMOPSBlockSize;
    end;

    if memset.implements_option_a then
        memset.nzcv = '0000';
        memset.toaddress = memset.toaddress + memset.setsize;
        memset.setsize   = 0 - memset.setsize;
    else
        memset.nzcv = '0010';
    end;
end;

memset.stagesetsize = MemSetStageSize(memset);

if memset.stage != MOPSStage_Prologue then
    CheckMemSetParams(memset, options);
end;

var memaddrdesc : AddressDescriptor;
var memstatus : PhysMemRetStatus;
var memory_set : integer;
var fault : boolean = FALSE;

if memset.implements_option_a then
    while memset.stagesetsize &lt; 0 &amp;&amp; !fault looplimit ArchMaxMOPSBlockSize do
        // IMP DEF selection of the block size that is worked on. While many
        // implementations might make this constant, that is not assumed.
        B = SETSizeChoice(memset, 1);
        assert B &lt;= -1 * memset.stagesetsize;

        (memory_set, memaddrdesc, memstatus) = MemSetBytes(memset.toaddress + memset.setsize,
                                                           data, B, accdesc);

        if memory_set != B then
            fault = TRUE;
        else
            memset.setsize      = memset.setsize      + B;
            memset.stagesetsize = memset.stagesetsize + B;
        end;
    end;

else
    while memset.stagesetsize &gt; 0 &amp;&amp; !fault looplimit ArchMaxMOPSBlockSize do
        // IMP DEF selection of the block size that is worked on. While many
        // implementations might make this constant, that is not assumed.
        B = SETSizeChoice(memset, 1);
        assert B &lt;= memset.stagesetsize;

        (memory_set, memaddrdesc, memstatus) = MemSetBytes(memset.toaddress, data, B, accdesc);

        if memory_set != B then
            fault = TRUE;
        else
            memset.toaddress    = memset.toaddress    + B;
            memset.setsize      = memset.setsize      - B;
            memset.stagesetsize = memset.stagesetsize - B;
        end;
    end;
end;

UpdateSetRegisters(memset, fault, memory_set);

if fault then
    if IsFault(memaddrdesc) then
        AArch64_Abort(memaddrdesc.fault);
    else
        let iswrite : boolean = TRUE;
        HandleExternalAbort(memstatus, iswrite, memaddrdesc, B, accdesc);
    end;
end;

if memset.stage == MOPSStage_Prologue then
    PSTATE.[N,Z,C,V] = memset.nzcv;
end;</pstext></ps>
  </ps_section>
  <timestamp>2026-03-12 12:23:09</timestamp>
  <commit_id>2025-09_rel_asl1</commit_id>
</instructionsection>
