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, 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}