本文由 简悦 SimpRead 转码, 原文地址 www.cnblogs.com
PowerPC 体系结构规范(PowerPC Architecture Specification)公布于 1993 年,它是一个 64 位规范 ( 也包括 32 位子集 )。差点儿全部常规可用的 PowerPC(除了新型号 IBM RS/6000 和全部 IBM pSeries 高端 server)都是 32 位的。
PowerPC 处理器有 32 个(32 位或 64 位)GPR(通用寄存器)以及诸如 PC(程序计数器,也称为 IAR/指令地址寄存器或 NIP/下一指令指针)、LR(链接寄存器)、CR(条件寄存器)等各种其他寄存器。
有些 PowerPC CPU 还有 32 个 64 位 FPR(浮点寄存器)。MPC555 使用的 PowerPC CPU 是带有 FPR 的。一些经常使用寄存器介绍例如以下:
通用寄存器的用途:
R0 在函数開始(function prologs)时使用。
R1 堆栈指针,相当于 ia32 架构中的 esp 寄存器,idapro 把这个寄存器反汇编标识为 sp。
R2 内容表(toc)指针,idapro 把这个寄存器反汇编标识为 rtoc。系统调用时。它包括系统调用号(这个好像跟系统有关吧)。
R3 作为第一个參数和返回值。
R4-R10 函数或系统调用開始的參数。
R11 用在指针的调用和当作一些语言的环境指针。
R12 它用在异常处理和 glink(动态连接器)代码。
R13 保留作为系统线程 ID。
R14-R31 作为本地变量。非易失性。
专用寄存器的用途:
lr 链接寄存器,它用来存放函数调用结束处的返回地址。
ctr 计数寄存器,它用来当作循环计数器,会随特定转移操作而递减。
xer 定点异常寄存器。存放整数运算操作的进位以及溢出信息。
msr 机器状态寄存器,用来配置微处理器的设定。
cr 条件寄存器。它分成 8 个 4 位字段,cr0-cr7。它反映了某个算法操作的结果而且提供条件分支的机制。
寄存器 r1、r14-r31 是非易失性的,这意味着它们的值在函数调用过程保持不变。寄存器 r2 也算非易失性,可是仅仅有在调用函数在调用后必须恢复它的值时才被处理。
寄存器 r0、r3-r12 和特殊寄存器 lr、ctr、xer、fpscr 是易失性的,它们的值在函数调用过程中会发生变化。此外寄存器 r0、r2、r11 和 r12 可能会被交叉模块调用改变,所以函数在调用的时候不能採用它们的值。
条件代码寄存器字段 cr0、cr1、cr5、cr6 和 cr7 是易失性的。
cr2、cr3 和 cr4 是非易失性的,函数假设要改变它们必须保存并恢复这些字段。
在 AIX 上,svca 指令(sc 是 PowerPC 的助记符)用来表示系统调用,r2 寄存器指定系统调用号,r3-r10 寄存器是给该系统调用的參数。在运行系统调用指令之前有两个额外的先决条件:LR 寄存器必须保存返回系统调用地址的值而且在系统调用前运行 crorc cr6, cr6, cr6 指令(?)。
- 应用程序二进制接口(ABI)
从技术而言。开发者能够将任一 GPR 用于不论什么操作。比如。因为不存在:“堆栈指针寄存器”。为此程序猿就能够使用不论什么寄存器。实际上,定义一组约定非常实用,这样二进制对象就能够与不同的编译器和预先编写好的汇编代码进行互操作。
调用约定是由使用的 ABI(应用程序二进制接口)决定的。ppc32 Linux 和 NetBSD 实现使用 SVR4(System V R4)ABI,而 ppc64 Linux 仿效了 AIX,使用 PowerOpen ABI。ABI 还指定当调用子例程时哪些寄存器被觉得是易失型的(调用者保存 (caller-save))以及哪些被觉得是非易失型的(被调用者保存 (callee-save))。以及很多其他内容。
SVR4 ABI 指定了一些行为的详细演示样例:
- 因为 PowerPC 拥有如此多的 GPR(32 个,而相比之下 IA32 仅仅有 8 个),所以传递參数的寄存器从 gpr3 開始。
- 寄存器 gpr3 到 gpr12 是易失型的(调用者保存)寄存器,假设须要的话。在调用子例程之前必须先保存它们并在返回之后恢复它们。 - 寄存器 gpr1 用来作为栈帧指针。
指令格式
PowerPC
指令包含操作码和操作数两部分,PowerPC 支持三操作数的指令格式。如算术指令:
add rD,rA,rB
表示把(rA)+(rB)的和存放到 rD 寄存器中。
注意:
指令中的点号 “.” 表示:指令将更新条件寄存器 CR0。如 add. rD,rA。rB。
指令中的字母 “c” 表示:指令显示说明结果影响 XER 寄存器中的进位位 [CA],如 addc rD。rA。rB。
指令中的字母 “e” 表示:在指令中把 XER[CA] 中的数据作为一个操作数,并在 XER[CA] 位记录进位位,如 adde rD。rA,rB
指令中的字母 “o” 表示:溢出标志。
对于整数,在 XER[OA] 位记录溢出和在 CR0[SO] 记录溢出位。如 addo rD,rA。rB
条件寄存器
条件寄存器 CR 包含 8 个 4bit 的字段,即 CR0~CR7。
每一个字段能够表示整数运算或比較的结果。
每一个条件字段能够记录比較结果,即大于、小于、等于和整体溢出等。条件寄存器格式如图 1 所看到的。
异常处理器
整数异常寄存器 XER 是一个特殊功能寄存器。它包含一些对添加计算精度实用的信息和出错信息。
XER 的格式例如以下:
SO 为整体溢出标志:一旦有溢出位 OV 置位。SO 就会置位。
OV 为溢出标志:当发生溢出时置位,否则清零。在作乘法或除法运算时。假设结果超过寄存器的表达范围。则溢出置位。
CA 为进位标志:当最高位产生进位时,置位。否则清零;扩展精度指令(后述)能够用 CA 作为操作符參与运算。
存储 / 载入指令
1 整数存储指令
整数存储指令如表 2 所看到的。
表 2 整数存储指令
名称 | 助记符 | 语法格式 |
字节存储(偏移地址寻址) | stb | rS, d(rA) |
字节存储(寄存器寻址) | stbx | rS, rA, rB |
记录有效地址的字节存储(偏移地址寻址) | stbu | rS, d(rA) |
记录有效地址的字节存储(寄存器寻址) | stbux | rS, rA, rB |
半字存储(偏移地址寻址) | sth | rS, d(rA) |
半字存储(寄存器寻址) | sthx | rS, rA, rB |
记录有效地址的半字存储(偏移地址寻址) | sthu | rS, d(rA) |
记录有效地址的半字存储(寄存器寻址) | sthux | rS, rA, rB |
字存储(偏移地址寻址) | stw | rS, d(rA) |
字存储(寄存器寻址) | stwx | rS, rA, rB |
记录有效地址的字存储(偏移地址寻址) | stwu | rS, d(rA) |
记录有效地址的字存储(寄存器寻址) | stwux | rS, rA, rB |
(1) 字节存储指令 stb(偏移地址寻址)
stb rS,d(rA)
有效地址为 rA 的内容加 d,rS 的低 8 位内容存储到有效地址为 EA 的存储器中。
(2) 字节存储指令 stbx(寄存器寻址)
stbx rS。rA,rB
有效地址为 rA 的内容加上 rB 的内容,rS 的低 8 位内容存储到有效地址为 EA 的存储器中。
(3) 记录有效地址的字节存储指令 stbu(偏移地址寻址)
stub rS,d(rA)
有效地址 EA=(rA)+d,rS 的低 8 位内容存储到有效地址为 EA 的存储器中。rA=EA,假设 rA=0。则指令无效。
(4) 记录有效地址的字节存储指令 stbux(寄存器寻址)
stbux rS,rA。rB
有效地址 EA=(rA)+(rB),rS 的低 8 位内容存储到有效地址为 EA 的存储器中。rA=EA,假设 rA=0,则指令无效。
(5) 半字存储指令 sth(偏移地址寻址)
sth rS,d(rA)
有效地址 EA=(rA)+d,rS 的低 16 位内容存储到有效地址为 EA 的存储器中。
(6) 记录有效地址的半字存储指令 sthu(偏移地址寻址)
sthu rS,d(rA)
有效地址 EA=(rA)+d,rS 的低 16 位内容存储到有效地址为 EA 的存储器中。
rA=EA。假设 rA=0,则指令无效。
(7) 字存储指令 stw(偏移地址寻址)
stw rS。d(rA)
有效地址 EA=(rA)+d,rS 的 32 位内容存储到有效地址为 EA 的存储器中。
(8) 记录有效地址的字存储指令 stwu(偏移地址寻址)
stwu rS,d(rA)
有效地址 EA=(rA)+d,rS 的 32 位内容存储到有效地址为 EA 的存储器中,rA=EA,假设 rA=0。则指令无效。
(9) 记录有效地址的字存储指令 stwux(寄存器寻址)
stwux rS,rA,rB
有效地址 EA=(rA)+(rB),rS 的 32 位内容存储到有效地址为 EA 的存储器中。rA=EA,假设 rA=0,则指令无效。
(10)字存储指令 stwx(寄存器寻址)
stwx rS,rA,rB
有效地址 EA=(rA)+(rB),rS 的 32 位内容存储到有效地址为 EA 的存储器中。
2、整数载入指令
整数载入指令如表 3 所看到的。
名称 | 助记符 | 语法格式 |
高位清零载入字节指令(偏移地址寻址) | lbz | rD, d(rA) |
高位清零的载入字节指令(寄存器寻址) | lbzx | rD, rA, rB |
高位清零的载入字节并记录有效地址指令(偏移地址寻址) | lbzu | rD, d(rA) |
高位清零的载入字节并记录有效地址指令(寄存器寻址) | lbzux | rD, rA, rB |
高位清零的载入半字指令(偏移地址寻址) | lhz | rD, d(rA) |
高位清零的载入半字指令(寄存器寻址) | lhzx | rD, rA, rB |
高位清零的载入半字并记录有效地址指令(偏移地址寻址) | lhzu | rD, d(rA) |
高位清零的载入半字并记录有效地址指令(寄存器寻址) | lhzux | rD, rA, rB |
载入半字指令(偏移地址寻址) | lha | rD, d(rA) |
载入半字指令(寄存器寻址) | lhax | rD, rA, rB |
载入半字并记录有效地址指令(偏移地址寻址) | lhau | rD, d(rA) |
载入半字并记录有效地址指令(寄存器寻址) | lhaux | rD, rA, rB |
载入字指令(偏移地址寻址) | lwz | rD, d(rA) |
载入字指令(寄存器寻址) | lwzx | rD, rA, rB |
载入字并记录有效地址指令(偏移地址寻址) | lwzu | rD, d(rA) |
载入字并记录有效地址指令(寄存器寻址) | lwzux | rD, rA, rB |
(1) lbz rD, d(rA) ;EA=(rA|0)+d。从存储器读取 EA 地址的内容。并载入低 8 位到 rD,rD 的其它位清 0。不影响其它寄存器。
(2) lbzu rD, d(rA) ;EA=(rA)+d。从存储器读取 EA 地址一个字节的内容,并载入低 8 位到 rD。rD 的其它各位清零。有效地址 EA 存放在 rA 中。
(3) lbzux rD,rA,rB ;EA=(rA)+(rB)。
从存储器读取 EA 地址一个字节的内容,并载入低 8 位到 rD,rD 的其它各位清零,EA 存放在 rA 中。
假设 rA=0 或者 rA=rD。则指令无效。
(4) lbzx rD,rA,rB ;EA=(rA|0)+(rB)。从存储器读取 EA 地址一个字节的内容。并载入低 8 位到 rD,rD 的其它各位清 0。
(5) lha rD, d(rA) ;EA=(rA|0)+d。从存储器 EA 处读取两个字节的数。并载入到 rD 的低 16 位。rD 的其它位填充最高位的值。
(6) lhax rD。rA,rB 。EA=(rA)+(rB)。从存储器 EA 处读取两个字节的数。并载入到 rD 的低 16 位。rD 的其它位填充最高位的值。
(7) lhau rD, d(rA) ;EA=(rA)+d。从存储器 EA 处读取两个字节的数,并载入到 rD 的低 16 位。rD 的其它位填充最高位的值。
EA 存放在 rA 中,假设 rA=0 或者 rA=rD,则指令格式无效。
(8) lhaux rD。rA,rB 。EA=(rA)+(rB)。从存储器 EA 处读取两个字节的数,并载入到 rD 的低 16 位。
rD 的其它位填充最高位的值。
EA 存放在 rA 中,假设 rA=0 或者 rA=rD。则指令格式无效。
(9) lhz rD, d(rA) ;EA=(rA|0)+d。从存储器 EA 处读取两个字节的数,并载入到 rD 的低 16 位。rD 的其它位清零。
(10)lhzu rD, d(rA) 。EA=(rA|0)+d。从存储器 EA 处读取两个字节的数,并载入到 rD 的低 16 位。rD 其它位清零。EA 存入 rA,假设 rA=0 或者 rA=rD,则指令格式无效。
(11)lhzux rD,rA。rB 。EA=(rA)+(rB)。从存储器 EA 处读取两个字节的数,载入到 rD 的低 16 位,rD 其它位清零。
EA 存入 rA,假设 rA=0 或者 rA=rD,则指令格式无效。
(12)lhzx rD,rA,rB ;EA=(rA|0)+(rB)。从 EA 处读取两个字节的数,并载入到 rD 的低 16 位。将 rD 的其它位清零。
(13)lwz rD,d(rA) 。EA=(rA|0)+d,从 EA 处读取 4 个字节的数,并载入到 rD。
(14)lwzu rD,d(rA) ;EA=(rA)+d,从 EA 处读取 4 个字节的数。并载入到 rD。rA=EA。假设 rA=0 或 rA=rD,则指令格式无效。
(15)lwzux rD,rA,rB 。EA=(rA)+(rB),从 EA 处读取 4 个字节的数。并载入到 rD。rA=EA,假设 rA=0 或 rA=rD,则指令格式无效。
(16)lwzx rD,rA,rB ;EA=(rA|0)+(rB),从 EA 处读取 4 个字节的数,并载入到 rD。
整数多字存储 / 载入指令
表 3 整数多字存储 / 载入指令
名称 | 助记符 | 语法格式 |
多字载入 | lmw | rD,d(rA) |
多字存储 | stmw | rS,d(rA) |
(1) lmw rD,d(rA) ;EA=rA+d。以 EA 起始的 n 个连续的字载入到通用寄存器 GPRs rD 到 r31 处。n=32-rD。EA 必须为 4 的倍数。假设 rA=0。则指令格式无效。指令运行时间长。
(2) stmw rS。d(rA) ;EA=rA+d。
把通用寄存器从 GPRs rS 到 GPRs r31。存储到以 EA 起始的 n 个连续的字存储器,EA 必须是 4 的倍数。
指令运行时间长。
转移指令
表 4 分支控制指令
名称 | 助记符 | 语法格式 |
无条件转移 | b( ba bl bla) | target_addr |
条件转移 | bc( bca bcl bcla) | BO,BI,target_addr |
条件转移(转移目标地址由LR指出) | bclr(bclrl) | BO,BI |
条件转移(转移目标地址由CTR指出) | bcctr(bcctrl) | BO,BI |
(1) 无条件转移指令 bx(b ba bl bla)
指令的编码格式:
指令的语法格式:
b target_addr(AA=0 LK=0)
ba target_addr(AA=1 LK=0)
bl target_addr(AA=0 LK=1)
bla target_addr(AA=1 LK=1)
假设 AA=0,则转移目标地址为 LI||0b00 的值经符号位扩展后加上指令地址。
假设 AA=1。则转移目标地址为 LI||0b00 的值经符号扩展后的值。
假设 LK=1,则转移指令下一条指令的有效地址存放到连接寄存器。
(1) 条件转移指令 bcx
指令编码格式:
指令语法格式:
bc BO, BI, target_addr(AA=0 LK=0)
bca BO, BI, target_addr(AA=1 LK=0)
bcl BO, BI, target_addr(AA=0 LK=1)
bcla BO, BI, target_addr(AA=1 LK=1)
BI 字段表示条件寄存器 CR 中的位用于转移条件。
BO 字段操作码定义见表 5。
表 5 BO 字段操作码定义
BO | 说明 |
0000y | 计数器CTR减量。假设条件不成立则转移 |
0001y | 计数器CTR减量,假设条件不成立则转移 |
001zy | 假设条件不成立,则转移 |
0100y | 计数器CTR减量,假设条件成立则转移 |
0101y | 计数器CTR减量,假设条件成立则转移 |
011zy | 假设条件成立则转移 |
1z00y | 计数器CTR减量,假设CTR!=0,则发生转移 |
1z01y | 计数器CTR减量。假设CTR=0,则发生转移 |
1z1zz | 发生转移 |
注:位 z 表示该位能够被忽略,位 y 表示是不是条件转移
(2) 条件转移指令 bclx(转移目标地址由 LR 指出)
指令的编码格式:
指令的语法格式:
bclr BO, BI(LK=0)
bclrl BO, BI(LK=1)
BI 字段表示条件寄存器 CR 中的位用于转移条件。
BO 字段操作码定义如表 5 所看到的。
转移目标地址为 LR[0-29]||0b00。
假设 LK=1,则转移指令下一条有效地址存放到连接寄存器。
(3) 条件转移指令 bcctrx(转移目标地址由 CTR 指出)
指令的编码格式:
指令的语法格式:
bcctr BO, BI(LK=0)
bcctrl BO, BI(LK=1)
转移目标地址是 CTR||0b00。
假设 LK=1,则转移指令下一条指令的有效地址存放到连接寄存器。
假设减量计数器(BO[2]=0)。指令格式无效,则转移到目标地址。
特殊寄存器传送指令
特殊寄存器传送指令如表 6 所看到的。
表 6 特殊寄存器传送指令
名称 | 助记符 | 语法格式 |
读取机器状态寄存器 | mfmsr | rD |
写入机器状态寄存器 | mtmsr | rS |
读取特殊功能寄存器 | mfspr | rD, SPR |
写入特殊功能寄存器 | mtspr | SPR, rS |
读取段寄存器 | mfsr | rD, SR |
写入段寄存器 | mtsr | SR, rS |
间接读取段寄存器 | mfsrin | rD, rB |
间接写入段寄存器 | mtsrin | rS, rB |
读取时基寄存器 | mftb | rD, TBR |
(1) 读取机器状态寄存器指令 mfmsr
指令的编码格式:
指令的语法格式:
mfmsr rD
读取 MSR 的内容放入 rD 中。这是超级用户层指令,不影响其它寄存器。
(2)写入机器状态寄存器指令 mtmsr
指令的编码格式:
指令的语法格式:
mtmsr rS
把 rS 的内容存入 MSR 中,这是超级用户指令。
(1) 读取特殊功能寄存器指令 mfspr
指令的编码格式:
指令的语法格式:
mfspr rD。SPR
指令操作:
n<—spr[5-9]||spr[0-4]
rD<—spr(n)
特殊功能寄存器(SPR)的编码如表 7 所看到的,将 SPR 的内容存入 rD 中。
表 7 Power PC UISA SPR 编码
spr | 寄存器名 |
编码n | spr[5-9] |
1 | 00000 |
8 | 00000 |
9 | 00000 |
(2) 写入特殊功能寄存器指令 mtspr
指令的编码格式:
指令的语法格式:
mtspr spr,rS
把 rS 的内容存入到指定的特殊功能寄存器中。
(3) 读取段寄存器指令 mfsr
指令的编码格式:
指令的语法格式:
mfsr rD,SR
指令操作:
rD<—SEGREG(SR)
将段寄存器 SR 的内容读入 rD 中。这是一个超级用户层指令。
(1) 写入段寄存器指令 mtsr
指令的编码格式:
指令的语法格式:
mtsr SR,rS
将 rS 中的内容读入 SR,这是一个超级用户层指令。
(2) 间接读取段寄存器指令 mfsrin
指令的编码格式:
指令的语法格式:
mfsrin rD,rB
指令操作:
rD<—SEGREG(rB[0-3])
由 rB 寄存器的 0~3 位选取的段寄存器的内容,拷贝到 rDzhong。
这是一个超级用户层指令。
(3) 间接写入段寄存器指令 mtsrin
指令的编码格式:
指令的语法格式:
mtsrin rS。rB
指令操作:
SEGREG(rB[0-3])<—(rS)
将 rS 中的内容拷贝到由 rB 的 0~3 位所指定的寄存器中。
这是一个超级用户层指令。
(4) 读取时基寄存器指令 mftb
指令的编码格式:
指令的语法格式:
mftb rD,TBR
指令操作:
n<—tbr[5-9]||tbr[0-4]
if n=268 then
rD<—TBL
else if n=269 then
rD<—TBU
该指令的 TBR 编码如表 8 所看到的。
表 8 指令 mftb 的 TBR 编码
TBR | 寄存器名 | 訪问 |
编码 | tbr[5-9] | tbr[0-4] |
268 | 01000 | 01100 |
269 | 01000 | 01101 |
系统调用指令
(1) 系统调用指令 sc
指令的编码格式:
指令的使用:
sc 指令调用操作系统去运行服务程序。当控制返回到一个运行系统调用的程序时。寄存器的内容依赖于程序提供的系统所使用的寄存器的约定。
跟在 sc 指令后面的有效指令地址被放在 SRR0 中。MSR 中的位 0、5~9 和 16~31 被放在 SRR1 中相应的位置,SRR1 中位 1~4 和 10~15 被设置为没有定义值。当 sc 异常产生。异常处理程序更改 MSR 寄存器。异常处理程序到 MSR[IP] 形成基址加 0xC00 偏移量形成的地址去取下一条指令。
受影响的寄存器有:
依赖于系统服务、SRR0、SRR1 及 MSR。
(2) 中断返回指令 rfi
指令的编码格式:
指令操作:
MSR[16-23,25-27,30-31] <—SRR1[16-23,25-27,30-31]
NIA<—iea SRR0[0-29]||0b00
SRR1 中的位 0、5~9 和 16~31 被放在 MSR 中相应的位置。假设新的 MSR 值没有使能不论什么未完的操作,则在 MSR 的控制下。从地址 SRR0[0-29]||0b00 取下一条指令。
指令的使用中受影响的寄存器为 MSR
PowerPC 体系结构规范(PowerPC Architecture Specification)公布于 1993 年,它是一个 64 位规范 ( 也包括 32 位子集 )。差点儿全部常规可用的 PowerPC(除了新型号 IBM RS/6000 和全部 IBM pSeries 高端 server)都是 32 位的。
PowerPC 处理器有 32 个(32 位或 64 位)GPR(通用寄存器)以及诸如 PC(程序计数器。也称为 IAR/指令地址寄存器或 NIP/下一指令指针)、LR(链接寄存器)、CR(条件寄存器)等各种其他寄存器。有些 PowerPC CPU 还有 32 个 64 位 FPR(浮点寄存器)。MPC555 使用的 PowerPC CPU 是带有 FPR 的。一些经常使用寄存器介绍例如以下:
通用寄存器的用途:
r0 在函数開始(function prologs)时使用。
r1 堆栈指针,相当于 ia32 架构中的 esp 寄存器,idapro 把这个寄存器反汇编标识为 sp。
r2 内容表(toc)指针,idapro 把这个寄存器反汇编标识为 rtoc。
系统调用时。它包括系统调用号(这个好像跟系统有关吧)。
r3 作为第一个參数和返回值。
r4-r10 函数或系统调用開始的參数。
r11 用在指针的调用和当作一些语言的环境指针。
r12 它用在异常处理和 glink(动态连接器)代码。
r13 保留作为系统线程 ID。
r14-r31 作为本地变量。非易失性。
专用寄存器的用途:
lr 链接寄存器,它用来存放函数调用结束处的返回地址。
ctr 计数寄存器,它用来当作循环计数器,会随特定转移操作而递减。
xer 定点异常寄存器,存放整数运算操作的进位以及溢出信息。
msr 机器状态寄存器。用来配置微处理器的设定。
cr 条件寄存器,它分成 8 个 4 位字段。cr0-cr7。它反映了某个算法操作的结果而且提供条件分支的机制。
寄存器 r1、r14-r31 是非易失性的。这意味着它们的值在函数调用过程保持不变。寄存器 r2 也算非易失性,可是仅仅有在调用函数在调用后必须恢复它的值时才被处理。
寄存器 r0、r3-r12 和特殊寄存器 lr、ctr、xer、fpscr 是易失性的,它们的值在函数调用过程中会发生变化。
此外寄存器 r0、r2、r11 和 r12 可能会被交叉模块调用改变。所以函数在调用的时候不能採用它们的值。
条件代码寄存器字段 cr0、cr1、cr5、cr6 和 cr7 是易失性的。cr2、cr3 和 cr4 是非易失性的。函数假设要改变它们必须保存并恢复这些字段。
在 AIX 上,svca 指令(sc 是 PowerPC 的助记符)用来表示系统调用,r2 寄存器指定系统调用号,r3-r10 寄存器是给该系统调用的參数。
在运行系统调用指令之前有两个额外的先决条件:LR 寄存器必须保存返回系统调用地址的值而且在系统调用前运行 crorc cr6, cr6, cr6 指令(?)。
- *应用程序二进制接口(**ABI)
从技术而言,开发者能够将任一 GPR 用于不论什么操作。
比如,因为不存在:“堆栈指针寄存器”,为此程序猿就能够使用不论什么寄存器。实际上,定义一组约定非常实用,这样二进制对象就能够与不同的编译器和预先编写好的汇编代码进行互操作。
调用约定是由使用的 ABI(应用程序二进制接口)决定的。ppc32 Linux 和 NetBSD 实现使用 SVR4(System V R4)ABI,而 ppc64 Linux 仿效了 AIX。使用 PowerOpen ABI。
ABI 还指定当调用子例程时哪些寄存器被觉得是易失型的(调用者保存 (caller-save))以及哪些被觉得是非易失型的(被调用者保存 (callee-save))。以及很多其他内容。
SVR4 ABI 指定了一些行为的详细演示样例:
- 因为 PowerPC 拥有如此多的 GPR(32 个,而相比之下 IA32 仅仅有 8 个),所以传递參数的寄存器从 gpr3 開始。
- 寄存器 gpr3 到 gpr12 是易失型的(调用者保存)寄存器,假设须要的话,在调用子例程之前必须先保存它们并在返回之后恢复它们。 - 寄存器 gpr1 用来作为栈帧指针。
指令格式
PowerPC
指令包含操作码和操作数两部分,PowerPC 支持三操作数的指令格式。如算术指令:
add rD。rA,rB
表示把(rA)+(rB)的和存放到 rD 寄存器中。
注意:
指令中的点号 “.” 表示:指令将更新条件寄存器 CR0。如 add. rD。rA。rB。
指令中的字母 “c” 表示:指令显示说明结果影响 XER 寄存器中的进位位 [CA]。如 addc rD,rA。rB。
指令中的字母 “e” 表示:在指令中把 XER[CA] 中的数据作为一个操作数,并在 XER[CA] 位记录进位位。如 adde rD,rA,rB
指令中的字母 “o” 表示:溢出标志。对于整数,在 XER[OA] 位记录溢出和在 CR0[SO] 记录溢出位。如 addo rD。rA,rB
条件寄存器
条件寄存器 CR 包含 8 个 4bit 的字段。即 CR0~CR7。
每一个字段能够表示整数运算或比較的结果。
每一个条件字段能够记录比較结果。即大于、小于、等于和整体溢出等。
条件寄存器格式如图 1 所看到的。
异常处理器
整数异常寄存器 XER 是一个特殊功能寄存器。它包含一些对添加计算精度实用的信息和出错信息。XER 的格式例如以下:
SO 为整体溢出标志:一旦有溢出位 OV 置位,SO 就会置位。
OV 为溢出标志:当发生溢出时置位,否则清零;在作乘法或除法运算时,假设结果超过寄存器的表达范围,则溢出置位。
CA 为进位标志:当最高位产生进位时,置位。否则清零;扩展精度指令(后述)能够用 CA 作为操作符參与运算。
存储 / 载入指令
1 整数存储指令
整数存储指令如表 2 所看到的。
表 2 整数存储指令
名称 | 助记符 | 语法格式 |
字节存储(偏移地址寻址) | stb | rS, d(rA) |
字节存储(寄存器寻址) | stbx | rS, rA, rB |
记录有效地址的字节存储(偏移地址寻址) | stbu | rS, d(rA) |
记录有效地址的字节存储(寄存器寻址) | stbux | rS, rA, rB |
半字存储(偏移地址寻址) | sth | rS, d(rA) |
半字存储(寄存器寻址) | sthx | rS, rA, rB |
记录有效地址的半字存储(偏移地址寻址) | sthu | rS, d(rA) |
记录有效地址的半字存储(寄存器寻址) | sthux | rS, rA, rB |
字存储(偏移地址寻址) | stw | rS, d(rA) |
字存储(寄存器寻址) | stwx | rS, rA, rB |
记录有效地址的字存储(偏移地址寻址) | stwu | rS, d(rA) |
记录有效地址的字存储(寄存器寻址) | stwux | rS, rA, rB |
(1) 字节存储指令 stb(偏移地址寻址)
stb rS,d(rA)
有效地址为 rA 的内容加 d,rS 的低 8 位内容存储到有效地址为 EA 的存储器中。
(2) 字节存储指令 stbx(寄存器寻址)
stbx rS,rA,rB
有效地址为 rA 的内容加上 rB 的内容,rS 的低 8 位内容存储到有效地址为 EA 的存储器中。
(3) 记录有效地址的字节存储指令 stbu(偏移地址寻址)
stub rS。d(rA)
有效地址 EA=(rA)+d,rS 的低 8 位内容存储到有效地址为 EA 的存储器中。rA=EA,假设 rA=0。则指令无效。
(4) 记录有效地址的字节存储指令 stbux(寄存器寻址)
stbux rS。rA,rB
有效地址 EA=(rA)+(rB),rS 的低 8 位内容存储到有效地址为 EA 的存储器中,rA=EA,假设 rA=0,则指令无效。
(5) 半字存储指令 sth(偏移地址寻址)
sth rS,d(rA)
有效地址 EA=(rA)+d。rS 的低 16 位内容存储到有效地址为 EA 的存储器中。
(6) 记录有效地址的半字存储指令 sthu(偏移地址寻址)
sthu rS,d(rA)
有效地址 EA=(rA)+d,rS 的低 16 位内容存储到有效地址为 EA 的存储器中。rA=EA,假设 rA=0,则指令无效。
(7) 字存储指令 stw(偏移地址寻址)
stw rS。d(rA)
有效地址 EA=(rA)+d,rS 的 32 位内容存储到有效地址为 EA 的存储器中。
(8) 记录有效地址的字存储指令 stwu(偏移地址寻址)
stwu rS。d(rA)
有效地址 EA=(rA)+d。rS 的 32 位内容存储到有效地址为 EA 的存储器中。rA=EA,假设 rA=0,则指令无效。
(9) 记录有效地址的字存储指令 stwux(寄存器寻址)
stwux rS,rA。rB
有效地址 EA=(rA)+(rB),rS 的 32 位内容存储到有效地址为 EA 的存储器中。rA=EA,假设 rA=0,则指令无效。
(10)字存储指令 stwx(寄存器寻址)
stwx rS,rA,rB
有效地址 EA=(rA)+(rB)。rS 的 32 位内容存储到有效地址为 EA 的存储器中。
2、整数载入指令
整数载入指令如表 3 所看到的。
名称 | 助记符 | 语法格式 |
高位清零载入字节指令(偏移地址寻址) | lbz | rD, d(rA) |
高位清零的载入字节指令(寄存器寻址) | lbzx | rD, rA, rB |
高位清零的载入字节并记录有效地址指令(偏移地址寻址) | lbzu | rD, d(rA) |
高位清零的载入字节并记录有效地址指令(寄存器寻址) | lbzux | rD, rA, rB |
高位清零的载入半字指令(偏移地址寻址) | lhz | rD, d(rA) |
高位清零的载入半字指令(寄存器寻址) | lhzx | rD, rA, rB |
高位清零的载入半字并记录有效地址指令(偏移地址寻址) | lhzu | rD, d(rA) |
高位清零的载入半字并记录有效地址指令(寄存器寻址) | lhzux | rD, rA, rB |
载入半字指令(偏移地址寻址) | lha | rD, d(rA) |
载入半字指令(寄存器寻址) | lhax | rD, rA, rB |
载入半字并记录有效地址指令(偏移地址寻址) | lhau | rD, d(rA) |
载入半字并记录有效地址指令(寄存器寻址) | lhaux | rD, rA, rB |
载入字指令(偏移地址寻址) | lwz | rD, d(rA) |
载入字指令(寄存器寻址) | lwzx | rD, rA, rB |
载入字并记录有效地址指令(偏移地址寻址) | lwzu | rD, d(rA) |
载入字并记录有效地址指令(寄存器寻址) | lwzux | rD, rA, rB |
(1) lbz rD, d(rA) ;EA=(rA|0)+d。
从存储器读取 EA 地址的内容,并载入低 8 位到 rD,rD 的其它位清 0。
不影响其它寄存器。
(2) lbzu rD, d(rA) ;EA=(rA)+d。从存储器读取 EA 地址一个字节的内容,并载入低 8 位到 rD,rD 的其它各位清零。有效地址 EA 存放在 rA 中。
(3) lbzux rD。rA,rB ;EA=(rA)+(rB)。
从存储器读取 EA 地址一个字节的内容,并载入低 8 位到 rD。rD 的其它各位清零,EA 存放在 rA 中。假设 rA=0 或者 rA=rD。则指令无效。
(4) lbzx rD,rA,rB 。EA=(rA|0)+(rB)。
从存储器读取 EA 地址一个字节的内容。并载入低 8 位到 rD。rD 的其它各位清 0。
(5) lha rD, d(rA) ;EA=(rA|0)+d。从存储器 EA 处读取两个字节的数,并载入到 rD 的低 16 位。
rD 的其它位填充最高位的值。
(6) lhax rD,rA,rB ;EA=(rA)+(rB)。
从存储器 EA 处读取两个字节的数。并载入到 rD 的低 16 位。rD 的其它位填充最高位的值。
(7) lhau rD, d(rA) ;EA=(rA)+d。从存储器 EA 处读取两个字节的数,并载入到 rD 的低 16 位。rD 的其它位填充最高位的值。EA 存放在 rA 中,假设 rA=0 或者 rA=rD。则指令格式无效。
(8) lhaux rD,rA。rB 。EA=(rA)+(rB)。从存储器 EA 处读取两个字节的数,并载入到 rD 的低 16 位。rD 的其它位填充最高位的值。
EA 存放在 rA 中,假设 rA=0 或者 rA=rD。则指令格式无效。
(9) lhz rD, d(rA) ;EA=(rA|0)+d。从存储器 EA 处读取两个字节的数。并载入到 rD 的低 16 位。rD 的其它位清零。
(10)lhzu rD, d(rA) ;EA=(rA|0)+d。从存储器 EA 处读取两个字节的数,并载入到 rD 的低 16 位。rD 其它位清零。EA 存入 rA,假设 rA=0 或者 rA=rD。则指令格式无效。
(11)lhzux rD,rA。rB ;EA=(rA)+(rB)。从存储器 EA 处读取两个字节的数。载入到 rD 的低 16 位。rD 其它位清零。EA 存入 rA,假设 rA=0 或者 rA=rD。则指令格式无效。
(12)lhzx rD,rA。rB ;EA=(rA|0)+(rB)。从 EA 处读取两个字节的数,并载入到 rD 的低 16 位。将 rD 的其它位清零。
(13)lwz rD。d(rA) 。EA=(rA|0)+d。从 EA 处读取 4 个字节的数。并载入到 rD。
(14)lwzu rD,d(rA) 。EA=(rA)+d。从 EA 处读取 4 个字节的数,并载入到 rD。rA=EA。假设 rA=0 或 rA=rD,则指令格式无效。
(15)lwzux rD,rA,rB 。EA=(rA)+(rB),从 EA 处读取 4 个字节的数。并载入到 rD。
rA=EA。假设 rA=0 或 rA=rD,则指令格式无效。
(16)lwzx rD,rA,rB ;EA=(rA|0)+(rB)。从 EA 处读取 4 个字节的数,并载入到 rD。
整数多字存储 / 载入指令
表 3 整数多字存储 / 载入指令
名称 | 助记符 | 语法格式 |
多字载入 | lmw | rD,d(rA) |
多字存储 | stmw | rS,d(rA) |
(1) lmw rD。d(rA) ;EA=rA+d。
以 EA 起始的 n 个连续的字载入到通用寄存器 GPRs rD 到 r31 处,n=32-rD。EA 必须为 4 的倍数,假设 rA=0,则指令格式无效。指令运行时间长。
(2) stmw rS,d(rA) ;EA=rA+d。把通用寄存器从 GPRs rS 到 GPRs r31,存储到以 EA 起始的 n 个连续的字存储器,EA 必须是 4 的倍数。指令运行时间长。
转移指令
表 4 分支控制指令
名称 | 助记符 | 语法格式 |
无条件转移 | b( ba bl bla) | target_addr |
条件转移 | bc( bca bcl bcla) | BO,BI,target_addr |
条件转移(转移目标地址由LR指出) | bclr(bclrl) | BO,BI |
条件转移(转移目标地址由CTR指出) | bcctr(bcctrl) | BO,BI |
(1) 无条件转移指令 bx(b ba bl bla)
指令的编码格式:
指令的语法格式:
b target_addr(AA=0 LK=0)
ba target_addr(AA=1 LK=0)
bl target_addr(AA=0 LK=1)
bla target_addr(AA=1 LK=1)
假设 AA=0,则转移目标地址为 LI||0b00 的值经符号位扩展后加上指令地址。
假设 AA=1,则转移目标地址为 LI||0b00 的值经符号扩展后的值。
假设 LK=1,则转移指令下一条指令的有效地址存放到连接寄存器。
(1) 条件转移指令 bcx
指令编码格式:
指令语法格式:
bc BO, BI, target_addr(AA=0 LK=0)
bca BO, BI, target_addr(AA=1 LK=0)
bcl BO, BI, target_addr(AA=0 LK=1)
bcla BO, BI, target_addr(AA=1 LK=1)
BI 字段表示条件寄存器 CR 中的位用于转移条件。BO 字段操作码定义见表 5。
表 5 BO 字段操作码定义
BO | 说明 |
0000y | 计数器CTR减量,假设条件不成立则转移 |
0001y | 计数器CTR减量,假设条件不成立则转移 |
001zy | 假设条件不成立,则转移 |
0100y | 计数器CTR减量。假设条件成立则转移 |
0101y | 计数器CTR减量,假设条件成立则转移 |
011zy | 假设条件成立则转移 |
1z00y | 计数器CTR减量,假设CTR!
=0,则发生转移 |
1z01y | 计数器CTR减量,假设CTR=0,则发生转移 |
1z1zz | 发生转移 |
注:位 z 表示该位能够被忽略,位 y 表示是不是条件转移
(2) 条件转移指令 bclx(转移目标地址由 LR 指出)
指令的编码格式:
指令的语法格式:
bclr BO, BI(LK=0)
bclrl BO, BI(LK=1)
BI 字段表示条件寄存器 CR 中的位用于转移条件。
BO 字段操作码定义如表 5 所看到的。
转移目标地址为 LR[0-29]||0b00。
假设 LK=1,则转移指令下一条有效地址存放到连接寄存器。
(3) 条件转移指令 bcctrx(转移目标地址由 CTR 指出)
指令的编码格式:
指令的语法格式:
bcctr BO, BI(LK=0)
bcctrl BO, BI(LK=1)
转移目标地址是 CTR||0b00。
假设 LK=1。则转移指令下一条指令的有效地址存放到连接寄存器。
假设减量计数器(BO[2]=0),指令格式无效,则转移到目标地址。
特殊寄存器传送指令
特殊寄存器传送指令如表 6 所看到的。
表 6 特殊寄存器传送指令
名称 | 助记符 | 语法格式 |
读取机器状态寄存器 | mfmsr | rD |
写入机器状态寄存器 | mtmsr | rS |
读取特殊功能寄存器 | mfspr | rD, SPR |
写入特殊功能寄存器 | mtspr | SPR, rS |
读取段寄存器 | mfsr | rD, SR |
写入段寄存器 | mtsr | SR, rS |
间接读取段寄存器 | mfsrin | rD, rB |
间接写入段寄存器 | mtsrin | rS, rB |
读取时基寄存器 | mftb | rD, TBR |
(1) 读取机器状态寄存器指令 mfmsr
指令的编码格式:
指令的语法格式:
mfmsr rD
读取 MSR 的内容放入 rD 中,这是超级用户层指令,不影响其它寄存器。
(2)写入机器状态寄存器指令 mtmsr
指令的编码格式:
指令的语法格式:
mtmsr rS
把 rS 的内容存入 MSR 中,这是超级用户指令。
(1) 读取特殊功能寄存器指令 mfspr
指令的编码格式:
指令的语法格式:
mfspr rD,SPR
指令操作:
n<—spr[5-9]||spr[0-4]
rD<—spr(n)
特殊功能寄存器(SPR)的编码如表 7 所看到的,将 SPR 的内容存入 rD 中。
表 7 Power PC UISA SPR 编码
spr | 寄存器名 |
编码n | spr[5-9] |
1 | 00000 |
8 | 00000 |
9 | 00000 |
(2) 写入特殊功能寄存器指令 mtspr
指令的编码格式:
指令的语法格式:
mtspr spr,rS
把 rS 的内容存入到指定的特殊功能寄存器中。
(3) 读取段寄存器指令 mfsr
指令的编码格式:
指令的语法格式:
mfsr rD,SR
指令操作:
rD<—SEGREG(SR)
将段寄存器 SR 的内容读入 rD 中。这是一个超级用户层指令。
(1) 写入段寄存器指令 mtsr
指令的编码格式:
指令的语法格式:
mtsr SR。rS
将 rS 中的内容读入 SR,这是一个超级用户层指令。
(2) 间接读取段寄存器指令 mfsrin
指令的编码格式:
指令的语法格式:
mfsrin rD,rB
指令操作:
rD<—SEGREG(rB[0-3])
由 rB 寄存器的 0~3 位选取的段寄存器的内容。拷贝到 rDzhong。这是一个超级用户层指令。
(3) 间接写入段寄存器指令 mtsrin
指令的编码格式:
指令的语法格式:
mtsrin rS,rB
指令操作:
SEGREG(rB[0-3])<—(rS)
将 rS 中的内容拷贝到由 rB 的 0~3 位所指定的寄存器中。这是一个超级用户层指令。
(4) 读取时基寄存器指令 mftb
指令的编码格式:
指令的语法格式:
mftb rD,TBR
指令操作:
n<—tbr[5-9]||tbr[0-4]
if n=268 then
rD<—TBL
else if n=269 then
rD<—TBU
该指令的 TBR 编码如表 8 所看到的。
表 8 指令 mftb 的 TBR 编码
TBR | 寄存器名 | 訪问 |
编码 | tbr[5-9] | tbr[0-4] |
268 | 01000 | 01100 |
269 | 01000 | 01101 |
系统调用指令
(1) 系统调用指令 sc
指令的编码格式:
指令的使用:
sc 指令调用操作系统去运行服务程序。当控制返回到一个运行系统调用的程序时,寄存器的内容依赖于程序提供的系统所使用的寄存器的约定。
跟在 sc 指令后面的有效指令地址被放在 SRR0 中。MSR 中的位 0、5~9 和 16~31 被放在 SRR1 中相应的位置,SRR1 中位 1~4 和 10~15 被设置为没有定义值。当 sc 异常产生,异常处理程序更改 MSR 寄存器。
异常处理程序到 MSR[IP] 形成基址加 0xC00 偏移量形成的地址去取下一条指令。
受影响的寄存器有:
依赖于系统服务、SRR0、SRR1 及 MSR。
(2) 中断返回指令 rfi
指令的编码格式:
指令操作:
MSR[16-23,25-27,30-31] <—SRR1[16-23,25-27,30-31]
NIA<—iea SRR0[0-29]||0b00
SRR1 中的位 0、5~9 和 16~31 被放在 MSR 中相应的位置。
假设新的 MSR 值没有使能不论什么未完的操作,则在 MSR 的控制下,从地址 SRR0[0-29]||0b00 取下一条指令。
指令的使用中受影响的寄存器为 MSR