Skip to main content

ab_riscv_interpreter/rv64/zk/
zbkx.rs

1//! RV64 Zbkx extension
2
3pub mod rv64_zbkx_helpers;
4// TODO: Portable SIMD attempts to use unsupported intrinsics under Miri:
5//  https://github.com/rust-lang/portable-simd/issues/524
6#[cfg(not(all(miri, target_arch = "aarch64")))]
7#[cfg(test)]
8mod tests;
9
10use crate::{ExecutableInstruction, ExecutionError, RegisterFile};
11use ab_riscv_macros::instruction_execution;
12use ab_riscv_primitives::prelude::*;
13use core::ops::ControlFlow;
14
15#[instruction_execution]
16impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
17    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
18    for Rv64ZbkxInstruction<Reg>
19where
20    Reg: Register<Type = u64>,
21    Regs: RegisterFile<Reg>,
22{
23    #[inline(always)]
24    fn execute(
25        self,
26        regs: &mut Regs,
27        _ext_state: &mut ExtState,
28        _memory: &mut Memory,
29        _program_counter: &mut PC,
30        _system_instruction_handler: &mut InstructionHandler,
31    ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
32        match self {
33            Self::Xperm4 { rd, rs1, rs2 } => {
34                let rs1_value = regs.read(rs1);
35                let rs2_value = regs.read(rs2);
36
37                regs.write(rd, rv64_zbkx_helpers::xperm4(rs1_value, rs2_value));
38            }
39            Self::Xperm8 { rd, rs1, rs2 } => {
40                let rs1_value = regs.read(rs1);
41                let rs2_value = regs.read(rs2);
42
43                regs.write(rd, rv64_zbkx_helpers::xperm8(rs1_value, rs2_value));
44            }
45        }
46
47        Ok(ControlFlow::Continue(()))
48    }
49}