Skip to content

Commit d784767

Browse files
author
Tim Hutt
authored
Use to_bits_truncate in the M extension (riscv#1081)
In this case truncation is intentional. Also some minor style cleanups.
1 parent 662db10 commit d784767

File tree

1 file changed

+22
-19
lines changed

1 file changed

+22
-19
lines changed

model/riscv_insts_mext.sail

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,19 @@ function clause execute (MUL(rs2, rs1, rd, mul_op)) = {
3131
let rs2_bits = X(rs2);
3232
let rs1_int = if mul_op.signed_rs1 then signed(rs1_bits) else unsigned(rs1_bits);
3333
let rs2_int = if mul_op.signed_rs2 then signed(rs2_bits) else unsigned(rs2_bits);
34-
let result_wide = to_bits_unsafe(2 * xlen, rs1_int * rs2_int);
35-
let result = if mul_op.high
36-
then result_wide[(2 * xlen - 1) .. xlen]
37-
else result_wide[(xlen - 1) .. 0];
38-
X(rd) = result;
34+
35+
let result_wide = to_bits_truncate(2 * xlen, rs1_int * rs2_int);
36+
X(rd) = if mul_op.high
37+
then result_wide[(2 * xlen - 1) .. xlen]
38+
else result_wide[(xlen - 1) .. 0];
3939
RETIRE_SUCCESS
4040
}
4141

4242
mapping mul_mnemonic : mul_op <-> string = {
4343
struct { high = false, signed_rs1 = true, signed_rs2 = true } <-> "mul",
4444
struct { high = true, signed_rs1 = true, signed_rs2 = true } <-> "mulh",
4545
struct { high = true, signed_rs1 = true, signed_rs2 = false } <-> "mulhsu",
46-
struct { high = true, signed_rs1 = false, signed_rs2 = false } <-> "mulhu"
46+
struct { high = true, signed_rs1 = false, signed_rs2 = false } <-> "mulhu",
4747
}
4848

4949
mapping clause assembly = MUL(rs2, rs1, rd, mul_op)
@@ -61,10 +61,11 @@ function clause execute (DIV(rs2, rs1, rd, is_unsigned)) = {
6161
let rs2_bits = X(rs2);
6262
let rs1_int = if is_unsigned then unsigned(rs1_bits) else signed(rs1_bits);
6363
let rs2_int = if is_unsigned then unsigned(rs2_bits) else signed(rs2_bits);
64+
6465
let quotient = if rs2_int == 0 then -1 else quot_round_zero(rs1_int, rs2_int);
65-
/* check for signed overflow */
66+
// Check for signed overflow.
6667
let quotient = if not(is_unsigned) & quotient >= 2 ^ (xlen - 1) then negate(2 ^ (xlen - 1)) else quotient;
67-
X(rd) = to_bits_unsafe(xlen, quotient);
68+
X(rd) = to_bits_truncate(quotient);
6869
RETIRE_SUCCESS
6970
}
7071

@@ -83,9 +84,10 @@ function clause execute (REM(rs2, rs1, rd, is_unsigned)) = {
8384
let rs2_bits = X(rs2);
8485
let rs1_int = if is_unsigned then unsigned(rs1_bits) else signed(rs1_bits);
8586
let rs2_int = if is_unsigned then unsigned(rs2_bits) else signed(rs2_bits);
87+
8688
let remainder = if rs2_int == 0 then rs1_int else rem_round_zero(rs1_int, rs2_int);
87-
/* signed overflow case returns zero naturally as required due to -1 divisor */
88-
X(rd) = to_bits_unsafe(xlen, remainder);
89+
// Signed overflow case returns zero naturally as required due to -1 divisor.
90+
X(rd) = to_bits_truncate(remainder);
8991
RETIRE_SUCCESS
9092
}
9193

@@ -104,10 +106,9 @@ function clause execute (MULW(rs2, rs1, rd)) = {
104106
let rs2_bits = X(rs2)[31..0];
105107
let rs1_int = signed(rs1_bits);
106108
let rs2_int = signed(rs2_bits);
107-
/* to_bits_unsafe requires expansion to 64 bits followed by truncation */
108-
let result32 = to_bits_unsafe(64, rs1_int * rs2_int)[31..0];
109-
let result : xlenbits = sign_extend(result32);
110-
X(rd) = result;
109+
110+
let result32 : bits(32) = to_bits_truncate(rs1_int * rs2_int);
111+
X(rd) = sign_extend(result32);
111112
RETIRE_SUCCESS
112113
}
113114

@@ -127,10 +128,11 @@ function clause execute (DIVW(rs2, rs1, rd, is_unsigned)) = {
127128
let rs2_bits = X(rs2)[31..0];
128129
let rs1_int = if is_unsigned then unsigned(rs1_bits) else signed(rs1_bits);
129130
let rs2_int = if is_unsigned then unsigned(rs2_bits) else signed(rs2_bits);
131+
130132
let quotient = if rs2_int == 0 then -1 else quot_round_zero(rs1_int, rs2_int);
131-
/* check for signed overflow */
132-
let quotient = if not(is_unsigned) & quotient > (2 ^ 31 - 1) then negate(2 ^ 31) else quotient;
133-
X(rd) = sign_extend(to_bits_unsafe(32, quotient));
133+
// Check for signed overflow.
134+
let quotient = if not(is_unsigned) & quotient >= 2 ^ 31 then negate(2 ^ 31) else quotient;
135+
X(rd) = sign_extend(to_bits_truncate(32, quotient));
134136
RETIRE_SUCCESS
135137
}
136138

@@ -150,9 +152,10 @@ function clause execute (REMW(rs2, rs1, rd, is_unsigned)) = {
150152
let rs2_bits = X(rs2)[31..0];
151153
let rs1_int = if is_unsigned then unsigned(rs1_bits) else signed(rs1_bits);
152154
let rs2_int = if is_unsigned then unsigned(rs2_bits) else signed(rs2_bits);
155+
153156
let remainder = if rs2_int == 0 then rs1_int else rem_round_zero(rs1_int, rs2_int);
154-
/* signed overflow case returns zero naturally as required due to -1 divisor */
155-
X(rd) = sign_extend(to_bits_unsafe(32, remainder));
157+
// Signed overflow case returns zero naturally as required due to -1 divisor.
158+
X(rd) = sign_extend(to_bits_truncate(32, remainder));
156159
RETIRE_SUCCESS
157160
}
158161

0 commit comments

Comments
 (0)