<?xml version="1.0" ?><?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-2026 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="SRS" title="SRS, SRSDA, SRSDB, SRSIA, SRSIB -- AArch32" type="instruction">
  <docvars>
    <docvar key="instr-class" value="general"/>
  </docvars>
  <heading>SRS, SRSDA, SRSDB, SRSIA, SRSIB</heading>
  <desc>
    <brief>
      <para>Store Return State</para>
    </brief>
    <authored>
      <para>Store Return State stores the LR_&lt;current_mode&gt; and
<xref linkend="ARMARM_CHDDAABB">SPSR</xref>_&lt;current_mode&gt; to the stack of a
specified mode. For information about memory accesses see
<xref linkend="ARMARM_Chddjfjf">Memory accesses</xref>.</para>
      <para><instruction>SRS</instruction> is <arm-defined-word>UNDEFINED</arm-defined-word> in Hyp mode.</para>
      <para><instruction>SRS</instruction> is <arm-defined-word>CONSTRAINED UNPREDICTABLE</arm-defined-word> if it is executed in User or
System mode, or if the specified mode is any of the following:</para>
      <list type="unordered">
        <listitem>
          <content>Not implemented.</content>
        </listitem>
        <listitem>
          <content>A mode that <xref linkend="ARMARM_tbl:CIHGHDGI">AArch32 PE modes</xref> does not show.</content>
        </listitem>
        <listitem>
          <content>Hyp mode.</content>
        </listitem>
        <listitem>
          <content>Monitor mode, if the <instruction>SRS</instruction> instruction is executed in Non-secure state.</content>
        </listitem>
      </list>
      <para>If EL3 is using AArch64 and an <instruction>SRS</instruction> instruction that is executed in a Secure EL1 mode specifies Monitor mode, it is trapped to EL3.</para>
    </authored>
    <encodingnotes>
      <para>For more information about the <arm-defined-word>CONSTRAINED UNPREDICTABLE</arm-defined-word> behavior of this instruction, see <xref linkend="ARMARM_CJAEGDJC">Architectural Constraints on UNPREDICTABLE behaviors</xref>, and particularly <xref linkend="ARMARM_CEGDFDHJ">SRS (T32)</xref> and <xref linkend="ARMARM_CEGJIFIF">SRS (A32)</xref>.</para>
    </encodingnotes>
    <syntaxnotes>
      <para><instruction>SRSFA</instruction>, <instruction>SRSEA</instruction>, <instruction>SRSFD</instruction>, and <instruction>SRSED</instruction> are pseudo-instructions for <instruction>SRSIB</instruction>, <instruction>SRSIA</instruction>, <instruction>SRSDB</instruction>, and <instruction>SRSDA</instruction> respectively, referring to their use for pushing data onto Full Ascending, Empty Ascending, Full Descending, and Empty Descending stacks.</para>
    </syntaxnotes>
  </desc>
  <alias_list howmany="0"/>
  <classes>
    <classesintro count="3">
      <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> and </txt>
      <a href="#iclass_t2">T2</a>
      <txt>)</txt>
      <txt>.</txt>
    </classesintro>
    <iclass name="A1" oneof="3" id="iclass_a1" no_encodings="4" isa="A32">
      <docvars>
        <docvar key="armarmheading" value="A1"/>
        <docvar key="instr-class" value="general"/>
        <docvar key="isa" value="A32"/>
      </docvars>
      <iclassintro count="4"/>
      <regdiagram form="32" psname="A32.brblk.ldstexcept.SRSDA_A1_AS" tworows="1">
        <box hibit="31" width="7" settings="7">
          <c>1</c>
          <c>1</c>
          <c>1</c>
          <c>1</c>
          <c>1</c>
          <c>0</c>
          <c>0</c>
        </box>
        <box hibit="24" width="1" name="P" usename="1">
          <c colspan="1"/>
        </box>
        <box hibit="23" width="1" name="U" usename="1">
          <c colspan="1"/>
        </box>
        <box hibit="22" name="S" usename="1" settings="1" psbits="x">
          <c>1</c>
        </box>
        <box hibit="21" width="1" name="W" usename="1">
          <c colspan="1"/>
        </box>
        <box hibit="20" name="L" usename="1" settings="1" psbits="x">
          <c>0</c>
        </box>
        <box hibit="19" width="4" name="Rn" usename="1" settings="4" psbits="xxxx">
          <c>(1)</c>
          <c>(1)</c>
          <c>(0)</c>
          <c>(1)</c>
        </box>
        <box hibit="15" width="11" name="op" usename="1" settings="11" psbits="xxxxxxxxxxx">
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(1)</c>
          <c>(0)</c>
          <c>(1)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
        </box>
        <box hibit="4" width="5" name="mode" usename="1">
          <c colspan="5"/>
        </box>
      </regdiagram>
      <encoding name="SRSDA_A1_AS" oneofinclass="4" oneof="6" label="Decrement After" bitdiffs="P == 0 &amp;&amp; U == 0">
        <docvars>
          <docvar key="armarmheading" value="A1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A32"/>
          <docvar key="ldmstm-mode" value="dec-after"/>
          <docvar key="mnemonic" value="SRSDA"/>
        </docvars>
        <box hibit="24" width="1" name="P">
          <c>0</c>
        </box>
        <box hibit="23" width="1" name="U">
          <c>0</c>
        </box>
        <asmtemplate><text>SRSDA{</text><a hover="For the &quot;Decrement After&quot;, &quot;Decrement Before&quot;, &quot;Increment After&quot;, and &quot;Increment Before&quot; variants: see x[Standard assembler syntax fields](Babbefhf). &lt;c&gt; must be AL or omitted." link="AL_option">&lt;c&gt;</a><text>}{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="qw_option">&lt;q&gt;</a><text>}  SP{</text><a hover="The address adjusted by the size of the data loaded is written back to the base register. If specified, it is encoded in the &quot;W&quot; field as 1, otherwise this field defaults to 0." link="bang_choice">!</a><text>}, #</text><a hover="Is the number of the mode whose Banked SP is used as the base register, encoded in the &quot;mode&quot; field. For details of PE modes and their numbers see x[AArch32 state PE modes](CIHBGJDI)." link="mode">&lt;mode&gt;</a></asmtemplate>
      </encoding>
      <encoding name="SRSDB_A1_AS" oneofinclass="4" oneof="6" label="Decrement Before" bitdiffs="P == 1 &amp;&amp; U == 0">
        <docvars>
          <docvar key="armarmheading" value="A1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A32"/>
          <docvar key="ldmstm-mode" value="dec-before"/>
          <docvar key="mnemonic" value="SRSDB"/>
        </docvars>
        <box hibit="24" width="1" name="P">
          <c>1</c>
        </box>
        <box hibit="23" width="1" name="U">
          <c>0</c>
        </box>
        <asmtemplate><text>SRSDB{</text><a hover="For the &quot;Decrement After&quot;, &quot;Decrement Before&quot;, &quot;Increment After&quot;, and &quot;Increment Before&quot; variants: see x[Standard assembler syntax fields](Babbefhf). &lt;c&gt; must be AL or omitted." link="AL_option">&lt;c&gt;</a><text>}{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="qw_option">&lt;q&gt;</a><text>}  SP{</text><a hover="The address adjusted by the size of the data loaded is written back to the base register. If specified, it is encoded in the &quot;W&quot; field as 1, otherwise this field defaults to 0." link="bang_choice">!</a><text>}, #</text><a hover="Is the number of the mode whose Banked SP is used as the base register, encoded in the &quot;mode&quot; field. For details of PE modes and their numbers see x[AArch32 state PE modes](CIHBGJDI)." link="mode">&lt;mode&gt;</a></asmtemplate>
      </encoding>
      <encoding name="SRSIA_A1_AS" oneofinclass="4" oneof="6" label="Increment After" bitdiffs="P == 0 &amp;&amp; U == 1">
        <docvars>
          <docvar key="armarmheading" value="A1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A32"/>
          <docvar key="ldmstm-mode" value="inc-after"/>
          <docvar key="mnemonic" value="SRS{IA}"/>
        </docvars>
        <box hibit="24" width="1" name="P">
          <c>0</c>
        </box>
        <box hibit="23" width="1" name="U">
          <c>1</c>
        </box>
        <asmtemplate><text>SRS{</text><a hover="For the &quot;Increment After&quot; variant: is an optional suffix to indicate the Increment After variant." link="IA">IA</a><text>}{</text><a hover="For the &quot;Decrement After&quot;, &quot;Decrement Before&quot;, &quot;Increment After&quot;, and &quot;Increment Before&quot; variants: see x[Standard assembler syntax fields](Babbefhf). &lt;c&gt; must be AL or omitted." link="AL_option">&lt;c&gt;</a><text>}{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="qw_option">&lt;q&gt;</a><text>}  SP{</text><a hover="The address adjusted by the size of the data loaded is written back to the base register. If specified, it is encoded in the &quot;W&quot; field as 1, otherwise this field defaults to 0." link="bang_choice">!</a><text>}, #</text><a hover="Is the number of the mode whose Banked SP is used as the base register, encoded in the &quot;mode&quot; field. For details of PE modes and their numbers see x[AArch32 state PE modes](CIHBGJDI)." link="mode">&lt;mode&gt;</a></asmtemplate>
      </encoding>
      <encoding name="SRSIB_A1_AS" oneofinclass="4" oneof="6" label="Increment Before" bitdiffs="P == 1 &amp;&amp; U == 1">
        <docvars>
          <docvar key="armarmheading" value="A1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="A32"/>
          <docvar key="ldmstm-mode" value="inc-before"/>
          <docvar key="mnemonic" value="SRSIB"/>
        </docvars>
        <box hibit="24" width="1" name="P">
          <c>1</c>
        </box>
        <box hibit="23" width="1" name="U">
          <c>1</c>
        </box>
        <asmtemplate><text>SRSIB{</text><a hover="For the &quot;Decrement After&quot;, &quot;Decrement Before&quot;, &quot;Increment After&quot;, and &quot;Increment Before&quot; variants: see x[Standard assembler syntax fields](Babbefhf). &lt;c&gt; must be AL or omitted." link="AL_option">&lt;c&gt;</a><text>}{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="qw_option">&lt;q&gt;</a><text>}  SP{</text><a hover="The address adjusted by the size of the data loaded is written back to the base register. If specified, it is encoded in the &quot;W&quot; field as 1, otherwise this field defaults to 0." link="bang_choice">!</a><text>}, #</text><a hover="Is the number of the mode whose Banked SP is used as the base register, encoded in the &quot;mode&quot; field. For details of PE modes and their numbers see x[AArch32 state PE modes](CIHBGJDI)." link="mode">&lt;mode&gt;</a></asmtemplate>
      </encoding>
      <ps_section howmany="1">
        <ps name="A32.brblk.ldstexcept.SRSDA_A1_AS" sections="1" secttype="noheading">
          <pstext mayhavelinks="1" section="Decode" rep_section="decode">let wback : boolean = (W == '1');
let increment : boolean = (U == '1');
let wordhigher : boolean = (P == U);</pstext></ps>
      </ps_section>
    </iclass>
    <iclass name="T1" oneof="3" id="iclass_t1" no_encodings="1" isa="T32">
      <docvars>
        <docvar key="armarmheading" value="T1"/>
        <docvar key="instr-class" value="general"/>
        <docvar key="isa" value="T32"/>
        <docvar key="ldmstm-mode" value="dec-before"/>
        <docvar key="mnemonic" value="SRSDB"/>
      </docvars>
      <iclassintro count="1"/>
      <regdiagram form="16x2" psname="T32.w.ldstm.SRS_T1_AS" tworows="1">
        <box hibit="31" width="3" settings="3">
          <c>1</c>
          <c>1</c>
          <c>1</c>
        </box>
        <box hibit="28" width="4" settings="4">
          <c>0</c>
          <c>1</c>
          <c>0</c>
          <c>0</c>
        </box>
        <box hibit="24" width="2" name="opc" usename="1" settings="2" psbits="xx">
          <c>0</c>
          <c>0</c>
        </box>
        <box hibit="22" width="1" settings="1">
          <c>0</c>
        </box>
        <box hibit="21" width="1" name="W" usename="1">
          <c colspan="1"/>
        </box>
        <box hibit="20" name="L" usename="1" settings="1" psbits="x">
          <c>0</c>
        </box>
        <box hibit="19" width="4" name="Rn" usename="1" settings="4" psbits="xxxx">
          <c>(1)</c>
          <c>(1)</c>
          <c>(0)</c>
          <c>(1)</c>
        </box>
        <box hibit="15" name="P" usename="1" settings="1" psbits="x">
          <c>(1)</c>
        </box>
        <box hibit="14" name="M" usename="1" settings="1" psbits="x">
          <c>(1)</c>
        </box>
        <box hibit="13" width="9" settings="9">
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
        </box>
        <box hibit="4" width="5" name="mode" usename="1">
          <c colspan="5"/>
        </box>
      </regdiagram>
      <encoding name="SRS_T1_AS" oneofinclass="1" oneof="6" label="">
        <docvars>
          <docvar key="armarmheading" value="T1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="T32"/>
          <docvar key="ldmstm-mode" value="dec-before"/>
          <docvar key="mnemonic" value="SRSDB"/>
        </docvars>
        <asmtemplate><text>SRSDB{</text><a hover="For the &quot;T1&quot; and &quot;T2&quot; variants: see x[Standard assembler syntax fields](Babbefhf)." link="AL_option__6">&lt;c&gt;</a><text>}{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="qw_option">&lt;q&gt;</a><text>}  SP{</text><a hover="The address adjusted by the size of the data loaded is written back to the base register. If specified, it is encoded in the &quot;W&quot; field as 1, otherwise this field defaults to 0." link="bang_choice">!</a><text>}, #</text><a hover="Is the number of the mode whose Banked SP is used as the base register, encoded in the &quot;mode&quot; field. For details of PE modes and their numbers see x[AArch32 state PE modes](CIHBGJDI)." link="mode">&lt;mode&gt;</a></asmtemplate>
      </encoding>
      <ps_section howmany="1">
        <ps name="T32.w.ldstm.SRS_T1_AS" sections="1" secttype="noheading">
          <pstext mayhavelinks="1" section="Decode" rep_section="decode">let wback : boolean = (W == '1');
let increment : boolean = FALSE;
let wordhigher : boolean = FALSE;</pstext></ps>
      </ps_section>
    </iclass>
    <iclass name="T2" oneof="3" id="iclass_t2" no_encodings="1" isa="T32">
      <docvars>
        <docvar key="armarmheading" value="T2"/>
        <docvar key="instr-class" value="general"/>
        <docvar key="isa" value="T32"/>
        <docvar key="ldmstm-mode" value="inc-after"/>
        <docvar key="mnemonic" value="SRS{IA}"/>
      </docvars>
      <iclassintro count="1"/>
      <regdiagram form="16x2" psname="T32.w.ldstm.SRS_T2_AS" tworows="1">
        <box hibit="31" width="3" settings="3">
          <c>1</c>
          <c>1</c>
          <c>1</c>
        </box>
        <box hibit="28" width="4" settings="4">
          <c>0</c>
          <c>1</c>
          <c>0</c>
          <c>0</c>
        </box>
        <box hibit="24" width="2" name="opc" usename="1" settings="2" psbits="xx">
          <c>1</c>
          <c>1</c>
        </box>
        <box hibit="22" width="1" settings="1">
          <c>0</c>
        </box>
        <box hibit="21" width="1" name="W" usename="1">
          <c colspan="1"/>
        </box>
        <box hibit="20" name="L" usename="1" settings="1" psbits="x">
          <c>0</c>
        </box>
        <box hibit="19" width="4" name="Rn" usename="1" settings="4" psbits="xxxx">
          <c>(1)</c>
          <c>(1)</c>
          <c>(0)</c>
          <c>(1)</c>
        </box>
        <box hibit="15" name="P" usename="1" settings="1" psbits="x">
          <c>(1)</c>
        </box>
        <box hibit="14" name="M" usename="1" settings="1" psbits="x">
          <c>(1)</c>
        </box>
        <box hibit="13" width="9" settings="9">
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
          <c>(0)</c>
        </box>
        <box hibit="4" width="5" name="mode" usename="1">
          <c colspan="5"/>
        </box>
      </regdiagram>
      <encoding name="SRS_T2_AS" oneofinclass="1" oneof="6" label="">
        <docvars>
          <docvar key="armarmheading" value="T2"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="T32"/>
          <docvar key="ldmstm-mode" value="inc-after"/>
          <docvar key="mnemonic" value="SRS{IA}"/>
        </docvars>
        <asmtemplate><text>SRS{</text><a hover="For the &quot;T2&quot; variant: is an optional suffix for the Increment After form." link="IA__4">IA</a><text>}{</text><a hover="For the &quot;T1&quot; and &quot;T2&quot; variants: see x[Standard assembler syntax fields](Babbefhf)." link="AL_option__6">&lt;c&gt;</a><text>}{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="qw_option">&lt;q&gt;</a><text>}  SP{</text><a hover="The address adjusted by the size of the data loaded is written back to the base register. If specified, it is encoded in the &quot;W&quot; field as 1, otherwise this field defaults to 0." link="bang_choice">!</a><text>}, #</text><a hover="Is the number of the mode whose Banked SP is used as the base register, encoded in the &quot;mode&quot; field. For details of PE modes and their numbers see x[AArch32 state PE modes](CIHBGJDI)." link="mode">&lt;mode&gt;</a></asmtemplate>
      </encoding>
      <ps_section howmany="1">
        <ps name="T32.w.ldstm.SRS_T2_AS" sections="1" secttype="noheading">
          <pstext mayhavelinks="1" section="Decode" rep_section="decode">let wback : boolean = (W == '1');
let increment : boolean = TRUE;
let wordhigher : boolean = FALSE;</pstext></ps>
      </ps_section>
    </iclass>
  </classes>
  <explanations scope="all">
    <explanation enclist="SRSDA_A1_AS, SRSDB_A1_AS, SRSIA_A1_AS, SRSIB_A1_AS" symboldefcount="1">
      <symbol link="AL_option">&lt;c&gt;</symbol>
      <account encodedin="">
        <intro>
          <para>For the &quot;Decrement After&quot;, &quot;Decrement Before&quot;, &quot;Increment After&quot;, and &quot;Increment Before&quot; variants: see <xref linkend="Babbefhf">Standard assembler syntax fields</xref>. <syntax>&lt;c&gt;</syntax> must be <value>AL</value> or omitted.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SRS_T1_AS, SRS_T2_AS" symboldefcount="2">
      <symbol link="AL_option__6">&lt;c&gt;</symbol>
      <account encodedin="">
        <intro>
          <para>For the &quot;T1&quot; and &quot;T2&quot; variants: see <xref linkend="Babbefhf">Standard assembler syntax fields</xref>.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SRSDA_A1_AS, SRSDB_A1_AS, SRSIA_A1_AS, SRSIB_A1_AS, SRS_T1_AS, SRS_T2_AS" symboldefcount="1">
      <symbol link="qw_option">&lt;q&gt;</symbol>
      <account encodedin="">
        <intro>
          <para>See <xref linkend="Babbefhf">Standard assembler syntax fields</xref>.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SRSDA_A1_AS, SRSDB_A1_AS, SRSIA_A1_AS, SRSIB_A1_AS, SRS_T1_AS, SRS_T2_AS" symboldefcount="1">
      <symbol link="bang_choice">!</symbol>
      <account encodedin="W">
        <intro>
          <para>The address adjusted by the size of the data loaded is written back to the base register. If specified, it is encoded in the &quot;W&quot; field as 1, otherwise this field defaults to 0.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SRSDA_A1_AS, SRSDB_A1_AS, SRSIA_A1_AS, SRSIB_A1_AS, SRS_T1_AS, SRS_T2_AS" symboldefcount="1">
      <symbol link="mode">&lt;mode&gt;</symbol>
      <account encodedin="mode">
        <intro>
          <para>Is the number of the mode whose Banked SP is used as the base register, encoded in the &quot;mode&quot; field. For details of PE modes and their numbers see <xref linkend="CIHBGJDI">AArch32 state PE modes</xref>.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SRSIA_A1_AS" symboldefcount="1">
      <symbol link="IA">IA</symbol>
      <account encodedin="">
        <intro>
          <para>For the &quot;Increment After&quot; variant: is an optional suffix to indicate the Increment After variant.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="SRS_T2_AS" symboldefcount="2">
      <symbol link="IA__4">IA</symbol>
      <account encodedin="">
        <intro>
          <para>For the &quot;T2&quot; variant: is an optional suffix for the Increment After form.</para>
        </intro>
      </account>
    </explanation>
  </explanations>
  <ps_section howmany="1">
    <ps name="A32.brblk.ldstexcept.SRSDA_A1_AS" sections="1" secttype="Operation">
      <pstext mayhavelinks="1" section="Execute" rep_section="execute">if <a link="func_CurrentInstrSet_0" file="shared_pseudocode.xml">CurrentInstrSet</a>() == <a link="enum_InstrSet_A32" file="shared_pseudocode.xml">InstrSet_A32</a> then
    if <a link="func_ConditionPassed_0" file="shared_pseudocode.xml">ConditionPassed</a>() then
        EncodingSpecificOperations();
        if <a link="global_PSTATE" file="shared_pseudocode.xml">PSTATE</a>.EL == <a link="global_EL2" file="shared_pseudocode.xml">EL2</a> then          // UNDEFINED at EL2
            Undefined();
        end;

        // Check for UNPREDICTABLE cases. The definition of UNPREDICTABLE does not permit these
        // to be security holes
        if <a link="global_PSTATE" file="shared_pseudocode.xml">PSTATE</a>.M IN {<a link="global_M32_User" file="shared_pseudocode.xml">M32_User</a>,<a link="global_M32_System" file="shared_pseudocode.xml">M32_System</a>} then
            UnpredictableProcedure();
        elsif mode == <a link="global_M32_Hyp" file="shared_pseudocode.xml">M32_Hyp</a> then        // Check for attempt to access Hyp mode SP
            UnpredictableProcedure();
        elsif mode == <a link="global_M32_Monitor" file="shared_pseudocode.xml">M32_Monitor</a> then    // Check for attempt to access Monitor mode SP
            if !<a link="func_HaveEL_1" file="shared_pseudocode.xml">HaveEL</a>(<a link="global_EL3" file="shared_pseudocode.xml">EL3</a>) || <a link="func_CurrentSecurityState_0" file="shared_pseudocode.xml">CurrentSecurityState</a>() != <a link="enum_SS_Secure" file="shared_pseudocode.xml">SS_Secure</a> then
                UnpredictableProcedure();
            elsif !<a link="func_ELUsingAArch32_1" file="shared_pseudocode.xml">ELUsingAArch32</a>(<a link="global_EL3" file="shared_pseudocode.xml">EL3</a>) then
                <a link="func_AArch64_MonitorModeTrap_0" file="shared_pseudocode.xml">AArch64_MonitorModeTrap</a>();
            end;
        elsif <a link="func_BadMode_1" file="shared_pseudocode.xml">BadMode</a>(mode) then
            UnpredictableProcedure();
        end;

        let base : bits(32) = <a link="accessor_Rmode_2" file="shared_pseudocode.xml">Rmode</a>(13,mode);
        var address : bits(32) = if increment then base else base-8;
        if wordhigher then address = address+4; end;
        <a link="accessor_MemA_2" file="shared_pseudocode.xml">MemA</a>{32}(address)   = <a link="accessor_LR_0" file="shared_pseudocode.xml">LR</a>();
        <a link="accessor_MemA_2" file="shared_pseudocode.xml">MemA</a>{32}(address+4) = <a link="accessor_SPSR_curr_0" file="shared_pseudocode.xml">SPSR_curr</a>();
        if wback then <a link="accessor_Rmode_2" file="shared_pseudocode.xml">Rmode</a>(13,mode) = if increment then base+8 else base-8; end;
    end;
else
    if <a link="func_ConditionPassed_0" file="shared_pseudocode.xml">ConditionPassed</a>() then
        EncodingSpecificOperations();
        if <a link="global_PSTATE" file="shared_pseudocode.xml">PSTATE</a>.EL == <a link="global_EL2" file="shared_pseudocode.xml">EL2</a> then          // UNDEFINED at EL2
            Undefined();
        end;

        // Check for UNPREDICTABLE cases. The definition of UNPREDICTABLE does not permit these
        // to be security holes
        if <a link="global_PSTATE" file="shared_pseudocode.xml">PSTATE</a>.M IN {<a link="global_M32_User" file="shared_pseudocode.xml">M32_User</a>,<a link="global_M32_System" file="shared_pseudocode.xml">M32_System</a>} then
            UnpredictableProcedure();
        elsif mode == <a link="global_M32_Hyp" file="shared_pseudocode.xml">M32_Hyp</a> then        // Check for attempt to access Hyp mode SP
            UnpredictableProcedure();
        elsif mode == <a link="global_M32_Monitor" file="shared_pseudocode.xml">M32_Monitor</a> then    // Check for attempt to access Monitor mode SP
            if !<a link="func_HaveEL_1" file="shared_pseudocode.xml">HaveEL</a>(<a link="global_EL3" file="shared_pseudocode.xml">EL3</a>) || <a link="func_CurrentSecurityState_0" file="shared_pseudocode.xml">CurrentSecurityState</a>() != <a link="enum_SS_Secure" file="shared_pseudocode.xml">SS_Secure</a> then
                UnpredictableProcedure();
            elsif !<a link="func_ELUsingAArch32_1" file="shared_pseudocode.xml">ELUsingAArch32</a>(<a link="global_EL3" file="shared_pseudocode.xml">EL3</a>) then
                <a link="func_AArch64_MonitorModeTrap_0" file="shared_pseudocode.xml">AArch64_MonitorModeTrap</a>();
            end;
        elsif <a link="func_BadMode_1" file="shared_pseudocode.xml">BadMode</a>(mode) then
            UnpredictableProcedure();
        end;

        let base : bits(32) = <a link="accessor_Rmode_2" file="shared_pseudocode.xml">Rmode</a>(13,mode);
        var address : bits(32) = if increment then base else base-8;
        if wordhigher then address = address+4; end;
        <a link="accessor_MemA_2" file="shared_pseudocode.xml">MemA</a>{32}(address)   = <a link="accessor_LR_0" file="shared_pseudocode.xml">LR</a>();
        <a link="accessor_MemA_2" file="shared_pseudocode.xml">MemA</a>{32}(address+4) = <a link="accessor_SPSR_curr_0" file="shared_pseudocode.xml">SPSR_curr</a>();
        if wback then <a link="accessor_Rmode_2" file="shared_pseudocode.xml">Rmode</a>(13,mode) = if increment then base+8 else base-8; end;
    end;
end;</pstext></ps>
  </ps_section>
  <constrained_unpredictables ps_block="Operation">
    <cu_case>
      <cu_cause>
        <pstext mayhavelinks="1">PSTATE.M IN {M32_User,M32_System}</pstext></cu_cause>
      <cu_type constraint="Constraint_UNDEF"/>
      <cu_type constraint="Constraint_NOP"/>
    </cu_case>
    <cu_case>
      <cu_cause>
        <pstext mayhavelinks="1">mode == M32_Hyp</pstext></cu_cause>
      <cu_type constraint="Constraint_UNDEF"/>
      <cu_type constraint="Constraint_NOP"/>
    </cu_case>
    <cu_case>
      <cu_cause>
        <pstext mayhavelinks="1">mode == M32_Monitor &amp;&amp; (!HaveEL(EL3) || CurrentSecurityState() != SS_Secure)</pstext></cu_cause>
      <cu_type constraint="Constraint_UNDEF"/>
      <cu_type constraint="Constraint_NOP"/>
    </cu_case>
    <cu_case>
      <cu_cause>
        <pstext mayhavelinks="1">BadMode(mode)</pstext></cu_cause>
      <cu_type constraint="Constraint_UNDEF"/>
      <cu_type constraint="Constraint_NOP"/>
      <cu_type>
        <cu_type_text>The instruction stores to the stack of the mode in which it is executed.</cu_type_text>
      </cu_type>
      <cu_type>
        <cu_type_text>The instruction stores to an UNKNOWN address, and if the instruction specifies writeback then any general-purpose register that can be accessed from the current Exception level without a privilege violation becomes UNKNOWN.</cu_type_text>
      </cu_type>
    </cu_case>
  </constrained_unpredictables>
  <timestamp>2026-03-26 20:27:25</timestamp>
  <commit_id>2026-03_rel</commit_id>
</instructionsection>