本文已收录到:MIPS架构CPU设计 专题
本章节将实现转移指令,转移指令包括跳转、分支两种,其中前者是绝对转移(长距离转移),后者是相对转移(短距离转移)。
8.1 延迟槽
为什么要有延迟槽?——挤掉有效指令,用延迟指令替代
下面这一段代码,因为jr指令会使得接下来执行or指令而不是ori指令。正确的指令执行顺序如右图所示:
那么这两条ori指令就没有用途了。
流水线执行阶段进行转移判断,并且转移发生,那么会有2条无效指令,导致浪费了两个时钟周期。为了减少损失,规定转移指令后面的指令位置为“延迟槽”,延迟槽中的指令被称为“延迟指令”(也可称之为“延迟槽指令”)。延迟指令总是被执行,与转移发生与否没有关系。
也就是说人为的规定了MIPS中转移指令后面的指令为延迟指令且总被执行,与是否发生转移无关。
为什么要在译码阶段进行转移判断?——避免浪费时钟周期
即使使用延迟槽在执行阶段可以识别是否发生转移,但是在执行阶段时仍然会导致已经进入取指阶段的指令无效,也就是仍浪费一个时钟周期,要解决这个问题,可以在译码阶段进行转移判断,这样就可以避免浪费时钟周期。OpenMIPS处理器就设计为在译码阶段进行转移判断。
8.2 MIPS32中的转移指令
MIPS32指令集架构中定义的转移指令共有14条,可分为如下两类。
跳转指令: jr 、jalr 、j 、jal
分支指令:b、bal、beq、bgez、bgezal、bgtz、blez、bltz、bltzal、bne
关于上述指令本身的格式、功能可以参考作者的文章:自己动手写CPU之第八阶段(1)——转移指令介绍