Files
archived-ballistic/spec/arm64_xml/reta.xml
Ronald Caesar 26a677f8b4 decoder: Add ARM specification docs
Signed-off-by: Ronald Caesar <github43132@proton.me>
2025-12-12 18:11:36 -04:00

194 lines
13 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<?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-2022 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="RETA" title="RETAA, RETAB -- A64" type="instruction">
<docvars>
<docvar key="instr-class" value="general" />
<docvar key="isa" value="A64" />
</docvars>
<heading>RETAA, RETAB</heading>
<desc>
<brief>
<para>Return from subroutine, with pointer authentication</para>
</brief>
<authored>
<para>Return from subroutine, with pointer authentication. This instruction authenticates the address that is held in LR, using SP as the modifier and the specified key, branches to the authenticated address, with a hint that this instruction is a subroutine return.</para>
<para>Key A is used for <instruction>RETAA</instruction>. Key B is used for <instruction>RETAB</instruction>.</para>
<para>If the authentication passes, the PE continues execution at the target of the branch. For information on behavior if the authentication fails, see <xref>Faulting on pointer authentication</xref>.</para>
<para>The authenticated address is not written back to LR.</para>
</authored>
</desc>
<alias_list howmany="0"></alias_list>
<classes>
<iclass name="Integer" oneof="1" id="iclass_general" no_encodings="2" isa="A64">
<docvars>
<docvar key="instr-class" value="general" />
<docvar key="isa" value="A64" />
</docvars>
<iclassintro count="2"></iclassintro>
<arch_variants>
<arch_variant name="ARMv8.3" feature="FEAT_PAuth" />
</arch_variants>
<regdiagram form="32" psname="aarch64/instrs/branch/unconditional/register" tworows="1">
<box hibit="31" width="7" settings="7">
<c>1</c>
<c>1</c>
<c>0</c>
<c>1</c>
<c>0</c>
<c>1</c>
<c>1</c>
</box>
<box hibit="24" name="Z" usename="1" settings="1" psbits="x">
<c>0</c>
</box>
<box hibit="23" name="opc[2:1]" settings="1">
<c>0</c>
</box>
<box hibit="22" width="2" name="op" usename="1" settings="2" psbits="xx">
<c>1</c>
<c>0</c>
</box>
<box hibit="20" width="5" name="op2" settings="5">
<c>1</c>
<c>1</c>
<c>1</c>
<c>1</c>
<c>1</c>
</box>
<box hibit="15" width="4" name="op3[5:2]" settings="4">
<c>0</c>
<c>0</c>
<c>0</c>
<c>0</c>
</box>
<box hibit="11" name="A" usename="1" settings="1" psbits="x">
<c>1</c>
</box>
<box hibit="10" name="M" usename="1">
<c></c>
</box>
<box hibit="9" width="5" name="Rn" usename="1" settings="5" psbits="xxxxx">
<c>1</c>
<c>1</c>
<c>1</c>
<c>1</c>
<c>1</c>
</box>
<box hibit="4" width="5" name="Rm" usename="1" settings="5" psbits="xxxxx">
<c>1</c>
<c>1</c>
<c>1</c>
<c>1</c>
<c>1</c>
</box>
</regdiagram>
<encoding name="RETAA_64E_branch_reg" oneofinclass="2" oneof="2" label="RETAA" bitdiffs="M == 0">
<docvars>
<docvar key="instr-class" value="general" />
<docvar key="isa" value="A64" />
<docvar key="mnemonic" value="RETAA" />
</docvars>
<box hibit="10" width="1" name="M">
<c>0</c>
</box>
<asmtemplate><text>RETAA</text></asmtemplate>
</encoding>
<encoding name="RETAB_64E_branch_reg" oneofinclass="2" oneof="2" label="RETAB" bitdiffs="M == 1">
<docvars>
<docvar key="instr-class" value="general" />
<docvar key="isa" value="A64" />
<docvar key="mnemonic" value="RETAB" />
</docvars>
<box hibit="10" width="1" name="M">
<c>1</c>
</box>
<asmtemplate><text>RETAB</text></asmtemplate>
</encoding>
<ps_section howmany="1">
<ps name="aarch64/instrs/branch/unconditional/register" mylink="aarch64.instrs.branch.unconditional.register" enclabels="" sections="1" secttype="noheading">
<pstext mayhavelinks="1" section="Decode" rep_section="decode">integer n = <a link="impl-shared.UInt.1" file="shared_pseudocode.xml" hover="function: integer UInt(bits(N) x)">UInt</a>(Rn);
<a link="BranchType" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType</a> branch_type;
integer m = <a link="impl-shared.UInt.1" file="shared_pseudocode.xml" hover="function: integer UInt(bits(N) x)">UInt</a>(Rm);
boolean pac = (A == '1');
boolean use_key_a = (M == '0');
boolean source_is_sp = ((Z == '1') &amp;&amp; (m == 31));
if !pac &amp;&amp; m != 0 then
UNDEFINED;
elsif pac &amp;&amp; !<a link="impl-aarch64.HavePACExt.0" file="shared_pseudocode.xml" hover="function: boolean HavePACExt()">HavePACExt</a>() then
UNDEFINED;
case op of
when '00' branch_type = <a link="BranchType_INDIR" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType_INDIR</a>;
when '01' branch_type = <a link="BranchType_INDCALL" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType_INDCALL</a>;
when '10' branch_type = <a link="BranchType_RET" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType_RET</a>;
otherwise UNDEFINED;
if pac then
if Z == '0' &amp;&amp; m != 31 then
UNDEFINED;
if branch_type == <a link="BranchType_RET" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType_RET</a> then
if n != 31 then UNDEFINED;
n = 30;
source_is_sp = TRUE;</pstext>
</ps>
</ps_section>
</iclass>
</classes>
<explanations scope="all"></explanations>
<ps_section howmany="1">
<ps name="aarch64/instrs/branch/unconditional/register" mylink="execute" enclabels="" sections="1" secttype="Operation">
<pstext mayhavelinks="1" section="Execute" rep_section="execute"><a link="GCSInstruction" file="shared_pseudocode.xml" hover="enumeration GCSInstruction { GCSInstType_PRET, GCSInstType_POPM, GCSInstType_PRETAA, GCSInstType_PRETAB, GCSInstType_SS1, GCSInstType_SS2, GCSInstType_POPCX, GCSInstType_POPX }">GCSInstruction</a> inst_type;
bits(64) target = <a link="impl-aarch64.X.read.2" file="shared_pseudocode.xml" hover="accessor: bits(width) X[integer n, integer width]">X</a>[n, 64];
boolean auth_then_branch = TRUE;
if pac then
bits(64) modifier = if source_is_sp then <a link="impl-aarch64.SP.read.0" file="shared_pseudocode.xml" hover="accessor: bits(64) SP[]">SP</a>[] else <a link="impl-aarch64.X.read.2" file="shared_pseudocode.xml" hover="accessor: bits(width) X[integer n, integer width]">X</a>[m, 64];
if use_key_a then
target = <a link="impl-aarch64.AuthIA.3" file="shared_pseudocode.xml" hover="function: bits(64) AuthIA(bits(64) x, bits(64) y, boolean is_combined)">AuthIA</a>(target, modifier, auth_then_branch);
else
target = <a link="impl-aarch64.AuthIB.3" file="shared_pseudocode.xml" hover="function: bits(64) AuthIB(bits(64) x, bits(64) y, boolean is_combined)">AuthIB</a>(target, modifier, auth_then_branch);
if branch_type == <a link="BranchType_RET" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType_RET</a> &amp;&amp; <a link="impl-shared.HaveGCS.0" file="shared_pseudocode.xml" hover="function: boolean HaveGCS()">HaveGCS</a>() &amp;&amp; <a link="impl-aarch64.GCSPCREnabled.1" file="shared_pseudocode.xml" hover="function: boolean GCSPCREnabled(bits(2) el)">GCSPCREnabled</a>(PSTATE.EL) then
if !pac then
inst_type = <a link="GCSInstType_PRET" file="shared_pseudocode.xml" hover="enumeration GCSInstruction { GCSInstType_PRET, GCSInstType_POPM, GCSInstType_PRETAA, GCSInstType_PRETAB, GCSInstType_SS1, GCSInstType_SS2, GCSInstType_POPCX, GCSInstType_POPX }">GCSInstType_PRET</a>;
else
if use_key_a then
inst_type = <a link="GCSInstType_PRETAA" file="shared_pseudocode.xml" hover="enumeration GCSInstruction { GCSInstType_PRET, GCSInstType_POPM, GCSInstType_PRETAA, GCSInstType_PRETAB, GCSInstType_SS1, GCSInstType_SS2, GCSInstType_POPCX, GCSInstType_POPX }">GCSInstType_PRETAA</a>;
else
inst_type = <a link="GCSInstType_PRETAB" file="shared_pseudocode.xml" hover="enumeration GCSInstruction { GCSInstType_PRET, GCSInstType_POPM, GCSInstType_PRETAA, GCSInstType_PRETAB, GCSInstType_SS1, GCSInstType_SS2, GCSInstType_POPCX, GCSInstType_POPX }">GCSInstType_PRETAB</a>;
target = <a link="impl-aarch64.LoadCheckGCSRecord.2" file="shared_pseudocode.xml" hover="function: bits(64) LoadCheckGCSRecord(bits(64) vaddress, GCSInstruction gcsinst_type)">LoadCheckGCSRecord</a>(target, inst_type);
<a link="impl-aarch64.SetCurrentGCSPointer.1" file="shared_pseudocode.xml" hover="function: SetCurrentGCSPointer(bits(64) ptr)">SetCurrentGCSPointer</a>(<a link="impl-aarch64.GetCurrentGCSPointer.0" file="shared_pseudocode.xml" hover="function: bits(64) GetCurrentGCSPointer()">GetCurrentGCSPointer</a>() + 8);
if branch_type == <a link="BranchType_INDCALL" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType_INDCALL</a> then
if <a link="impl-shared.HaveGCS.0" file="shared_pseudocode.xml" hover="function: boolean HaveGCS()">HaveGCS</a>() &amp;&amp; <a link="impl-aarch64.GCSPCREnabled.1" file="shared_pseudocode.xml" hover="function: boolean GCSPCREnabled(bits(2) el)">GCSPCREnabled</a>(PSTATE.EL) then
<a link="impl-aarch64.AddGCSRecord.1" file="shared_pseudocode.xml" hover="function: AddGCSRecord(bits(64) vaddress)">AddGCSRecord</a>(<a link="impl-aarch64.PC.read.0" file="shared_pseudocode.xml" hover="accessor: bits(64) PC[]">PC</a>[] + 4);
<a link="impl-aarch64.X.write.2" file="shared_pseudocode.xml" hover="accessor: X[integer n, integer width] = bits(width) value">X</a>[30, 64] = <a link="impl-aarch64.PC.read.0" file="shared_pseudocode.xml" hover="accessor: bits(64) PC[]">PC</a>[] + 4;
// Value in BTypeNext will be used to set PSTATE.BTYPE
case branch_type of
when <a link="BranchType_INDIR" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType_INDIR</a> // BR, BRAA, BRAB, BRAAZ, BRABZ
if InGuardedPage then
if n == 16 || n == 17 then
BTypeNext = '01';
else
BTypeNext = '11';
else
BTypeNext = '01';
when <a link="BranchType_INDCALL" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType_INDCALL</a> // BLR, BLRAA, BLRAB, BLRAAZ, BLRABZ
BTypeNext = '10';
when <a link="BranchType_RET" file="shared_pseudocode.xml" hover="enumeration BranchType { BranchType_DIRCALL, BranchType_INDCALL, BranchType_ERET, BranchType_DBGEXIT, BranchType_RET, BranchType_DIR, BranchType_INDIR, BranchType_EXCEPTION, BranchType_TMFAIL, BranchType_RESET, BranchType_UNKNOWN}">BranchType_RET</a> // RET, RETAA, RETAB
BTypeNext = '00';
boolean branch_conditional = FALSE;
<a link="impl-shared.BranchTo.3" file="shared_pseudocode.xml" hover="function: BranchTo(bits(N) target, BranchType branch_type, boolean branch_conditional)">BranchTo</a>(target, branch_type, branch_conditional);</pstext>
</ps>
</ps_section>
</instructionsection>