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, 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 Rv32ZalasrInstruction<Hart>
17where
18    Reg: Register<Type = u32>,
19    Hart: HartConfig<Reg = Reg>,
20{
21}
22
23#[instruction_execution]
24const impl<Reg, Hart, Env> ExecutableInstructionCsr<Env> for Rv32ZalasrInstruction<Hart>
25where
26    Reg: Register<Type = u32>,
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 Rv32ZalasrInstruction<Hart>
34where
35    Reg: [const] Register<Type = u32>,
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 addr = u64::from(rs1_value);
56                let value = i32::from(memory.read::<i8>(addr)?);
57                ExecutionResult::Continue {
58                    rd,
59                    value: value.cast_unsigned(),
60                }
61            }
62            Self::LhAq { rd, rs1: _, rl: _ } => {
63                let addr = u64::from(rs1_value);
64                let value = i32::from(memory.read::<i16>(addr)?);
65                ExecutionResult::Continue {
66                    rd,
67                    value: value.cast_unsigned(),
68                }
69            }
70            Self::LwAq { rd, rs1: _, rl: _ } => {
71                let addr = u64::from(rs1_value);
72                let value = memory.read::<u32>(addr)?;
73                ExecutionResult::Continue { rd, value }
74            }
75            Self::SbRl {
76                rs1: _,
77                rs2: _,
78                aq: _,
79            } => {
80                let addr = u64::from(rs1_value);
81                memory.write(addr, rs2_value as u8)?;
82                ExecutionResult::ContinueNoWrite
83            }
84            Self::ShRl {
85                rs1: _,
86                rs2: _,
87                aq: _,
88            } => {
89                let addr = u64::from(rs1_value);
90                memory.write(addr, rs2_value as u16)?;
91                ExecutionResult::ContinueNoWrite
92            }
93            Self::SwRl {
94                rs1: _,
95                rs2: _,
96                aq: _,
97            } => {
98                let addr = u64::from(rs1_value);
99                memory.write(addr, rs2_value)?;
100                ExecutionResult::ContinueNoWrite
101            }
102        }
103    }
104}