本文将开始从开发者的角度研究Hexagon DSP的硬件细节。
在文章一开始,我们自然要对芯片所提供的寄存器给出详细的介绍。
在Hexagon 处理器的寄存器组中包含了两种寄存器,分别称之为通用寄存器以及控制寄存器,与我们见过的很多DSP类似,通用寄存器适用于通用类型的计算,例如地址的生成以及标量数据矢量数据的数学计算。
而在Hexagon处理器中,控制寄存器还可以支持特殊用途的处理器特性,例如硬件回路以及分支预测。
通用寄存器:
Hexagon处理器一共包含了32个32位的通用寄存器(命名为R0至R31).这些寄存器的用途便是为所有的操作存储操作数了,他们可以为load/store指令集的地址寻址,算数以及布尔运算的操作数,向量指令的向量操作数提供存储服务。
举例如下:
R1=memh(R0) //从地址R0中导入数据
R4=add(R2,R3) //相加
R28=vaddh(R11,R10) //向量加半字
下图也显示了通用寄存器的构成:
在这些通用寄存器当中,R29-R32被用来支持子程序的调用以及程序栈,这些寄存器可以无保留的被子程序调用或栈指令改变。在编程环境中,R29-R32可以用符号来表示。例如:
SP=add(SP,#-8) //sp是R29的别名
Allocfram //更改寄存器R29(SP)以及R30(FP)
call init //更改LR(R31)
下图显示了这些别名后的通用寄存器
寄存器对
寄存器在使用时,可以通过定义一个寄存器对来表示一个64位的寄存器,例如:
R1:0 =memd(R3) //导入双字
R7:6=valignb(R9:8,R7:6,#2) //适量对齐
下图显示了寄存器对的结构
控制寄存器:
Hexagon处理器包含了一系列的32位的控制寄存器,这些寄存器可以让我们对处理器中的PC,硬件回路以及矢量分支预测进行操作。
与通用寄存器不同,控制寄存器中有些特殊的控制寄存器可用来当做操作数,有时候寄存器可以被转换成指令从而被用作操作数。例如
R2 = memw(R0++M1) //自动加地址模式(M1)
R9 = PC //读取当前指针值
LC1 = R3 //设置硬件回路数
注意:当控制寄存器被用来作为寄存器转移或其他操作数时,操作数必须为寄存器。
下图也给出了控制寄存器的别名命名规则
可以认为这些控制寄存器用来确定指令编码过程中的控制寄存器。
寄存器对
控制寄存器同样可以被定义为寄存器对从而表示一个64位的寄存器,控制寄存器的凑对使用别名来定义,例如:
C1:0 = R5:4
下图列出了控制器存器能配对的种类
程序计数器
程序计数器(PC)在程序执行过程中用来指向下一个指令的位置,它可以通过指令执行来间接修改,不过可以被直接读取例如:
R7=PC //获得当前PC值
注意:对程序计数器的写操作没有任何效果
循环寄存器
Hexagon处理器包括两组循环寄存器从而支持硬件回路,每个硬件回路由包含了循环计数器以及循环开始位置的寄存器所实现。循环寄存器可以通过loop指令来间接修改,同时我们也可以直接访问,例如:
Loop0(start ,R4) //修改LC0与SA0
LC1 = R22 //获得loop1的数值
R9=SA1 //获得loop1的开始位置
下图定义了循环计数器
用户状态寄存器
用户状态寄存器(USR)可保存处理器状态并且维护这一组可被用户访问的寄存器。状态位的设定包含了各种指令可能的结果,特别是当硬件需要提前获取处理器中可写的处理器模式,而该模式可被控制寄存器更改时。
例如:
R9:8 = vaddw(R9:8 , R3:2):sat // 矢量加字
R6 = USR //获得saturation 状态
USR可包含如下的状态以及控制值
1. Cache预取使能
2. Cache预取状态
3. 浮点模式
4. 浮点状态
5. 硬件回路配置
6. 溢出
应当注意到,我们如果将用户控制模式转换到USR模式,我们不能将其并列至浮点指令中
无论在何时改变使能位,在异常发生影响前,应执行isync指令(这部分内容将在后面第五章讲到)
如下列出了全部的用户模式
分支预测寄存器
分支预测寄存器(P0-P3)保存了标量与矢量对比计算的结果,例如:
P1 = cmp.eq(R2,R3) //标量对比
If (P1) jump end //跳至地址
R8 = P1 //获得对比状态(P1)
P3:0 = P1 //设置比较状态位(P0-P3)
这四个分支预测寄存器可被设置成四倍状态,此时此四个寄存器被表示成一个32位的寄存器