|  | 
 
| 9.1  协处理器指令 
 ARM体系结构允许通过增加协处理器来扩展指令集。最常用的协处理器是用于控制片上功能的系统协处理器。例如控制Cache和存储管理单元的CP15寄存器。此外,还有用于浮点运算的浮点ARM协处理器,各生产商还可以根据需要开发自己的专用协处理器。
 
 ARM协处理器具有自己专用的寄存器组,它们的状态由控制ARM状态的指令的镜像指令来控制。
 
 程序的控制流指令由ARM处理器来处理,所有协处理器指令只能同数据处理和数据传送有关。按照RISC的Load/Store体系原则,数据的处理和传送指令是被清楚分开的,所以它们有不同的指令格式。
 
 ARM处理器支持16个协处理器,在程序执行过程中,每个协处理器忽略ARM和其他协处理器指令。当一个协处理器硬件不能执行属于它的协处理器指令时,将产生一个未定义指令异常中断,在该异常中断处理过程中,可以通过软件仿真该硬件操作。如果,一个系统中不包含向量浮点运算器,则可以选择浮点运算软件包来支持向量浮点运算。
 
 ARM协处理器可以部分地执行一条指令,而后产生中断。如除法运算除数为0和溢出,这样可以更好地处理运行时产生(run-time-generated)的异常。但是,指令的部分执行是由协处理器完成的,此过程对ARM来说是透明的。当ARM处理器重新获得执行时,它将从产生异常的指令处开始执行。
 
 对某一个协处理器来说,并不一定用到协处理器指令中的所有的域。具体协处理器如何定义和操作完全由协处理器的制造商自己决定,因此ARM协处理器指令中的协处理器寄存器的标识符以及操作助记符也有各种不同的实现定义。程序员可以通过宏定义这些指令的语法格式。
 
 ARM协处理器指令分以下3类。
 ·  协处理器数据操作。协处理器数据操作完全是协处理器内部操作,它完成协处理器寄存器的状态改变。如浮点加运算,在浮点协处理器中两个寄存器相加,结果放在第3个寄存器中。这类指令包括CDP指令。
 ·  协处理器数据传送指令。这类指令从寄存器读取数据装入协处理器寄存器,或将协处理器寄存器的数据装入存储器。因为协处理器可以支持自己的数据类型,所以每个寄存器传送的字数与协处理器有关。ARM处理器产生存储器地址,但传送的字节由协处理器控制。这类指令包括LDC和STC指令。
 ·  协处理器寄存器传送指令。在某些情况下,需要ARM处理器和协处理器之间传送数据。如一个浮点运算协处理器,FIX指令从协处理器寄存器取得浮点数据,将它转换为整数,并将整数传送到ARM寄存器中。经常需要用浮点比较产生的结果来影响控制流,因此,比较结果必须传送到ARM的CPSR中。这类协处理器寄存器传送指令包括MCR和MRC。
 
 表9.1列出了所有协处理器处理指令。
 表9.1 协处理器指令
 
 | 助  记  符 
 | 操    作 
 |  | CDP 
 | 协处理器数据操作 
 |  | LDC 
 | 装载协处理器寄存器 
 |  | MCR 
 | 从ARM寄存器传数据到协处理器寄存器 
 |  | MRC 
 | 从协处理器寄存器传数据到ARM寄存器 
 |  | STC 
 | 存储协处理器寄存器 
 | 
 9.1.1  协处理器数据操作指令CDP
 
 1.指令编码格式
 
 此指令用于控制数据在协处理器寄存器内部的操作。通常情况下该指令由协处理器完成,如果协处理器不能成功地执行该操作,将产生未定义指令异常。
 
 指令的编码格式如图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>
 为指令编码中的条件域。它指示指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
 
 ② CDP2
 协处理器数据操作指令CDP的一种特殊格式。这种格式中指定编码的条件域<cond>为ob1111。这种设计为协处理器的设计者提供了一个灵活的扩展空间。此指令只能无条件执行。
 
 ③ <coproc>
 指定协处理器的编号,标准的协处理器的名字为p0、p1、…、p15。
 
 ④ <opcode_1>
 指定协处理器执行的操作码,确定哪一个协处理器指令将被执行。
 
 ⑤ <CRd>
 作为目标寄存器的协处理器寄存器。
 
 ⑥ <CRn>
 确定包含第一个操作数的协处理器寄存器。
 
 ⑦ <CRm>
 确定包含第二个操作数的协处理器寄存器。
 
 ⑧ <opcode_2>
 指定协处理器执行的操作码,确定哪一个协处理器指令将被执行。通常与<opcode_1>配合使用。
 
 3.指令操作的伪代码
 
 指令操作的伪代码如下面程序段所示。
 
 If  ConditionPassed{cond}  then
 Coprocessor[cp_num]-dependent operation
 
 
 4.指令举例|   
 | 注意 
 | CDP指令通常被用来初始化协处理器。比如在作浮点运算操作时,使用CDP指令初始化协处理器寄存器。 
 | 
 
 对协处理器P15进行操作。第一操作数opcode_1=2,第二操作数opcode_2=4,目标寄存器为协处理器寄存器c12,源寄存器分别为协处理器寄存器c10和c3。
 
 CDP   p15,2,c12,c10,c3,4
 
 5.指令的使用
 
 ·  CDP指令一般用于初始化协处理器,对ARM寄存器和存储器没有任何影响。
 ·  指令的编码格式中,bits[31∶24]、bits[11∶8]和bit[4]为ARM体系结构定义。其他域由各生产商定义。
 ·  硬件协处理器支持与否完全由生产商定义,某款ARM芯片中,是否支持协处理器或支持哪个协处理器与ARM版本无关。生产商可以选择实现部分协处理器指令或者完全不支持协处理器。
 
 9.1.2  协处理器数据读取指令LDC
 
 1.指令编码格式
 
 LDC(Load Coprocessor)指令通过一定的寻址模式从一系列连续的内存单元将数据读取到协处理器的寄存器中。如果协处理器不能成功地执行操作,将产生未定义的指令异常中断。
 
 指令的编码格式如图9.2所示。
 
 
         图9.2  LDC指令编码格式 
 2.指令的语法格式
 
 LDC{<cond>}{L}   <coproc>,<CRd>,<addressing_mode>
 LDC2{L}          <coproc>,<CRd>,<addressing_mode>
 
 ① <cond>
 为指令编码中的条件域。它指示指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
 
 ② LDC2
 协处理器数据读取指令LDC的一种特殊格式。这种格式中指定编码的条件域<cond>为ob1111。这种设计为协处理器的设计者提供了一个灵活的扩展空间。此指令只能无条件执行。
 
 ③ <coproc>
 指定协处理器的编号,标准的协处理器的名字为p0、p1、…、p15。
 
 ④ L
 长读取操作指示域。设置指令编码格式中的Nbit(bit[22]),如果该位设置为1,说明指令是一个长读取指令;该位为0,说明指令为短读取指令。该指令常用于双精度数据传送。
 
 ⑤ <CRd>
 确定协处理器目的寄存器。
 
 ⑥ <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)将数据从内存传送到协处理器p6寄存器c1中,使用寄存器寻址模式,将内存地址放到ARM寄存器r4中。
 
 LDC   p6,CR1,[r4]
 
 (2)将数据从内存传送到协处理器p6寄存器c4中,使用寄存器变址寻址。
 
 LDC   p6,CR4,[r2,#4]
 
 5.指令的使用
 
 ·  指令的编码格式中,bits[31∶23]、bits[21∶16]和bits[11∶0]为ARM体系结构定义。其他域由各生产商定义。
 
 ·  协处理器数据读取指令忽略地址后两位。如果系统中定义了系统控制协处理器,而且地址对齐检测使能打开,当地址bits[1∶0]!=0b00时,产生地址对齐异常。
 
 ·  硬件协处理器支持与否完全由生产商定义,某款ARM芯片中,是否支持协处理器或支持哪个协处理器与ARM版本无关。生产商可以选择实现部分协处理器指令或者完全不支持协处理器。
 
 ·  指令中字的传送数目由协处理器控制。ARM将连续产生后续地址,直到协处理器指示传送应该结束。在数据传送过程中,ARM将不影响中断请求,所以协处理器设计者应该注意不应因为传送非常长的数据而损坏系统的中断响应时间。
 
 9.1.3  协处理器数据写入指令STC
 
 1.指令编码格式
 
 STC(Store Coprocessor)指令通过一定的寻址模式将协处理器寄存器中的数据存储到一系列连续的内存单元中。如果协处理器不能成功地执行操作,将产生未定义的指令异常中断。
 
 指令的编码格式如图9.3所示。
 
 
         图9.3  STC指令编码格式 
           2.指令的语法格式
 
 STC{<cond>}{L}   <coproc>,<CRd>,<addressing_mode>
 STC2{L}          <coproc>,<CRd>,<addressing_mode>
 
 ① <cond>
 为指令编码中的条件域。它指示指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
 
 ② STC2
 协处理器数据写入指令STC的一种特殊格式。这种格式中指定编码的条件域<cond>为ob1111。这种设计为协处理器的设计者提供了一个灵活的扩展空间。此指令只能无条件执行。
 
 ③ <coproc>
 指定协处理器的编号,标准的协处理器的名字为p0、p1、…、p15。
 
 ④ L
 长写入操作指示域。设置指令编码格式中的Nbit(bit[22]),如果该位设置为1,说明指令是一个长写入指令;该位为0,说明指令为短写入指令。该指令常用于双精度数据传送。
 
 ⑤ <CRd>
 确定协处理器目的寄存器。
 
 ⑥ <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)将协处理器p8和寄存器c8的数据写入存储器中。寻址模式采用后寄存器寻址变址模式,内存基地址放入ARM寄存器r2中。
 
 STC   p8,CR8,[r2,#4]!
 
 (2)将协处理器p8和寄存器c9的数据写入存储器中。
 
 STC   p8,CR9,[r2],#-16
 
 5.指令的使用
 
 详见LDC指令。
 
 9.1.4  ARM寄存器到协处理器寄存器的数据传送指令MCR
 
 1.指令编码格式
 
 ARM寄存器到协处理器寄存器的数据传送指令MCR(Move to Coprocessor from ARM Register)将ARM寄存器<Rd>的值传送到协处理器寄存器cp_num中。如果没有协处理器执行指定操作,将产生未定义指令异常。
 
 指令的编码格式如图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>
 为指令编码中的条件域。它指示指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
 
 ② MCR2
 MCR2指令的一种特殊格式。这种格式中指定编码的条件域<cond>为ob1111。这种设计为协处理器的设计者提供了一个灵活的扩展空间。此指令只能无条件执行。
 
 ③ <coproc>
 指定协处理器的编号,标准的协处理器的名字为p0、p1、…、p15。
 
 ④ <opcode_1>
 指定协处理器执行的操作码,确定哪一个协处理器指令将被执行。
 
 ⑤ <Rd>
 确定哪一个ARM寄存器的数值将被传送。如果程序计数器PC的值被传送,指令的执行结果不可预知。
 
 ⑥ <CRn>
 确定包含第一个操作数的协处理器寄存器。
 
 ⑦ <CRm>
 确定包含第二个操作数的协处理器寄存器。
 
 ⑧ <opcode_2>
 指定协处理器执行的操作码,确定哪一个协处理器指令将被执行。通常与<opcode_1>配合使用。
 
 3.指令操作的伪代码
 
 指令操作的伪代码如下面程序段所示。
 
 If  ConditionPassed{cond}  then
 Send  Rd value to coprocessor[cp_num]
 
 4.指令举例
 
 将ARM寄存器r7中的值传送到协处理器p14的寄存器c7中,第一操作数opcode_1=1,第二操作数opcode_2=6。
 
 MCR   p14,1,r7,c7,c12,6
 
 5.指令的使用
 
 ·  指令的编码格式中,bits[31∶24]、bit[20]、bits[15∶8]和bit[4]为ARM体系结构定义。其他域由各生产商定义。
 
 ·  硬件协处理器支持与否完全由生产商定义,某款ARM芯片中,是否支持协处理器或支持哪个协处理器与ARM版本无关。生产商可以选择实现部分协处理器指令或者完全不支持协处理器。
 
 9.1.5  协处理器寄存器到ARM寄存器的数据传送指令MRC
 
 1.指令编码格式
 
 协处理器寄存器到ARM寄存器的数据传送指令MRC(Move to ARM register from Coprocessor)将协处理器cp_num的寄存器的值传送到ARM寄存器中。如果没有协处理器执行指定操作,将产生未定义指令异常。
 
 指令的编码格式如图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>
 为指令编码中的条件域。它指示指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
 
 ② MRC2
 MRC2指令的一种特殊格式。这种格式中指定编码的条件域<cond>为ob1111。这种设计为协处理器的设计者提供了一个灵活的扩展空间。此指令只能无条件执行。
 
 ③ <coproc>
 指定协处理器的编号,标准的协处理器的名字为p0、p1、…、p15。
 
 ④ <opcode_1>
 指定协处理器执行的操作码,确定哪一个协处理器指令将被执行。
 
 ⑤ <Rd>
 确定哪一个ARM寄存器接受协处理器传送的数值。如果程序计数器PC被用作目的寄存器,指令的执行结果不可预知。
 
 ⑥ <CRn>
 确定包含第一个操作数的协处理器寄存器。
 
 ⑦ <CRm>
 确定包含第二个操作数的协处理器寄存器。
 
 ⑧ <opcode_2>
 指定协处理器执行的操作码,确定哪一个协处理器指令将被执行。通常与<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.指令举例
 
 协处理器源寄存器为c0和c2,目的寄存器为ARM寄存器r4,第一操作数opcode_1=5,第二操作数opcode_2=3。
 
 MRC  p15,5,r4,c0,c2,3
 5.指令的使用
 
 ·  如果目的寄存器为程序计数器r15,则程序状态字条件标准位根据传送数据的前4bit确定,后28bit被忽略。
 
 ·  指令的编码格式中,bits[31∶24]、bit[20]、bits[15∶8]和bit[4]为ARM体系结构定义。其他域由各生产商定义。
 
 ·  硬件协处理器支持与否完全由生产商定义,某款ARM芯片中,是否支持协处理器或支持哪个协处理器与ARM版本无关。生产商可以选择实现部分协处理器指令或者完全不支持协处理器。
 
 ·  如果协处理器必须完成一些内部工作来准备一个32位数据向ARM传送(例如,浮点FIX操作必须将浮点值转换为等效的定点值),那么这些工作必须在协处理器提交传送前进行。因此,在准备数据时经常需要协处理器握手信号处于“忙-等待”状态。ARM可以在忙-等待时间内产生中断。如果它确实得以中断,那么它将暂停握手以服务中断。当它从中断服务程序返回时,将可能重试协处理器指令,但也可能不重试。例如,中断可能导致任务切换。无论哪种情况,协处理器必须给出一致结果,因此,在握手提交阶段之前的准备工作不允许改变处理器的可见状态。
 | 
 |