<?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="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 "Decrement After", "Decrement Before", "Increment After", and "Increment Before" 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 "T1" and "T2" 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 "W" 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 "mode" 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 "Increment After" 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 "T2" 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 CurrentInstrSet() == InstrSet_A32 then
    if ConditionPassed() then
        EncodingSpecificOperations();
        if PSTATE.EL == EL2 then          // UNDEFINED at EL2
            Undefined();
        end;

        // Check for UNPREDICTABLE cases. The definition of UNPREDICTABLE does not permit these
        // to be security holes
        if PSTATE.M IN {M32_User,M32_System} then
            UnpredictableProcedure();
        elsif mode == M32_Hyp then        // Check for attempt to access Hyp mode SP
            UnpredictableProcedure();
        elsif mode == M32_Monitor then    // Check for attempt to access Monitor mode SP
            if !HaveEL(EL3) || CurrentSecurityState() != SS_Secure then
                UnpredictableProcedure();
            elsif !ELUsingAArch32(EL3) then
                AArch64_MonitorModeTrap();
            end;
        elsif BadMode(mode) then
            UnpredictableProcedure();
        end;

        let base : bits(32) = Rmode(13,mode);
        var address : bits(32) = if increment then base else base-8;
        if wordhigher then address = address+4; end;
        MemA{32}(address)   = LR();
        MemA{32}(address+4) = SPSR_curr();
        if wback then Rmode(13,mode) = if increment then base+8 else base-8; end;
    end;
else
    if ConditionPassed() then
        EncodingSpecificOperations();
        if PSTATE.EL == EL2 then          // UNDEFINED at EL2
            Undefined();
        end;

        // Check for UNPREDICTABLE cases. The definition of UNPREDICTABLE does not permit these
        // to be security holes
        if PSTATE.M IN {M32_User,M32_System} then
            UnpredictableProcedure();
        elsif mode == M32_Hyp then        // Check for attempt to access Hyp mode SP
            UnpredictableProcedure();
        elsif mode == M32_Monitor then    // Check for attempt to access Monitor mode SP
            if !HaveEL(EL3) || CurrentSecurityState() != SS_Secure then
                UnpredictableProcedure();
            elsif !ELUsingAArch32(EL3) then
                AArch64_MonitorModeTrap();
            end;
        elsif BadMode(mode) then
            UnpredictableProcedure();
        end;

        let base : bits(32) = Rmode(13,mode);
        var address : bits(32) = if increment then base else base-8;
        if wordhigher then address = address+4; end;
        MemA{32}(address)   = LR();
        MemA{32}(address+4) = SPSR_curr();
        if wback then Rmode(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-12 12:23:09</timestamp>
  <commit_id>2025-09_rel_asl1</commit_id>
</instructionsection>
