1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use crate::core_arch::x86::__m128i;
#[cfg(test)]
use crate::stdarch_test::assert_instr;
#[allow(improper_ctypes)]
extern "C" {
#[link_name = "llvm.x86.pclmulqdq"]
fn pclmulqdq(a: __m128i, round_key: __m128i, imm8: u8) -> __m128i;
}
#[inline]
#[target_feature(enable = "pclmulqdq")]
#[cfg_attr(all(test, not(target_os = "linux")), assert_instr(pclmulqdq, imm8 = 0))]
#[cfg_attr(all(test, target_os = "linux"), assert_instr(pclmullqlqdq, imm8 = 0))]
#[cfg_attr(all(test, target_os = "linux"), assert_instr(pclmulhqlqdq, imm8 = 1))]
#[cfg_attr(all(test, target_os = "linux"), assert_instr(pclmullqhqdq, imm8 = 16))]
#[cfg_attr(all(test, target_os = "linux"), assert_instr(pclmulhqhqdq, imm8 = 17))]
#[rustc_args_required_const(2)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn _mm_clmulepi64_si128(a: __m128i, b: __m128i, imm8: i32) -> __m128i {
macro_rules! call {
($imm8:expr) => {
pclmulqdq(a, b, $imm8)
};
}
constify_imm8!(imm8, call)
}
#[cfg(test)]
mod tests {
#![allow(overflowing_literals)]
use stdarch_test::simd_test;
use crate::core_arch::x86::*;
#[simd_test(enable = "pclmulqdq")]
unsafe fn test_mm_clmulepi64_si128() {
let a = _mm_set_epi64x(0x7b5b546573745665, 0x63746f725d53475d);
let b = _mm_set_epi64x(0x4869285368617929, 0x5b477565726f6e5d);
let r00 = _mm_set_epi64x(0x1d4d84c85c3440c0, 0x929633d5d36f0451);
let r01 = _mm_set_epi64x(0x1bd17c8d556ab5a1, 0x7fa540ac2a281315);
let r10 = _mm_set_epi64x(0x1a2bf6db3a30862f, 0xbabf262df4b7d5c9);
let r11 = _mm_set_epi64x(0x1d1e1f2c592e7c45, 0xd66ee03e410fd4ed);
assert_eq_m128i(_mm_clmulepi64_si128(a, b, 0x00), r00);
assert_eq_m128i(_mm_clmulepi64_si128(a, b, 0x10), r01);
assert_eq_m128i(_mm_clmulepi64_si128(a, b, 0x01), r10);
assert_eq_m128i(_mm_clmulepi64_si128(a, b, 0x11), r11);
let a0 = _mm_set_epi64x(0x0000000000000000, 0x8000000000000000);
let r = _mm_set_epi64x(0x4000000000000000, 0x0000000000000000);
assert_eq_m128i(_mm_clmulepi64_si128(a0, a0, 0x00), r);
}
}