Skip to content

Commit 0751277

Browse files
committed
Merge Retire_Failure into ExecutionResult
There's really no reason to have two levels of unions here so I added `Retire_Success` into `Retire_Failure` and then used that directly as `ExecutionResult`. This is definitely simpler and it also removes the weird case of WFI which was included in `Retire_Failure` when it isn't really failing to retire (especially if `wfi_is_nop()` is true). I left the `RETIRE_SUCCESS` to make the commit smaller, but it does mean there is some stylistic inconsistency. We can fix that with a simple search and replace in future.
1 parent ee9c15a commit 0751277

28 files changed

+430
-433
lines changed

README.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ mapping clause assembly = ITYPE(imm, rs1, rd, op)
181181
```
182182
union clause ast = SRET : unit
183183
184-
mapping clause encdec = SRET() <-> 0b0001000 @ 0b00010 @ 0b00000 @ 0b000 @ 0b00000 @ 0b1110011
184+
mapping clause encdec = SRET()
185+
<-> 0b0001000 @ 0b00010 @ 0b00000 @ 0b000 @ 0b00000 @ 0b1110011
185186
186187
function clause execute SRET() = {
187188
let sret_illegal : bool = match cur_privilege {
@@ -190,9 +191,9 @@ function clause execute SRET() = {
190191
Machine => not(currentlyEnabled(Ext_S))
191192
};
192193
if sret_illegal
193-
then { handle_illegal(); RETIRE_FAIL }
194+
then Illegal_Instruction()
194195
else if not(ext_check_xret_priv (Supervisor))
195-
then { ext_fail_xret_priv(); RETIRE_FAIL }
196+
then Ext_XRET_Priv_Failure()
196197
else {
197198
set_next_pc(exception_handler(cur_privilege, CTL_SRET(), PC));
198199
RETIRE_SUCCESS

model/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,13 @@ foreach (xlen IN ITEMS 32 64)
176176
"riscv_vmem_types.sail"
177177
${sail_regs_srcs}
178178
${sail_sys_srcs}
179+
"riscv_inst_retire.sail"
179180
"riscv_platform.sail"
180181
"riscv_mem.sail"
181182
${sail_vm_srcs}
182183
# Shared/common code for the cryptography extension.
183184
"riscv_types_kext.sail"
184185
"riscv_zvk_utils.sail"
185-
"riscv_inst_retire.sail"
186186
)
187187

188188
if (variant STREQUAL "rvfi")

model/riscv_inst_retire.sail

+11-6
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,21 @@
66
/* SPDX-License-Identifier: BSD-2-Clause */
77
/*=======================================================================================*/
88

9-
/* Reasons an instruction retire might fail or be incomplete. */
9+
// Return value from `execute()` function.
10+
union ExecutionResult = {
11+
// Successfully retired.
12+
Retire_Success : unit,
1013

11-
union Retire_Failure = {
12-
// standard reasons
13-
Illegal_Instruction : unit,
14+
// WFI executed, which may or may not retire
15+
// depending on the configuration.
1416
Wait_For_Interrupt : unit,
17+
18+
// Did not retire for a standard reason.
19+
Illegal_Instruction : unit,
1520
Trap : (Privilege, ctl_result, xlenbits),
1621
Memory_Exception : (virtaddr, ExceptionType),
1722

18-
// reasons from external extensions
23+
// Did not retire for custom reason.
1924
Ext_CSR_Check_Failure : unit,
2025
Ext_ControlAddr_Check_Failure : ext_control_addr_error,
2126
Ext_DataAddr_Check_Failure : ext_data_addr_error,
@@ -27,4 +32,4 @@ union Retire_Failure = {
2732
// RETIRE_SUCCESS enum value so that we don't have to immediately
2833
// update all the places RETIRE_SUCCESS was used.
2934

30-
let RETIRE_SUCCESS : ExecutionResult(Retire_Failure) = RETIRE_OK()
35+
let RETIRE_SUCCESS : ExecutionResult = Retire_Success()

model/riscv_insts_aext.sail

+15-15
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,19 @@ function clause execute(LOADRES(aq, rl, rs1, width, rd)) = {
7474
* Extensions might perform additional checks on address validity.
7575
*/
7676
match ext_data_get_addr(rs1, zeros(), Read(Data), width_bytes) {
77-
Ext_DataAddr_Error(e) => RETIRE_FAIL(Ext_DataAddr_Check_Failure(e)),
77+
Ext_DataAddr_Error(e) => Ext_DataAddr_Check_Failure(e),
7878
Ext_DataAddr_OK(vaddr) => {
7979
/* "LR faults like a normal load, even though it's in the AMO major opcode space."
8080
* - Andrew Waterman, isa-dev, 10 Jul 2018.
8181
*/
8282
if not(is_aligned(bits_of(vaddr), width))
83-
then RETIRE_FAIL(Memory_Exception(vaddr, E_Load_Addr_Align()))
83+
then Memory_Exception(vaddr, E_Load_Addr_Align())
8484
else match translateAddr(vaddr, Read(Data)) {
85-
TR_Failure(e, _) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
85+
TR_Failure(e, _) => Memory_Exception(vaddr, e),
8686
TR_Address(addr, _) =>
8787
match mem_read(Read(Data), addr, width_bytes, aq, aq & rl, true) {
8888
Ok(result) => { load_reservation(bits_of(addr)); X(rd) = sign_extend(result); RETIRE_SUCCESS },
89-
Err(e) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
89+
Err(e) => Memory_Exception(vaddr, e),
9090
},
9191
}
9292
}
@@ -123,28 +123,28 @@ function clause execute (STORECON(aq, rl, rs2, rs1, width, rd)) = {
123123
* Extensions might perform additional checks on address validity.
124124
*/
125125
match ext_data_get_addr(rs1, zeros(), Write(Data), width_bytes) {
126-
Ext_DataAddr_Error(e) => RETIRE_FAIL(Ext_DataAddr_Check_Failure(e)),
126+
Ext_DataAddr_Error(e) => Ext_DataAddr_Check_Failure(e),
127127
Ext_DataAddr_OK(vaddr) => {
128128
if not(is_aligned(bits_of(vaddr), width))
129-
then RETIRE_FAIL(Memory_Exception(vaddr, E_SAMO_Addr_Align()))
129+
then Memory_Exception(vaddr, E_SAMO_Addr_Align())
130130
else {
131131
match translateAddr(vaddr, Write(Data)) { /* Write and ReadWrite are equivalent here:
132132
* both result in a SAMO exception */
133-
TR_Failure(e, _) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
133+
TR_Failure(e, _) => Memory_Exception(vaddr, e),
134134
TR_Address(addr, _) => {
135135
// Check reservation with physical address.
136136
if not(match_reservation(bits_of(addr))) then {
137137
/* cannot happen in rmem */
138138
X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS
139139
} else {
140140
match mem_write_ea(addr, width_bytes, aq & rl, rl, true) {
141-
Err(e) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
141+
Err(e) => Memory_Exception(vaddr, e),
142142
Ok(_) => {
143143
let rs2_val = X(rs2);
144144
match mem_write_value(addr, width_bytes, rs2_val[width_bytes * 8 - 1 .. 0], aq & rl, rl, true) {
145145
Ok(true) => { X(rd) = zero_extend(0b0); cancel_reservation(); RETIRE_SUCCESS },
146146
Ok(false) => { X(rd) = zero_extend(0b1); cancel_reservation(); RETIRE_SUCCESS },
147-
Err(e) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
147+
Err(e) => Memory_Exception(vaddr, e),
148148
}
149149
}
150150
}
@@ -193,19 +193,19 @@ function clause execute (AMO(op, aq, rl, rs2, rs1, width, rd)) = {
193193
* Some extensions perform additional checks on address validity.
194194
*/
195195
match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width_bytes) {
196-
Ext_DataAddr_Error(e) => RETIRE_FAIL(Ext_DataAddr_Check_Failure(e)),
196+
Ext_DataAddr_Error(e) => Ext_DataAddr_Check_Failure(e),
197197
Ext_DataAddr_OK(vaddr) => {
198198
if not(is_aligned(bits_of(vaddr), width))
199-
then RETIRE_FAIL(Memory_Exception(vaddr, E_SAMO_Addr_Align()))
199+
then Memory_Exception(vaddr, E_SAMO_Addr_Align())
200200
else match translateAddr(vaddr, ReadWrite(Data, Data)) {
201-
TR_Failure(e, _) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
201+
TR_Failure(e, _) => Memory_Exception(vaddr, e),
202202
TR_Address(addr, _) => {
203203
let rs2_val = X(rs2)[width_bytes * 8 - 1 .. 0];
204204
match mem_write_ea(addr, width_bytes, aq & rl, rl, true) {
205-
Err(e) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
205+
Err(e) => Memory_Exception(vaddr, e),
206206
Ok(_) => {
207207
match mem_read(ReadWrite(Data, Data), addr, width_bytes, aq, aq & rl, true) {
208-
Err(e) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
208+
Err(e) => Memory_Exception(vaddr, e),
209209
Ok(loaded) => {
210210
let result : bits('width_bytes * 8) =
211211
match op {
@@ -222,7 +222,7 @@ function clause execute (AMO(op, aq, rl, rs2, rs1, width, rd)) = {
222222
match mem_write_value(addr, width_bytes, sign_extend(result), aq & rl, rl, true) {
223223
Ok(true) => { X(rd) = sign_extend(loaded); RETIRE_SUCCESS },
224224
Ok(false) => { internal_error(__FILE__, __LINE__, "AMO got false from mem_write_value") },
225-
Err(e) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
225+
Err(e) => Memory_Exception(vaddr, e),
226226
}
227227
}
228228
}

model/riscv_insts_base.sail

+25-25
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ function clause execute (JAL(imm, rd)) = {
6262
let target = PC + sign_extend(imm);
6363
/* Extensions get the first checks on the prospective target address. */
6464
match ext_control_check_pc(target) {
65-
Ext_ControlAddr_Error(e) => RETIRE_FAIL(Ext_ControlAddr_Check_Failure(e)),
65+
Ext_ControlAddr_Error(e) => Ext_ControlAddr_Check_Failure(e),
6666
Ext_ControlAddr_OK(target) => {
6767
/* Perform standard alignment check */
6868
let target_bits = bits_of(target);
6969
if bit_to_bool(target_bits[1]) & not(currentlyEnabled(Ext_Zca)) then {
70-
RETIRE_FAIL(Memory_Exception(target, E_Fetch_Addr_Align()))
70+
Memory_Exception(target, E_Fetch_Addr_Align())
7171
} else {
7272
X(rd) = get_next_pc();
7373
set_next_pc(target_bits);
@@ -121,11 +121,11 @@ function clause execute (BTYPE(imm, rs2, rs1, op)) = {
121121
let target = PC + sign_extend(imm);
122122
/* Extensions get the first checks on the prospective target address. */
123123
match ext_control_check_pc(target) {
124-
Ext_ControlAddr_Error(e) => RETIRE_FAIL(Ext_ControlAddr_Check_Failure(e)),
124+
Ext_ControlAddr_Error(e) => Ext_ControlAddr_Check_Failure(e),
125125
Ext_ControlAddr_OK(target) => {
126126
let target_bits = bits_of(target);
127127
if bit_to_bool(target_bits[1]) & not(currentlyEnabled(Ext_Zca)) then {
128-
RETIRE_FAIL(Memory_Exception(target, E_Fetch_Addr_Align()))
128+
Memory_Exception(target, E_Fetch_Addr_Align())
129129
} else {
130130
set_next_pc(target_bits);
131131
RETIRE_SUCCESS
@@ -305,16 +305,16 @@ function clause execute (LOAD(imm, rs1, rd, is_unsigned, width, aq, rl)) = {
305305
/* Get the address, X(rs1) + offset.
306306
Some extensions perform additional checks on address validity. */
307307
match ext_data_get_addr(rs1, offset, Read(Data), width_bytes) {
308-
Ext_DataAddr_Error(e) => RETIRE_FAIL(Ext_DataAddr_Check_Failure(e)),
308+
Ext_DataAddr_Error(e) => Ext_DataAddr_Check_Failure(e),
309309
Ext_DataAddr_OK(vaddr) => {
310310
if check_misaligned(vaddr, width)
311-
then RETIRE_FAIL(Memory_Exception(vaddr, E_Load_Addr_Align()))
311+
then Memory_Exception(vaddr, E_Load_Addr_Align())
312312
else match translateAddr(vaddr, Read(Data)) {
313-
TR_Failure(e, _) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
313+
TR_Failure(e, _) => Memory_Exception(vaddr, e),
314314
TR_Address(paddr, _) =>
315315
match mem_read(Read(Data), paddr, width_bytes, aq, rl, false) {
316316
Ok(result) => { X(rd) = extend_value(is_unsigned, result); RETIRE_SUCCESS },
317-
Err(e) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
317+
Err(e) => Memory_Exception(vaddr, e),
318318
},
319319
}
320320
},
@@ -361,21 +361,21 @@ function clause execute (STORE(imm, rs2, rs1, width, aq, rl)) = {
361361
/* Get the address, X(rs1) + offset.
362362
Some extensions perform additional checks on address validity. */
363363
match ext_data_get_addr(rs1, offset, Write(Data), width_bytes) {
364-
Ext_DataAddr_Error(e) => RETIRE_FAIL(Ext_DataAddr_Check_Failure(e)),
364+
Ext_DataAddr_Error(e) => Ext_DataAddr_Check_Failure(e),
365365
Ext_DataAddr_OK(vaddr) =>
366366
if check_misaligned(vaddr, width)
367-
then RETIRE_FAIL(Memory_Exception(vaddr, E_SAMO_Addr_Align()))
367+
then Memory_Exception(vaddr, E_SAMO_Addr_Align())
368368
else match translateAddr(vaddr, Write(Data)) {
369-
TR_Failure(e, _) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
369+
TR_Failure(e, _) => Memory_Exception(vaddr, e),
370370
TR_Address(paddr, _) => {
371371
match mem_write_ea(paddr, width_bytes, aq, rl, false) {
372-
Err(e) => RETIRE_FAIL(Memory_Exception(vaddr, e)),
372+
Err(e) => Memory_Exception(vaddr, e),
373373
Ok(_) => {
374374
let rs2_val = X(rs2);
375375
match mem_write_value(paddr, width_bytes, rs2_val[width_bytes * 8 - 1 .. 0], aq, rl, false) {
376376
Ok(true) => RETIRE_SUCCESS,
377377
Ok(false) => internal_error(__FILE__, __LINE__, "store got false from mem_write_value"),
378-
Err(e) => RETIRE_FAIL(Memory_Exception(vaddr, e))
378+
Err(e) => Memory_Exception(vaddr, e)
379379
}
380380
}
381381
}
@@ -584,7 +584,7 @@ function clause execute ECALL() = {
584584
},
585585
excinfo = (None() : option(xlenbits)),
586586
ext = None() };
587-
RETIRE_FAIL(Trap(cur_privilege, CTL_TRAP(t), PC))
587+
Trap(cur_privilege, CTL_TRAP(t), PC)
588588
}
589589

590590
mapping clause assembly = ECALL() <-> "ecall"
@@ -597,9 +597,9 @@ mapping clause encdec = MRET()
597597

598598
function clause execute MRET() = {
599599
if cur_privilege != Machine
600-
then RETIRE_FAIL(Illegal_Instruction())
600+
then Illegal_Instruction()
601601
else if not(ext_check_xret_priv(Machine))
602-
then RETIRE_FAIL(Ext_XRET_Priv_Failure())
602+
then Ext_XRET_Priv_Failure()
603603
else {
604604
set_next_pc(exception_handler(cur_privilege, CTL_MRET(), PC));
605605
RETIRE_SUCCESS
@@ -621,9 +621,9 @@ function clause execute SRET() = {
621621
Machine => not(currentlyEnabled(Ext_S))
622622
};
623623
if sret_illegal
624-
then RETIRE_FAIL(Illegal_Instruction())
624+
then Illegal_Instruction()
625625
else if not(ext_check_xret_priv (Supervisor))
626-
then RETIRE_FAIL(Ext_XRET_Priv_Failure())
626+
then Ext_XRET_Priv_Failure()
627627
else {
628628
set_next_pc(exception_handler(cur_privilege, CTL_SRET(), PC));
629629
RETIRE_SUCCESS
@@ -639,7 +639,7 @@ mapping clause encdec = EBREAK()
639639
<-> 0b000000000001 @ 0b00000 @ 0b000 @ 0b00000 @ 0b1110011
640640

641641
function clause execute EBREAK() =
642-
RETIRE_FAIL(Memory_Exception(Virtaddr(PC), E_Breakpoint()))
642+
Memory_Exception(Virtaddr(PC), E_Breakpoint())
643643

644644
mapping clause assembly = EBREAK() <-> "ebreak"
645645

@@ -651,11 +651,11 @@ mapping clause encdec = WFI()
651651

652652
function clause execute WFI() =
653653
match cur_privilege {
654-
Machine => RETIRE_FAIL(Wait_For_Interrupt()),
654+
Machine => Wait_For_Interrupt(),
655655
Supervisor => if mstatus[TW] == 0b1
656-
then RETIRE_FAIL(Illegal_Instruction())
657-
else RETIRE_FAIL(Wait_For_Interrupt()),
658-
User => RETIRE_FAIL(Illegal_Instruction())
656+
then Illegal_Instruction()
657+
else Wait_For_Interrupt(),
658+
User => Illegal_Instruction()
659659
}
660660

661661
mapping clause assembly = WFI() <-> "wfi"
@@ -673,9 +673,9 @@ function clause execute SFENCE_VMA(rs1, rs2) = {
673673
// is 9 but we always set it to 16 for RV64.
674674
let asid = if rs2 != zreg then Some(X(rs2)[asidlen - 1 .. 0]) else None();
675675
match cur_privilege {
676-
User => RETIRE_FAIL(Illegal_Instruction()),
676+
User => Illegal_Instruction(),
677677
Supervisor => match mstatus[TVM] {
678-
0b1 => RETIRE_FAIL(Illegal_Instruction()),
678+
0b1 => Illegal_Instruction(),
679679
0b0 => { flush_TLB(asid, addr); RETIRE_SUCCESS },
680680
},
681681
Machine => { flush_TLB(asid, addr); RETIRE_SUCCESS }

model/riscv_insts_begin.sail

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
scattered union ast
1515

1616
/* returns whether an instruction was retired, used for computing minstret */
17-
val execute : ast -> ExecutionResult(Retire_Failure)
17+
val execute : ast -> ExecutionResult
1818
scattered function execute
1919

2020
val assembly : ast <-> string

0 commit comments

Comments
 (0)