在 risc-v 架构中,mulh[[s]u] 操作返回的位是什么样的?



TLDR:给定 64 位寄存器rs1(signed) = 0xffff'ffff'ffff'fff6和 riscv mulhsu 指令rs2(unsigned) = 0x10是否将0x0000'0000'0000'000f0xffff'ffff'ffff'ffff或其他东西完全返回给 RD?

我正在努力实现RiscV架构的模拟版本,并且在实现RV64M mulh[[s]u]指令时遇到了障碍。我不确定 mulhsu 是否返回有符号或无符号的数字。如果它确实返回了一个有符号的数字,那么 mulhsu 和 mulh 有什么区别?

下面是一些演示问题的伪代码(S64 和 U64 分别表示有符号和无符号 64 位寄存器)

rs1.s64 = 0xffff'ffff'ffff'fff6;   //-10
rs2.u64 = 0x10;                    // 16
execute(mulhsu(rs1, rs2));
// which of these is correct? Note: rd only returns the upper 64 bits of the product
EXPECT_EQ(0x0000'0000'0000'000f, rd);
EXPECT_EQ(0xffff'ffff'ffff'ffff, rd);
EXPECT_EQ(<some other value>, rd);

RD 应该签名吗?

从说明手册:

MUL 执行 rs1 乘以 rs2 的 XLEN 位× XLEN 位乘法,并将较低的 XLEN 位放置 在目标寄存器中。MULH、MULHU 和MULHSU执行相同的乘法,但返回 完整的 2 × XLEN 位产品的上部 XLEN 位,用于有符号×有符号、无符号×无符号, 和有符号 rs1×无符号 rs2 乘法分别。如果高位和低位相同 产品是必需的,那么推荐的代码序列是:MULH[[S]U] rdh、rs1、rs2;穆尔 RDL、RS1、RS2(源寄存器说明符的顺序必须相同,RDH 不能与 RS1 或 rs2)。然后,微架构可以将这些融合到单个乘法运算中,而不是执行 两个单独的乘法。

您的问题的答案是:EXPECT_EQ(0xffff'ffff'ffff'ffff, rd);

Murhsu 将执行 rs1.s64 的符号扩展和零扩展 rs2.u64 的乘法。 您可以在编译器机器描述中看到riscv.md.

所以 mulhsu(64 位)将返回等效的:((s128) rs1.s64 * (u128) rs2.u64) >> 64. 其中 S128 是有符号的 128 int,U128 是无符号的 128 Int。

三个 mul 之间的区别是:
mulhsu 是符号扩展寄存器和零扩展寄存器之间的乘法。
mulh 是两个符号扩展寄存器的乘法。
mulhu 是两个零扩展寄存器的乘法。

最新更新