1. 概述
Book E 定义的 PowerPC 指令集的指令可分为以下几类:
分支跳转指令
CR 指令
整数指令
浮点指令
处理器控制指令
存储管理相关指令
CR 指令主要是对 CR 内部位运算支持的一些指令,如 crand, cror, crxor 等等。
2. 常用指令
先看一个测试程序:
------------------------------------------------------------------
int test_call(int a, int b, int c)
{
a = b + c;
return a;
}
int test_if(int s)
{
int i;
if(s > 0)
i = s;
else if(s < 0)
i = -s;
else
i = s * 8;
return i;
}
int test_cyc1(int c)
{
int sum = 0;
do {
sum += c;
c--;
} while(c > 0);
return c;
}
int test_cyc2(int c)
{
int sum = 0;
for(; c > 0; c--)
sum += c;
return c;
}
int main()
{
int a, b, c, d;
a = test_if(5);
b = test_cyc1(10);
c = test_cyc2(10);
d = test_call(1, 2, 3);
return a + b + c + d;
}
------------------------------------------------------------------
引入的目的在于查看判断、循环和过程调用这些基本结构在 PowerPC 里怎么被支持。
-O2 参数编译后,objdump -S -d 反汇编,则:
------------------------------------------------------------------
1000040c :
int test_call(int a, int b, int c)
{
a = b + c;
return a;
}
1000040c: 7c 64 2a 14 add
r3,r4,r5 ----> 对应 a, b, c 三个参数,同时 r3 又置返回值
10000410: 4e 80 00 20 blr
----> 跳转到 LR 所存放的地址处,即函数返回
10000414 :
int test_if(int s)
{
int i;
if(s > 0)
10000414: 7c 60 1b 79 mr.
r0,r3 -----> r3 移到 r0,若 r0 小于、大于、等于 0,则置 CR0
的相应位。指令后多一点,则说明该指令会据执行结果,设置 CR 的相应位
10000418: 7c 03 03 78 mr
r3,r0 -----> 此条指令多余
1000041c: 4d a1 00 20 bgtlr+
-----> 若 CR0[gt] 位为 1,则跳转到 LR
所存放的地址处,即直接函数返回了。此条指令等价于 bclr 13, 1
i = s;
else if(s < 0)
10000420: 38 60 00 00 li
r3,0
10000424: 4d 82 00 20 beqlr
-----> 若 CR0[eq] 位为 1,则跳转到 LR
所存放的地址处,也直接函数返回了。此条指令等价于 bclr 12, 2
i = -s;
10000428: 7c 60 00 d0 neg
r3,r0 -----> r0 取反,入 r3
else
i = s * 8;
return i;
}
1000042c: 4e 80 00 20 blr
-----> 跳转到 LR 所存放的地址处,函数返回
10000430 :
int test_cyc1(int c)
{
10000430: 34 03 ff ff addic. r0,r3,-1
10000434: 7c 69 03 a6 mtctr
r3
10000438: 41 80 00 10 blt-
10000448
int sum = 0;
do {
sum += c;
c--;
1000043c: 38 63 ff ff addi
r3,r3,-1
} while(c > 0);
10000440: 42 00 ff fc bdnz+
1000043c
return c;
}
10000444: 4e 80 00 20 blr
10000448: 38 00 00 01 li
r0,1
1000044c: 7c 09 03 a6 mtctr
r0
10000450: 4b ff ff ec b
1000043c
10000454 :
int test_cyc2(int c)
{
10000454: 2c 03 00 00 cmpwi
r3,0
10000458: 39 20 00 00 li
r9,0
1000045c: 7d 23 48 1e .long 0x7d23481e
int sum = 0;
for(; c > 0; c--)
sum += c;
return c;
}
10000460: 7d 23 4b 78 mr
r3,r9
10000464: 4e 80 00 20 blr
int main()
{
10000468: 94 21 ff e0 stwu
r1,-32(r1)
1000046c: 7c 08 02 a6 mflr
r0
int a, b, c, d;
a = test_if(5);
10000470: 38 60 00 05 li
r3,5
10000474: 90 01 00 24 stw
r0,36(r1)
10000478: 93 61 00 0c stw
r27,12(r1)
1000047c: 93 81 00 10 stw
r28,16(r1)
10000480: 93 a1 00 14 stw
r29,20(r1)
10000484: 4b ff ff 91 bl
10000414
10000488: 7c 7d 1b 78 mr
r29,r3
b = test_cyc1(10);
1000048c: 38 60 00 0a li
r3,10
10000490: 4b ff ff a1 bl
10000430
10000494: 7c 7b 1b 78 mr
r27,r3
c = test_cyc2(10);
10000498: 38 60 00 0a li
r3,10
d = test_call(1, 2, 3);
1000049c: 7f bd da 14 add
r29,r29,r27
100004a0: 4b ff ff b5 bl
10000454
100004a4: 38 80 00 02 li
r4,2
100004a8: 7c 7c 1b 78 mr
r28,r3
100004ac: 38 a0 00 03 li
r5,3
100004b0: 38 60 00 01 li
r3,1
100004b4: 4b ff ff 59 bl
1000040c
return a + b + c + d;
}
100004b8: 80 01 00 24 lwz
r0,36(r1)
100004bc: 7f 9c 1a 14 add
r28,r28,r3
100004c0: 83 61 00 0c lwz
r27,12(r1)
100004c4: 7c 7d e2 14 add
r3,r29,r28
100004c8: 83 81 00 10 lwz
r28,16(r1)
100004cc: 83 a1 00 14 lwz
r29,20(r1)
100004d0: 7c 08 03 a6 mtlr
r0
100004d4: 38 21 00 20 addi
r1,r1,32
100004d8: 4e 80 00 20 blr
------------------------------------------------------------------
3. 分类概述
3.1 分支跳转指令
这类指令算是 PowerPC 里比较有特色的,也是稍显复杂的。这类指令与 CR, LR 和 CTR
紧密相联,建构起判断、循环和过程调用这些程序的基本结构。其大致可分为四类:
Branch
Branch Conditional
Branch Conditional to Count Register
Branch Conditional to Link Register
3.1.1 Branch
这类指令与 CR 没有联系,即为非条件跳转,助记符后直接跟立即数地址。指令内为立即数地址预留 26 位,即可跳转 2^26
大小的空间,如:(CIA, Current Instruction Address)
b 0x20
-----> 以当前指令地址为基点,往后跳转 0x20 字节,即 PC = CIA + 0x20
ba 0x20
-----> 直接跳转到地址 0x20 处。后缀为 a,则表示使用
Absolute Address,PC = 0x20。
bl 0x20
-----> 在 b 0x20 的基础上,将 LR 更新为 CIA + 4
bla 0x20
-----> 使用绝对地址,且更新 LR。后缀带 l,则表示更新 LR 为 CIA + 4
以上针对 32 位的情形,对 64 位则使用指令 be, bea, bel, bela 功能与上同。
3.1.2 Branch Conditional
此类为条件跳转指令。皆以 bc 开头,带 3 个操作数,如:
bc BO, BI, BD
bca BO, BI, BD
bcl BO, BI, BD
bcla BO, BI, BD
后缀 a, l 的含义与 branch 类指令同。BO 指定跳转的条件,5 位;BI 指定关联的 CR 位,也是 5 位;BD
为跳转的立即数地址,16 位。
其中以 BO 的编码最为复杂(BO 从左到右编号为 0 ~ 4):
BO[0]: 为 1,则直接跳转
BO[1]: 为 1,则条件为真时,跳转。否则条件为假时,跳转
BO[2]: 为 1,则 CTR 不自动减 1
BO[3]: 为 1 时,则 CTR == 0 时跳转;为 0 时,则 CTR != 0 时跳转
BO[4]: 静态预测位,1 表示 unlikely,0 表示 likely
则常见的 BO 值:
20 (0b10100) 则表示无条件跳转
12 (0b01100) 则表示 CR 的某个位为 1 时跳转
4 (0b00100) 则表示 CR 的某个位为 0 时跳转
至于静态预测的策略位,默认被置为 0,则其行为为:
b1. 目标地址小于当前指令地址,预测为跳转
b2. 目标地址大于当前指令地址,预测为不跳转
b3. 对于目标地址在 CTR/LR 中的条件跳转指令,一律预测为不跳转
若该位被置 1,则上述 b1, b2, b3 的静态预测行为分别为:不
跳转,跳转,跳转。
可以给分支指令加一个 +/- 的后缀,来简化。加 '+' 的指令,一律预测为跳转。加 '-' 的分支指令,一律预测为不跳转。
则对于 b1,后缀 '+' 会将 y 位置 0,'-' 则将 y 位置 1。
对于 b2,后缀 '+' 会将 y 位置 1,'-' 则将 y 位置 0。
对于 b3,后缀 '+' 会将 y 位置 1,'-' 则将 y 位置 0。
BI 与关联 CR 位的关系为:
32 + BI
即,若 BI 为 2,则对应于 CR[34],即为 CR0[gt] 位。
以上针对 32 位的情形,对 64 位则使用指令 bce, bcea, bcel, bcela 功能与上同。
3.1.3 Branch Conditional to Count Register
bcctr BO, BI
bcctrl BO, BI
后缀 l 的含义与 branch 类指令同。
BO,BI 的编码与 Branch Conditional 类指令同。
跳转目标地址位于 CTR 中。
以上针对 32 位的情形,对 64 位则使用指令 bcctre, bcctrel 功能与上同。
3.1.4 Branch Conditional to Link Register
bclr BO, BI
bclrl BO, BI
后缀 l 的含义与 branch 类指令同。
BO,BI 的编码与 Branch Conditional 类指令同。
跳转目标地址位于 LR 中。
以上针对 32 位的情形,对 64 位则使用指令 bclre, bclrel 功能与上同。
3.2 CR 指令
这类指令包括用来支持 CR 内部位运算的指令和 CR 与 GPR 之间的数据交换指令。
3.2.1 CR 内位运算指令
这类指令的格式皆为: crxxx BT, BA, BB
BT, BA, BB 是 CR 内的位编号,取值范围为 0 ~ 31,如 crand 0, 8, 12,则将
CR[32+8] (CR2[lt]) 与 CR[32+12] (CR3[lt]) 作与操作后,将结果置入 CR[32+0]
(CR0[lt]),即 CR[32] = CR[40] & CR[44]
crand: CR[32+BA] &
CR[32+BB]
crandc: CR[32+BA] &
(~CR[32+BB])
creqv: ~(CR[32+BA] ^
CR[32+BB]),即位相等,则置 1;不等则置 0
crnand: ~(CR[32+BA] & CR[32+BB])
crnor: ~(CR[32+BA] | CR[32+BB])
cror: CR[32+BA] | CR[32+BB]
crorc: CR[32+BA] | (~CR[32+BB]),先取反后再或
crxor: CR[32+BA] ^ CR[32+BB],位异或
3.2.2 CR 与 GPR 间数据交换指令
3.2.2.1 mcrf BF, BFA
--- Move Condition Register Fields
将 CR 之 BFA 域复制到 BF 域。如 mcrf 0, 3 则将 CR3 拷入 CR0
3.2.2.2 mtcrf FXM, RS ---
Move To Condition Register Fields
通用寄存器 RS 之 32 ~ 63 位以 4 位为单位,对应于 CR 的 8 个域,编号为 RS0 ~ RS7;
FXM 为域掩码,8 位,从左到右编号为 0 ~ 7,对应于 RS、CR 的 8 个域。某位为 1,则将对应的 RS 域拷贝到对应的 CR
域中。
若 FXM 为 0x80,则只将 CR0 = RS0
若 FXM 为 0xc8,则将 CR0 = RS0, CR1 = RS1, CR4 = RS4
3.2.2.3 mfcr RT
--- Move From Condition Register
将 CR 的内容移入通用寄存器 RT 的 32 ~ 63 位。
3.3 整数指令
这类指令大致分为如下几类:
整数访存指令
整数算术运算指令
整数逻辑运算指令
整数比较指令
整数陷阱指令
整数移位指令
XER 指令
其中以整数循环移位指令最为特别。
3.3.1 整数访存指令
3.3.1.1 Load Byte/Half-word/Word and Zero
该类指令从指定地址处读取 8 位、16 位、32 位数据,置入 RT,RT 高位置 0
lbz/lbzu RT, D(RA)
lbzx/lbzux RT, RA, RB
lhz/lhzu RT, D(RA)
lhzx/lhzux RT, RA, RB
lwz/lwzu RT, D(RA)
lwzx/lwzux RT, RA, RB
RT, RA, RB 皆为 GPR,D 为有符号立即数。则有效地址的计算分别为:RA[32:63] + D,RA[32:63] +
RB[32:63],有效地址高 32 位置 0。
后缀 u 表示 Update,即将有效地址更新到 RA 中
后缀 x 表示 Indexed,即使用 RA + RB 的寻址方式
以上用于 32 位,对 64 位,上述指令皆加后缀 'e'。则有效地址的 0 ~ 31 位, 不再置 0,其计算方式如下:RA + D,RA +
RB。
此外,用于 64 位的还有对双字操作的支持:
lde/ldue/ldxe/lduxe
3.3.1.2 Load Half-word Algebraic
lha/lhau RT, D(RA)
lhax/lhaux RT, RA, RB
与 lhz 不同的是,该指令将所读取的半字的最高位 (RT[48]) 填充到 RT[32:47],实际上就是形成一个 16
位的补码有符号数。
有效地址计算与上同;后缀 u, x 与上同。
对 64 位情形,上述指令皆加后缀 'e',有效地址计算与上小节同。
3.3.1.3 Load Halfword/Word
Byte-Reverse
从指定地址处读取 16 位/32 位数据,将字节反转后置入 RT,RT 高位置 0
lhbrx RT, RA, RB
lwbrx RT, RA, RB
如: lwbrx r3, r2, r1,若 r2 + r1 地址处的数据为 0x55aa66bb,则 r3 的结果为
0xbb66aa55
对 64 位情形,上述指令皆加后缀 'e',有效地址计算与上小节同。
3.3.1.4 Load Multiple Word
lmw RT, D(RA)
该指令将 RA + D 开始处的数据,顺序置入 RT ~ R31 中,共读取 31 - T 个字
该指令无 64 位扩展。
3.3.1.5 Load String Word
lswi RT, RA, NB (后缀 i,表示立即数 Immediate)
lswx RT, RA, RB (后缀 x,表示 Indexed 寻址方式)
加载 n 个字节到 RT 开始的寄存器中;
当 NB == 0 时 n = 32; NB != 0 时 n = NB,NB 取值范围为 0 ~ 31
如 r3 = 0x1000 :
lswi r4, r3, 16
则将 0x1000 处的 16 字节,依次写入 r4, r5, r6, r7
对于 lswx,要加载的字节数则位于 XER[57:63]
该指令无 64 位扩展。
3.3.1.6 Load Word/Doubleword and
Reserve
lwarx RT, RA, RB
该指令与 lwzx 的差别在于,其还将处理器内部的 RESERVE 位置为 1,并将有效地址对应的物理地址放入 RESERVE_ADDR 中。
该指令的 64 位版本为: lwarxe RT, RA, RB,差别还是在于有效地址的 0 ~ 31 不被置 0
此外还有一个 ldarxe RT, RA, RB,与 lwarxe 的差别在于其加载 8 字节的数据。
这三条指令常分别与 stwcx./stwcxe./stdcxe. 联用,用于实现锁操作,类似 MIPS 之 ll/sc 指令。
3.3.1.7 Store
stb/stbu RS, D(RA)
stbx/stbux RS, RA, RB
sth/sthu RS, D(RA)
sthx/sthux RS, RA, RB
stw/stwu RS, D(RA)
stwx/stwux RS, RA, RB
该类指令将 RS 中的 8 位、16 位、32 位数据写入有效地址处。后缀 'u', 'x' 之含义与 3.3.1.1 同。
上述 12 条指令加后缀 'e' 则用于 64 位。有效地址计算与与 3.3.1.1 同。
另用于 64 位的还有对双字操作的支持:
stde/stdue/stdxe/stduxe
3.3.1.8 Store Halfword/Word
Byte-Reverse
sthbrx RS, RA, RB
stwbrx RS, RA, RB
将 RS 中的 16/32 bit
的数据字节反转后置入有效地址处。该指令用于支持在大端系统上以小端序存储数据,亦或在小端系统上以大端序存储数据。
对 64 位情形,上述指令皆加后缀 'e',有效地址计算与上小节同。
3.3.1.9 Store Multiple Word
smw RS, D(RA)
该指令将 RS ~ R31 中的数据 (一个字),写入到 RA + D 处
该指令无 64 位扩展。
3.3.1.10 Store String Word
stswi RS, RA, NB (后缀 i,表示立即数 Immediate)
stswx RS, RA, RB (后缀 x,表示 Indexed 寻址方式)
与 lswi/lswx 的操作相反,其将 RS 开始的寄存器组中的 n 个字节,写入到有效地址处(位于 RA)
当 NB == 0 时 n = 32; NB != 0 时 n = NB,NB 取值范围为 0 ~ 31
如 r3 = 0x1000 :
stswi r4, r3, 16
则将 r4, r5, r6, r7 中的 16 字节数据依次写入 0x1000 处
对于 stswx,要加载的字节数则位于 XER[57:63]
该指令无 64 位扩展。
3.3.1.11 Store Word/Doubleword
Conditional
stwcx. RS, RA, RB
如果 RESERVE 位为 1,且 RA + RB 对应的物理地址与 RESERVE_ADDR 一致,则将 RS[32:63] 的内容写入到
RA + RB 处,将 CR0[eq] 位置为 1 后,再将 RESERVE 位复位为 0。
若条件不满足,则仅将 CR0[eq] 位置为 0
可用该指令与 lwarx 联用,实现 spin_lock:
li r0, 1
loop:
lwarx r4, 0, r3
cmpwi r4, 0 # r4[32:63] 与 0 比较
bne loop
stwcw. r0, 0, r3
bne loop
isync
解锁则为:
msync
li r0, 0
stw r0, 0(r3)
下面的指令用于 64 位:
stwcxe. RS, RA, RB
stdcxe. RS, RA, RB
差别在于有效地址的高 32 位不再被置为 0。
3.3.2 整数算术运算指令
3.3.3 整数逻辑运算指令
3.3.4 整数比较指令
cmp BF, L, RA, RB
cmpi BF, L, RA, SI # RA 与有符号立即数 SI 比较
cmpl BF, L, RA, RB # RA, RB 逻辑比较。l
---> logical
cmpli BF, L, RA, UI # RA 与无符号立即数 UI
逻辑比较
BF 取值 0 ~ 7,用于指定使用的 CR 域
L 为 0,则为 32 位比较;为 1,则为 64 位比较
如:
cmpi 0, 0, r3, 5
若 r3 > 5,则 CR0[gt] = 1;若 r3 < 5,则 CR0[lt] = 1
3.3.5 整数陷阱指令
tw TO, RA, RB
twi TO, RA, SI
TO 为立即数,5 位,从左到右标号为 0 ~ 4,依次表示小于、大于、等于、无符号小于、无符号大于。用于指定 Trap 的条件。
SI: Signed Immediate
如:
twi 0x10, r3, 5
则如果 r3 < 5,则陷入异常。
以上用于单字 (32 bit) 比较,双字比较则用:
td TO, RA, RB
tdi TO, RA, SI
3.3.6 整数移位指令
3.3.6.1 Rotate
rlwimi RA, RS, SH, MB, ME #
Rotate Left Word Immediate then Mask Insert
rlwinm RA, RS, SH, MB, ME #
Rotate Left Word Immediate then AND with Mask
rlwnm RA, RS, RB, MB, ME #
Rotate Left Word then AND with Mask
以下是该指令的一些例子:
all r11 is: 0x55aa67bb
r0 = 0x00000000
rlwimi r0, r11, 8, 0, 31
r0 is: 0xaa67bb55
r0 = 0x12345678
rlwimi r0, r11, 8, 0, 14
r0 is: 0xaa665678
r0 = 0x12345678
rlwimi r0, r11, 8, 28, 3
r0 is: 0xa2345675
即:取 RS 循环左移 SH 位后的 WB 到 WE 位,替换 RA 的 WB 到 WE 位。
r0 = 0x00000000
rlwinm r0, r11, 8, 0, 31
r0 is: 0xaa67bb55
r0 = 0x12345678
rlwinm r0, r11, 8, 0, 14
r0 is: 0xaa660000
即:取 RS 循环左移 SH 位后的 WB 到 WE 位,替换归零后的 RA
rldcl
rldcr
rldic
rldicl
rldicr
rldimi
3.3.6.2 Shift
slw
srw
sraw
srawi
slw./srw./sraw./srawi.
sld
srd
srad
sradi
3.3.7 XER 指令
mcrxr BF
mcrxr64 BF
3.4 浮点指令
这类指令包括:
浮点数据加载与存储指令
浮点运算指令
浮点数近似和转化指令
浮点比较指令
浮点状态和控制寄存器指令
有关该指令的详情留待以后以《PowerPC 浮点结构》的形式讨论吧。
3.5 处理器控制指令
这类指令包括用于支持异常中断处理的:
sc System Call
rfci Return From Critical Interrupt
rfi Return From Interrup
用于处理器控制寄存器维护的:
mfspr RT, SPRN Move From SPRN (Special
Purpose Register) to RT
mtspr SPRN, RS Move RS To SPRN
mfdcr RT, DCRN Move From DCRN (Device
Control Register) to RT
mtdcr DCRN, RS Move RS To DCRN
mfmsr RT Move From MSR to RT
mtmsr RS Move RS To MSR
wrtee RA Write MSR External Enable, MSR[EE] = RA[48]
wrteei E Write MSR External Enable Immediate, MSR[EE] = E
以及用于指令同步的:
isync
其保证在其之前的所有指令皆提交,在其自己被提交前,其之后的指令不会进入流水线
3.6 存储管理相关指令
这类指令包括用于 TLB 管理的:
tlbivax
tlbre
tlbwe
tlbsx
tlbsync
tlbivaxe
tlbsxe
用于 Cache 管理的:
dcba/dcbf/dcbi/dcbst/dcbt/dcbtst/dctz/icbi/icbt
dcbae/dcbfe/dcbie/dcbste/dcbte/dcbtste/dctze/icbie/icbte
用于存储同步的:
msync
mbar
阅读(7931) | 评论(0) | 转发(0) |