Skip to main content

ab_riscv_interpreter/rv64/
zalasr.rs

1//! RV64 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 Rv64ZalasrInstruction<Reg> where
16    Reg: Register<Type = u64>
17{
18}
19
20#[instruction_execution]
21const impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
22    for Rv64ZalasrInstruction<Reg>
23where
24    Reg: Register<Type = u64>,
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 Rv64ZalasrInstruction<Reg>
32where
33    Reg: [const] Register<Type = u64>,
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 value = i64::from(memory.read::<i8>(rs1_value)?);
54                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
55            }
56            Self::LhAq { rd, rs1: _, rl: _ } => {
57                let value = i64::from(memory.read::<i16>(rs1_value)?);
58                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
59            }
60            Self::LwAq { rd, rs1: _, rl: _ } => {
61                let value = i64::from(memory.read::<i32>(rs1_value)?);
62                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
63            }
64            Self::LdAq { rd, rs1: _, rl: _ } => {
65                let value = memory.read::<u64>(rs1_value)?;
66                Ok(ControlFlow::Continue((rd, value)))
67            }
68            Self::SbRl {
69                rs1: _,
70                rs2: _,
71                aq: _,
72            } => {
73                memory.write(rs1_value, rs2_value as u8)?;
74                Ok(ControlFlow::Continue(Default::default()))
75            }
76            Self::ShRl {
77                rs1: _,
78                rs2: _,
79                aq: _,
80            } => {
81                memory.write(rs1_value, rs2_value as u16)?;
82                Ok(ControlFlow::Continue(Default::default()))
83            }
84            Self::SwRl {
85                rs1: _,
86                rs2: _,
87                aq: _,
88            } => {
89                memory.write(rs1_value, rs2_value as u32)?;
90                Ok(ControlFlow::Continue(Default::default()))
91            }
92            Self::SdRl {
93                rs1: _,
94                rs2: _,
95                aq: _,
96            } => {
97                memory.write(rs1_value, rs2_value)?;
98                Ok(ControlFlow::Continue(Default::default()))
99            }
100        }
101    }
102}