1. PowerPC級別
PowerPC 體系結構分爲三個級別(或者說是“book”)。通過對體系結構以這種方式進行劃分,爲實現可以選擇價格/性能比平衡的複雜性級別留出了空間,同時還保持了實現間的代碼兼容性。
Book I. 用戶指令集體系結構
定義了通用於所有 PowerPC 實現的用戶指令和寄存器的基本集合。這些是非特權指令,爲大多數程序所用。
Book II. 虛擬環境體系結構
定義了常規應用軟件要求之外的附加的用戶級功能,比如高速緩存管理、原子操作和用戶級計時器支持。雖然這些操作也是非特權的,但是程序通常還是通過操作系統調用來訪問這些函數。
Book III. 操作環境體系結構
定義了操作系統級需要和使用的操作。其中包括用於內存管理、異常向量處理、特權寄存器訪問、特權計時器訪問的函數。Book III 中詳細說明了對各種系統服務和功能的直接硬件支持。
2. PowerPC存儲模型
PowerPC 體系結構本身支持字節(8 位)、字(16 位)、雙字(32 位) 和四字(64 位) 數據類型。PowerPC 實現還可以處理最長 128 字節的多字節字符串操作。32 位 PowerPC 實現支持 4-gigabyte 的有效地址空間,而 64 位 PowerPC 實現支持 16-exabyte 的有效地址空間。所有存儲都可以字節尋址。
3. PowerPC應用級寄存器
PowerPC 的應用級寄存器分爲三類:通用寄存器(general-purpose register,GPR)、浮點寄存器(floating-point register [FPR] 和浮點狀態和控制寄存器 [Floating-Point Status and Control Register,FPSCR])和專用寄存器(special-purpose register,SPR)。讓我們來分別看一下這三類寄存器。
通用寄存器(GPR)
用戶指令集體系結構(Book I)規定,所有實現都有 32 個 GPR(從GPR0 到 GPR31)。GPR 是所有整數操作的源和目的,也是所有加載/存儲操作的地址操作數的源。GPR 還提供對 SPR 的訪問。所有 GRP 都是可用的,只有一種情況例外:在某些指令中,GPR0 只是代表數值 0,而不會去查找 GPR0 的內容。
浮點寄存器(FPR)
Book I 規定,所有實現都有 32 個 FPR(從 FPR0 到 FPR31)。FPR 是所有浮點操作的源和目的操作數,可以存放 32 位和 64 位的有符號和無符號整數,以及單精度和雙精度浮點數。FPR 還提供對 FPSCR 的訪問。
注意,嵌入式微處理器實現時經常不提供對浮點指令集的直接硬件支持,或者只是提供一個附加浮點硬件的接口。很多嵌入式應用程序很少或者根本不需要浮點算法,而當需要的時候,對 PowerPC 浮點指令執行進行軟件仿真就足夠了。在嵌入式微處理器中,硬件中省去浮點(支持)而爲實現帶來的芯片面積和功率的減少是至關重要的。
浮點狀態和控制寄存器(FPSCR)捕獲浮點操作的狀態和異常結果,FPSCR 還具有控制位,以支持特定的異常類型和對四種舍入模式之一的選擇。對 FPSCR 的訪問要通過 FPR。
專用寄存器(SPR)
SPR 給出處理器核心內部資源的狀態並對其進行控制。不需要系統服務的支持就可以由應用程序讀寫的 SPR 包括計數寄存器(Count Register)、鏈接寄存器(Link Register)和整型異常寄存器(Integer Exception Register)。需要系統服務的支持纔可以由應用程序讀寫的 SPR 包括時基(Time Base)和其他各種可能支持的計時器。
- 指令地址寄存器(Instruction Address Register,IAR)
這個寄存器就是程序員們所熟知的 程序計數器或者 指令指針。它是當前指令的地址。這實際上是一個僞寄存器,用戶只能通過“branch and link”指令才能直接使用這個寄存器。IAR 主要是由調試器使用,顯示將要被執行的下一條指令。 - 鏈接寄存器(Link Register,LR)
這個寄存器存放的是函數調用結束處的返回地址。某些轉移指令可以自動加載 LR 到轉移之後的指令。每個轉移指令編碼中都有一個 LK 位。如果 LK 爲 1,轉移指令就會將程序計數器移爲 LR 中的地址。而且,條件轉移指令bclr
轉移到 LR 中的值。 - 定點異常寄存器(Fixed-Point Exception Register,XER)
這個寄存器存放整數運算操作的進位以及溢出信息。它還存放某些整數運算操作的進位輸入以及加載和存儲指令(lswx
和stswx
)中傳輸的字節數。 - 計數寄存器(Count Register,CTR)
這個寄存器中存放了一個循環計數器,會隨特定轉移操作而遞減。條件轉移指令bcctr
轉移到 CTR 中的值。 - 條件寄存器(Condition Register,CR)
這個寄存器分爲八個字段,每個字段 4 位。很多 PowerPC 指令將指令的第 31 位編碼爲 Rc 位,有一些指令要求 Rc 值等於 1。當 Rc 等於 1 且進行整數操作時,CR 字段 0 被設置來表示指令操作的結果:相等(Equal, EQ),大於(Greater Than, GT),小於(Less Than, LT),以及和溢出(Summary Overflow, SO)。當 Rc 等於 1 且進行浮點操作時,CR 字段 1 被設置用來表示 FPSCR 中異常狀態位的狀態:FX、FEX、VX 和 OX。任何一個 CR 字段都可以是整數或者浮點比較指令的目標。CR 字段 0 還被設置用來表示條件存儲指令(stwcx
或者stdcx
) 的結果。還有一組指令可以操縱特定的 CR 位、特定的 CR 字段或者整個 CR,通常爲了測試而將幾個條件組合到同一個位中。 - 處理器版本寄存器(Processor Version Register,PVR)
PVR 是一個 32 位只讀寄存器,標識處理器的版本和修訂級別。處理器版本由 PowerPC 體系結構過程分配。修訂級別由實現定義。需要有特權才能訪問 PVR,所以應用程序只能在操作系統函數的幫助下才可以確定處理器版本。
4. PowerPC應用級指令集
表 1 列出了不同的指令類別以及每類的指令類型。
表 1. 指令類別
指令類別 | 基本指令 |
---|---|
Branch | branch, branch conditional, branch to LR, branch to CTR |
Condition register | crand, crnor, creqv, crxor, crandc, crorc, crnand, cror, CR move |
Storage access | load GPR/FPR, store GPR/FPR |
Integer arithmetic | add, subtract, negate, multiply, divide |
Integer comparison | compare algebraic, compare algebraic immediate, compare logical,compare logical immediate |
Integer logical | and, andc, nand, or, orc, nor, xor, eqv, sign extension, countleading zeros |
Integer rotate/shift | rotate, rotate and mask, shift left, shift right |
Floating-point arithmetic | add, subtract, negate, multiply, divide, square root, multiply-add,multiply-subtract, negative multiply-add, negative multiply-subtract |
Floating-point comparison | compare ordered, compare unordered |
Floating-point conversion | round to single, convert from/to integer word/doubleword |
FPSCR management | move to/from FPSCR, set/clear FPSCR bit, copy FPSCR field to CR |
Cache control | touch, zero, flush, store |
Processor management | system call, move to/from special purpose registers, mtcrf, mfcr |
指令解析
所有指令的編碼長度都是 32 位。PowerPC 的位編號方式與大部分其他定義相反:第 0 位是最重要的位,第 31 位是最不重要的位。指令首先由一個字段中較高的 6 位進行解碼,這 6 位稱爲 主要操作碼(primary opcode)。其餘 26 位包含的字段分別是操作數說明、立即(immediate)操作數以及擴展的操作碼(opcode),而且這些還可能是保留的位或字段。表 2 列出了 PowerPC 定義的基本指令格式。
表 2. PowerPC 指令格式
格式 | 0 | 6 | 11 | 16 | 21 | 26 | 30 | 31 |
---|---|---|---|---|---|---|---|---|
D-form | opcd | tgt/src | src/tgt | immediate | ||||
X-form | opcd | tgt/src | src/tgt | src | extended opcd | |||
A-form | opcd | tgt/src | src/tgt | src | src | extended opcd | Rc | |
BD-form | opcd | BO | BI | BD | AA | LK | ||
I-form | opcd | LI | AA | LK |
- D-form
這一指令格式提供至多兩個寄存器作爲源操作數,一個立即源,至多兩個寄存器作爲目的操作數。這一指令格式的一些變種使用部分目的和源寄存器操作數說明符作爲立即字段或作爲擴展的操作碼。 - X-form
這一指令格式提供至多兩個寄存器作爲源操作數,至多兩個目的操作數。這一指令格式的一些變種使用部分目的和源寄存器操作數說明符作爲立即字段或作爲擴展的操作碼。 - A-form
這一指令格式提供至多三個寄存器作爲源操作數,以及一個目的操作數。這一指令格式的一些變種使用部分目的和源寄存器操作數說明符作爲立即字段或作爲擴展的操作碼。 - BD-form
條件轉移指令使用的是這一指令格式。BO 指令字段指定了條件的類型;BI 指令字段指定了以哪個 CR 位作爲條件;BD 字段用作轉移位置。AA 位指定了轉移是絕對轉移還是相對轉移。換名話說,轉移目標地址是立即字段的值,還是立即字段的值與轉移地址的和。LK 位指定了下一個順序指令的地址是否作爲子例程調用的返回地址保存在鏈接寄存器中。 - I-form
無條件轉移指令使用這一指令格式。由於是無條件的,BD 格式中的 BO 和 BI 字段改變爲另外的轉移位置,以構成 LI 指令字段。同 BD 格式一樣,這一指令格式也支持 AA 和 LK 位。
如前所述,這些指令格式各有其變種。不過,這些格式是對大部分 PowerPC 指令集編碼結構的最好描述。
轉移指令
PowerPC 爲控制流程提供了一組指令,包括:
- 條件和無條件轉移指令。
- “遞減計數和如果是零或者非零時轉移”的能力。
- 絕對轉移和相對轉移。
- 使用鏈接寄存器或計數寄存器來指定轉移目標地址的轉移指令。
所有的轉移指令都具備保存後繼順序指令地址的能力,包括到鏈接寄存器的轉移。條件寄存器 32 位中的任意一位都可以指定爲條件轉移的條件,並可以指定 CR 位是否必須爲 0 或 1 時轉移條件才成立。
條件寄存器指令
PowerPC 提供了一組用於對 CR 的特定位執行布爾操作和對 CR 字段進行拷貝的指令。它允許組合多個轉移條件,這樣可以減少代價高昂的條件轉移的數量。表 3 列出了 PowerPC CR 邏輯指令。
表 3. PowerPC CR 邏輯指令
助記符 | 指令名 |
---|---|
crand | CR logical and |
crandc | CR logical and with complement |
creqv | CR logical equivalent |
crnand | CR logical not and |
crnor | CR logical not or |
cror | CR logical or |
crorc | CR logical or with complement |
crxor | CR logical xor |
整數運算指令
很多指令用於執行運算操作,包括 add、substract、negate、compare、multiply 和 divide。很多格式用於立即值、溢出檢測以及進位和借位。各實現中 multiply 和 divide 的執行是不同的,因爲這些通常是多週期指令。表 4 列出了 PowerPC 整數運算指令。
表 4. PowerPC 整數運算指令
助記符 | 指令名 |
---|---|
add[o][.] | add [& record OV] [& record CR0] |
addc[o][.] | add carrying [& record OV] [& record CR0] |
adde[o][.] | add extended [& record OV] [& record CR0] |
addi | add immediate |
addis | add immediate shifted |
addic[.] | add immediate carrying [& record CR0] |
addme[o][.] | add to minus one [& record OV] [& record CR0] |
addze[o][.] | add to zero [& record OV] [& record CR0] |
divd[o][.] | divide doubleword [& record OV] [& record CR0] |
divdu[o][.] | divide doubleword unsigned [& record OV] [& record CR0] |
divw[o][.] | divide word [& record OV] [& record CR0] |
divwu[o][.] | divide word unsigned [& record OV] [& record CR0] |
mulhd[.] | multiply high doubleword [& record CR0] |
mulhdu[.] | multiply high doubleword unsigned [& record CR0] |
mulhw[.] | multiply high word [& record CR0] |
mulhwu[.] | multiply high word unsigned [& record CR0] |
mulld[o][.] | multiply low doubleword [& record OV] [& record CR0] |
mulli | multiply low immediate |
mullw[o][.] | multiply low word [& record OV] [& record CR0] |
neg[o][.] | negate [& record OV] [& record CR0] |
subf[o][.] | subtract from [& record OV] [& record CR0] |
subfc[o][.] | subtract from carrying [& record OV] [& record CR0] |
subfe[o][.] | subtract from extended [& record OV] [& record CR0] |
subfi | subtract from immediate |
subfis | subtract from immediate shifted |
subfic[.] | subtract from immediate carrying [& record CR0] |
subfme[o][.] | subtract from to minus one [& record OV] [& record CR0] |
subfze[o][.] | subtract from to zero [& record OV] [& record CR0] |
邏輯、循環和移位指令
PowerPC 提供了一組完整的邏輯操作(指令),還支持對符號的擴展以及對 GPR 中前置零的統計。表 5 列出了 PowerPC 邏輯指令。
表 5. PowerPC 邏輯指令
助記符 | 指令名 |
---|---|
and[.] | and [& record CR0] |
andc[.] | and with complement [& record CR0] |
andi. | and immediate & record CR0 |
andis. | and immediate shifted & record CR0 |
eqv[.] | equivalent [& record CR0] |
nand[.] | not and [& record CR0] |
nor[.] | not or [& record CR0] |
or[.] | or [& record CR0] |
orc[.] | or with complement [& record CR0] |
oris | or immediate shifted |
ori | or immediate |
xor[.] | xor [& record CR0] |
xoris | xor immediate shifted |
xori | xor immediate |
cntlzd[.] | count leading zeros doubleword [& record CR0] |
cntlzw[.] | count leading zeros word [& record CR0] |
extsb[.] | extend sign byte [& record CR0] |
extsh[.] | extend sign halfword [& record CR0] |
extsw[.] | extend sign word [& record CR0] |
PowerPC 提供了一組健壯而強大的循環和移位操作(指令),如表 6 所列。
表 6. PowerPC 循環和移位指令
助記符 | 指令名 |
---|---|
rldc[.] | rotate left doubleword then clear [& record CR0] |
rldcl[.] | rotate left doubleword then clear left [& record CR0] |
rldcr[.] | rotate left doubleword then clear right [& record CR0] |
rldicl[.] | rotate left doubleword immediate then clear left [& record CR0] |
rldicr[.] | rotate left doubleword immediate then clear right [& record CR0] |
rldimi[.] | rotate left doubleword immediate then mask insert [& record CR0] |
rlwimi[.] | rotate left word immediate then mask insert [& record CR0] |
rlwinm[.] | rotate left word immediate then and with mask [& record CR0] |
rlwnm[.] | rotate left word then and with mask [& record CR0] |
sld[.] | shift left doubleword [& record CR0] |
slw[.] | shift left word [& record CR0] |
srad[.] | shift right doubleword [& record CR0] |
sradi[.] | shift right doubleword immediate [& record CR0] |
sraw[.] | shift right word [& record CR0] |
srawi[.] | shift right word immediate [& record CR0] |
srd[.] | shift right doubleword [& record CR0] |
srw[.] | shift right word [& record CR0] |
浮點指令
PowerPC 提供了一組健壯的浮點運算、比較和轉換操作(指令)。與軟件支持一道,PowerPC 浮點運算完全符合 ANSI/IEEE 標準 754-1985 規範。在所有運算和比較操作中都支持單精度和雙精度浮點格式。
雖然浮點數以雙精度格式存儲於 FPR 中,但是,有一組單精度運算指令,可以執行運算操作並將最終結果舍入爲單精度,同時檢測進行單精度操作時可能會發生的異常(比如指數溢出、下溢和失去精度)。
- 一組 Load Floating-point Single指令可以訪問存儲器中的字,並在將其放入目標 FPR 前把單精度值轉換爲雙精度值。
- 一組 Store Floating-point Single指令可以將源 FPR 中的源操作數在存儲到存儲器中目標字之前轉換爲單精度格式。
可以啓用或禁用具體種類的浮點異常來支持設陷(trapping) 環境。表 7 列出了基本的和可選的 PowerPC 浮點指令集。
表 7. PowerPC 浮點指令
助記符 | 指令名 |
---|---|
fmr[.] | FP move [& record CR1] |
fneg[.] | FP negate [& record CR1] |
fabs[.] | FP absolute value [& record CR1] |
fnabs[.] | FP negative absolute value [& record CR1] |
fadd[s][.] | FP add [single] [& record CR1] |
fsub[s][.] | FP subtract [single] [& record CR1] |
fmul[s][.] | FP multiply [single] [& record CR1] |
fdiv[s][.] | FP divide [single] [& record CR1] |
fsqrt[s][.] | FP square root [single] [& record CR1] |
fmadd[s][.] | FP multiply-add [single] [& record CR1] |
fmsub[s][.] | FP multiply-subtract [single] [& record CR1] |
fnmadd[s][.] | FP negative multiply-add [single] [& record CR1] |
fnmsub[s][.] | FP negative multiply-subtract [single] [& record CR1] |
fcmpo | FP compare ordered |
fcmpu | FP compare unordered |
fsel[.] | FP select [& record CR1] |
frsp[.] | FP round to single [& record CR1] |
fcfid[.] | FP convert from integer doubleword [& record CR1] |
fctid[z][.] | FP convert to integer doubleword [& round to zero] [& record CR1] |
fctiw[z][.] | FP convert to integer word [& round to zero] [& record CR1] |
fres[.] | FP reciprocal estimate single [& record CR1] |
frsqrte[.] | FP reciprocal square root estimate [& record CR1] |
FPSCR 處理指令
表 8 列出了基本的 PowerPC FPSCR 處理指令集。
表 8. PowerPC FPSCR 處理指令集
助記符 | 指令名 |
---|---|
mcrfs | move to CR from FPSCR |
mffs[.] | move from FPSCR |
mtfsb0[.] | move to FPSCR bit 0 |
mtfsb1[.] | move to FPSCR bit 1 |
mtfsf[.] | move to FPSCR field |
mtfsfi[.] | move to FPSCR field immediate |
加載和存儲指令
所有加載和存儲指令的執行都使用 GPR 或者 GPR 和指令中的立即字段作爲存儲器訪問的地址說明符。用指令生成的數據有效地址來更新基址寄存器(也就是 RA)是大部分加載和存儲指令的一個可選項。
有用於以下方面的指令:
- 字節、半字、字和雙字大小。
- 在 GPR 或 FPR 與存儲器之間移動數據。
- 在 GPR 或 FPR 與存儲器之間移動數據。
特殊的存儲器訪問指令包括:
- 多字加載/存儲
即lmw
和stmw
,可以操作最多 31 個 32 位字。 - 字符串指令
這些指令可以操作最長 128 字節的字符串。 - 內存同步指令
這些用於實現內存同步。CR 的第 2 位(EQ 位) 設置用來記錄存儲操作的成功完成。內存同步指令包括:lwarx
(加載字並預留變址)ldarx
(加載雙字並預留變址)stwcx
(存儲字條件變址)stdcx
(存儲雙字條件變址)
lwarx
/ldarx
執行加載並設置處理器內部的預留位,編程模型不必明確瞭解這些行爲。如果設置了預留位,相應的存儲指令stwcx.
/stdcx.
執行條件存儲,並清除預留位。