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{
33    #[inline(always)]
34    fn execute(
35        self,
36        Rs1Rs2OperandValues {
37            rs1_value,
38            rs2_value,
39        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
40        regs: &mut Regs,
41        _ext_state: &mut ExtState,
42        memory: &mut Memory,
43        program_counter: &mut PC,
44        system_instruction_handler: &mut InstructionHandler,
45    ) -> Result<
46        ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
47        ExecutionError<Reg::Type, CustomError>,
48    > {
49        Ok(ControlFlow::Continue(Default::default()))
50    }
51}
52
53#[instruction_execution]
54impl<Reg> ExecutableInstructionOperands for Rv64ZcbOnlyInstruction<Reg> where
55    Reg: Register<Type = u64>
56{
57}
58
59#[instruction_execution]
60impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
61    for Rv64ZcbOnlyInstruction<Reg>
62where
63    Reg: Register<Type = u64>,
64{
65}
66
67#[instruction_execution]
68impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
69    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
70    for Rv64ZcbOnlyInstruction<Reg>
71where
72    Reg: Register<Type = u64>,
73    Regs: RegisterFile<Reg>,
74    Memory: VirtualMemory,
75    PC: ProgramCounter<Reg::Type, Memory, CustomError>,
76    InstructionHandler: SystemInstructionHandler<Reg, Regs, Memory, PC, CustomError>,
77{
78    #[inline(always)]
79    fn execute(
80        self,
81        Rs1Rs2OperandValues {
82            rs1_value,
83            rs2_value,
84        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
85        regs: &mut Regs,
86        _ext_state: &mut ExtState,
87        memory: &mut Memory,
88        _program_counter: &mut PC,
89        _system_instruction_handler: &mut InstructionHandler,
90    ) -> Result<
91        ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
92        ExecutionError<Reg::Type, CustomError>,
93    > {
94        match self {
95            Self::CLbu { rd, rs1: _, uimm } => {
96                let addr = rs1_value.wrapping_add(u64::from(uimm));
97                let value = memory.read::<u8>(addr)?;
98                Ok(ControlFlow::Continue((rd, u64::from(value))))
99            }
100            Self::CLh { rd, rs1: _, uimm } => {
101                let addr = rs1_value.wrapping_add(u64::from(uimm));
102                let value = i64::from(memory.read::<i16>(addr)?);
103                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
104            }
105            Self::CLhu { rd, rs1: _, uimm } => {
106                let addr = rs1_value.wrapping_add(u64::from(uimm));
107                let value = memory.read::<u16>(addr)?;
108                Ok(ControlFlow::Continue((rd, u64::from(value))))
109            }
110            Self::CSb {
111                rs1: _,
112                rs2: _,
113                uimm,
114            } => {
115                let addr = rs1_value.wrapping_add(u64::from(uimm));
116                memory.write(addr, rs2_value as u8)?;
117                Ok(ControlFlow::Continue(Default::default()))
118            }
119            Self::CSh {
120                rs1: _,
121                rs2: _,
122                uimm,
123            } => {
124                let addr = rs1_value.wrapping_add(u64::from(uimm));
125                memory.write(addr, rs2_value as u16)?;
126
127                Ok(ControlFlow::Continue(Default::default()))
128            }
129            Self::CZextB { rd } => {
130                let value = regs.read(rd) & 0xff;
131                Ok(ControlFlow::Continue((rd, value)))
132            }
133            Self::CSextB { rd } => {
134                let value = i64::from(regs.read(rd) as i8);
135                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
136            }
137            Self::CZextH { rd } => {
138                let value = regs.read(rd) & 0xffff;
139                Ok(ControlFlow::Continue((rd, value)))
140            }
141            Self::CSextH { rd } => {
142                let value = i64::from(regs.read(rd) as i16);
143                Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
144            }
145            Self::CZextW { rd } => {
146                let value = regs.read(rd) & 0xffff_ffff;
147                Ok(ControlFlow::Continue((rd, value)))
148            }
149            Self::CNot { rd } => {
150                let value = !regs.read(rd);
151                Ok(ControlFlow::Continue((rd, value)))
152            }
153            Self::CMul { rd, rs2: _ } => {
154                let value = regs.read(rd).wrapping_mul(rs2_value);
155                Ok(ControlFlow::Continue((rd, value)))
156            }
157        }
158    }
159}