ab_riscv_interpreter/rv32/a/
zalrsc.rs1#[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}