Skip to main content

ab_riscv_interpreter/rv32/b/
zbs.rs

1//! RV32 Zbs extension
2
3#[cfg(test)]
4mod tests;
5
6use crate::{
7    ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
8    RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
9};
10use ab_riscv_macros::instruction_execution;
11use ab_riscv_primitives::prelude::*;
12use core::ops::ControlFlow;
13
14#[instruction_execution]
15impl<Reg> ExecutableInstructionOperands for Rv32ZbsInstruction<Reg> where Reg: Register<Type = u32> {}
16
17#[instruction_execution]
18impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
19    for Rv32ZbsInstruction<Reg>
20where
21    Reg: Register<Type = u32>,
22{
23}
24
25#[instruction_execution]
26impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
27    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
28    for Rv32ZbsInstruction<Reg>
29where
30    Reg: Register<Type = u32>,
31    Regs: RegisterFile<Reg>,
32{
33    #[inline(always)]
34    fn execute(
35        self,
36        Rs1Rs2OperandValues {
37            rs1_value,
38            rs2_value,
39        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
40        _regs: &mut Regs,
41        _ext_state: &mut ExtState,
42        _memory: &mut Memory,
43        _program_counter: &mut PC,
44        _system_instruction_handler: &mut InstructionHandler,
45    ) -> Result<
46        ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
47        ExecutionError<Reg::Type, CustomError>,
48    > {
49        match self {
50            Self::Bset { rd, rs1: _, rs2: _ } => {
51                // Only the bottom 5 bits for RV32
52                let index = rs2_value & 0x1f;
53                let result = rs1_value | (1u32 << index);
54                Ok(ControlFlow::Continue((rd, result)))
55            }
56            Self::Bseti { rd, rs1: _, shamt } => {
57                let index = shamt;
58                let result = rs1_value | (1u32 << index);
59                Ok(ControlFlow::Continue((rd, result)))
60            }
61            Self::Bclr { rd, rs1: _, rs2: _ } => {
62                let index = rs2_value & 0x1f;
63                let result = rs1_value & !(1u32 << index);
64                Ok(ControlFlow::Continue((rd, result)))
65            }
66            Self::Bclri { rd, rs1: _, shamt } => {
67                let index = shamt;
68                let result = rs1_value & !(1u32 << index);
69                Ok(ControlFlow::Continue((rd, result)))
70            }
71            Self::Binv { rd, rs1: _, rs2: _ } => {
72                let index = rs2_value & 0x1f;
73                let result = rs1_value ^ (1u32 << index);
74                Ok(ControlFlow::Continue((rd, result)))
75            }
76            Self::Binvi { rd, rs1: _, shamt } => {
77                let index = shamt;
78                let result = rs1_value ^ (1u32 << index);
79                Ok(ControlFlow::Continue((rd, result)))
80            }
81            Self::Bext { rd, rs1: _, rs2: _ } => {
82                let index = rs2_value & 0x1f;
83                let result = (rs1_value >> index) & 1;
84                Ok(ControlFlow::Continue((rd, result)))
85            }
86            Self::Bexti { rd, rs1: _, shamt } => {
87                let index = shamt;
88                let result = (rs1_value >> index) & 1;
89                Ok(ControlFlow::Continue((rd, result)))
90            }
91        }
92    }
93}