Skip to main content

ab_riscv_interpreter/rv32/zce/
zcb.rs

1//! Zcb compressed instruction execution (RV32)
2//!
3//! C.ZEXT.W is absent in RV32 - the enum has no such variant.
4
5#[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}