ab_riscv_interpreter/rv32/b/zbc/
rv32_zbc_helpers.rs1#[inline(always)]
4#[doc(hidden)]
5#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
6pub fn clmul(a: u32, b: u32) -> u32 {
7 cfg_select! {
9 all(not(miri), target_arch = "riscv32", target_feature = "zbkc") => {
10 unsafe { core::arch::riscv32::clmul(a as usize, b as usize) as u32 }
12 }
13 _ => {{
14 let result = clmul_internal(a, b);
15 result as u32
16 }}
17 }
18}
19
20#[inline(always)]
21#[doc(hidden)]
22#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
23pub fn clmulh(a: u32, b: u32) -> u32 {
24 cfg_select! {
26 all(not(miri), target_arch = "riscv32", target_feature = "zbkc") => {
27 unsafe { core::arch::riscv32::clmulh(a as usize, b as usize) as u32 }
29 }
30 _ => {{
31 let result = clmul_internal(a, b);
32 (result >> 32) as u32
33 }}
34 }
35}
36
37#[inline(always)]
38#[doc(hidden)]
39#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
40pub fn clmulr(a: u32, b: u32) -> u32 {
41 cfg_select! {
43 all(not(miri), target_arch = "riscv32", target_feature = "zbc") => {
44 unsafe { core::arch::riscv32::clmulr(a as usize, b as usize) as u32 }
46 }
47 _ => {{
48 let result = clmul_internal(a, b);
49 (result >> 31) as u32
50 }}
51 }
52}
53
54#[cfg(any(miri, not(all(target_arch = "riscv32", target_feature = "zbc"))))]
56#[inline(always)]
57#[doc(hidden)]
58#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
59fn clmul_internal(a: u32, b: u32) -> u64 {
60 let a = u64::from(a);
61 let b = u64::from(b);
62
63 cfg_select! {
64 all(
67 not(miri), target_arch = "aarch64", target_feature = "neon", target_feature = "aes"
68 ) => {{
69 use core::arch::aarch64::vmull_p64;
70
71 unsafe { vmull_p64(a, b) as u64 }
74 }}
75 all(target_arch = "x86_64", target_feature = "pclmulqdq") => {{
76 use core::arch::x86_64::{__m128i, _mm_clmulepi64_si128, _mm_cvtsi64_si128};
77 use core::mem::transmute;
78
79 unsafe {
81 let result = transmute::<__m128i, u128>(_mm_clmulepi64_si128(
82 _mm_cvtsi64_si128(a.cast_signed()),
83 _mm_cvtsi64_si128(b.cast_signed()),
84 0,
85 ));
86 result as u64
87 }
88 }}
89 _ => {{
90 let mut result = 0u64;
92 let mut b = b;
93 for i in 0..u32::BITS {
94 let bit = b & 1;
95 result ^= a.wrapping_shl(i) & (0u64.wrapping_sub(bit));
96 b >>= 1;
97 }
98 result
99 }}
100 }
101}