Skip to main content

ab_riscv_interpreter/rv32/
a.rs

1//! RV32 A extension
2
3pub mod zaamo;
4pub mod zalrsc;
5
6use crate::{
7    ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
8    ExecutionResult, FetchInstructionResult, InstructionFetcher, OpaqueThreadedExecutionResult,
9    PackedAddress, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
10    ThreadedExecutableInstruction, ThreadedExecutionResult, VirtualMemory,
11};
12use ab_riscv_macros::instruction_execution;
13use ab_riscv_primitives::prelude::*;
14
15/// Reservation set used to implement `Zalrsc` extension's `lr`/`sc` instruction pairs.
16///
17/// `lr` places a reservation on an address, and a subsequent `sc` succeeds only if the reservation
18/// is still held for the same address. Regardless of success or failure, executing `sc` always
19/// invalidates the reservation, as does a subsequent `lr`.
20pub const trait ReservationSet<Reg>
21where
22    Reg: [const] Register,
23{
24    /// Returns the address of the currently held reservation, if any
25    fn reservation(&self) -> Option<Reg::Type>;
26
27    /// Place a reservation on `address`, replacing any previously held reservation
28    fn set_reservation(&mut self, address: Reg::Type);
29
30    /// Clear any currently held reservation
31    fn clear_reservation(&mut self);
32}
33
34// Convenience for threaded execution
35const impl<Reg, T> ReservationSet<Reg> for &mut T
36where
37    Reg: [const] Register,
38    T: [const] ReservationSet<Reg>,
39{
40    #[inline(always)]
41    fn reservation(&self) -> Option<Reg::Type> {
42        T::reservation(self)
43    }
44
45    #[inline(always)]
46    fn set_reservation(&mut self, address: Reg::Type) {
47        T::set_reservation(self, address);
48    }
49
50    #[inline(always)]
51    fn clear_reservation(&mut self) {
52        T::clear_reservation(self);
53    }
54}
55
56#[instruction_execution]
57const impl<Reg> ExecutableInstructionOperands for Rv32AInstruction<Reg> where
58    Reg: Register<Type = u32>
59{
60}
61
62#[instruction_execution]
63const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv32AInstruction<Reg> where
64    Reg: Register<Type = u32>
65{
66}
67
68#[instruction_execution]
69const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
70    for Rv32AInstruction<Reg>
71where
72    Reg: [const] Register<Type = u32>,
73    Regs: [const] RegisterFile<Reg>,
74    Memory: [const] VirtualMemory,
75    Env: [const] ReservationSet<Reg>,
76{
77    #[inline(always)]
78    #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
79    fn execute(
80        self,
81        Rs1Rs2OperandValues {
82            rs1_value,
83            rs2_value,
84        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
85        _regs: &mut Regs,
86        env: &mut Env,
87        memory: &mut Memory,
88        _program_counter: &mut PC,
89    ) -> ExecutionResult<Self::Reg> {
90        ExecutionResult::ContinueNoWrite
91    }
92}