MIPS CP0冒险概念

转自:http://www.kernelchina.org/node/277

对于协处理器CP0的访问,需要使用特别的指令。这些指令属于“特权级指令”,只有在内核态(Kernel Mode)下才能执行。如果在用户态下,会引起一个异常(Exception)。
对CP0的主要操作有以下的指令:
mfc0 rt, rd 将CP0中的rd寄存器内容传输到rt通用寄存器;
mtc0 rt, rd 将rt通用寄存器中内容传输到CP0中寄存器rd;
mfhi/mflo rt 将CP0的hi/lo寄存器内容传输到rt通用寄存器中;
mthi/mtlo rt 将rt通用寄存器内容传输到CP0的hi/lo寄存器中;
当MIPS体系结构演进到MIPS IV的64位架构后,新增了两条指令dmfc0和dmtc0,向CP0的寄存器中读/写一个64bit的数据。

前面提到,MIPS体系结构是一个无互锁,高度流水的五级pipeline架构,这就意味着,前一条指令如果尚未执行完,后一条指令有可能已经进入了取指令/译码阶段。这样,就有可能发生所谓的CP0冒险(CP0 Hazard)现象。简单地说,就是mfc和mtc指令的执行速度是比较慢的,因此,开始执行完下一条指令时,有可能CP0寄存器的值尚未最后传输到指定的目标通用寄存器中。此时,如果读取该通用寄存器,有可能并未得到正确的值。这就是所谓的CP0冒险现象。
为了避免CP0冒险,我们在编程时需要在CP0操作指令的后面加上一条与前一条指令的目的通用寄存器无关的指令,也就是所谓的延迟槽(delay slot)。如果对性能不敏感,可以考虑用一条nop空操作指令填充延迟槽。
例如,经常在异常处理例程(exception handler)中出现的内容:

....
mfc0 k0, $cause
nop /* mfc0指令执行速度慢,在延迟槽中加一个空操作 */
mov t0, k0 /* 将cause寄存器内容放到t0,进行下一步操作 */

对于异常处理的具体内容,大家可以在下一章《MIPS的异常与中断》中看到。


你可能感兴趣的:(MIPS)