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, Hart> ExecutableInstructionOperands for Rv32AInstruction<Hart>
59where
60    Reg: Register<Type = u32>,
61    Hart: HartConfig<Reg = Reg>,
62{
63}
64
65#[instruction_execution]
66const impl<Reg, Hart, Env> ExecutableInstructionCsr<Env> for Rv32AInstruction<Hart>
67where
68    Reg: Register<Type = u32>,
69    Hart: HartConfig<Reg = Reg>,
70{
71}
72
73#[instruction_execution]
74const impl<Reg, Hart, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
75    for Rv32AInstruction<Hart>
76where
77    Reg: [const] Register<Type = u32>,
78    Hart: HartConfig<Reg = Reg>,
79    Regs: [const] RegisterFile<Reg>,
80    Memory: [const] VirtualMemory,
81    Env: [const] ReservationSet<Reg>,
82{
83    #[inline(always)]
84    #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
85    fn execute(
86        self,
87        Rs1Rs2OperandValues {
88            rs1_value,
89            rs2_value,
90        }: Rs1Rs2OperandValues<Reg::Type>,
91        _regs: &mut Regs,
92        env: &mut Env,
93        memory: &mut Memory,
94        _program_counter: &PC,
95    ) -> ExecutionResult<Reg> {
96        ExecutionResult::ContinueNoWrite
97    }
98}