根据this MIPS instruction reference,有两条指令(bgezal
和bltzal
)执行相对跳转和链接,而不是仅在执行分支时进行相对跳转。
可以分别使用bgez
或bltz
模拟这些说明,然后使用jal
进行模拟,这意味着bgezal
和bltzal
都应归类作为伪指令。但是,它们都分配了操作码,因此它们被归类为基本指令。
将它们添加到基本指令集并且不将它们作为伪指令的理由是什么?另外,为什么只有bgezal
和bltzal
包含在指令集中,而不是,例如blezal
,bgzal
等?
答案 0 :(得分:4)
jal
使用半绝对目标编码(替换PC的低28位),而bgezal
/ bltzal
是相对的(添加18位位移,imm16 << 2)。 How to Calculate Jump Target Address and Branch Target Address?
它们是经典MIPS唯一的分支和链接(而不是跳转和链接),因此对于与位置无关的可重定位代码非常重要。(您甚至可以使用一个来获取当前代码与jal
不同,PC进入寄存器并找出要从何处执行。
您可以将bal
(无条件相对函数调用)编码为bgezal $zero, target
。
由于它们使用I类型的指令格式,就像其他b
分支指令一样,因此一个寄存器的编码空间很大,因此可以有选择地将其设为有条件而不是 有一条bal
指令。完成“和链接”的硬件逻辑已经存在,所有其他相对分支指令都是有条件的。
请记住,MIPS指令编码在早期的MIPS硬件中直接用作内部控制信号,因此两者之间编码不同的一位可能会连接到XOR门,该XOR门会反转(或不反转)符号位的校验。 (正如Konrad的答案指出的那样,这些分支条件仅取决于寄存器的MSB,因为它始终与零相对,因此没有等待32位加法器产生比较结果的等待时间。)
来自http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
0000 01ss sss1 0001 iiii iiii iiii iiii BGEZAL
0000 01ss sss1 0000 iiii iiii iiii iiii BLTZAL
在指令编码中缺乏灵活性(因为它直接驱动内部控制信号而不需要在解码中进行大量转换)可能是为什么不存在单个bal
的28位范围的原因26位相对位移)。相对分支的硬件设置为具有16位立即数的I型指令。
TL:DR:有2条条件分支和链接指令,因为很自然地就其中一条实现无条件bal
,而另一条几乎免费。< / strong>
MIPS b
(无链接的无条件相对分支)也是beq $zero, $zero, target
的伪指令,或者是bgez $zero, target
的汇编程序选择的伪指令。 (What is the difference between unconditional branch and unconditional jump (instructions in MIPS)?)。
与零比较的编码只有一个5位寄存器字段,因此与beq
/ bne
相比,它们消耗的编码空间更少。这可能是选择bgezal
而不是beqal
作为要提供的一对条件分支之一的原因。
答案 1 :(得分:1)
bgez和bltz不是伪指令。
bgezal和bltzal是一样的,这并不奇怪。
虽然它是RISC,但并非所有指令都应该是基本的。两个指令需要更多的内存,如果频繁使用可能需要更多的时间,并且操作码中有很多空间,为什么不将它们组合成一个呢?
答案 2 :(得分:1)
主要原因是效率。
您的初始假设(执行bgez
后跟jal
可以模拟或在功能上等同于执行beqzal
)是正确的,但它可能效率较低如此。
为什么伪指令首先存在?马里兰大学关于pseudoinstructions和branching的说明解释了这一点。答案在于MIPS的设计方式。 MIPS是精简指令集。如果速度有明显改善,说明可以保留在ISA中。如果它可以使用两个或更多指令编写,没有明显的延迟(因为它们没有经常使用),那么这些指令不包含在MIPS ISA中。相反,它们变成了伪指令。
让我们使用另一个伪指令,例如la
或加载地址。 la
是一个伪指令,可以分解为lui
指令和ori
指令。在32位MIPS架构上,每条指令以及每个寄存器的大小为32位。因此,为了存储32位地址,使用两个指令。可以找到有关la
指令的更多信息here。
bgezal
和bltzal
指令最不可能是psudoinstructions,因为在一条指令中执行完整操作更有效。硬件必须能够执行条件检查,跳转到分支地址,并将返回地址存储在一条指令中。如果jal
指令被分离出来,这不仅是对空间的不必要使用,而且在某些硬件实现上,这个额外的指令可能会耗尽处理器数据路径的执行周期,从而有效地减慢程序执行速度。
其他来源:
答案 3 :(得分:1)
将它们添加到基本指令集并且不将它们作为伪指令的理由是什么?
仅仅因为一条指令可以分成几块并不意味着它应该是。我知道这是一个RISC,但是在指令集的大小和整个系统的性能之间仍然需要权衡。
两条指令意味着比单条指令更长的执行时间,因此设计团队可能会在看到它对流行基准测试产生的影响后决定是否包含此指令。
另外,为什么只有bgezal
和bltzal
包含在指令集中,例如blezal
,bgzal
等? < / p>
我可以给出的最简单的解释是这些指令最容易实现:对于bgezal
和bltzal
,只需要检查符号位。