Hexagon 学习 --- 寄存器篇

Hexagon 学习

就是按照手册过了一遍,仅仅是个人的笔记。

Registers 寄存器

The Hexagon processor has two sets of registers: general registers and control registers. The general registers include thirty-two 32-bit registers (named R0 through R31) which can be accessed either as single registers or as aligned 64-bit register pairs. The general registers are used to contain all pointer, scalar, vector, and accumulator data. The control registers include special-purpose registers such as program counter, status register, loop registers, etc.

分为通用寄存器和控制寄存器, 通用寄存器包括32个32位寄存器,以R0到R31命名,另外这里提到了可以通过定义一个寄存器对来表示一个64位寄存器..例如

1
2
R1:0 =memd(R3)          //导入双字
R7:6=valignb(R9:8,R7:6,#2) //适量对齐

寄存器对

下图显示了寄存器对的结构

在这些通用寄存器当中,R29-R32被用来支持子程序的调用以及程序栈,这些寄存器可以无保留的被子程序调用或栈指令改变。在编程环境中,R29-R32可以用符号来表示。例如:

SP=add(SP,#-8) //sp是R29的别名

Allocfram //更改寄存器R29(SP)以及R30(FP)

call init //更改LR(R31)

通用寄存器

下图显示了这些别名后的通用寄存器

1
2
3
4
For example:
SP = add(SP, #-8) // SP is alias of R29
allocframe // Modifies SP (R29) and FP (R30)
call init // Modifies LR (R31)

在这些通用寄存器当中,R29-R32被用来支持子程序的调用以及程序栈,这些寄存器可以无保留的被子程序调用或栈指令改变。在编程环境中,R29-R32可以用符号来表示。

控制寄存器

Hexagon处理器包含了一系列的32位的控制寄存器,这些寄存器可以让我们对处理器中的PC,硬件回路以及矢量分支预测进行操作。

与通用寄存器不同,控制寄存器中有些特殊的控制寄存器可用来当做操作数,有时候寄存器可以被转换成指令从而被用作操作数。

1
2
3
4
For example:
R2 = memw(R0++M1) // Auto-increment addressing mode (M1)
R9 = PC // Get program counter (PC)
LC1 = R3 // Set hardware loop count (LC1)

控制寄存器别名规则:

控制寄存器同样可以被定义为寄存器对从而表示一个64位的寄存器,控制寄存器的凑对使用别名来定义,例如:

1
C1:0 = R5:4 // C1:0 specifies the LC0/SA0 register pair

程序计数器 Program Counter(PC)

PC 寄存器是用来指向下一个指令的位置. 他可以通过指令的执行来间接修改,也可被直接读取例如:

1
R7 = PC // Get program counter

NOTE The PC register is read-only: writing to it has no effect.

循环寄存器 Loop registers

Hewxagon 的处理器包括两组循环寄存器用来支持嵌套的硬件循环, 每个循环包含了循环计数器以及循环开始位置的寄存器。循环寄存器可以通过 loop 指令修改,同时也可以直接访问,例如:

1
2
3
loop0(start, R4) // Modifies LC0 and SA0 (LC0=R4, SA0=&start)
LC1 = R22 // Set loop1 count
R9 = SA1 // Get loop1 start address

用户状态寄存器 User Status register

用户状态寄存器(USR)存储可由用户程序访问的处理器状态和控制位。状态位包含某些指令的状态结果,而控制位包含用户可设置的处理器模式,用于硬件预取

1
2
R9:8 = vaddw(R9:8, R3:2):sat // Vector add words
R6 = USR // Get saturation status

USR 可包含一下的状态和控制值

  • 启用缓存预取 Cache prefetch enable

  • 缓存预取状态 Cache prefetch status

  • 浮点模式 Floating point modes

  • 浮点状态 Floating point status

  • 硬件回路配置 Hardware loop configuration

  • Sticky saturation overflow

NOTE A user control register transfer to USR cannot be grouped in an instruction packet with a floating point instruction (Section 4.3.4). Whenever a transfer to USR changes the Enable trap bits [29:25], an isync instruction (Section 5.10) must be executed before the new exception programming can take effect.

修饰寄存器 Modifier registers

修饰寄存器用于 (M0-M1) 用于以下寻址模式

  • 间接自动递增寄存器寻址 Indirect auto-increment register addressing

  • 循环寻址 Circular addressing

  • bit-reversed 寻址 Bit-reversed addressing

Indirect auto-increment register addressing

在间接自动递增寄存器寻址中,修改符寄存器存储一个
带符号的32位值,用于指定增量(或减量)值

1
2
M1 = R0 // Set modifier register
R3 = memw(R2++M1) // Load word

Circular

在循环寻址中,修饰寄存器存储循环缓冲区的长度和相关的 “k” 和 “I” 的值

1
2
3
4
5
M0 = R7 // Set modifier register
R0 = memb(R2++#4:circ(M0)) // Load from circ buffer pointed
// to by R2 with size/K vals in M0
R0 = memb(R7++I:circ(M1)) // Load from circ buffer pointed
// to by R7 with size/K/I vals in M1

Bit-reversed

在位反转寻址中,修改器寄存器存储带符号的32位 指定增量(或减量)值的值。例如

1
2
3
4
M1 = R7 // Set modifier register
R2 = memub(R0++M1:brev) // The address is (R0.H | bitrev(R0.L))
// The orginal R0 (not reversed) is added
// to M1 and written back to R0

分支预测寄存器 Predicate registers

分支预测寄存器(P0-P3)保存了标量与矢量对比计算的结果,例如:

1
2
3
4
P1 = cmp.eq(R2, R3) // Scalar compare
if (P1) jump end // Jump to address (conditional)
R8 = P1 // Get compare status (P1 only)
P3:0 = R4 // Set compare status (P0-P3)

这四个分支预测寄存器可被设置成四倍状态,此时此四个寄存器被表示成一个32位的寄存器

循环起始寄存器 Circular start registers

循环起始寄存器(CS0-CS1)将循环缓冲区的起始地址存储在循环寻址

1
2
3
4
CS0 = R5 // Set circ start register
M0 = R7 // Set modifier register
R0 = memb(R2++#4:circ(M0)) // Load from circ buffer pointed
// to by CS0 with size/K vals in M0

用户通用指针寄存器 User general pointer register

The user general pointer (UGP) register is a general-purpose control register.

1
2
R9 = UGP // Get UGP
UGP = R3 // Set UGP

UGP通常用于存储线程本地存储的地址。

全局指针 Global pointer

全局指针(GP)用于GP相对寻址

1
2
GP = R7 // Set GP
R2 = memw(GP+#200) // GP-relative load

周期计数寄存器 Cycle count registers

周期计数寄存器(UPCYCLELO-UPCYCLEHI)存储一个64位值,其中包含自从上次重置Hexagon处理器以来当前执行的处理器周期数。

[^NOTE]: The RTOS must grant permission to access these registers. Without this permission, reading these registers from user code always returns zero.

1
2
3
R5 = UPCYCLEHI // Get cycle count (high)
R4 = UPCYCLELO // Get cycle count (low)
R5:4 = UPCYCLE // Get cycle count

帧限制寄存器 Frame limit register

帧限制寄存器(FRAMELIMIT)存储存储区的低地址为软件栈保留

1
2
R9 = FRAMELIMIT // Get frame limit register
FRAMELIMIT = R3 // Set frame limit register

栈key寄存器 Frame key registe

frame key register (FRAMEKEY)当它们存储在软件堆栈中时返回地址时用来存储用于XOR加密的密钥值

1
2
R2 = FRAMEKEY // Get frame key register
FRAMEKEY = R1 // Set frame key register

数据包计数寄存器 Packet count registers

数据包计数寄存器(PKTCOUNTLO-PKTCOUNTHI)存储一个64位值,其中包含自上次写入PKTCOUNT寄存器以来执行的指令数据包的当前数量。

1
2
3
R9 = PKTCOUNTHI // Get packet count (high)
R8 = PKTCOUNTLO // Get packet count (low)
R9:8 = PKTCOUNT // Get packet count

Qtimer寄存器

Qtimer寄存器(UTIMERLO-UTIMERHI)提供对Qtimer全局参考计数值的访问。 它们使Hexagon软件能够读取64位时间值,而不必执行昂贵的AHB加载。

1
2
3
R5 = UTIMERHI // Get Qtimer reference count (high)
R4 = UTIMERLO // Get Qtimer reference count (low)
R5:4 = UTIMER // Get Qtimer reference count