Skip to main content

ab_riscv_interpreter/rv64/a/
zalrsc.rs

1//! RV64 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 Rv64ZalrscInstruction<Reg> where
17    Reg: Register<Type = u64>
18{
19}
20
21#[instruction_execution]
22const impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
23    for Rv64ZalrscInstruction<Reg>
24where
25    Reg: Register<Type = u64>,
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 Rv64ZalrscInstruction<Reg>
33where
34    Reg: [const] Register<Type = u64>,
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::<i32>(rs1_value)?;
61                ext_state.set_reservation(rs1_value);
62                Ok(ControlFlow::Continue((
63                    rd,
64                    i64::from(value).cast_unsigned(),
65                )))
66            }
67            Self::Sc {
68                rd,
69                rs1: _,
70                rs2: _,
71                aq: _,
72                rl: _,
73            } => {
74                let success = ext_state.reservation() == Some(rs1_value);
75                ext_state.clear_reservation();
76
77                if success {
78                    memory.write(rs1_value, rs2_value as u32)?;
79                    Ok(ControlFlow::Continue((rd, 0)))
80                } else {
81                    Ok(ControlFlow::Continue((rd, 1)))
82                }
83            }
84            Self::LrD {
85                rd,
86                rs1: _,
87                aq: _,
88                rl: _,
89            } => {
90                let value = memory.read::<u64>(rs1_value)?;
91                ext_state.set_reservation(rs1_value);
92                Ok(ControlFlow::Continue((rd, value)))
93            }
94            Self::ScD {
95                rd,
96                rs1: _,
97                rs2: _,
98                aq: _,
99                rl: _,
100            } => {
101                let success = ext_state.reservation() == Some(rs1_value);
102                ext_state.clear_reservation();
103
104                if success {
105                    memory.write(rs1_value, rs2_value)?;
106                    Ok(ControlFlow::Continue((rd, 0)))
107                } else {
108                    Ok(ControlFlow::Continue((rd, 1)))
109                }
110            }
111        }
112    }
113}