Skip to main content

ab_riscv_interpreter/rv32/zce/
zcb.rs

1//! Zcb compressed instruction execution (RV32)
2//!
3//! C.ZEXT.W is absent in RV32 - the enum has no such variant.
4
5#[cfg(test)]
6mod tests;
7
8use crate::{
9    ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
10    ProgramCounter, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, SystemInstructionHandler,
11    VirtualMemory,
12};
13use ab_riscv_macros::instruction_execution;
14use ab_riscv_primitives::prelude::*;
15use core::ops::ControlFlow;
16
17#[instruction_execution]
18impl<Reg> ExecutableInstructionOperands for Rv32ZcbInstruction<Reg> where Reg: Register<Type = u32> {}
19
20#[instruction_execution]
21impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
22    for Rv32ZcbInstruction<Reg>
23where
24    Reg: Register<Type = u32>,
25{
26}
27
28#[instruction_execution]
29impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
30    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
31    for Rv32ZcbInstruction<Reg>
32where
33    Reg: Register<Type = u32>,
34{
35    #[inline(always)]
36    fn execute(
37        self,
38        Rs1Rs2OperandValues {
39            rs1_value,
40            rs2_value,
41        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
42        regs: &mut Regs,
43        _ext_state: &mut ExtState,
44        memory: &mut Memory,
45        program_counter: &mut PC,
46        system_instruction_handler: &mut InstructionHandler,
47    ) -> Result<
48        ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
49        ExecutionError<Reg::Type, CustomError>,
50    > {
51        Ok(ControlFlow::Continue(Default::default()))
52    }
53}
54
55#[instruction_execution]
56impl<Reg> ExecutableInstructionOperands for Rv32ZcbOnlyInstruction<Reg> where
57    Reg: Register<Type = u32>
58{
59}
60
61#[instruction_execution]
62impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
63    for Rv32ZcbOnlyInstruction<Reg>
64where
65    Reg: Register<Type = u32>,
66{
67}
68
69#[instruction_execution]
70impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
71    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
72    for Rv32ZcbOnlyInstruction<Reg>
73where
74    Reg: Register<Type = u32>,
75    Regs: RegisterFile<Reg>,
76    Memory: VirtualMemory,
77    PC: ProgramCounter<Reg::Type, Memory, CustomError>,
78    InstructionHandler: SystemInstructionHandler<Reg, Regs, Memory, PC, CustomError>,
79{
80    #[inline(always)]
81    fn execute(
82        self,
83        Rs1Rs2OperandValues {
84            rs1_value,
85            rs2_value,
86        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
87        regs: &mut Regs,
88        _ext_state: &mut ExtState,
89        memory: &mut Memory,
90        _program_counter: &mut PC,
91        _system_instruction_handler: &mut InstructionHandler,
92    ) -> Result<
93        ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
94        ExecutionError<Reg::Type, CustomError>,
95    > {
96        match self {
97            Self::CLbu { rd, rs1: _, uimm } => {
98                let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
99                let value = memory.read::<u8>(addr)?;
100                Ok(ControlFlow::Continue((rd, u32::from(value))))
101            }
102            Self::CLh { rd, rs1: _, uimm } => {
103                let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
104                let value = i32::from(memory.read::<i16>(addr)?);
105                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
106            }
107            Self::CLhu { rd, rs1: _, uimm } => {
108                let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
109                let value = memory.read::<u16>(addr)?;
110                Ok(ControlFlow::Continue((rd, u32::from(value))))
111            }
112            Self::CSb {
113                rs1: _,
114                rs2: _,
115                uimm,
116            } => {
117                let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
118                memory.write(addr, rs2_value as u8)?;
119                Ok(ControlFlow::Continue(Default::default()))
120            }
121            Self::CSh {
122                rs1: _,
123                rs2: _,
124                uimm,
125            } => {
126                let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
127                memory.write(addr, rs2_value as u16)?;
128                Ok(ControlFlow::Continue(Default::default()))
129            }
130            Self::CZextB { rd } => {
131                let value = regs.read(rd) & 0xff;
132                Ok(ControlFlow::Continue((rd, value)))
133            }
134            Self::CSextB { rd } => {
135                let value = i32::from(regs.read(rd) as i8);
136                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
137            }
138            Self::CZextH { rd } => {
139                let value = regs.read(rd) & 0xffff;
140                Ok(ControlFlow::Continue((rd, value)))
141            }
142            Self::CSextH { rd } => {
143                let value = i32::from(regs.read(rd) as i16);
144                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
145            }
146            Self::CNot { rd } => {
147                let value = !regs.read(rd);
148                Ok(ControlFlow::Continue((rd, value)))
149            }
150            Self::CMul { rd, rs2: _ } => {
151                let value = regs.read(rd).wrapping_mul(rs2_value);
152                Ok(ControlFlow::Continue((rd, value)))
153            }
154        }
155    }
156}