Skip to main content

ab_riscv_interpreter/rv32/zk/
zbkb.rs

1//! RV32 Zbkb extension
2
3pub mod rv32_zbkb_helpers;
4#[cfg(test)]
5mod tests;
6
7use crate::{
8    ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
9    RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
10};
11use ab_riscv_macros::instruction_execution;
12use ab_riscv_primitives::prelude::*;
13use core::ops::ControlFlow;
14
15#[instruction_execution]
16impl<Reg> ExecutableInstructionOperands for Rv32ZbkbInstruction<Reg> where Reg: Register<Type = u32> {}
17
18#[instruction_execution]
19impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
20    for Rv32ZbkbInstruction<Reg>
21where
22    Reg: Register<Type = u32>,
23{
24}
25
26#[instruction_execution]
27impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
28    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
29    for Rv32ZbkbInstruction<Reg>
30where
31    Reg: Register<Type = u32>,
32    Regs: RegisterFile<Reg>,
33{
34    #[inline(always)]
35    fn execute(
36        self,
37        Rs1Rs2OperandValues {
38            rs1_value,
39            rs2_value,
40        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
41        _regs: &mut Regs,
42        _ext_state: &mut ExtState,
43        _memory: &mut Memory,
44        _program_counter: &mut PC,
45        _system_instruction_handler: &mut InstructionHandler,
46    ) -> Result<
47        ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
48        ExecutionError<Reg::Type, CustomError>,
49    > {
50        match self {
51            Self::Pack { rd, rs1: _, rs2: _ } => {
52                // Pack low 16 bits of rs1 into rd[15:0],
53                // low 16 bits of rs2 into rd[31:16].
54                let lo = rs1_value & 0x0000_FFFFu32;
55                let hi = (rs2_value & 0x0000_FFFFu32) << 16;
56                Ok(ControlFlow::Continue((rd, lo | hi)))
57            }
58            Self::Packh { rd, rs1: _, rs2: _ } => {
59                // Pack low byte of rs1 into bits [7:0], low byte of rs2 into bits [15:8].
60                // Upper bits of rd are zeroed.
61                let lo = rs1_value & 0xFF;
62                let hi = (rs2_value & 0xFF) << 8;
63                Ok(ControlFlow::Continue((rd, lo | hi)))
64            }
65            Self::Brev8 { rd, rs1: _ } => {
66                // Reverse bits within each byte of rs1
67                let src = rs1_value;
68                let mut bytes = src.to_le_bytes();
69                for byte in &mut bytes {
70                    *byte = byte.reverse_bits();
71                }
72                Ok(ControlFlow::Continue((rd, u32::from_le_bytes(bytes))))
73            }
74            Self::Zip { rd, rs1: _ } => {
75                // Bit-interleave: scatter bits of rs1 so that
76                // rs1[i]    -> rd[2*i]   (even positions, lower half source)
77                // rs1[i+16] -> rd[2*i+1] (odd positions, upper half source)
78                // for i in 0..16.
79                let src = rs1_value;
80
81                Ok(ControlFlow::Continue((rd, rv32_zbkb_helpers::zip(src))))
82            }
83            Self::Unzip { rd, rs1: _ } => {
84                // Inverse of zip: gather bits of rs1 so that
85                // rs1[2*i]   -> rd[i]    (even-position bits -> lower half)
86                // rs1[2*i+1] -> rd[i+16] (odd-position bits -> upper half)
87                // for i in 0..16.
88                let src = rs1_value;
89
90                Ok(ControlFlow::Continue((rd, rv32_zbkb_helpers::unzip(src))))
91            }
92        }
93    }
94}