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