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