Skip to main content

ab_riscv_interpreter/rv32/a/
zalrsc.rs

1//! RV32 Zalrsc extension
2
3#[cfg(test)]
4mod tests;
5
6use crate::rv32::a::ReservationSet;
7use crate::{
8    ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands,
9    ExecutableInstructionResult, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, VirtualMemory,
10};
11use ab_riscv_macros::instruction_execution;
12use ab_riscv_primitives::prelude::*;
13use core::ops::ControlFlow;
14
15#[instruction_execution]
16const impl<Reg> ExecutableInstructionOperands for Rv32ZalrscInstruction<Reg> where
17    Reg: Register<Type = u32>
18{
19}
20
21#[instruction_execution]
22const impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
23    for Rv32ZalrscInstruction<Reg>
24where
25    Reg: Register<Type = u32>,
26{
27}
28
29#[instruction_execution]
30const impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
31    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
32    for Rv32ZalrscInstruction<Reg>
33where
34    Reg: [const] Register<Type = u32>,
35    Regs: [const] RegisterFile<Reg>,
36    Memory: [const] VirtualMemory,
37    ExtState: [const] ReservationSet<Reg>,
38{
39    #[inline(always)]
40    #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
41    fn execute(
42        self,
43        Rs1Rs2OperandValues {
44            rs1_value,
45            rs2_value,
46        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
47        _regs: &mut Regs,
48        ext_state: &mut ExtState,
49        memory: &mut Memory,
50        _program_counter: &mut PC,
51        _system_instruction_handler: &mut InstructionHandler,
52    ) -> ExecutableInstructionResult<(), Self, CustomError> {
53        match self {
54            Self::Lr {
55                rd,
56                rs1: _,
57                aq: _,
58                rl: _,
59            } => {
60                let value = memory.read::<u32>(u64::from(rs1_value))?;
61                ext_state.set_reservation(rs1_value);
62                Ok(ControlFlow::Continue((rd, value)))
63            }
64            Self::Sc {
65                rd,
66                rs1: _,
67                rs2: _,
68                aq: _,
69                rl: _,
70            } => {
71                let success = ext_state.reservation() == Some(rs1_value);
72                ext_state.clear_reservation();
73
74                if success {
75                    memory.write(u64::from(rs1_value), rs2_value)?;
76                    Ok(ControlFlow::Continue((rd, 0)))
77                } else {
78                    Ok(ControlFlow::Continue((rd, 1)))
79                }
80            }
81        }
82    }
83}