Skip to main content

ab_riscv_interpreter/rv32/
a.rs

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