Skip to main content

ab_riscv_interpreter/
zawrs.rs

1//! Zawrs extension
2
3#[cfg(test)]
4mod tests;
5
6use crate::{
7    ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands,
8    ExecutableInstructionResult, Rs1Rs2OperandValues, Rs1Rs2Operands,
9};
10use ab_riscv_macros::instruction_execution;
11use ab_riscv_primitives::prelude::*;
12use core::ops::ControlFlow;
13
14/// Custom handler for `Zawrs` extension's `wrs.nto`/`wrs.sto` instructions.
15///
16/// These are hint instructions that may complete for any reason, so a no-op is a valid
17/// implementation for both.
18pub const trait WrsHandler {
19    /// Handle a `wrs.nto` instruction (Wait-on-Reservation-Set, no timeout)
20    #[inline(always)]
21    fn handle_wrs_nto(&mut self) {
22        // NOP by default
23    }
24
25    /// Handle a `wrs.sto` instruction (Wait-on-Reservation-Set, short timeout)
26    #[inline(always)]
27    fn handle_wrs_sto(&mut self) {
28        // NOP by default
29    }
30}
31
32#[instruction_execution]
33const impl<Reg> ExecutableInstructionOperands for ZawrsInstruction<Reg> where Reg: Register {}
34
35#[instruction_execution]
36const impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
37    for ZawrsInstruction<Reg>
38where
39    Reg: Register,
40{
41}
42
43#[instruction_execution]
44const impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
45    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
46    for ZawrsInstruction<Reg>
47where
48    Reg: [const] Register,
49    InstructionHandler: [const] WrsHandler,
50{
51    #[inline(always)]
52    #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
53    fn execute(
54        self,
55        Rs1Rs2OperandValues {
56            rs1_value: _,
57            rs2_value: _,
58        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
59        _regs: &mut Regs,
60        _ext_state: &mut ExtState,
61        _memory: &mut Memory,
62        _program_counter: &mut PC,
63        system_instruction_handler: &mut InstructionHandler,
64    ) -> ExecutableInstructionResult<(), Self, CustomError> {
65        match self {
66            Self::WrsNto => {
67                system_instruction_handler.handle_wrs_nto();
68                Ok(ControlFlow::Continue(Default::default()))
69            }
70            Self::WrsSto => {
71                system_instruction_handler.handle_wrs_sto();
72                Ok(ControlFlow::Continue(Default::default()))
73            }
74        }
75    }
76}