OXYGENHUB
◆ v0.6.0 oxygen / vendor / crc-fast / src / arch / x86_64 / avx512.rs
5.6 KiB · Rust · last changed Strata: the cloud stores send through ureq, so every release target links 1 month ago source blame history raw
1
// Copyright 2025 Don MacAskill. Licensed under MIT or Apache-2.0.
2
3
//! This module provides x86_64-specific implementations of the ArchOps trait.
4
//!
5
//! It uses the AVX-512 instruction sets for SIMD operations.
6
7
#![cfg(target_arch = "x86_64")]
8
9
use crate::arch::x86::sse::X86SsePclmulqdqOps;
10
use crate::traits::ArchOps;
11
use std::arch::x86_64::*;
12
13
/// x86_64-only AVX512+PCLMULQDQ tier - delegates to SSE tier and overrides XOR3 operations
14
/// Uses AVX512 ternary logic for XOR3 operations with PCLMULQDQ
15
#[derive(Debug, Copy, Clone)]
16
pub struct X86_64Avx512PclmulqdqOps(X86SsePclmulqdqOps);
17
18
impl Default for X86_64Avx512PclmulqdqOps {
19
    fn default() -> Self {
20
        Self::new()
21
    }
22
}
23
24
impl X86_64Avx512PclmulqdqOps {
25
    #[inline(always)]
26
    pub fn new() -> Self {
27
        Self(X86SsePclmulqdqOps)
28
    }
29
}
30
31
impl ArchOps for X86_64Avx512PclmulqdqOps {
32
    type Vector = __m128i;
33
34
    // Delegate all methods to the base SSE implementation
35
    #[inline(always)]
36
    unsafe fn create_vector_from_u64_pair(
37
        &self,
38
        high: u64,
39
        low: u64,
40
        reflected: bool,
41
    ) -> Self::Vector {
42
        self.0.create_vector_from_u64_pair(high, low, reflected)
43
    }
44
45
    #[inline(always)]
46
    unsafe fn create_vector_from_u64_pair_non_reflected(
47
        &self,
48
        high: u64,
49
        low: u64,
50
    ) -> Self::Vector {
51
        self.0.create_vector_from_u64_pair_non_reflected(high, low)
52
    }
53
54
    #[inline(always)]
55
    unsafe fn create_vector_from_u64(&self, value: u64, high: bool) -> Self::Vector {
56
        self.0.create_vector_from_u64(value, high)
57
    }
58
59
    #[inline(always)]
60
    unsafe fn extract_u64s(&self, vector: Self::Vector) -> [u64; 2] {
61
        self.0.extract_u64s(vector)
62
    }
63
64
    #[inline(always)]
65
    unsafe fn extract_poly64s(&self, vector: Self::Vector) -> [u64; 2] {
66
        self.0.extract_poly64s(vector)
67
    }
68
69
    #[inline(always)]
70
    unsafe fn xor_vectors(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
71
        self.0.xor_vectors(a, b)
72
    }
73
74
    #[inline(always)]
75
    unsafe fn load_bytes(&self, ptr: *const u8) -> Self::Vector {
76
        self.0.load_bytes(ptr)
77
    }
78
79
    #[inline(always)]
80
    unsafe fn load_aligned(&self, ptr: *const [u64; 2]) -> Self::Vector {
81
        self.0.load_aligned(ptr)
82
    }
83
84
    #[inline(always)]
85
    unsafe fn shuffle_bytes(&self, data: Self::Vector, mask: Self::Vector) -> Self::Vector {
86
        self.0.shuffle_bytes(data, mask)
87
    }
88
89
    #[inline(always)]
90
    unsafe fn blend_vectors(
91
        &self,
92
        a: Self::Vector,
93
        b: Self::Vector,
94
        mask: Self::Vector,
95
    ) -> Self::Vector {
96
        self.0.blend_vectors(a, b, mask)
97
    }
98
99
    #[inline(always)]
100
    unsafe fn shift_left_8(&self, vector: Self::Vector) -> Self::Vector {
101
        self.0.shift_left_8(vector)
102
    }
103
104
    #[inline(always)]
105
    unsafe fn set_all_bytes(&self, value: u8) -> Self::Vector {
106
        self.0.set_all_bytes(value)
107
    }
108
109
    #[inline(always)]
110
    unsafe fn create_compare_mask(&self, vector: Self::Vector) -> Self::Vector {
111
        self.0.create_compare_mask(vector)
112
    }
113
114
    #[inline(always)]
115
    unsafe fn and_vectors(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
116
        self.0.and_vectors(a, b)
117
    }
118
119
    #[inline(always)]
120
    unsafe fn shift_right_32(&self, vector: Self::Vector) -> Self::Vector {
121
        self.0.shift_right_32(vector)
122
    }
123
124
    #[inline(always)]
125
    unsafe fn shift_left_32(&self, vector: Self::Vector) -> Self::Vector {
126
        self.0.shift_left_32(vector)
127
    }
128
129
    #[inline(always)]
130
    unsafe fn create_vector_from_u32(&self, value: u32, high: bool) -> Self::Vector {
131
        self.0.create_vector_from_u32(value, high)
132
    }
133
134
    #[inline(always)]
135
    unsafe fn shift_left_4(&self, vector: Self::Vector) -> Self::Vector {
136
        self.0.shift_left_4(vector)
137
    }
138
139
    #[inline(always)]
140
    unsafe fn shift_right_4(&self, vector: Self::Vector) -> Self::Vector {
141
        self.0.shift_right_4(vector)
142
    }
143
144
    #[inline(always)]
145
    unsafe fn shift_right_8(&self, vector: Self::Vector) -> Self::Vector {
146
        self.0.shift_right_8(vector)
147
    }
148
149
    #[inline(always)]
150
    unsafe fn shift_right_5(&self, vector: Self::Vector) -> Self::Vector {
151
        self.0.shift_right_5(vector)
152
    }
153
154
    #[inline(always)]
155
    unsafe fn shift_right_6(&self, vector: Self::Vector) -> Self::Vector {
156
        self.0.shift_right_6(vector)
157
    }
158
159
    #[inline(always)]
160
    unsafe fn shift_right_7(&self, vector: Self::Vector) -> Self::Vector {
161
        self.0.shift_right_7(vector)
162
    }
163
164
    #[inline(always)]
165
    unsafe fn shift_right_12(&self, vector: Self::Vector) -> Self::Vector {
166
        self.0.shift_right_12(vector)
167
    }
168
169
    #[inline(always)]
170
    unsafe fn shift_left_12(&self, vector: Self::Vector) -> Self::Vector {
171
        self.0.shift_left_12(vector)
172
    }
173
174
    #[inline(always)]
175
    unsafe fn carryless_mul_00(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
176
        self.0.carryless_mul_00(a, b)
177
    }
178
179
    #[inline(always)]
180
    unsafe fn carryless_mul_01(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
181
        self.0.carryless_mul_01(a, b)
182
    }
183
184
    #[inline(always)]
185
    unsafe fn carryless_mul_10(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
186
        self.0.carryless_mul_10(a, b)
187
    }
188
189
    #[inline(always)]
190
    unsafe fn carryless_mul_11(&self, a: Self::Vector, b: Self::Vector) -> Self::Vector {
191
        self.0.carryless_mul_11(a, b)
192
    }
193
194
    #[inline]
195
    #[target_feature(enable = "avx512vl")]
196
    unsafe fn xor3_vectors(
197
        &self,
198
        a: Self::Vector,
199
        b: Self::Vector,
200
        c: Self::Vector,
201
    ) -> Self::Vector {
202
        // AVX512 tier always uses ternary logic
203
        _mm_ternarylogic_epi64(a, b, c, 0x96) // XOR3 operation
204
    }
205
}