# Instruction encoding

## Instructions

Hexagon processor instructions are encoded in a 32-bit instruction
word. The instruction word format varies according to the instruction
type.

The instruction words contain two types of bit fields:

- Common fields appear in every processor instruction, and are defined
the same in all instructions.
- Instruction-specific fields appear only in some instructions, or vary
in definition across the instruction set.

| **Name** | **Description** | **Type** |
| --- | --- | --- |
| ICLASS | Instruction class | Common |
| Parse | Packet / loop bits | Common |
| MajOp Maj | Major opcode | Instruction- specific |
| MinOp Min | Minor opcode | Instruction- specific |
| RegType | Register type (32-bit, 64-bit) | Instruction- specific |
| Type | Operand type (byte, halfword, and so on) | Instruction- specific |
| Amode | Addressing mode | Instruction- specific |
| d*n* | Destination register operand | Instruction- specific |
| s*n* | Source register operand | Instruction- specific |
| t*n* | Source register operand #2 | Instruction- specific |
| x*n* | Source and destination register operand | Instruction- specific |
| u*n* | Predicate or modifier register operand | Instruction- specific |
| sH | Source register bit field (Rs.H or Rs.L) | Instruction- specific |
| tH | Source register #2 bit field (Rt.H or Rt.L) | Instruction- specific |
| UN | Unsigned operand | Instruction- specific |
| Rs | No source register read | Instruction- specific |
| P | Predicate expression | Instruction- specific |
| PS | Predicate sense (Pu or !Pu) | Instruction- specific |
| DN | Dot-new predicate | Instruction- specific |
| PT | Predict taken | Instruction- specific |
| sm | Supervisor mode only | Instruction- specific |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |

Note

In some cases, instruction-specific fields encode
instruction attributes other than the ones described for the fields
in [Table 10-1](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#_bookmark286).

### Reserved bits

Some instructions contain reserved bits that do not currently encode
instruction attributes. Always set these bits to 0 to ensure
compatibility with any future changes in the instruction encoding.

Note

Reserved bits appear as ‘-’ characters in the instruction encoding tables.

## Sub-instructions

To reduce code size, the Hexagon processor supports the encoding of
certain pairs of instructions in a single 32-bit container.
Instructions encoded this way are sub-instructions, and the
containers are [duplexes](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-prm-duplexes)).

Sub-instructions are limited to certain commonly-used instructions:

- Arithmetic and logical operations
- Register transfer
- Loads and stores
- Stack frame allocation/deallocation
- Subroutine return

[Sub-instructions](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-tbl-sub-instructions) lists the sub-instructions along with
the group identifiers that encode them in duplexes.

Sub-instructions can access only a subset of the general registers
(R0 to R7, R16 to R23). [Table 10-3](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#_bookmark290) lists the
sub-instruction register encodings.

Note

Certain sub-instructions implicitly access registers such as SP (R29).

Sub-instructions

| **Group** | **Instruction** | **Description** |
| --- | --- | --- |
| L1 | `Rd = memw(Rs+#u4:2)` | Word load |
| L1 | `Rd = memub(Rs+#u4:0)` | Unsigned byte load |
| L2 | `Rd = memh/memuh(Rs+#u3:1)` | Halfword loads |
| L2 | `Rd = memb(Rs+#u3:0)` | Signed byte load |
| L2 | `Rd = memw(r29+#u5:2)` | Load word from stack |
| L2 | `Rdd = memd(r29+#u5:3)` | Load pair from stack |
| L2 | `deallocframe` | Deallocate stack frame |
| L2 | if ([!]P0) dealloc_return<br>    if ([!]P0.new) dealloc_return:nt<br>    Copy to clipboard | Deallocate stack frame and return |
| L2 | jumpr R31<br>    if ([!]P0) jumpr R31<br>    if ([!]P0.new) jumpr:nt R31<br>    Copy to clipboard | Return |
| S1 | `memw(Rs+#u4:2) = Rt` | Store word |
| S1 | `memb(Rs+#u4:0) = Rt` | Store byte |
| S2 | `memh(Rs+#u3:1) = Rt` | Store halfword |
| S2 | `memw(r29+#u5:2) = Rt` | Store word to stack |
| S2 | `memd(r29+#s6:3) = Rtt` | Store pair to stack |
| S2 | `memw(Rs+#u4:2) = #U1` | Store immediate word #0 or #1 |
| S2 | `memb(Rs+#u4) = #U1` | Store immediate byte #0 or #1 |
| S2 | `allocframe(#u11:3)` | Allocate stack frame |
| A | `Rx = add(Rx,#s7)` | Add immediate |
| A | `Rd = Rs` | Transfer |
| A | `Rd = #u6` | Set to unsigned immediate |
| A | `Rd = #-1` | Set to -1 |
| A | `if ([!]P0[.new]) Rd = #0` | Conditional clear |
| A | `Rd = add(r29,#u6:2)` | Add immediate to stack pointer |
| A | `Rx = add(Rx,Rs)` | Register add |
| A | `P0 = cmp.eq(Rs,#u2)` | Compare register equal immediate |
| A | `Rdd = combine(#0,Rs)` | Combine zero and register into pair |
| A | `Rdd = combine(Rs,#0)` | Combine register and zero into pair |
| A | `Rdd = combine(#u2,#U2)` | Combine immediates into pair |
| A | `Rd = add(Rs,#1) Rd = add(Rs,#-1)` | Add and subtract 1 |
| A | `Rd = sxth/sxtb/zxtb/zxth(Rs)` | Sign- and zero-extends |
| A | `Rd = and(Rs,#1)` | And with 1 |

Sub-instruction registers

| **Register** | **Encoding** |
| --- | --- |
| Rs,Rt,Rd,Rx | <ul class="simple"><br><li><p>0000 = R0</p></li><br><li><p>0001 = R1</p></li><br><li><p>0010 = R2</p></li><br><li><p>0011 = R3</p></li><br><li><p>0100 = R4</p></li><br><li><p>0101 = R5</p></li><br><li><p>0110 = R6</p></li><br><li><p>0111 = R7</p></li><br><li><p>1000 = R16</p></li><br><li><p>1001 = R17</p></li><br><li><p>1010 = R18</p></li><br><li><p>1011 = R19</p></li><br><li><p>1100 = R20</p></li><br><li><p>1101 = R21</p></li><br><li><p>1110 = R22</p></li><br><li><p>1111 = R23</p></li><br></ul> |
| Rdd,Rtt | <ul class="simple"><br><li><p>000 = R1:0</p></li><br><li><p>001 = R3:2</p></li><br><li><p>010 = R5:4</p></li><br><li><p>011 = R7:6</p></li><br><li><p>100 = R17:16</p></li><br><li><p>101 = R19:18</p></li><br><li><p>110 = R21:20</p></li><br><li><p>111 = R23:22</p></li><br></ul> |

## Duplexes

A duplex is encoded as a 32-bit instruction with bits [15:14] set to
00. The sub-instructions that comprise a duplex are encoded as 13-bit
fields in the duplex.

An instruction packet can contain one duplex and up to two other
(non-duplex) instructions. The duplex must always appear as the last
word in a packet.

The sub-instructions in a duplex always execute in slot 0 and slot 1.

Duplex instruction encoding

| **Bits** | **Name** | **Description** |
| --- | --- | --- |
| 15:14 | Parse bits | 00 = Duplex type, ends the packet and indicates that word<br>contains two sub-instructions |
| 12:0 | Sub-instruction low | Encodes slot 0 sub-instruction |
| 28:16 | Sub-instruction high | Encodes slot 1 sub-instruction |
| 31:29, 13 | 4-bit ICLASS | Indicates the group to which the low and high sub- instructions<br>belong. |

The duplex ICLASS field values that specify the group of each
sub-instruction in a duplex are shown in [Duplex ICLASS field](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-tbl-duplex-iclass-field).

Duplex ICLASS field

| **ICLASS** | **Low slot 0 subinsn type** | **High slot 1 subinsn type** |
| --- | --- | --- |
| 0x0 | L1-type | L1-type |
| 0x1 | L2-type | L1-type |
| 0x2 | L2-type | L2-type |
| 0x3 | A-type | A-type |
| 0x4 | L1-type | A-type |
| 0x5 | L2-type | A-type |
| 0x6 | S1-type | A-type |
| 0x7 | S2-type | A-type |
| 0x8 | S1-type | L1-type |
| 0x9 | S1-type | L2-type |
| 0xA | S1-type | S1-type |
| 0xB | S2-type | S1-type |
| 0xC | S2-type | L1-type |
| 0xD | S2-type | L2-type |
| 0xE | S2-type | S2-type |
| 0xF | Reserved | Reserved |

Duplexes have the following grouping constraints:

- [Constant extenders](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-prm-constant-extenders) expand the range of the
immediate operand of an instruction to 32 bits, and can expand the
following sub-instructions:

    - Rx = add(Rx,#s7)
    - Rd = #u6

    A duplex can contain only one constant-extended instruction, and it
must appear in the slot 1 position.
- When the sub-instructions are treated as 13-bit unsigned integer
values for two instructions with the same sub-instruction group in a
duplex, the instruction corresponding to the numerically smaller
value must be encoded in the slot 1 position of the duplex.[\[1\]](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#iefn1)
- Sub-instructions must conform to any slot assignment grouping rules
that apply to the individual instructions, even if a duplex pattern
exists that violates those assignments. One exception to this rule
exists:

    - jumpr R31 must appear in the Slot 0 position

[[1](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#id1)]

The sub-instruction register and immediate fields are
assumed to be 0 when performing this comparison.

## Instruction classes

The [instruction class](https://docs.qualcomm.com/doc/80-N2040-60/topic/instructions.html#v79-prm-instruction-classes)) is
encoded in the four most-significant bits of the instruction word
(31:28). These bits are referred to as the ICLASS field of the
instruction. The Slots column in [Instruction class encoding](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-tbl-instruction-class-encoding)
indicates which slots can receive the instruction class.

Instruction class encoding

| **Encoding** | **Instruction class** | **Slots** |
| --- | --- | --- |
| 0000 | [Constant extender](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-prm-constant-extenders) | — |
| 0001 | J | 2, 3 |
| 0010 | J | 2, 3 |
| 0011 | LD ST | 0, 1 |
| 0100 | LD ST<br><br><br>(conditional or GP-relative) | 0, 1 |
| 0101 | J | 2, 3 |
| 0110 | CR | 3 |
| 0111 | ALU32 | 0, 1, 2, 3 |
| 1000 | XTYPE | 2, 3 |
| 1001 | LD | 0, 1 |
| 1010 | ST | 0 |
| 1011 | ALU32 | 0, 1, 2, 3 |
| 1100 | XTYPE | 2, 3 |
| 1101 | XTYPE | 2, 3 |
| 1110 | XTYPE | 2, 3 |
| 1111 | ALU32 | 0, 1, 2, 3 |

For details on encoding the individual class types, see [Instruction set](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-set.html).

## Instruction packets

Instruction packets are encoded using two bits of the instruction
word (15:14), which are referred to as the Parse field of the
instruction word. The field values have the following definitions:

- ‘11’ indicates that an instruction is the last instruction in a
packet (the instruction word at the highest address).
- ‘01’ or ‘10’ indicate that an instruction is not the last instruction
in a packet.
- ‘00’indicates a duplex.

If any sequence of four consecutive instructions occurs without one
of them containing ‘11’ or ‘00’, the processor raises an error
exception (illegal opcode).

<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

<!-- Generated by Microsoft Visio, SVG Export fig-instruction-packets.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="4.86194in" height="2.72744in" viewbox="0 0 350.06 196.376" xml:space="preserve" color-interpolation-filters="sRGB" class="st7"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvConvertTheme"></v:ud>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-1 .st1 { stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st2 { fill: #2a2aea; font-family: Roboto; font-size: 1.00001em }
.svg-1 .st3 { fill: none; stroke: #2a2aea; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st4 { fill: none; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.72 }
.svg-1 .st5 { font-size: 1em }
.svg-1 .st6 { stroke: #2a2aea; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st7 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<v:userdefs>		<v:ud v:nameu="SchemeName" v:val="VT4(Default)"></v:ud>	</v:userdefs>	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="0" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<v:layer v:name="Connector" v:index="0"></v:layer>	<g id="shape1-1" v:mid="1" v:groupcontext="shape" transform="translate(302.76,-165.198)">		<title>Sheet.1</title>		<desc>16</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="14.04" cy="190.398" width="28.09" height="11.9549"></v:textrect>		<path d="M28.08 184.42 L0 184.42 L0 196.38 L28.08 196.38 L28.08 184.42" class="st1"></path>		<text x="7.3" y="194" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>16</text>		</g>	<g id="shape6-5" v:mid="6" v:groupcontext="shape" transform="translate(65.16,-143.198)">		<title>Rectangle.32</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape7-7" v:mid="7" v:groupcontext="shape" transform="translate(85.3488,-143.238)">		<title>Rectangle.7</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape8-9" v:mid="8" v:groupcontext="shape" transform="translate(105.48,-143.238)">		<title>Rectangle.8</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape9-11" v:mid="9" v:groupcontext="shape" transform="translate(125.64,-143.238)">		<title>Rectangle.9</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape10-13" v:mid="10" v:groupcontext="shape" transform="translate(145.8,-143.238)">		<title>Rectangle.10</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape11-15" v:mid="11" v:groupcontext="shape" transform="translate(165.989,-143.238)">		<title>Rectangle.11</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape12-17" v:mid="12" v:groupcontext="shape" transform="translate(186.12,-143.238)">		<title>Rectangle.12</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape13-19" v:mid="13" v:groupcontext="shape" transform="translate(206.28,-143.238)">		<title>Rectangle.13</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape14-21" v:mid="14" v:groupcontext="shape" transform="translate(226.44,-143.238)">		<title>Rectangle.14</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape15-23" v:mid="15" v:groupcontext="shape" transform="translate(246.6,-143.238)">		<title>Rectangle.15</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape17-25" v:mid="17" v:groupcontext="shape" transform="translate(45,-143.238)">		<title>Rectangle.17</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape18-27" v:mid="18" v:groupcontext="shape" transform="translate(266.789,-143.238)">		<title>Rectangle.18</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape19-29" v:mid="19" v:groupcontext="shape" transform="translate(286.92,-143.238)">		<title>Rectangle.19</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape20-31" v:mid="20" v:groupcontext="shape" transform="translate(24.8688,-143.238)">		<title>Rectangle.20</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape21-33" v:mid="21" v:groupcontext="shape" transform="translate(307.109,-143.238)">		<title>Rectangle.21</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape22-35" v:mid="22" v:groupcontext="shape" transform="translate(19.3074,-165.198)">		<title>Sheet.22</title>		<desc>31</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="14.04" cy="190.398" width="28.09" height="11.9549"></v:textrect>		<path d="M28.08 184.42 L0 184.42 L0 196.38 L28.08 196.38 L28.08 184.42" class="st1"></path>		<text x="7.3" y="194" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>31</text>		</g>	<g id="shape57-39" v:mid="57" v:groupcontext="shape" transform="translate(303.48,-124.443)">		<title>Sheet.57</title>		<desc>0</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="14.04" cy="190.398" width="28.09" height="11.9549"></v:textrect>		<path d="M28.08 184.42 L0 184.42 L0 196.38 L28.08 196.38 L28.08 184.42" class="st1"></path>		<text x="10.67" y="194" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>0</text>		</g>	<g id="shape58-43" v:mid="58" v:groupcontext="shape" transform="translate(65.88,-102.443)">		<title>Rectangle.58</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape59-45" v:mid="59" v:groupcontext="shape" transform="translate(86.0688,-102.483)">		<title>Rectangle.59</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape60-47" v:mid="60" v:groupcontext="shape" transform="translate(106.2,-102.483)">		<title>Rectangle.60</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape61-49" v:mid="61" v:groupcontext="shape" transform="translate(126.36,-102.483)">		<title>Rectangle.61</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape62-51" v:mid="62" v:groupcontext="shape" transform="translate(146.52,-102.483)">		<title>Rectangle.62</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape63-53" v:mid="63" v:groupcontext="shape" transform="translate(166.709,-102.483)">		<title>Rectangle.63</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape64-55" v:mid="64" v:groupcontext="shape" transform="translate(186.84,-102.483)">		<title>Rectangle.64</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape65-57" v:mid="65" v:groupcontext="shape" transform="translate(207,-102.483)">		<title>Rectangle.65</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape66-59" v:mid="66" v:groupcontext="shape" transform="translate(227.16,-102.483)">		<title>Rectangle.66</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape67-61" v:mid="67" v:groupcontext="shape" transform="translate(247.32,-102.483)">		<title>Rectangle.67</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape68-63" v:mid="68" v:groupcontext="shape" transform="translate(45.72,-102.483)">		<title>Rectangle.68</title>		<desc>P</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="10.0656" cy="187.376" width="20.14" height="18"></v:textrect>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>		<text x="6.28" y="190.98" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>P</text>		</g>	<g id="shape69-66" v:mid="69" v:groupcontext="shape" transform="translate(267.509,-102.483)">		<title>Rectangle.69</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape70-68" v:mid="70" v:groupcontext="shape" transform="translate(287.64,-102.483)">		<title>Rectangle.70</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape71-70" v:mid="71" v:groupcontext="shape" transform="translate(25.5888,-102.483)">		<title>Rectangle.71</title>		<desc>P</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="10.0656" cy="187.376" width="20.14" height="18"></v:textrect>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>		<text x="6.28" y="190.98" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>P</text>		</g>	<g id="shape72-73" v:mid="72" v:groupcontext="shape" transform="translate(307.829,-102.483)">		<title>Rectangle.72</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(10):26"></v:ud>		</v:userdefs>		<rect x="0" y="178.376" width="20.1312" height="18" class="st3"></rect>	</g>	<g id="shape73-75" v:mid="73" v:groupcontext="shape" transform="translate(20.0274,-124.443)">		<title>Sheet.73</title>		<desc>15</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="14.04" cy="190.398" width="28.09" height="11.9549"></v:textrect>		<path d="M28.08 184.42 L0 184.42 L0 196.38 L28.08 196.38 L28.08 184.42" class="st1"></path>		<text x="7.3" y="194" class="st2" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>15</text>		</g>	<g id="shape74-79" v:mid="74" v:groupcontext="shape" transform="translate(18.36,-21.1982)">		<title>Sheet.74</title>		<desc>Packet/loop parse bits: 01, 10 = not end of packet 11 = end o...</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="93.4173" cy="170.774" width="186.84" height="51.2036"></v:textrect>		<rect x="0" y="145.172" width="186.835" height="51.2036" class="st4"></rect>		<text x="4" y="152.77" class="st2" v:langid="1033"><v:paragraph v:bulletsize="0.166667"></v:paragraph><v:tablist></v:tablist>Packet/loop parse bits:<v:newlinechar></v:newlinechar><tspan x="4" dy="1.2em" class="st5">01, 10 = not end of packet<v:newlinechar></v:newlinechar></tspan><tspan x="4" dy="1.2em" class="st5">11 = end of packet<v:newlinechar></v:newlinechar></tspan><tspan x="4" dy="1.2em" class="st5">00 = duplex</tspan></text>		</g>	<g id="shape75-85" v:mid="75" v:groupcontext="shape" transform="translate(221.936,97.3606) rotate(90)">		<title>Right Brace</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:prompt="" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<path d="M0 196.38 A29.603 6.72218 -180 0 0 11.06 192.36 L11.06 176.29 L22.11 176.29 L11.06 176.29 L11.06 160.22 A29.603					 6.72218 -180 0 0 0 156.21" class="st6"></path>	</g></g>
</svg>

**Parse field instruction packet encoding**

The following examples show how to use the Parse field to encode
instruction packets:

{ A ; B}
    01 11              // Parse fields of instructions A,B
    { A ; B ; C}
    01 01 11           // Parse fields of instructions A,B,C
    { A ; B ; C ; D}
    01 01 01 11        // Parse fields of instructions A,B,C,D
    Copy to clipboard

## Loop packets

In addition to encoding the last instruction in a packet, the Parse
field of the instruction word ([instruction packets](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-prm-instruction-packets-encoding))
encodes the last packet in a hardware loop.

The Hexagon processor supports two [hardware loops](https://docs.qualcomm.com/doc/80-N2040-60/topic/program-flow.html#v79-prm-hardware-loops)
that are labeled 0 and 1. The last packet in these loops is subject to the
following restrictions:

- The last packet in a hardware loop 0 must contain two or more
instruction words.
- The last packet in a hardware loop 1 must contain three or more
instruction words.

If the last packet in a loop is expressed in assembly language with
fewer than the required number of words, the assembler automatically
adds one or two NOP instructions to the encoded packet so it contains
the minimum required number of instruction words.

The Parse fields in the first and second instruction words (the words
at the lowest addresses) of a packet encode whether the packet is the
last packet in a hardware loop.

Parse field loop packet encoding

| **Packet** | **Parse field in first Instruction** | **Parse field in second Instruction** |
| --- | --- | --- |
| Not last in loop | 01 or 11 | 01 or 11[\[2\]](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#iefn2) |
| Last in loop 0 | 10 | 01 or 11 |
| Last in loop 1 | 01 | 10 |
| Last in loops 0 & 1 | 10 | 10 |

[[2](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#id2)]

Not applicable for single-instruction packets.

The following examples show how to use the Parse field to encode loop
packets:

{ A B}:endloop0
    10 11                          // Parse fields of instrs A,B
    { A B C}:endloop0
    10 01 11                       // Parse fields of instrs A,B,C
    { A B C D}:endloop0
    10 01 01 11                    // Parse fields of instrs A,B,C,D
    { A B C}:endloop1
    01 10 11                       // Parse fields of instrs A,B,C
    { A B C D}:endloop1
    01 10 01 11                    // Parse fields of instrs A,B,C,D
    { A B C}:endloop0:endloop1
    10 10 11                       // Parse fields of instrs A,B,C
    { A B C D}:endloop0:endloop1
    10 10 01 11                    // Parse fields of instrs A,B,C,D
    Copy to clipboard

## Immediate values

To conserve encoding space, the Hexagon processor often stores
immediate values in instruction fields that are smaller (in bit size)
than the values actually needed in the instruction operation.

When an instruction operates on one of its immediate operands, the
processor automatically extends the immediate value to the bit size
required by the operation:

- Signed immediate values are sign-extended
- Unsigned immediate values are zero-extended

## Scaled immediate values

To minimize the number of bits in instruction words to store certain
immediate values, the Hexagon processor stores the values as scaled
immediate values. Use scaled immediate values when an immediate value
must represent integral multiples of a power of 2 in a specific
range.

For example, consider an instruction operand whose possible values
are the following:

> 
> 
> -32, -28, -24, -20, -16, -12, -8, -4, 0, 4, 8, 12, 16, 20, 24, 28

Encoding the full range of integers -32…28 normally requires 6
bits. However, if the operand is stored as a scaled immediate, it can
first be shifted right by two bits, storing only the four remaining
bits in the instruction word. When the operand is fetched from the
instruction word, the processor automatically shifts the value left
by two bits to recreate the original operand value.

Note

The scaled immediate value in the example above is represented notationally as #s4:2.

Scaled immediate values commonly encode address offsets that apply to
data types of varying size. For example,
[Scaled immediate encoding (indirect offsets)](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-tbl-scaled-immediate-encoding-indirect-offsets)
shows how to use the byte offsets in immediate-with-offset addressing mode
that are stored as 11-bit scaled immediate values. This enables the offsets
to span the same range of data elements regardless of the data type.

Scaled immediate encoding (indirect offsets)
 :widths: 12 10 8 11 16 16
 :header-rows: 1
 :class: longtable table-wrap

| **Data type** | **Offset size (stored)** | **Scale bits** | **Offset size (effective)** | **Offset range (bytes)** | **Offset range (elements)** |
| --- | --- | --- | --- | --- | --- |
| byte | 11 | 0 | 11 | -1024 … 1023 | -1024 … 1023 |
| halfword | 11 | 1 | 12 | -2048 … 2046 | -1024 … 1023 |
| word | 11 | 2 | 13 | -4096 … 4092 | -1024 … 1023 |
| doubleword | 11 | 3 | 14 | -8192 … 8184 | -1024 … 1023 |

## Constant extenders

To support the use of 32-bit operands in a number of instructions,
the Hexagon processor defines constant extenders, which are an
instruction word that exists ony to extend the bit range of an
immediate or address operand that is contained in an adjacent
instruction in a packet.

For example, the absolute addressing mode specifies a 32-bit constant
value as the effective address. Instructions using this addressing
mode are encoded in a single packet that contains both the normal
instruction word and a second word with a constant extender that
increases the range of the normal constant operand of the instruction
to a full 32 bits.

Note

Constant extended operands can encode symbols.

A constant extender is encoded as a 32-bit instruction with the 4-bit
ICLASS field set to 0 and the 2-bit Parse field follows the rules outlined
in [instruction packets](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-prm-instruction-packets-encoding).
The remaining 26 bits in the instruction word store the data bits that are
appended to an operand as small as 6 bits to create a full 32-bit value.

Constant extender encoding

| **Bits** | **Name** | **Description** |
| --- | --- | --- |
| 31:28 | ICLASS | Instruction class = 0000 |
| 27:16 | Extender high | High 12 bits of 26-bit constant extension |
| 15:14 | Parse | Parse bits |
| 13:0 | Extender low | Low 14 bits of 26-bit constant extension |

Within a packet, a constant extender must be positioned immediately
before the instruction that it extends: in terms of memory addresses,
the extender word must reside at address (&lt;instr\_address&gt; - 4).

The constant extender effectively serves as a prefix for an
instruction: it does not execute in a slot, nor does it consume any
slot resources. All packets must contain four or fewer words, and the
constant extender occupies one word. Two instructions that use constant
extenders can be in the same packet.

If the instruction operand to extend is longer than 6 bits, the
overlapping bits in the base instruction must be encoded as zeros.
The value in the constant extender always supplies the upper 26 bits.

The Regclass field in [Constant extender instructions](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-tbl-constant-extender-instructions)
lists the values to set bits [27:24] to in the instruction word to identify the
instruction as one that might include a constant extender.

Note

When the base instruction encodes two constant operands,
the extended immediate is the one specified in the table.

Constant extenders appear in disassembly listings as Hexagon
instructions with the name immext.

Note

If a constant extender is encoded in a packet for an
instruction that does not accept a constant extender, the execution
result is undefined. The assembler normally ensures that only valid
constant extenders are generated.

Constant extender instructions

| **ICLASS** | **Regclass** | **Instructions** |
| --- | --- | --- |
| LD | `---1` | Rd = mem{b,ub,h,uh,w,d}(##U32)<br>    if ([!]Pt[.new]) Rd = mem{b,ub,h,uh,w,d} (Rs + ##U32)<br>    // predicated loads<br>    Copy to clipboard |
| LD | `----` | Rd = mem{b,ub,h,uh,w,d} (Rs + ##U32)<br>    Rd = mem{b,ub,h,uh,w,d} (Re=##U32)<br>    Rd = mem{b,ub,h,uh,w,d} (Rt<<#u2 + ##U32)<br>    if ([!]Pt[.new]) Rd = mem{b,ub,h,uh,w,d} (##U32)<br>    Copy to clipboard |
| ST | `---0` | mem{b,h,w,d}(##U32) = Rs[.new] // GP-stores<br>    if ([!]Pt[.new]) mem{b,h,w,d}(Rs + ##U32) = Rt[.new]<br>    // predicated stores<br>    Copy to clipboard |
| ST | `----` | mem{b,h,w,d}(Rs + ##U32) = Rt[.new]<br>    mem{b,h,w,d}(Rd=##U32) = Rt[.new]<br>    mem{b,h,w,d}(Ru<<#u2 + ##U32) = Rt[.new]<br>    if ([!]Pt[.new]) mem{b,h,w,d}(##U32) = Rt[.new]<br>    allocframe(##U32)<br>    Copy to clipboard |
| MEMOP | `----` | [if [!]Ps] memw(Rs + #u6) = ##U32 // constant store<br>    memw(Rs + Rt<<#u2) = ##U32 // constant store<br>    Copy to clipboard |
| NV | `----` | if (cmp.xx(Rs.new,##U32)) jump:hint target<br>    Copy to clipboard |
| ALU32 | `----` | Rd = ##u32<br>    Rdd = combine(Rs,##u32)<br>    Rdd = combine(##u32,Rs)<br>    Rdd = combine(##u32,#s8)<br>    Rdd = combine(#s8,##u32)<br>    Rd = mux (Pu, Rs,##u32)<br>    Rd = mux (Pu, ##u32, Rs)<br>    Rd = mux(Pu,##u32,#s8)<br>    if ([!]Pu[.new]) Rd = add(Rs,##u32)<br>    if ([!]Pu[.new]) Rd = ##u32<br>    Pd = [!]cmp.eq (Rs,##u32)<br>    Pd = [!]cmp.gt (Rs,##u32)<br>    Pd = [!]cmp.gtu (Rs,##u32)<br>    Rd = [!]cmp.eq(Rs,##u32)<br>    Rd = and(Rs,##u32)<br>    Rd = or(Rs,##u32)<br>    Rd = sub(##u32,Rs)<br>    Copy to clipboard |
| ALU32 | `----` | Rd = add(Rs,##s32)<br>    Copy to clipboard |
| XTYPE | `00--` | Rd = mpyi(Rs,##u32)<br>    Rd += mpyi(Rs,##u32)<br>    Rd -= mpyi(Rs,##u32)<br>    Rx += add(Rs,##u32)<br>    Rx -= add(Rs,##u32)<br>    Copy to clipboard |
| ALU32 | `----` [\[3\]](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#iefn3) | Rd = ##u32<br>    Rd = add(Rs,##s32)<br>    Copy to clipboard |
| J | `1---` | jump (PC + ##s32)<br>    call (PC + ##s32)<br>    if ([!]Pu) call (PC + ##s32)<br>    Copy to clipboard |
|  |  |  |
| CR | `----` | Pd = spNloop0(PC+##s32,Rs/#U10)<br>    loop0/1 (PC+##s32,#Rs/#U10)<br>    Copy to clipboard |
| XTYPE | `1---` | Rd = add(pc,##s32)<br>    Rd = add(##u32,mpyi(Rs,#u6))<br>    Rd = add(##u32,mpyi(Rs,Rt))<br>    Rd = add(Rs,add(Rt,##u32))<br>    Rd = add(Rs,sub(##u32,Rt))<br>    Rd = sub(##u32,add(Rs,Rt))<br>    Rd = or(Rs,and(Rt,##u32))<br>    Rx = add/sub/and/or (##u32,asl/asr/lsr(Rx,#U5))<br>    Rx = add/sub/and/or (##u32,asl/asr/lsr(Rs,Rx))<br>    Rx = add/sub/and/or (##u32,asl/asr/lsr(Rx,Rs))<br>    Pd = cmpb/h.{eq,gt,gtu} (Rs,##u32)<br>    Copy to clipboard |

[[3](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#id3)]

Constant extension is only for a slot 1 sub-instruction.

### Encoding 32-bit address operands in load/stores

Two methods exist for encoding a 32-bit absolute address in a load or
store instruction:

- For unconditional load/stores, the GP-relative load/store instruction
is used. The assembler encodes the absolute 32-bit address as
follows:

    - The upper 26 bits are encoded in a constant extender
    - The lower 6 bits are encoded in the 6 operand bits contained in
the GP-relative instruction

    In this case the 32-bit value encoded must be a plain address, and
the value stored in the GP register is ignored.

Note

When a constant extender is explicitly specified with a
GP-relative load/store, the processor ignores the value in GP and
creates the effective address directly from the 32-bit constant
value.
- For conditional load/store instructions that have their base address
encoded only by a 6-bit immediate operand, a constant extender must
be explicitly specified; otherwise, the execution result is
undefined. The assembler ensures that these instructions always
include a constant extender.

    This case applies also to instructions that use the absolute-set
addressing mode or absolute- plus-register-offset addressing mode.

### Encoding 32-bit immediate operands

The immediate operands of certain instructions use
[scaled immediates](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html#v79-prm-scaled-immediate-values) to increase
their addressable range. When using constant extenders, scaled immediates
are not scaled by the processor. Instead, the assembler must encode
the full 32-bit unscaled value as follows:

- The upper 26 bits are encoded in the constant extender
- The lower six 6 bits are encoded in the base instruction in the
least-significant bit positions of the immediate operand field.
- Any overlapping bits in the base instruction are encoded as zeros.

Encoding 32-bit jump/call target addresses

When a jump/call has a constant extender, the resulting target
address is forced to a 32-bit alignment (bits 1:0 in the address are
cleared by hardware). The resulting jump/call operation never causes
an alignment violation.

## New-value operands

Instructions that include a new-value register operand specify in
their encodings which instruction in the packet has its destination
register accessed as the new-value register.

New-value consumers include a 3-bit instruction field named Nt that
specifies this information.

- Nt[0] is reserved and must always be encoded as zero. A nonzero value
produces undefined results.
- Nt[2:1] encodes the distance (in instructions) from the producer to
the consumer, as follows:

    - Nt[2:1] = 00 // reserved
    - Nt[2:1] = 01 // producer is +1 instruction ahead of consumer
    - Nt[2:1] = 10 // producer is +2 instructions ahead of consumer
    - Nt[2:1] = 11 // producer is +3 instructions ahead of consumer

“ahead” is defined here as the instruction encoded at a lower memory
address than the consumer instruction, not counting empty slots or
constant extenders. For example, the following producer/consumer
relationship is encoded with `Nt[2:1]` set to 01.

...
    <producer instruction word>
    <consumer constant extender word>
    <consumer instruction word>
    ...
    Copy to clipboard

Note

Instructions with 64-bit register pair destinations cannot
produce new-values. The assembler flags this case with an error, as
the result is undefined.

## Instruction mapping

Some Hexagon processor instructions are encoded by the assembler as
variants of other instructions. This is done for operations that are
functionally equivalent to other instructions, but are still defined
as separate instructions because of their programming utility as
common operations.

Instructions mapped to other instructions

| **Instruction** | **Mapping** |
| --- | --- |
| Rd = not(Rs) | Rd = sub(#-1,Rs) |
| Rd = neg(Rs) | Rd = sub(#0,Rs) |
| Rdd = Rss | Rdd = combine(Rss.H32, Rss.L32) |

Last Published: Jan 16, 2025

[Previous Topic
PMU events](https://docs.qualcomm.com/bundle/publicresource/80-N2040-60/topics/pmu-events.md) [Next Topic
Instruction set](https://docs.qualcomm.com/bundle/publicresource/80-N2040-60/topics/instruction-set.md)

Source: [https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html](https://docs.qualcomm.com/doc/80-N2040-60/topic/instruction-encoding.html)