Botan 3.11.0
Crypto and TLS for C&
simd_8x64.h
Go to the documentation of this file.
1/*
2* (C) 2022,2025 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#ifndef BOTAN_SIMD_8X64_H_
8#define BOTAN_SIMD_8X64_H_
9
10#include <botan/compiler.h>
11#include <botan/types.h>
12#include <botan/internal/isa_extn.h>
13#include <botan/internal/target_info.h>
14#include <immintrin.h>
15
16namespace Botan {
17
18// NOLINTBEGIN(portability-simd-intrinsics)
19
20class SIMD_8x64 final {
21 public:
22 SIMD_8x64& operator=(const SIMD_8x64& other) = default;
23 SIMD_8x64(const SIMD_8x64& other) = default;
24
25 SIMD_8x64& operator=(SIMD_8x64&& other) = default;
26 SIMD_8x64(SIMD_8x64&& other) = default;
27
28 ~SIMD_8x64() = default;
29
30 // zero initialized
31 BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64() : m_simd(_mm512_setzero_si512()) {}
32
33 // Load two halves at different addresses
34 static BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 load_le4(const void* in0,
35 const void* in1,
36 const void* in2,
37 const void* in3) {
38 auto r = _mm512_setzero_si512();
39 r = _mm512_inserti32x4(r, _mm_loadu_si128(reinterpret_cast<const __m128i*>(in0)), 3);
40 r = _mm512_inserti32x4(r, _mm_loadu_si128(reinterpret_cast<const __m128i*>(in1)), 2);
41 r = _mm512_inserti32x4(r, _mm_loadu_si128(reinterpret_cast<const __m128i*>(in2)), 1);
42 r = _mm512_inserti32x4(r, _mm_loadu_si128(reinterpret_cast<const __m128i*>(in3)), 0);
43 return SIMD_8x64(r);
44 }
45
46 static BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 load_be4(const void* in0,
47 const void* in1,
48 const void* in2,
49 const void* in3) {
50 return SIMD_8x64::load_le4(in0, in1, in2, in3).bswap();
51 }
52
53 static BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 load_le(const void* in) {
54 return SIMD_8x64(_mm512_loadu_si512(reinterpret_cast<const __m512i*>(in)));
55 }
56
57 BOTAN_FN_ISA_AVX512
58 static SIMD_8x64 broadcast_2x64(const uint64_t* in) {
59 return SIMD_8x64(_mm512_broadcast_i64x2(_mm_loadu_si128(reinterpret_cast<const __m128i*>(in))));
60 }
61
62 static BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 load_be(const void* in) { return SIMD_8x64::load_le(in).bswap(); }
63
64 SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 bswap() const {
65 // clang-format off
66 const auto idx = _mm512_set_epi8(
67 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7,
68 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7);
69 // clang-format on
70
71 return SIMD_8x64(_mm512_shuffle_epi8(m_simd, idx));
72 }
73
74 void store_le(uint64_t out[8]) const { this->store_le(reinterpret_cast<uint8_t*>(out)); }
75
76 BOTAN_FN_ISA_SIMD_8X64 void store_le(uint8_t out[]) const {
77 _mm512_storeu_si512(reinterpret_cast<__m512i*>(out), m_simd);
78 }
79
80 BOTAN_FN_ISA_SIMD_8X64 void store_be(uint8_t out[]) const { bswap().store_le(out); }
81
82 BOTAN_FN_ISA_SIMD_8X64 void store_le4(void* out0, void* out1, void* out2, void* out3) {
83 _mm_storeu_si128(reinterpret_cast<__m128i*>(out0), _mm512_extracti32x4_epi32(m_simd, 3));
84 _mm_storeu_si128(reinterpret_cast<__m128i*>(out1), _mm512_extracti32x4_epi32(m_simd, 2));
85 _mm_storeu_si128(reinterpret_cast<__m128i*>(out2), _mm512_extracti32x4_epi32(m_simd, 1));
86 _mm_storeu_si128(reinterpret_cast<__m128i*>(out3), _mm512_extracti32x4_epi32(m_simd, 0));
87 }
88
89 SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 operator+(const SIMD_8x64& other) const {
90 SIMD_8x64 retval(*this);
91 retval += other;
92 return retval;
93 }
94
95 SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 operator^(const SIMD_8x64& other) const {
96 SIMD_8x64 retval(*this);
97 retval ^= other;
98 return retval;
99 }
100
101 SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 operator&(const SIMD_8x64& other) const {
102 SIMD_8x64 retval(*this);
103 retval &= other;
104 return retval;
105 }
106
107 SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 operator|(const SIMD_8x64& other) const {
108 SIMD_8x64 retval(*this);
109 retval |= other;
110 return retval;
111 }
112
113 BOTAN_FN_ISA_SIMD_8X64 void operator+=(const SIMD_8x64& other) {
114 m_simd = _mm512_add_epi64(m_simd, other.m_simd);
115 }
116
117 BOTAN_FN_ISA_SIMD_8X64 void operator^=(const SIMD_8x64& other) {
118 m_simd = _mm512_xor_si512(m_simd, other.m_simd);
119 }
120
121 BOTAN_FN_ISA_SIMD_8X64 void operator&=(const SIMD_8x64& other) {
122 m_simd = _mm512_and_si512(m_simd, other.m_simd);
123 }
124
125 BOTAN_FN_ISA_SIMD_8X64 void operator|=(const SIMD_8x64& other) { m_simd = _mm512_or_si512(m_simd, other.m_simd); }
126
127 template <size_t ROT>
128 BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 rotr() const
129 requires(ROT > 0 && ROT < 64)
130 {
131 return SIMD_8x64(_mm512_ror_epi64(m_simd, ROT));
132 }
133
134 template <size_t ROT>
135 BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 rotl() const {
136 return this->rotr<64 - ROT>();
137 }
138
139 template <int SHIFT>
140 SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 shr() const noexcept {
141 return SIMD_8x64(_mm512_srli_epi64(m_simd, SHIFT));
142 }
143
144 template <int SHIFT>
145 SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 shl() const noexcept {
146 return SIMD_8x64(_mm512_slli_epi64(m_simd, SHIFT));
147 }
148
149 static SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 alignr8(const SIMD_8x64& a, const SIMD_8x64& b) {
150 return SIMD_8x64(_mm512_alignr_epi8(a.m_simd, b.m_simd, 8));
151 }
152
153 BOTAN_FN_ISA_SIMD_8X64
154 static SIMD_8x64 splat(uint64_t v) { return SIMD_8x64(_mm512_set1_epi64(v)); }
155
156 __m512i BOTAN_FN_ISA_SIMD_8X64 raw() const noexcept { return m_simd; }
157
158 explicit BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64(__m512i x) : m_simd(x) {}
159
160 private:
161 __m512i m_simd;
162};
163
164// NOLINTEND(portability-simd-intrinsics)
165
166} // namespace Botan
167
168#endif
BOTAN_FN_ISA_SIMD_8X64 void operator+=(const SIMD_8x64 &other)
Definition simd_8x64.h:113
BOTAN_FN_ISA_SIMD_8X64 void operator&=(const SIMD_8x64 &other)
Definition simd_8x64.h:121
BOTAN_FN_ISA_SIMD_8X64 void store_le(uint8_t out[]) const
Definition simd_8x64.h:76
SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 bswap() const
Definition simd_8x64.h:64
static BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 load_le4(const void *in0, const void *in1, const void *in2, const void *in3)
Definition simd_8x64.h:34
SIMD_8x64(SIMD_8x64 &&other)=default
void store_le(uint64_t out[8]) const
Definition simd_8x64.h:74
~SIMD_8x64()=default
static BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 load_be4(const void *in0, const void *in1, const void *in2, const void *in3)
Definition simd_8x64.h:46
SIMD_8x64(const SIMD_8x64 &other)=default
SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 operator&(const SIMD_8x64 &other) const
Definition simd_8x64.h:101
BOTAN_FN_ISA_SIMD_8X64 void operator|=(const SIMD_8x64 &other)
Definition simd_8x64.h:125
static BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 load_le(const void *in)
Definition simd_8x64.h:53
SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 operator|(const SIMD_8x64 &other) const
Definition simd_8x64.h:107
static BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 splat(uint64_t v)
Definition simd_8x64.h:154
__m512i BOTAN_FN_ISA_SIMD_8X64 raw() const noexcept
Definition simd_8x64.h:156
static BOTAN_FN_ISA_AVX512 SIMD_8x64 broadcast_2x64(const uint64_t *in)
Definition simd_8x64.h:58
static SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 alignr8(const SIMD_8x64 &a, const SIMD_8x64 &b)
Definition simd_8x64.h:149
BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64()
Definition simd_8x64.h:31
SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 shl() const noexcept
Definition simd_8x64.h:145
BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 rotr() const
Definition simd_8x64.h:128
BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 rotl() const
Definition simd_8x64.h:135
BOTAN_FN_ISA_SIMD_8X64 void store_be(uint8_t out[]) const
Definition simd_8x64.h:80
BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64(__m512i x)
Definition simd_8x64.h:158
BOTAN_FN_ISA_SIMD_8X64 void store_le4(void *out0, void *out1, void *out2, void *out3)
Definition simd_8x64.h:82
SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 operator+(const SIMD_8x64 &other) const
Definition simd_8x64.h:89
BOTAN_FN_ISA_SIMD_8X64 void operator^=(const SIMD_8x64 &other)
Definition simd_8x64.h:117
SIMD_8x64 & operator=(SIMD_8x64 &&other)=default
static BOTAN_FN_ISA_SIMD_8X64 SIMD_8x64 load_be(const void *in)
Definition simd_8x64.h:62
SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 operator^(const SIMD_8x64 &other) const
Definition simd_8x64.h:95
SIMD_8x64 BOTAN_FN_ISA_SIMD_8X64 shr() const noexcept
Definition simd_8x64.h:140
SIMD_8x64 & operator=(const SIMD_8x64 &other)=default