Skip to main content

ab_riscv_interpreter/rv32/
zalasr.rs

1//! RV32 Zalasr extension
2
3#[cfg(test)]
4mod tests;
5
6use crate::{
7    ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands,
8    ExecutableInstructionResult, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, VirtualMemory,
9};
10use ab_riscv_macros::instruction_execution;
11use ab_riscv_primitives::prelude::*;
12use core::ops::ControlFlow;
13
14#[instruction_execution]
15const impl<Reg> ExecutableInstructionOperands for Rv32ZalasrInstruction<Reg> where
16    Reg: Register<Type = u32>
17{
18}
19
20#[instruction_execution]
21const impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
22    for Rv32ZalasrInstruction<Reg>
23where
24    Reg: Register<Type = u32>,
25{
26}
27
28#[instruction_execution]
29const impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
30    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
31    for Rv32ZalasrInstruction<Reg>
32where
33    Reg: [const] Register<Type = u32>,
34    Regs: [const] RegisterFile<Reg>,
35    Memory: [const] VirtualMemory,
36{
37    #[inline(always)]
38    #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
39    fn execute(
40        self,
41        Rs1Rs2OperandValues {
42            rs1_value,
43            rs2_value,
44        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
45        _regs: &mut Regs,
46        _ext_state: &mut ExtState,
47        memory: &mut Memory,
48        _program_counter: &mut PC,
49        _system_instruction_handler: &mut InstructionHandler,
50    ) -> ExecutableInstructionResult<(), Self, CustomError> {
51        match self {
52            Self::LbAq { rd, rs1: _, rl: _ } => {
53                let addr = u64::from(rs1_value);
54                let value = i32::from(memory.read::<i8>(addr)?);
55                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
56            }
57            Self::LhAq { rd, rs1: _, rl: _ } => {
58                let addr = u64::from(rs1_value);
59                let value = i32::from(memory.read::<i16>(addr)?);
60                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
61            }
62            Self::LwAq { rd, rs1: _, rl: _ } => {
63                let addr = u64::from(rs1_value);
64                let value = memory.read::<u32>(addr)?;
65                Ok(ControlFlow::Continue((rd, value)))
66            }
67            Self::SbRl {
68                rs1: _,
69                rs2: _,
70                aq: _,
71            } => {
72                let addr = u64::from(rs1_value);
73                memory.write(addr, rs2_value as u8)?;
74                Ok(ControlFlow::Continue(Default::default()))
75            }
76            Self::ShRl {
77                rs1: _,
78                rs2: _,
79                aq: _,
80            } => {
81                let addr = u64::from(rs1_value);
82                memory.write(addr, rs2_value as u16)?;
83                Ok(ControlFlow::Continue(Default::default()))
84            }
85            Self::SwRl {
86                rs1: _,
87                rs2: _,
88                aq: _,
89            } => {
90                let addr = u64::from(rs1_value);
91                memory.write(addr, rs2_value)?;
92                Ok(ControlFlow::Continue(Default::default()))
93            }
94        }
95    }
96}