Skip to main content

ab_riscv_interpreter/rv64/zce/
zcb.rs

1//! Zcb compressed instruction execution
2
3#[cfg(test)]
4mod tests;
5
6use crate::{
7    ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
8    ProgramCounter, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, SystemInstructionHandler,
9    VirtualMemory,
10};
11use ab_riscv_macros::instruction_execution;
12use ab_riscv_primitives::prelude::*;
13use core::ops::ControlFlow;
14
15#[instruction_execution]
16impl<Reg> ExecutableInstructionOperands for Rv64ZcbInstruction<Reg> where Reg: Register<Type = u64> {}
17
18#[instruction_execution]
19impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
20    for Rv64ZcbInstruction<Reg>
21where
22    Reg: Register<Type = u64>,
23{
24}
25
26#[instruction_execution]
27impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
28    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
29    for Rv64ZcbInstruction<Reg>
30where
31    Reg: Register<Type = u64>,
32    Regs: RegisterFile<Reg>,
33    Memory: VirtualMemory,
34    PC: ProgramCounter<Reg::Type, Memory, CustomError>,
35    InstructionHandler: SystemInstructionHandler<Reg, Regs, Memory, PC, CustomError>,
36{
37    #[inline(always)]
38    fn execute(
39        self,
40        Rs1Rs2OperandValues {
41            rs1_value,
42            rs2_value,
43        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
44        regs: &mut Regs,
45        _ext_state: &mut ExtState,
46        memory: &mut Memory,
47        _program_counter: &mut PC,
48        _system_instruction_handler: &mut InstructionHandler,
49    ) -> Result<
50        ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
51        ExecutionError<Reg::Type, CustomError>,
52    > {
53        match self {
54            Self::CLbu { rd, rs1: _, uimm } => {
55                let addr = rs1_value.wrapping_add(u64::from(uimm));
56                let value = memory.read::<u8>(addr)?;
57                Ok(ControlFlow::Continue((rd, u64::from(value))))
58            }
59            Self::CLh { rd, rs1: _, uimm } => {
60                let addr = rs1_value.wrapping_add(u64::from(uimm));
61                let value = i64::from(memory.read::<i16>(addr)?);
62                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
63            }
64            Self::CLhu { rd, rs1: _, uimm } => {
65                let addr = rs1_value.wrapping_add(u64::from(uimm));
66                let value = memory.read::<u16>(addr)?;
67                Ok(ControlFlow::Continue((rd, u64::from(value))))
68            }
69            Self::CSb {
70                rs1: _,
71                rs2: _,
72                uimm,
73            } => {
74                let addr = rs1_value.wrapping_add(u64::from(uimm));
75                memory.write(addr, rs2_value as u8)?;
76                Ok(ControlFlow::Continue(Default::default()))
77            }
78            Self::CSh {
79                rs1: _,
80                rs2: _,
81                uimm,
82            } => {
83                let addr = rs1_value.wrapping_add(u64::from(uimm));
84                memory.write(addr, rs2_value as u16)?;
85
86                Ok(ControlFlow::Continue(Default::default()))
87            }
88            Self::CZextB { rd } => {
89                let value = regs.read(rd) & 0xff;
90                Ok(ControlFlow::Continue((rd, value)))
91            }
92            Self::CSextB { rd } => {
93                let value = i64::from(regs.read(rd) as i8);
94                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
95            }
96            Self::CZextH { rd } => {
97                let value = regs.read(rd) & 0xffff;
98                Ok(ControlFlow::Continue((rd, value)))
99            }
100            Self::CSextH { rd } => {
101                let value = i64::from(regs.read(rd) as i16);
102                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
103            }
104            Self::CZextW { rd } => {
105                let value = regs.read(rd) & 0xffff_ffff;
106                Ok(ControlFlow::Continue((rd, value)))
107            }
108            Self::CNot { rd } => {
109                let value = !regs.read(rd);
110                Ok(ControlFlow::Continue((rd, value)))
111            }
112            Self::CMul { rd, rs2: _ } => {
113                let value = regs.read(rd).wrapping_mul(rs2_value);
114                Ok(ControlFlow::Continue((rd, value)))
115            }
116        }
117    }
118}