ab_riscv_interpreter/rv32/zce/
zcb.rs1#[cfg(test)]
6mod tests;
7
8use crate::{
9 ExecutableInstruction, ExecutionError, ProgramCounter, RegisterFile, SystemInstructionHandler,
10 VirtualMemory,
11};
12use ab_riscv_macros::instruction_execution;
13use ab_riscv_primitives::prelude::*;
14use core::ops::ControlFlow;
15
16#[instruction_execution]
17impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
18 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
19 for Rv32ZcbInstruction<Reg>
20where
21 Reg: Register<Type = u32>,
22 Regs: RegisterFile<Reg>,
23 Memory: VirtualMemory,
24 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
25 InstructionHandler: SystemInstructionHandler<Reg, Regs, Memory, PC, CustomError>,
26{
27 #[inline(always)]
28 fn execute(
29 self,
30 regs: &mut Regs,
31 _ext_state: &mut ExtState,
32 memory: &mut Memory,
33 _program_counter: &mut PC,
34 _system_instruction_handler: &mut InstructionHandler,
35 ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
36 match self {
37 Self::CLbu { rd, rs1, uimm } => {
38 let addr = u64::from(regs.read(rs1).wrapping_add(u32::from(uimm)));
39 let value = memory.read::<u8>(addr)?;
40 regs.write(rd, u32::from(value));
41 }
42 Self::CLh { rd, rs1, uimm } => {
43 let addr = u64::from(regs.read(rs1).wrapping_add(u32::from(uimm)));
44 let value = i32::from(memory.read::<i16>(addr)?);
45 regs.write(rd, value.cast_unsigned());
46 }
47 Self::CLhu { rd, rs1, uimm } => {
48 let addr = u64::from(regs.read(rs1).wrapping_add(u32::from(uimm)));
49 let value = memory.read::<u16>(addr)?;
50 regs.write(rd, u32::from(value));
51 }
52 Self::CSb { rs1, rs2, uimm } => {
53 let addr = u64::from(regs.read(rs1).wrapping_add(u32::from(uimm)));
54 memory.write(addr, regs.read(rs2) as u8)?;
55 }
56 Self::CSh { rs1, rs2, uimm } => {
57 let addr = u64::from(regs.read(rs1).wrapping_add(u32::from(uimm)));
58 memory.write(addr, regs.read(rs2) as u16)?;
59 }
60 Self::CZextB { rd } => {
61 let value = regs.read(rd) & 0xff;
62 regs.write(rd, value);
63 }
64 Self::CSextB { rd } => {
65 let value = i32::from(regs.read(rd) as i8);
66 regs.write(rd, value.cast_unsigned());
67 }
68 Self::CZextH { rd } => {
69 let value = regs.read(rd) & 0xffff;
70 regs.write(rd, value);
71 }
72 Self::CSextH { rd } => {
73 let value = i32::from(regs.read(rd) as i16);
74 regs.write(rd, value.cast_unsigned());
75 }
76 Self::CNot { rd } => {
77 let value = !regs.read(rd);
78 regs.write(rd, value);
79 }
80 Self::CMul { rd, rs2 } => {
81 let value = regs.read(rd).wrapping_mul(regs.read(rs2));
82 regs.write(rd, value);
83 }
84 }
85
86 Ok(ControlFlow::Continue(()))
87 }
88}