<?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="TBB" title="TBB, TBH -- AArch32" type="instruction">
  <docvars>
    <docvar key="armarmheading" value="T1"/>
    <docvar key="instr-class" value="general"/>
    <docvar key="isa" value="T32"/>
  </docvars>
  <heading>TBB, TBH</heading>
  <desc>
    <brief>
      <para>Table Branch Byte or Halfword</para>
    </brief>
    <authored>
      <para>Table Branch Byte or Halfword causes a PC-relative forward branch
using a table of single byte or halfword offsets. A base register
provides a pointer to the table, and a second register supplies an
index into the table. The branch length is twice the value returned
from the table.</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>.</para>
    </encodingnotes>
  </desc>
  <alias_list howmany="0"/>
  <classes>
    <iclass name="T1" oneof="1" id="iclass_t1" no_encodings="2" isa="T32">
      <docvars>
        <docvar key="armarmheading" value="T1"/>
        <docvar key="instr-class" value="general"/>
        <docvar key="isa" value="T32"/>
      </docvars>
      <iclassintro count="2"/>
      <regdiagram form="16x2" psname="T32.w.dstd.tblbr.TBB_T1" tworows="1">
        <box hibit="31" width="7" settings="7">
          <c>1</c>
          <c>1</c>
          <c>1</c>
          <c>0</c>
          <c>1</c>
          <c>0</c>
          <c>0</c>
        </box>
        <box hibit="24" width="4" name="op0" usename="1" settings="4" psbits="xxxx">
          <c>0</c>
          <c>1</c>
          <c>1</c>
          <c>0</c>
        </box>
        <box hibit="20" width="1" settings="1">
          <c>1</c>
        </box>
        <box hibit="19" width="4" name="Rn" usename="1">
          <c colspan="4"/>
        </box>
        <box hibit="15" width="11" settings="11">
          <c>(1)</c>
          <c>(1)</c>
          <c>(1)</c>
          <c>(1)</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="1" name="H" usename="1">
          <c colspan="1"/>
        </box>
        <box hibit="3" width="4" name="Rm" usename="1">
          <c colspan="4"/>
        </box>
      </regdiagram>
      <encoding name="TBB_T1" oneofinclass="2" oneof="2" label="Byte" bitdiffs="H == 0">
        <docvars>
          <docvar key="armarmheading" value="T1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="T32"/>
          <docvar key="loadstore-size" value="ls-byte"/>
          <docvar key="mnemonic" value="TBB"/>
        </docvars>
        <box hibit="4" width="1" name="H">
          <c>0</c>
        </box>
        <asmtemplate comment="Outside or last in IT block"><text>TBB{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="AL_option__4">&lt;c&gt;</a><text>}{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="qn_option">&lt;q&gt;</a><text>}  [</text><a hover="Is the general-purpose base register holding the address of the table of branch lengths, encoded in the &quot;Rn&quot; field. The PC can be used. If it is, the table immediately follows this instruction." link="Rn__41">&lt;Rn&gt;</a><text>, </text><a hover="For the &quot;Byte&quot; variant: is the general-purpose index register, encoded in the &quot;Rm&quot; field. This register contains an integer pointing to a single byte in the table. The offset in the table is the value of the index." link="Rm__23">&lt;Rm&gt;</a><text>]</text></asmtemplate>
      </encoding>
      <encoding name="TBH_T1" oneofinclass="2" oneof="2" label="Halfword" bitdiffs="H == 1">
        <docvars>
          <docvar key="armarmheading" value="T1"/>
          <docvar key="instr-class" value="general"/>
          <docvar key="isa" value="T32"/>
          <docvar key="loadstore-size" value="ls-halfword"/>
          <docvar key="mnemonic" value="TBH"/>
        </docvars>
        <box hibit="4" width="1" name="H">
          <c>1</c>
        </box>
        <asmtemplate comment="Outside or last in IT block"><text>TBH{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="AL_option__4">&lt;c&gt;</a><text>}{</text><a hover="See x[Standard assembler syntax fields](Babbefhf)." link="qn_option">&lt;q&gt;</a><text>}  [</text><a hover="Is the general-purpose base register holding the address of the table of branch lengths, encoded in the &quot;Rn&quot; field. The PC can be used. If it is, the table immediately follows this instruction." link="Rn__41">&lt;Rn&gt;</a><text>, </text><a hover="For the &quot;Halfword&quot; variant: is the general-purpose index register, encoded in the &quot;Rm&quot; field. This register contains an integer pointing to a halfword in the table. The offset in the table is twice the value of the index." link="Rm__22">&lt;Rm&gt;</a><text>, LSL #1]</text></asmtemplate>
      </encoding>
      <ps_section howmany="1">
        <ps name="T32.w.dstd.tblbr.TBB_T1" sections="1" secttype="noheading">
          <pstext mayhavelinks="1" section="Decode" rep_section="decode">let n : integer = UInt(Rn);
let m : integer = UInt(Rm);
let is_tbh : boolean = (H == '1');
// Armv8-A removes UNPREDICTABLE for R13
if m == 15 then UnpredictableProcedure(); end;
if InITBlock() &amp;&amp; !LastInITBlock() then UnpredictableProcedure(); end;</pstext></ps>
      </ps_section>
    </iclass>
  </classes>
  <explanations scope="all">
    <explanation enclist="TBB_T1, TBH_T1" symboldefcount="1">
      <symbol link="AL_option__4">&lt;c&gt;</symbol>
      <account encodedin="">
        <intro>
          <para>See <xref linkend="Babbefhf">Standard assembler syntax fields</xref>.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="TBB_T1, TBH_T1" symboldefcount="1">
      <symbol link="qn_option">&lt;q&gt;</symbol>
      <account encodedin="">
        <intro>
          <para>See <xref linkend="Babbefhf">Standard assembler syntax fields</xref>.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="TBB_T1, TBH_T1" symboldefcount="1">
      <symbol link="Rn__41">&lt;Rn&gt;</symbol>
      <account encodedin="Rn">
        <intro>
          <para>Is the general-purpose base register holding the address of the table of branch lengths, encoded in the "Rn" field. The PC can be used. If it is, the table immediately follows this instruction.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="TBB_T1" symboldefcount="1">
      <symbol link="Rm__23">&lt;Rm&gt;</symbol>
      <account encodedin="Rm">
        <intro>
          <para>For the "Byte" variant: is the general-purpose index register, encoded in the "Rm" field. This register contains an integer pointing to a single byte in the table. The offset in the table is the value of the index.</para>
        </intro>
      </account>
    </explanation>
    <explanation enclist="TBH_T1" symboldefcount="2">
      <symbol link="Rm__22">&lt;Rm&gt;</symbol>
      <account encodedin="Rm">
        <intro>
          <para>For the "Halfword" variant: is the general-purpose index register, encoded in the "Rm" field. This register contains an integer pointing to a halfword in the table. The offset in the table is twice the value of the index.</para>
        </intro>
      </account>
    </explanation>
  </explanations>
  <ps_section howmany="1">
    <ps name="T32.w.dstd.tblbr.TBB_T1" sections="1" secttype="Operation">
      <pstext mayhavelinks="1" section="Execute" rep_section="execute">if ConditionPassed() then
    EncodingSpecificOperations();
    var halfwords : integer;
    if is_tbh then
        halfwords = UInt(MemU{16}(R(n)+LSL(R(m), 1)));
    else
        halfwords = UInt(MemU{8}(R(n)+R(m)));
    end;
    BranchWritePC(PC32() + 2*halfwords, BranchType_INDIR);
end;</pstext></ps>
  </ps_section>
  <timestamp>2026-03-12 12:23:09</timestamp>
  <commit_id>2025-09_rel_asl1</commit_id>
</instructionsection>
