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