Skip to main content

ab_riscv_interpreter/rv32/b/
zbs.rs

1//! RV32 Zbs extension
2
3#[cfg(test)]
4mod tests;
5
6use crate::{ExecutableInstruction, ExecutionError, InterpreterState};
7use ab_riscv_macros::instruction_execution;
8use ab_riscv_primitives::instructions::rv32::b::zbs::Rv32ZbsInstruction;
9use ab_riscv_primitives::registers::general_purpose::Register;
10use core::ops::ControlFlow;
11
12#[instruction_execution]
13impl<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>
14    ExecutableInstruction<
15        InterpreterState<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>,
16        CustomError,
17    > for Rv32ZbsInstruction<Reg>
18where
19    Reg: Register<Type = u32>,
20    [(); Reg::N]:,
21{
22    #[inline(always)]
23    fn execute(
24        self,
25        state: &mut InterpreterState<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>,
26    ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
27        match self {
28            Self::Bset { rd, rs1, rs2 } => {
29                // Only the bottom 5 bits for RV32
30                let index = state.regs.read(rs2) & 0x1f;
31                let result = state.regs.read(rs1) | (1u32 << index);
32                state.regs.write(rd, result);
33            }
34            Self::Bseti { rd, rs1, shamt } => {
35                let index = shamt;
36                let result = state.regs.read(rs1) | (1u32 << index);
37                state.regs.write(rd, result);
38            }
39            Self::Bclr { rd, rs1, rs2 } => {
40                let index = state.regs.read(rs2) & 0x1f;
41                let result = state.regs.read(rs1) & !(1u32 << index);
42                state.regs.write(rd, result);
43            }
44            Self::Bclri { rd, rs1, shamt } => {
45                let index = shamt;
46                let result = state.regs.read(rs1) & !(1u32 << index);
47                state.regs.write(rd, result);
48            }
49            Self::Binv { rd, rs1, rs2 } => {
50                let index = state.regs.read(rs2) & 0x1f;
51                let result = state.regs.read(rs1) ^ (1u32 << index);
52                state.regs.write(rd, result);
53            }
54            Self::Binvi { rd, rs1, shamt } => {
55                let index = shamt;
56                let result = state.regs.read(rs1) ^ (1u32 << index);
57                state.regs.write(rd, result);
58            }
59            Self::Bext { rd, rs1, rs2 } => {
60                let index = state.regs.read(rs2) & 0x1f;
61                let result = (state.regs.read(rs1) >> index) & 1;
62                state.regs.write(rd, result);
63            }
64            Self::Bexti { rd, rs1, shamt } => {
65                let index = shamt;
66                let result = (state.regs.read(rs1) >> index) & 1;
67                state.regs.write(rd, result);
68            }
69        }
70
71        Ok(ControlFlow::Continue(()))
72    }
73}