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