我正在设计一个MIPS处理器作为我的个人项目,到现在我遇到了一个非常混乱的问题。我只是不能总结何时使用signed-extend以及何时在MIPS中使用零扩展。
我搜索过很多资源,大多说:
1)ADDI,ADDIU都使用signed-extend。 2)ADDI,ORI,XORI都使用零扩展。
然而,在这两条指令中,我开始感到困惑:
SLTIU / SLTI
在Imagination的“面向程序员的MIPS架构第二卷-A:MIPS指令集手册”第368页中说:
它明确提到16位立即签名扩展。但我不明白以下声明:
[0,32767]或最大[max_unsigned-32767,max_unsigned]无符号范围的结尾。
和其他一些人说16位立即数是零延伸,如下所示:
那么,有人可以解释MIPS中签名指令和无符号指令之间究竟有什么区别吗?
非常感谢你!
答案 0 :(得分:2)
我不确定您展示的两个描述是否完全相同。它们似乎是不同的实现。
Imagination的MIPS在其文档中的实现如下(在SystemVerilog语法中,假设GPR寄存器为32位):
if ({1'b0 , GPR[rs]} < {1'b0 , sign_extend(immediate)}
GPR[rd] = 32'h00000001;
else
GPR[rd] = 32'h00000000;
请注意,这是一个33位比较,其中第33位为0,因此是无符号比较。
另外,请注意:
sign_extend(immediate) returns: { {16{immediate[15]}}, immediate }
这意味着立即首先将立即数视为有符号数,即15位值,第16位为符号。因此:
If immediate >=0, then sign_extend(immediate) is in [0,32767].
另一方面,如果立即数为负数,我们将:
sign_extend(immediate) = { {16{1'b1}}, 1'b1, immediate[15:0] }, which is in [32'hFFFFFFFF-32767, 32'hFFFFFFFF]
其中32&#39; hFFFFFFFF称为max_unsigned。
基本上,该指令使您能够在[0,32767]或[32&#39; hFFFFFFFF-32767,32&#39;中执行GPR [rs]和无符号数字之间的无符号比较。 HFFFFFFFF]。
第二种实现在GPR [rs]和[0,65535]之间执行无符号比较。
修改强>
请注意,在SLTI和SLTIU中,立即值是符号扩展但具有不同的意图。在SLTIU中,被比较的两个数字被强制取消(通过添加第33位)。因此立即符号扩展启用了不同的比较范围:32767最小和32767最大无符号值,而不是0到65535.符号扩展不是为了签名比较的目的,因为可能会混淆。
然而,在SLTI中,立即符号扩展的目的不同:将负值与正值进行比较(带符号的比较)。
答案 1 :(得分:1)
文档暗示指令首先对16位立即数进行符号扩展,然后执行32位无符号比较。在verilog中,这应该是:
if (gpr[rs] < { {16{imm[15]}}, imm })
gpr[rt] = 1;
else
gpr[rt] = 0;