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, ExecutionError,
8    ExecutionResult, FetchInstructionResult, InstructionFetcher, OpaqueThreadedExecutionResult,
9    RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, ThreadedExecutableInstruction,
10    ThreadedExecutionResult, VirtualMemory,
11};
12use ab_riscv_macros::instruction_execution;
13use ab_riscv_primitives::prelude::*;
14
15#[instruction_execution]
16const impl<Reg> ExecutableInstructionOperands for Rv64ZalasrInstruction<Reg> where
17    Reg: Register<Type = u64>
18{
19}
20
21#[instruction_execution]
22const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv64ZalasrInstruction<Reg> where
23    Reg: Register<Type = u64>
24{
25}
26
27#[instruction_execution]
28const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
29    for Rv64ZalasrInstruction<Reg>
30where
31    Reg: [const] Register<Type = u64>,
32    Regs: [const] RegisterFile<Reg>,
33    Memory: [const] VirtualMemory,
34{
35    #[inline(always)]
36    #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
37    fn execute(
38        self,
39        Rs1Rs2OperandValues {
40            rs1_value,
41            rs2_value,
42        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
43        _regs: &mut Regs,
44        _env: &mut Env,
45        memory: &mut Memory,
46        _program_counter: &mut PC,
47    ) -> ExecutionResult<Self::Reg> {
48        match self {
49            Self::LbAq { rd, rs1: _, rl: _ } => {
50                let value = i64::from(memory.read::<i8>(rs1_value)?);
51                ExecutionResult::Continue {
52                    rd,
53                    value: value.cast_unsigned(),
54                }
55            }
56            Self::LhAq { rd, rs1: _, rl: _ } => {
57                let value = i64::from(memory.read::<i16>(rs1_value)?);
58                ExecutionResult::Continue {
59                    rd,
60                    value: value.cast_unsigned(),
61                }
62            }
63            Self::LwAq { rd, rs1: _, rl: _ } => {
64                let value = i64::from(memory.read::<i32>(rs1_value)?);
65                ExecutionResult::Continue {
66                    rd,
67                    value: value.cast_unsigned(),
68                }
69            }
70            Self::LdAq { rd, rs1: _, rl: _ } => {
71                let value = memory.read::<u64>(rs1_value)?;
72                ExecutionResult::Continue { rd, value }
73            }
74            Self::SbRl {
75                rs1: _,
76                rs2: _,
77                aq: _,
78            } => {
79                memory.write(rs1_value, rs2_value as u8)?;
80                ExecutionResult::ContinueNoWrite
81            }
82            Self::ShRl {
83                rs1: _,
84                rs2: _,
85                aq: _,
86            } => {
87                memory.write(rs1_value, rs2_value as u16)?;
88                ExecutionResult::ContinueNoWrite
89            }
90            Self::SwRl {
91                rs1: _,
92                rs2: _,
93                aq: _,
94            } => {
95                memory.write(rs1_value, rs2_value as u32)?;
96                ExecutionResult::ContinueNoWrite
97            }
98            Self::SdRl {
99                rs1: _,
100                rs2: _,
101                aq: _,
102            } => {
103                memory.write(rs1_value, rs2_value)?;
104                ExecutionResult::ContinueNoWrite
105            }
106        }
107    }
108}