本章介绍 Hexagon 处理器指令和指令包的二进制编码。
所有 Hexagon 处理器指令都以 32 位指令字编码。 指令字格式因指令类型而异。
指令字包含两种类型的位域:
表 10-1 列出了指令位字段。
表 10-1 指令字段
Name | Description | Type |
---|---|---|
ICLASS | 指令类 | 命令 |
Parse | 数据包/ 循环比特 | 命令 |
MajOpMaj | 主要操作码 | 已下均为特定指令 |
MinOpMin | 次要操作码 | |
RegType | 寄存器类型(32 位、64 位) | |
Type | 操作数类型(字节、半字等) | |
Amode | 寻址方式 | |
dn | 目标寄存器操作数 | |
sn | 源寄存器操作数 | |
tn | 源寄存器操作数 #2 | |
xn | 源和目标寄存器操作数 | |
un | 条件或修饰符寄存器操作数 | |
sH | 源寄存器位域(Rs.H 或 Rs.L) | |
tH | 源寄存器 #2 位域(Rt.H 或 Rt.L) | |
UN | 无符号操作数 | |
Rs | 无源寄存器读取 | |
P | 条件表达式 | |
PS | 条件含义(Pu 或 !Pu) | |
DN | Dot-new 条件 | |
PT | Predict taken | |
sm | 仅Supervisor模式 |
注:在某些情况下,指令特定字段用于编码指令属性,而不是表 10-1 中的字段描述的属性。
保留位
一些指令包含当前不用于编码指令属性的保留位。 这些位应始终设置为 0,以确保与指令编码中的任何未来更改兼容。
注意 保留位在指令编码表中显示为“-”字符。
为了减少代码大小,Hexagon 处理器支持在单个 32 位容器中对某些指令对进行编码。 以这种方式编码的指令称为子指令,容器称为双工(第 10.3 节)。
子指令仅限于某些常用指令:
表 10-2 列出了子指令以及用于对它们进行双工编码的组标识符。
子指令只能访问通用寄存器的子集(R0-R7、R16-R23)。 表 10-3 列出了子指令寄存器编码。
注意 某些子指令隐式访问诸如 SP (R29) 之类的寄存器。
表 10-2 子指令
表 10-3 子指令寄存器
双工被编码为 32 位指令,位 [15:14] 设置为 00。组成双工的子指令(第 10.2 节)被编码为双工中的 13 位字段。
表 10-4 显示了双工的编码细节。
一个指令包可以包含一个双工指令和最多两个其他(非双工)指令。 双工必须始终作为数据包中的最后一个字出现。
双工中的子指令总是在 Slot 0 和 Slot 1 中执行。
表 10-4 双工指令
表 10-5 列出了双工 ICLASS 字段值,它们指定了双工中每个子指令的组。
表 10-5 双工 ICLASS 字段
双工具有以下分组约束:
• Rx = add(Rx,#s7)
• Rd = #u6
请注意,双工只能包含一个常量扩展指令,并且它必须出现在插槽 1 的位置。
如果一个双工包含两条具有相同子指令组的指令,则指令必须在双工中按如下顺序排列:当子指令被视为 13 位无符号整数值时,数值较小的值对应的指令必须在双工的插槽 1 位置进行编码。
子指令必须符合适用于各个指令的任何槽分配分组规则,即使存在违反这些分配的双工模式。 此规则存在一个例外:
指令类(第 3.2 节)被编码在指令字的四个最高有效位中(31:28)。 这些位被称为指令的 ICLASS 字段。
表 10-6 列出了指令类的编码值。 Slots 列指示哪些插槽可以接收指令类。
表 10-6 指令类编码
指令包使用指令字的两位编码 (15:14),称为指令字的 Parse 字段。 字段值具有以下定义:
如果出现任何四个连续指令的序列而其中没有一个包含“11”或“00”,则处理器将引发错误异常(非法操作码)。
图 10-1 显示了 Parse 字段在指令字中的位置。
图 10-1 指令包编码
以下示例显示如何使用 Parse 字段对指令包进行编码:
{ A ; B}
01 11 // Parse fields of instrs A,B
{ A ; B ; C}
01 01 11 // Parse fields of instrs A,B,C
{ A ; B ; C ; D}
01 01 01 11 // Parse fields of instrs A,B,C,D