title: In the risc-v architecture, what do the bits returned by the mulh[[s]u] operation look like?
body: <p>TLDR: given 64 bit registers <code>rs1(signed) = 0xffff'ffff'ffff'fff6</code> and <code>rs2(unsigned) = 0x10</code> does the riscv mulhsu instruction return <code>0x0000'0000'0000'000f</code> or <code>0xffff'ffff'ffff'ffff</code> or something else entirely to rd?</p>
  <p>I am working on implementing a simulated version of the RiscV architecture and have run into a snag when implementing the RV64M mulh[[s]u] instruction. I'm not sure if mulhsu returns a signed or unsigned number. If it does return a signed number, then what is the difference between mulhsu and mulh?</p>
  <p>here is some pseudocode demonstrating the problem (s64 and u64 denote signed and unsigned 64-bit register respectively)</p>
  <pre><code>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(&lt;some other value&gt;, rd);
  </code></pre>
  <p>Should rd be signed? unsigned?</p>
  <p>From the instruction manual:</p>
  <p>MUL performs an XLEN-bit × XLEN-bit multiplication of rs1 by rs2 and places the lower XLEN bits
  in the destination register. MULH, MULHU, and <strong>MULHSU</strong> perform the same multiplication but return
  the upper XLEN bits of the full 2 × XLEN-bit product, for signed × signed, unsigned × unsigned,
  and <strong>signed rs1×unsigned rs2 multiplication</strong>, respectively. If both the high and low bits of the same
  product are required, then the recommended code sequence is: MULH[[S]U] rdh, rs1, rs2; MUL
  rdl, rs1, rs2 (source register specifiers must be in same order and rdh cannot be the same as rs1 or
  rs2). Microarchitectures can then fuse these into a single multiply operation instead of performing
  two separate multiplies.</p>