ab_riscv_interpreter/rv64/b/zbc/
rv64_zbc_helpers.rs1#[inline(always)]
4#[doc(hidden)]
5#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
6pub fn clmul(a: u64, b: u64) -> u64 {
7 cfg_select! {
9 all(not(miri), target_arch = "riscv64", target_feature = "zbkc") => {
10 unsafe { core::arch::riscv64::clmul(a as usize, b as usize) as u64 }
12 }
13 _ => {{
14 let result = clmul_internal(a, b);
15 result as u64
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: u64, b: u64) -> u64 {
24 cfg_select! {
26 all(not(miri), target_arch = "riscv64", target_feature = "zbkc") => {
27 unsafe { core::arch::riscv64::clmulh(a as usize, b as usize) as u64 }
29 }
30 _ => {{
31 let result = clmul_internal(a, b);
32 (result >> 64) as u64
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: u64, b: u64) -> u64 {
41 cfg_select! {
43 all(not(miri), target_arch = "riscv64", target_feature = "zbc") => {
44 unsafe { core::arch::riscv64::clmulr(a as usize, b as usize) as u64 }
46 }
47 _ => {{
48 let result = clmul_internal(a, b);
49 (result >> 63) as u64
50 }}
51 }
52}
53
54#[cfg(any(miri, not(all(target_arch = "riscv64", target_feature = "zbc"))))]
56#[inline(always)]
57#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
58fn clmul_internal(a: u64, b: u64) -> u128 {
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) }
69 }}
70 all(target_arch = "x86_64", target_feature = "pclmulqdq") => {{
71 use core::arch::x86_64::{__m128i, _mm_clmulepi64_si128, _mm_cvtsi64_si128};
72 use core::mem::transmute;
73
74 unsafe {
77 transmute::<__m128i, u128>(_mm_clmulepi64_si128(
78 _mm_cvtsi64_si128(a.cast_signed()),
79 _mm_cvtsi64_si128(b.cast_signed()),
80 0,
81 ))
82 }
83 }}
84 _ => {{
85 let mut result = 0u128;
87 let a = u128::from(a);
88 let mut b = b;
89 for i in 0..u64::BITS {
90 let bit = u128::from(b & 1);
91 result ^= a.wrapping_shl(i) & (0u128.wrapping_sub(bit));
92 b >>= 1u8;
93 }
94 result
95 }}
96 }
97}