ab_riscv_interpreter/rv32/zce/
zcb.rs1#[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}