ab_riscv_interpreter/rv32/zk/zbkx/
rv32_zbkx_helpers.rs1#[inline]
4#[doc(hidden)]
5#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
6pub fn xperm4(rs1: u32, rs2: u32) -> u32 {
7 cfg_select! {
9 all(not(miri), target_arch = "riscv32", target_feature = "zbkx") => {
10 unsafe { core::arch::riscv32::xperm4(rs1 as usize, rs2 as usize) as u32 }
11 }
12 _ => {
13 use core::simd::num::SimdUint;
14 use core::simd::{simd_swizzle, u32x8};
15
16 const SHIFT: u32x8 = u32x8::from_array([0, 4, 8, 12, 16, 20, 24, 28]);
17 const MASK: u32x8 = u32x8::splat(0xf);
18
19 let lut = (u32x8::splat(rs1) >> SHIFT) & MASK;
21 let idx = (u32x8::splat(rs2) >> SHIFT) & MASK;
23 let nibbles = lut.cast().swizzle_dyn(idx.cast());
25 let lo = simd_swizzle!(nibbles, [0, 2, 4, 6]);
27 let hi = simd_swizzle!(nibbles, [1, 3, 5, 7]);
28 u32::from_le_bytes((lo | (hi << 4)).to_array())
29 }
30 }
31}
32
33#[inline]
34#[doc(hidden)]
35#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
36pub fn xperm8(rs1: u32, rs2: u32) -> u32 {
37 cfg_select! {
39 all(not(miri), target_arch = "riscv32", target_feature = "zbkx") => {
40 unsafe { core::arch::riscv32::xperm8(rs1 as usize, rs2 as usize) as u32 }
41 }
42 _ => {
43 use core::simd::u8x4;
44
45 let lut = u8x4::from_array(rs1.to_le_bytes());
46 let idx = u8x4::from_array(rs2.to_le_bytes());
47
48 let result = lut.swizzle_dyn(idx);
49
50 u32::from_le_bytes(result.to_array())
51 }
52 }
53}