在 MIPS 中,什么时候使用有符号扩展,什么时候使用零扩展?
In MIPS, when to use a signed-extend, when to use a zero-extend?
我正在设计一个 MIPS 处理器作为我的个人项目,现在我遇到了一个非常困惑的问题。我无法总结何时在 MIPS 中使用符号扩展以及何时使用零扩展。
我搜索了很多资源,主要是说:
1) ADDI, ADDIU 都使用signed-extend.
2) ANDI、ORI、XORI都使用零扩展。
然而,在这两条指令中,我开始感到困惑:
SLTIU/SLTI
Imagination 的 "MIPS Architecture for Programmers Volume II-A: The MIPS instruction set Manual" 第 368 页说:
它明确提到16位立即数是有符号的-extend.But我不明白下面的说法:
[0, 32767] 或最大 [max_unsigned-32767, max_unsigned] 无符号范围的结尾。
还有一些人说16位立即数是零扩展的,像这样:
那么,有人可以解释一下 MIPS 中有符号指令和无符号指令之间的确切区别吗?
文档暗示该指令首先对 16 位立即数进行符号扩展,然后执行 32 位无符号比较。在 verilog 中,这应该等于:
if (gpr[rs] < { {16{imm[15]}}, imm })
gpr[rt] = 1;
else
gpr[rt] = 0;
我不确定您显示的两个描述的行为是否完全相同。它们似乎是不同的实现。
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。
基本上,这条指令使您能够在 GPR[rs] 和 [0,32767] 或 [32'hFFFFFFFF-32767, 32] 中的 unsigned 数字之间执行无符号比较'hFFFFFFFF].
第二个实现在 GPR[rs] 和 [0,65535] 之间执行无符号比较。
编辑:
请注意,在 SLTI 和 SLTIU 中,立即数是符号扩展的,但意图不同。在 SLTIU 中,被比较的两个数字被强制取消(通过添加第 33 位)。因此,立即数的符号扩展启用了不同的比较范围:最小的 32767 个和最大的 32767 个无符号值,而不是仅仅 0 到 65535。符号扩展不是为了符号比较而进行的,因为人们可能会混淆。
然而,在 SLTI 中,立即数的符号扩展用于不同的目的:将负值与正值进行比较(带符号比较)。
我正在设计一个 MIPS 处理器作为我的个人项目,现在我遇到了一个非常困惑的问题。我无法总结何时在 MIPS 中使用符号扩展以及何时使用零扩展。
我搜索了很多资源,主要是说:
1) ADDI, ADDIU 都使用signed-extend.
2) ANDI、ORI、XORI都使用零扩展。
然而,在这两条指令中,我开始感到困惑:
SLTIU/SLTI
Imagination 的 "MIPS Architecture for Programmers Volume II-A: The MIPS instruction set Manual" 第 368 页说:
它明确提到16位立即数是有符号的-extend.But我不明白下面的说法:
[0, 32767] 或最大 [max_unsigned-32767, max_unsigned] 无符号范围的结尾。
还有一些人说16位立即数是零扩展的,像这样:
那么,有人可以解释一下 MIPS 中有符号指令和无符号指令之间的确切区别吗?
文档暗示该指令首先对 16 位立即数进行符号扩展,然后执行 32 位无符号比较。在 verilog 中,这应该等于:
if (gpr[rs] < { {16{imm[15]}}, imm })
gpr[rt] = 1;
else
gpr[rt] = 0;
我不确定您显示的两个描述的行为是否完全相同。它们似乎是不同的实现。
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。
基本上,这条指令使您能够在 GPR[rs] 和 [0,32767] 或 [32'hFFFFFFFF-32767, 32] 中的 unsigned 数字之间执行无符号比较'hFFFFFFFF].
第二个实现在 GPR[rs] 和 [0,65535] 之间执行无符号比较。
编辑:
请注意,在 SLTI 和 SLTIU 中,立即数是符号扩展的,但意图不同。在 SLTIU 中,被比较的两个数字被强制取消(通过添加第 33 位)。因此,立即数的符号扩展启用了不同的比较范围:最小的 32767 个和最大的 32767 个无符号值,而不是仅仅 0 到 65535。符号扩展不是为了符号比较而进行的,因为人们可能会混淆。
然而,在 SLTI 中,立即数的符号扩展用于不同的目的:将负值与正值进行比较(带符号比较)。