rem
Signed remainder
Calculate the remainder of signed division of xs1 by xs2, and store the result in xd.
If the value in register xs2 is zero, write the value in xs1 into xd;
If the result of the division overflows, write zero into xd;
Decode Variables
Bits<5> xs2 = $encoding[24:20];
Bits<5> xs1 = $encoding[19:15];
Bits<5> xd = $encoding[11:7];
Execution
-
IDL
-
Sail
if (implemented?(ExtensionName::M) && (misa.M == 1'b0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}
XReg src1 = X[xs1];
XReg src2 = X[xs2];
if (src2 == 0) {
X[xd] = src1;
} else if ((src1 == {1'b1, {MXLEN - 1{1'b0}}}) && (src2 == {MXLEN{1'b1}})) {
X[xd] = 0;
} else {
X[xd] = $signed(src1) % $signed(src2);
}
{
if extension("M") then {
let rs1_val = X(rs1);
let rs2_val = X(rs2);
let rs1_int : int = if s then signed(rs1_val) else unsigned(rs1_val);
let rs2_int : int = if s then signed(rs2_val) else unsigned(rs2_val);
let r : int = if rs2_int == 0 then rs1_int else rem_round_zero(rs1_int, rs2_int);
/* signed overflow case returns zero naturally as required due to -1 divisor */
X(rd) = to_bits(sizeof(xlen), r);
RETIRE_SUCCESS
} else {
handle_illegal();
RETIRE_FAIL
}
}