?
9.1??協(xié)處理器指令
ARM體系結(jié)構(gòu)允許通過增加協(xié)處理器來擴展指令集。最常用的協(xié)處理器是用于控制片上功能的系統(tǒng)協(xié)處理器。例如控制Cache和存儲管理單元的CP15寄存器。此外,還有用于浮點運算的浮點ARM協(xié)處理器,各生產(chǎn)商還可以根據(jù)需要開發(fā)自己的專用協(xié)處理器。
ARM協(xié)處理器具有自己專用的寄存器組,它們的狀態(tài)由控制ARM狀態(tài)的指令的鏡像指令來控制。
程序的控制流指令由ARM處理器來處理,所有協(xié)處理器指令只能同數(shù)據(jù)處理和數(shù)據(jù)傳送有關。按照RISC的Load/Store體系原則,數(shù)據(jù)的處理和傳送指令是被清楚分開的,所以它們有不同的指令格式。
ARM處理器支持16個協(xié)處理器,在程序執(zhí)行過程中,每個協(xié)處理器忽略ARM和其他協(xié)處理器指令。當一個協(xié)處理器硬件不能執(zhí)行屬于它的協(xié)處理器指令時,將產(chǎn)生一個未定義指令異常中斷,在該異常中斷處理過程中,可以通過軟件仿真該硬件操作。如果,一個系統(tǒng)中不包含向量浮點運算器,則可以選擇浮點運算軟件包來支持向量浮點運算。
ARM協(xié)處理器可以部分地執(zhí)行一條指令,而后產(chǎn)生中斷。如除法運算除數(shù)為0和溢出,這樣可以更好地處理運行時產(chǎn)生(run-time-generated)的異常。但是,指令的部分執(zhí)行是由協(xié)處理器完成的,此過程對ARM來說是透明的。當ARM處理器重新獲得執(zhí)行時,它將從產(chǎn)生異常的指令處開始執(zhí)行。
對某一個協(xié)處理器來說,并不一定用到協(xié)處理器指令中的所有的域。具體協(xié)處理器如何定義和操作完全由協(xié)處理器的制造商自己決定,因此ARM協(xié)處理器指令中的協(xié)處理器寄存器的標識符以及操作助記符也有各種不同的實現(xiàn)定義。程序員可以通過宏定義這些指令的語法格式。
ARM協(xié)處理器指令分以下3類。
·??協(xié)處理器數(shù)據(jù)操作。協(xié)處理器數(shù)據(jù)操作完全是協(xié)處理器內(nèi)部操作,它完成協(xié)處理器寄存器的狀態(tài)改變。如浮點加運算,在浮點協(xié)處理器中兩個寄存器相加,結(jié)果放在第3個寄存器中。這類指令包括CDP指令。
·??協(xié)處理器數(shù)據(jù)傳送指令。這類指令從寄存器讀取數(shù)據(jù)裝入?yún)f(xié)處理器寄存器,或?qū)f(xié)處理器寄存器的數(shù)據(jù)裝入存儲器。因為協(xié)處理器可以支持自己的數(shù)據(jù)類型,所以每個寄存器傳送的字數(shù)與協(xié)處理器有關。ARM處理器產(chǎn)生存儲器地址,但傳送的字節(jié)由協(xié)處理器控制。這類指令包括LDC和STC指令。
·??協(xié)處理器寄存器傳送指令。在某些情況下,需要ARM處理器和協(xié)處理器之間傳送數(shù)據(jù)。如一個浮點運算協(xié)處理器,F(xiàn)IX指令從協(xié)處理器寄存器取得浮點數(shù)據(jù),將它轉(zhuǎn)換為整數(shù),并將整數(shù)傳送到ARM寄存器中。經(jīng)常需要用浮點比較產(chǎn)生的結(jié)果來影響控制流,因此,比較結(jié)果必須傳送到ARM的CPSR中。這類協(xié)處理器寄存器傳送指令包括MCR和MRC。
表9.1列出了所有協(xié)處理器處理指令。
表9.1 協(xié)處理器指令
助??記??符 |
操????作 |
CDP |
協(xié)處理器數(shù)據(jù)操作 |
LDC |
裝載協(xié)處理器寄存器 |
MCR |
從ARM寄存器傳數(shù)據(jù)到協(xié)處理器寄存器 |
MRC |
從協(xié)處理器寄存器傳數(shù)據(jù)到ARM寄存器 |
STC |
存儲協(xié)處理器寄存器 |
9.1.1??協(xié)處理器數(shù)據(jù)操作指令CDP
1.指令編碼格式
此指令用于控制數(shù)據(jù)在協(xié)處理器寄存器內(nèi)部的操作。通常情況下該指令由協(xié)處理器完成,如果協(xié)處理器不能成功地執(zhí)行該操作,將產(chǎn)生未定義指令異常。
指令的編碼格式如圖9.1所示。
圖9.1??CDP指令編碼格式
?
2.指令的語法格式
CDP{<cond>}??<coproc>,<opcode_1>,<CRd>,<CRn>,<CRm>,<opcode_2>
CDP2??<coproc>,<opcode_1>,<CRd>,<CRn>,<CRm>,<opcode_2>
①?<cond>
為指令編碼中的條件域。它指示指令在什么條件下執(zhí)行。當<cond>忽略時,指令為無條件執(zhí)行(cond=AL(Alway))。
②?CDP2
協(xié)處理器數(shù)據(jù)操作指令CDP的一種特殊格式。這種格式中指定編碼的條件域<cond>為ob1111。這種設計為協(xié)處理器的設計者提供了一個靈活的擴展空間。此指令只能無條件執(zhí)行。
③?<coproc>
指定協(xié)處理器的編號,標準的協(xié)處理器的名字為p0、p1、…、p15。
④?<opcode_1>
指定協(xié)處理器執(zhí)行的操作碼,確定哪一個協(xié)處理器指令將被執(zhí)行。
⑤?<CRd>
作為目標寄存器的協(xié)處理器寄存器。
⑥?<CRn>
確定包含第一個操作數(shù)的協(xié)處理器寄存器。
⑦?<CRm>
確定包含第二個操作數(shù)的協(xié)處理器寄存器。
⑧?<opcode_2>
指定協(xié)處理器執(zhí)行的操作碼,確定哪一個協(xié)處理器指令將被執(zhí)行。通常與<opcode_1>配合使用。
3.指令操作的偽代碼
指令操作的偽代碼如下面程序段所示。
If??ConditionPassed{cond}??then
?????Coprocessor[cp_num]-dependent?operation
注意 |
CDP指令通常被用來初始化協(xié)處理器。比如在作浮點運算操作時,使用CDP指令初始化協(xié)處理器寄存器。 |
4.指令舉例
對協(xié)處理器P15進行操作。第一操作數(shù)opcode_1=2,第二操作數(shù)opcode_2=4,目標寄存器為協(xié)處理器寄存器c12,源寄存器分別為協(xié)處理器寄存器c10和c3。
CDP???p15,2,c12,c10,c3,4
5.指令的使用
·??CDP指令一般用于初始化協(xié)處理器,對ARM寄存器和存儲器沒有任何影響。
·??指令的編碼格式中,bits[31∶24]、bits[11∶8]和bit[4]為ARM體系結(jié)構(gòu)定義。其他域由各生產(chǎn)商定義。
·??硬件協(xié)處理器支持與否完全由生產(chǎn)商定義,某款ARM芯片中,是否支持協(xié)處理器或支持哪個協(xié)處理器與ARM版本無關。生產(chǎn)商可以選擇實現(xiàn)部分協(xié)處理器指令或者完全不支持協(xié)處理器。
?
9.1.2??協(xié)處理器數(shù)據(jù)讀取指令LDC
1.指令編碼格式
LDC(Load?Coprocessor)指令通過一定的尋址模式從一系列連續(xù)的內(nèi)存單元將數(shù)據(jù)讀取到協(xié)處理器的寄存器中。如果協(xié)處理器不能成功地執(zhí)行操作,將產(chǎn)生未定義的指令異常中斷。
指令的編碼格式如圖9.2所示。
圖9.2??LDC指令編碼格式
2.指令的語法格式
LDC{<cond>}{L}???<coproc>,<CRd>,<addressing_mode>
LDC2{L}??????????<coproc>,<CRd>,<addressing_mode>
①?<cond>
為指令編碼中的條件域。它指示指令在什么條件下執(zhí)行。當<cond>忽略時,指令為無條件執(zhí)行(cond=AL(Alway))。
②?LDC2
協(xié)處理器數(shù)據(jù)讀取指令LDC的一種特殊格式。這種格式中指定編碼的條件域<cond>為ob1111。這種設計為協(xié)處理器的設計者提供了一個靈活的擴展空間。此指令只能無條件執(zhí)行。
③?<coproc>
指定協(xié)處理器的編號,標準的協(xié)處理器的名字為p0、p1、…、p15。
④?L
長讀取操作指示域。設置指令編碼格式中的Nbit(bit[22]),如果該位設置為1,說明指令是一個長讀取指令;該位為0,說明指令為短讀取指令。該指令常用于雙精度數(shù)據(jù)傳送。
⑤?<CRd>
確定協(xié)處理器目的寄存器。
⑥?<addressing_mode>
確定指令的尋址方式。它將指定指令編碼格式中的P、U、Rn、W和8_bit_word_offset域。
3.指令操作的偽代碼
指令操作的偽代碼如下面程序段所示。
If???ConditionPassed{cond}??then
??????Address=start_address
??????load??Memory[address,4]??for??Coprocess[cp_num]
??????while??{NotFinished{Conprocess[cp_num]}}
?????????????address=address+4
?????????????load?Memory[address,4]??for??Coprocessor[cp_num]
??????assert??address==end_address
4.指令舉例
(1)將數(shù)據(jù)從內(nèi)存?zhèn)魉偷絽f(xié)處理器p6寄存器c1中,使用寄存器尋址模式,將內(nèi)存地址放到ARM寄存器r4中。
LDC???p6,CR1,[r4]
(2)將數(shù)據(jù)從內(nèi)存?zhèn)魉偷絽f(xié)處理器p6寄存器c4中,使用寄存器變址尋址。
LDC???p6,CR4,[r2,#4]
5.指令的使用
·??指令的編碼格式中,bits[31∶23]、bits[21∶16]和bits[11∶0]為ARM體系結(jié)構(gòu)定義。其他域由各生產(chǎn)商定義。
·??協(xié)處理器數(shù)據(jù)讀取指令忽略地址后兩位。如果系統(tǒng)中定義了系統(tǒng)控制協(xié)處理器,而且地址對齊檢測使能打開,當?shù)刂穊its[1∶0]!=0b00時,產(chǎn)生地址對齊異常。
·??硬件協(xié)處理器支持與否完全由生產(chǎn)商定義,某款ARM芯片中,是否支持協(xié)處理器或支持哪個協(xié)處理器與ARM版本無關。生產(chǎn)商可以選擇實現(xiàn)部分協(xié)處理器指令或者完全不支持協(xié)處理器。
·??指令中字的傳送數(shù)目由協(xié)處理器控制。ARM將連續(xù)產(chǎn)生后續(xù)地址,直到協(xié)處理器指示傳送應該結(jié)束。在數(shù)據(jù)傳送過程中,ARM將不影響中斷請求,所以協(xié)處理器設計者應該注意不應因為傳送非常長的數(shù)據(jù)而損壞系統(tǒng)的中斷響應時間。
?
9.1.3??協(xié)處理器數(shù)據(jù)寫入指令STC
1.指令編碼格式
STC(Store?Coprocessor)指令通過一定的尋址模式將協(xié)處理器寄存器中的數(shù)據(jù)存儲到一系列連續(xù)的內(nèi)存單元中。如果協(xié)處理器不能成功地執(zhí)行操作,將產(chǎn)生未定義的指令異常中斷。
指令的編碼格式如圖9.3所示。
圖9.3??STC指令編碼格式
?
2.指令的語法格式
STC{<cond>}{L}???<coproc>,<CRd>,<addressing_mode>
STC2{L}??????????<coproc>,<CRd>,<addressing_mode>
①?<cond>
為指令編碼中的條件域。它指示指令在什么條件下執(zhí)行。當<cond>忽略時,指令為無條件執(zhí)行(cond=AL(Alway))。
②?STC2
協(xié)處理器數(shù)據(jù)寫入指令STC的一種特殊格式。這種格式中指定編碼的條件域<cond>為ob1111。這種設計為協(xié)處理器的設計者提供了一個靈活的擴展空間。此指令只能無條件執(zhí)行。
③?<coproc>
指定協(xié)處理器的編號,標準的協(xié)處理器的名字為p0、p1、…、p15。
④?L
長寫入操作指示域。設置指令編碼格式中的Nbit(bit[22]),如果該位設置為1,說明指令是一個長寫入指令;該位為0,說明指令為短寫入指令。該指令常用于雙精度數(shù)據(jù)傳送。
⑤?<CRd>
確定協(xié)處理器目的寄存器。
⑥?<addressing_mode>
確定指令的尋址方式。它將指定指令編碼格式中的P、U、Rn、W和8_bit_word_offset域。
3.指令操作的偽代碼
指令操作的偽代碼如下面程序段所示。
If???ConditionPassed{cond}??then
??????Address=start_address
??????Memory[address,4]?=?value?from?Coprocess[cp_num]
??????while??{NotFinished{Conprocess[cp_num]}}
?????????????address=address+4
?????????????Memory[address,4]?=?value?from?Coprocessor[cp_num]
??????assert??address==end_address
4.指令舉例
(1)將協(xié)處理器p8和寄存器c8的數(shù)據(jù)寫入存儲器中。尋址模式采用后寄存器尋址變址模式,內(nèi)存基地址放入ARM寄存器r2中。
STC???p8,CR8,[r2,#4]!
(2)將協(xié)處理器p8和寄存器c9的數(shù)據(jù)寫入存儲器中。
STC???p8,CR9,[r2],#-16
5.指令的使用
詳見LDC指令。
?
9.1.4??ARM寄存器到協(xié)處理器寄存器的數(shù)據(jù)傳送指令MCR
1.指令編碼格式
ARM寄存器到協(xié)處理器寄存器的數(shù)據(jù)傳送指令MCR(Move?to?Coprocessor?from?ARM?Register)將ARM寄存器<Rd>的值傳送到協(xié)處理器寄存器cp_num中。如果沒有協(xié)處理器執(zhí)行指定操作,將產(chǎn)生未定義指令異常。
指令的編碼格式如圖9.4所示。
圖9.4??MCR指令編碼格式
?
2.指令的語法格式
MCR{<cond>}??<coproc>,<opcode_1>,<Rd>,<CRn>,<CRm>{,<opcode_2>}
MCR2?????????<coproc>,<opcode_1>,<Rd>,<CRn>,<CRm>{,<opcode_2>}
①?<cond>
為指令編碼中的條件域。它指示指令在什么條件下執(zhí)行。當<cond>忽略時,指令為無條件執(zhí)行(cond=AL(Alway))。
②?MCR2
MCR2指令的一種特殊格式。這種格式中指定編碼的條件域<cond>為ob1111。這種設計為協(xié)處理器的設計者提供了一個靈活的擴展空間。此指令只能無條件執(zhí)行。
③?<coproc>
指定協(xié)處理器的編號,標準的協(xié)處理器的名字為p0、p1、…、p15。
④?<opcode_1>
指定協(xié)處理器執(zhí)行的操作碼,確定哪一個協(xié)處理器指令將被執(zhí)行。
⑤?<Rd>
確定哪一個ARM寄存器的數(shù)值將被傳送。如果程序計數(shù)器PC的值被傳送,指令的執(zhí)行結(jié)果不可預知。
⑥?<CRn>
確定包含第一個操作數(shù)的協(xié)處理器寄存器。
⑦?<CRm>
確定包含第二個操作數(shù)的協(xié)處理器寄存器。
⑧?<opcode_2>
指定協(xié)處理器執(zhí)行的操作碼,確定哪一個協(xié)處理器指令將被執(zhí)行。通常與<opcode_1>配合使用。
3.指令操作的偽代碼
指令操作的偽代碼如下面程序段所示。
If??ConditionPassed{cond}??then
?????Send??Rd?value?to?coprocessor[cp_num]
4.指令舉例
將ARM寄存器r7中的值傳送到協(xié)處理器p14的寄存器c7中,第一操作數(shù)opcode_1=1,第二操作數(shù)opcode_2=6。
MCR???p14,1,r7,c7,c12,6
5.指令的使用
·??指令的編碼格式中,bits[31∶24]、bit[20]、bits[15∶8]和bit[4]為ARM體系結(jié)構(gòu)定義。其他域由各生產(chǎn)商定義。
·??硬件協(xié)處理器支持與否完全由生產(chǎn)商定義,某款ARM芯片中,是否支持協(xié)處理器或支持哪個協(xié)處理器與ARM版本無關。生產(chǎn)商可以選擇實現(xiàn)部分協(xié)處理器指令或者完全不支持協(xié)處理器。
?
9.1.5??協(xié)處理器寄存器到ARM寄存器的數(shù)據(jù)傳送指令MRC
1.指令編碼格式
協(xié)處理器寄存器到ARM寄存器的數(shù)據(jù)傳送指令MRC(Move?to?ARM?register?from?Coprocessor)將協(xié)處理器cp_num的寄存器的值傳送到ARM寄存器中。如果沒有協(xié)處理器執(zhí)行指定操作,將產(chǎn)生未定義指令異常。
指令的編碼格式如圖9.5所示。
圖9.5??MRC指令編碼格式
?
2.指令的語法格式
MRC{<cond>}??<coproc>,<opcode_1>,<Rd>,<CRn>,<CRm>{,<opcode_2>}
MRC2?????????<coproc>,<opcode_1>,<Rd>,<CRn>,<CRm>{,<opcode_2>}
①?<cond>
為指令編碼中的條件域。它指示指令在什么條件下執(zhí)行。當<cond>忽略時,指令為無條件執(zhí)行(cond=AL(Alway))。
②?MRC2
MRC2指令的一種特殊格式。這種格式中指定編碼的條件域<cond>為ob1111。這種設計為協(xié)處理器的設計者提供了一個靈活的擴展空間。此指令只能無條件執(zhí)行。
③?<coproc>
指定協(xié)處理器的編號,標準的協(xié)處理器的名字為p0、p1、…、p15。
④?<opcode_1>
指定協(xié)處理器執(zhí)行的操作碼,確定哪一個協(xié)處理器指令將被執(zhí)行。
⑤?<Rd>
確定哪一個ARM寄存器接受協(xié)處理器傳送的數(shù)值。如果程序計數(shù)器PC被用作目的寄存器,指令的執(zhí)行結(jié)果不可預知。
⑥?<CRn>
確定包含第一個操作數(shù)的協(xié)處理器寄存器。
⑦?<CRm>
確定包含第二個操作數(shù)的協(xié)處理器寄存器。
⑧?<opcode_2>
指定協(xié)處理器執(zhí)行的操作碼,確定哪一個協(xié)處理器指令將被執(zhí)行。通常與<opcode_1>配合使用。
3.指令操作的偽代碼
指令操作的偽代碼如下面程序段所示。
If??ConditionPassed{cond}??then
?????Data=value?from?coprocessor[cp_num]
?????If?Rd?is?R15?then
???????????N??flag?=?data[31]
???????????Z??flag?=?data[30]
???????????C??flag?=?data[29]
???????????V??flag?=?data[28]
?????Else??/*Rd?≠R15*/
???????????Rd?=?data
4.指令舉例
協(xié)處理器源寄存器為c0和c2,目的寄存器為ARM寄存器r4,第一操作數(shù)opcode_1=5,第二操作數(shù)opcode_2=3。
MRC??p15,5,r4,c0,c2,3
5.指令的使用
·??如果目的寄存器為程序計數(shù)器r15,則程序狀態(tài)字條件標準位根據(jù)傳送數(shù)據(jù)的前4bit確定,后28bit被忽略。
·??指令的編碼格式中,bits[31∶24]、bit[20]、bits[15∶8]和bit[4]為ARM體系結(jié)構(gòu)定義。其他域由各生產(chǎn)商定義。
·??硬件協(xié)處理器支持與否完全由生產(chǎn)商定義,某款ARM芯片中,是否支持協(xié)處理器或支持哪個協(xié)處理器與ARM版本無關。生產(chǎn)商可以選擇實現(xiàn)部分協(xié)處理器指令或者完全不支持協(xié)處理器。
·??如果協(xié)處理器必須完成一些內(nèi)部工作來準備一個32位數(shù)據(jù)向ARM傳送(例如,浮點FIX操作必須將浮點值轉(zhuǎn)換為等效的定點值),那么這些工作必須在協(xié)處理器提交傳送前進行。因此,在準備數(shù)據(jù)時經(jīng)常需要協(xié)處理器握手信號處于“忙-等待”狀態(tài)。ARM可以在忙-等待時間內(nèi)產(chǎn)生中斷。如果它確實得以中斷,那么它將暫停握手以服務中斷。當它從中斷服務程序返回時,將可能重試協(xié)處理器指令,但也可能不重試。例如,中斷可能導致任務切換。無論哪種情況,協(xié)處理器必須給出一致結(jié)果,因此,在握手提交階段之前的準備工作不允許改變處理器的可見狀態(tài)。