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