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