我正在将MIPS处理器设计为我的个人项目,到目前为止,我遇到了一个非常困惑的问题。我只是无法总结何时在MIPS中使用有符号扩展和何时使用零扩展。
我搜索了很多资源,大部分都说:
1)ADDI,ADDIU都使用符号扩展。2)ANDI,ORI,XORI都使用零扩展。
但是,在这两个说明中,我开始感到困惑:
SLTIU / SLTI
在Imagination的“程序员的MIPS体系结构第II-A卷:MIPS指令集手册”中,第368页说:
它清楚地提到了16位立即数是有符号扩展的。但是我不理解以下声明:
[[0,32767]或无符号范围的最大值[max_unsigned-32767,max_unsigned]的结尾。
和其他一些人说16位立即数是零扩展,像这样:
嗯,有人可以解释一下MIPS中的带符号指令和无符号指令到底有什么区别吗?
我不确定您显示的两个描述的行为是否完全相同。它们似乎是不同的实现。
在他们的文档中,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'hFFFFFFFF被称为max_unsigned。
基本上,该指令使您能够在[0,32767]或[32'hFFFFFFFF-32767,32'hFFFFFFFF]中的GPR [rs]和unsigned数字之间执行无符号比较。
第二种实现在GPR [rs]和[0,65535]之间执行无符号比较。
编辑:
请注意,在SLTI和SLTIU中,立即数被符号扩展,但其意图不同。在SLTIU中,被比较的两个数字被强制取消单个(通过添加第33位)。因此,立即数的符号扩展启用了不同的比较范围:最小的32767和最大的32767无符号值,而不是0到65535。符号扩展未出于签名比较的目的而进行,因为这可能会造成混淆。
但是,在SLTI中,即时数的符号扩展是出于不同的目的:将负值与正值进行比较(有符号比较)。>>
文档暗示该指令首先对16位立即数进行符号扩展,然后执行32位无符号比较。在verilog中,这应为: