mulw
Signed 32-bit multiply
This instruction is defined by:
-
anyOf:
-
M, version >= 0
-
Zmmul, version >= 0
-
This instruction is included in the following profiles:
-
RVA20U64 (Mandatory)
-
RVA22U64 (Mandatory)
-
RVI20U32 (Optional)
-
RVI20U64 (Optional)
Synopsis
This instruction must have data-independent timing when extension Zkt is enabled. |
Multiplies the lower 32 bits of the source registers, placing the sign-extension of the lower 32 bits of the result into the destination register.
Any overflow is thrown away.
In RV64, MUL can be used to obtain the upper 32 bits of the 64-bit product, but signed arguments must be proper 32-bit signed values, whereas unsigned arguments must have their upper 32 bits clear. If the arguments are not known to be sign- or zero-extended, an alternative is to shift both arguments left by 32 bits, then use MULH[[S]U]. |
Decode Variables
Bits<5> rs2 = $encoding[24:20];
Bits<5> rs1 = $encoding[19:15];
Bits<5> rd = $encoding[11:7];
Execution
-
IDL
-
Sail
if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}
Bits<32> src1 = X[rs1][31:0];
Bits<32> src2 = X[rs2][31:0];
Bits<32> result = src1 * src2;
Bits<1> sign_bit = result[31];
X[rd] = {{32{sign_bit}}, result};
{
if extension("M") | haveZmmul() then {
let rs1_val = X(rs1)[31..0];
let rs2_val = X(rs2)[31..0];
let rs1_int : int = signed(rs1_val);
let rs2_int : int = signed(rs2_val);
/* to_bits requires expansion to 64 bits followed by truncation */
let result32 = to_bits(64, rs1_int * rs2_int)[31..0];
let result : xlenbits = sign_extend(result32);
X(rd) = result;
RETIRE_SUCCESS
} else {
handle_illegal();
RETIRE_FAIL
}
}