Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

Public Member Functions | Static Public Member Functions | List of all members
Botan::SIMD_4x32 Class Referencefinal

`#include <simd_32.h>`

## Public Member Functions
SIMD_4x32 | andc (const SIMD_4x32 &other) const
SIMD_4x32 | bswap () const
SIMD_4x32 | operator& (const SIMD_4x32 &other) const
void | operator&= (const SIMD_4x32 &other)
SIMD_4x32 | operator+ (const SIMD_4x32 &other) const
void | operator+= (const SIMD_4x32 &other)
SIMD_4x32 | operator- (const SIMD_4x32 &other) const
void | operator-= (const SIMD_4x32 &other)
SIMD_4x32 & | operator= (const SIMD_4x32 &other)=default
SIMD_4x32 & | operator= (SIMD_4x32 &&other)=default
SIMD_4x32 | operator^ (const SIMD_4x32 &other) const
void | operator^= (const SIMD_4x32 &other)
SIMD_4x32 | operator| (const SIMD_4x32 &other) const
void | operator|= (const SIMD_4x32 &other)
SIMD_4x32 | operator~ () const
native_simd_type | raw () const BOTAN_FUNC_ISA(BOTAN_SIMD_ISA)
template<size_t ROT1, size_t ROT2, size_t ROT3>
SIMD_4x32 | rho () const
template<size_t ROT>
SIMD_4x32 | rotl () const
template<size_t ROT>
SIMD_4x32 | rotr () const
template<size_t I>
SIMD_4x32 | shift_elems_left () const
template<size_t I>
SIMD_4x32 | shift_elems_right () const
template<int SHIFT>
SIMD_4x32 | shl () const
template<int SHIFT>
SIMD_4x32 | shr () const
| SIMD_4x32 (const SIMD_4x32 &other)=default
| SIMD_4x32 (SIMD_4x32 &&other)=default
| SIMD_4x32 ()
| SIMD_4x32 (const uint32_t B[4])
| SIMD_4x32 (uint32_t B0, uint32_t B1, uint32_t B2, uint32_t B3)
| SIMD_4x32 (native_simd_type x)
void | store_be (uint8_t out[]) const
void | store_le (uint32_t out[4]) const
void | store_le (uint64_t out[2]) const
void | store_le (uint8_t out[]) const

## Static Public Member Functions
static SIMD_4x32 | load_be (const void *in)
static SIMD_4x32 | load_le (const void *in)
static SIMD_4x32 | splat (uint32_t B)
static SIMD_4x32 | splat_u8 (uint8_t B)
static void | transpose (SIMD_4x32 &B0, SIMD_4x32 &B1, SIMD_4x32 &B2, SIMD_4x32 &B3)

## Detailed Description

4x32 bit SIMD register

This class is not a general purpose SIMD type, and only offers instructions needed for evaluation of specific crypto primitives. For example it does not currently have equality operators of any kind.

Implemented for SSE2, VMX (Altivec), and NEON.

Definition at line 71 of file simd_32.h.

## Constructor & Destructor Documentation

Botan::SIMD_4x32::SIMD_4x32 | ( | const SIMD_4x32 & | other | ) |
| default

Botan::SIMD_4x32::SIMD_4x32 | ( | SIMD_4x32 && | other | ) |
| default

Botan::SIMD_4x32::SIMD_4x32 | ( |  | ) |
| inline

Zero initialize SIMD register with 4 32-bit elements

Definition at line 84 of file simd_32.h.

Referenced by andc(), bswap(), load_be(), load_le(), operator~(), rotl(), shift_elems_left(), shift_elems_right(), shl(), shr(), splat(), and splat_u8().

85 {
86 #if defined(BOTAN_SIMD_USE_SSE2)
87 m_simd = _mm_setzero_si128();
88 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
89 m_simd = vec_splat_u32(0);
90 #elif defined(BOTAN_SIMD_USE_NEON)
91 m_simd = vdupq_n_u32(0);
92 #endif
93 }

Botan::SIMD_4x32::SIMD_4x32 | ( | const uint32_t | B[4] | ) |
| inline explicit

Load SIMD register with 4 32-bit elements

Definition at line 98 of file simd_32.h.

99 {
100 #if defined(BOTAN_SIMD_USE_SSE2)
101 m_simd = _mm_loadu_si128(reinterpret_cast<const __m128i*>(B));
102 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
103 __vector unsigned int val = { B[0], B[1], B[2], B[3]};
104 m_simd = val;
105 #elif defined(BOTAN_SIMD_USE_NEON)
106 m_simd = vld1q_u32(B);
107 #endif
108 }

Botan::SIMD_4x32::SIMD_4x32 | ( | uint32_t | B0,
|  | uint32_t | B1,
|  | uint32_t | B2,
|  | uint32_t | B3
| ) |  |
| inline

Load SIMD register with 4 32-bit elements

Definition at line 113 of file simd_32.h.

114 {
115 #if defined(BOTAN_SIMD_USE_SSE2)
116 m_simd = _mm_set_epi32(B3, B2, B1, B0);
117 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
118 __vector unsigned int val = {B0, B1, B2, B3};
119 m_simd = val;
120 #elif defined(BOTAN_SIMD_USE_NEON)
121 // Better way to do this?
122 const uint32_t B[4] = { B0, B1, B2, B3 };
123 m_simd = vld1q_u32(B);
124 #endif
125 }

Botan::SIMD_4x32::SIMD_4x32 | ( | native_simd_type | x | ) |
| inline explicit

Definition at line 613 of file simd_32.h.

613 : m_simd(x) {}

## Member Function Documentation

SIMD_4x32 Botan::SIMD_4x32::andc | ( | const SIMD_4x32 & | other | ) | const
| inline

Definition at line 472 of file simd_32.h.

References SIMD_4x32().

473 {
474 #if defined(BOTAN_SIMD_USE_SSE2)
475 return SIMD_4x32(_mm_andnot_si128(m_simd, other.m_simd));
476 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
477 /*
478 AltiVec does arg1 & ~arg2 rather than SSE's ~arg1 & arg2
479 so swap the arguments
480 */
481 return SIMD_4x32(vec_andc(other.m_simd, m_simd));
482 #elif defined(BOTAN_SIMD_USE_NEON)
483 // NEON is also a & ~b
484 return SIMD_4x32(vbicq_u32(other.m_simd, m_simd));
485 #endif
486 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

SIMD_4x32 Botan::SIMD_4x32::bswap | ( |  | ) | const
| inline

Return copy *this with each word byte swapped

Definition at line 491 of file simd_32.h.

References Botan::bswap_4(), SIMD_4x32(), and T.

Referenced by load_be(), load_le(), store_be(), and store_le().

492 {
493 #if defined(BOTAN_SIMD_USE_SSE2)
494
495 __m128i T = m_simd;
496 T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
497 T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
498 return SIMD_4x32(_mm_or_si128(_mm_srli_epi16(T, 8), _mm_slli_epi16(T, 8)));
499
500 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
501
502 union {
503 __vector unsigned int V;
504 uint32_t R[4];
505 } vec;
506
507 vec.V = m_simd;
508 bswap_4(vec.R);
509 return SIMD_4x32(vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
510
511 #elif defined(BOTAN_SIMD_USE_NEON)
512 return SIMD_4x32(vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(m_simd))));
513 #endif
514 }
Botan::bswap_4
void bswap_4(T x[4])
Definition: bswap.h:98
T
fe T
Definition: ge.cpp:37
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

static SIMD_4x32 Botan::SIMD_4x32::load_be | ( | const void * | in | ) |
| inline static

Load a SIMD register with big-endian convention

Definition at line 176 of file simd_32.h.

References bswap(), Botan::CPUID::is_little_endian(), Botan::load_be(), load_le(), and SIMD_4x32().

177 {
178 #if defined(BOTAN_SIMD_USE_SSE2)
179 return load_le(in).bswap();
180
181 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
182 uint32_t R[4];
183 Botan::load_be(R, static_cast<const uint8_t*>(in), 4);
184 return SIMD_4x32(R);
185
186 #elif defined(BOTAN_SIMD_USE_NEON)
187 SIMD_4x32 l(vld1q_u32(static_cast<const uint32_t*>(in)));
188 return CPUID::is_little_endian() ? l.bswap() : l;
189 #endif
190 }
Botan::SIMD_4x32::bswap
SIMD_4x32 bswap() const
Definition: simd_32.h:491
Botan::SIMD_4x32::load_le
static SIMD_4x32 load_le(const void *in)
Definition: simd_32.h:159
Botan::load_be
T load_be(const uint8_t in[], size_t off)
Definition: loadstor.h:107
Botan::CPUID::is_little_endian
static bool is_little_endian()
Definition: cpuid.h:73
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

static SIMD_4x32 Botan::SIMD_4x32::load_le | ( | const void * | in | ) |
| inline static

Load a SIMD register with little-endian convention

Definition at line 159 of file simd_32.h.

References bswap(), Botan::CPUID::is_big_endian(), Botan::load_le(), and SIMD_4x32().

Referenced by Botan::gcm_clmul_precompute(), Botan::gcm_multiply_clmul(), and load_be().

160 {
161 #if defined(BOTAN_SIMD_USE_SSE2)
162 return SIMD_4x32(_mm_loadu_si128(reinterpret_cast<const __m128i*>(in)));
163 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
164 uint32_t R[4];
165 Botan::load_le(R, static_cast<const uint8_t*>(in), 4);
166 return SIMD_4x32(R);
167 #elif defined(BOTAN_SIMD_USE_NEON)
168 SIMD_4x32 l(vld1q_u32(static_cast<const uint32_t*>(in)));
169 return CPUID::is_big_endian() ? l.bswap() : l;
170 #endif
171 }
Botan::load_le
T load_le(const uint8_t in[], size_t off)
Definition: loadstor.h:123
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84
Botan::CPUID::is_big_endian
static bool is_big_endian()
Definition: cpuid.h:84

SIMD_4x32 Botan::SIMD_4x32::operator& | ( | const SIMD_4x32 & | other | ) | const
| inline

Binary AND elements of a SIMD vector

Definition at line 366 of file simd_32.h.

367 {
368 SIMD_4x32 retval(*this);
369 retval &= other;
370 return retval;
371 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

void Botan::SIMD_4x32::operator&= | ( | const SIMD_4x32 & | other | ) |
| inline

Definition at line 418 of file simd_32.h.

419 {
420 #if defined(BOTAN_SIMD_USE_SSE2)
421 m_simd = _mm_and_si128(m_simd, other.m_simd);
422 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
423 m_simd = vec_and(m_simd, other.m_simd);
424 #elif defined(BOTAN_SIMD_USE_NEON)
425 m_simd = vandq_u32(m_simd, other.m_simd);
426 #endif
427 }

SIMD_4x32 Botan::SIMD_4x32::operator+ | ( | const SIMD_4x32 & | other | ) | const
| inline

Add elements of a SIMD vector

Definition at line 326 of file simd_32.h.

327 {
328 SIMD_4x32 retval(*this);
329 retval += other;
330 return retval;
331 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

void Botan::SIMD_4x32::operator+= | ( | const SIMD_4x32 & | other | ) |
| inline

Definition at line 373 of file simd_32.h.

374 {
375 #if defined(BOTAN_SIMD_USE_SSE2)
376 m_simd = _mm_add_epi32(m_simd, other.m_simd);
377 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
378 m_simd = vec_add(m_simd, other.m_simd);
379 #elif defined(BOTAN_SIMD_USE_NEON)
380 m_simd = vaddq_u32(m_simd, other.m_simd);
381 #endif
382 }

SIMD_4x32 Botan::SIMD_4x32::operator- | ( | const SIMD_4x32 & | other | ) | const
| inline

Subtract elements of a SIMD vector

Definition at line 336 of file simd_32.h.

337 {
338 SIMD_4x32 retval(*this);
339 retval -= other;
340 return retval;
341 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

void Botan::SIMD_4x32::operator-= | ( | const SIMD_4x32 & | other | ) |
| inline

Definition at line 384 of file simd_32.h.

385 {
386 #if defined(BOTAN_SIMD_USE_SSE2)
387 m_simd = _mm_sub_epi32(m_simd, other.m_simd);
388 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
389 m_simd = vec_sub(m_simd, other.m_simd);
390 #elif defined(BOTAN_SIMD_USE_NEON)
391 m_simd = vsubq_u32(m_simd, other.m_simd);
392 #endif
393 }

SIMD_4x32& Botan::SIMD_4x32::operator= | ( | const SIMD_4x32 & | other | ) |
| default

SIMD_4x32& Botan::SIMD_4x32::operator= | ( | SIMD_4x32 && | other | ) |
| default

SIMD_4x32 Botan::SIMD_4x32::operator^ | ( | const SIMD_4x32 & | other | ) | const
| inline

XOR elements of a SIMD vector

Definition at line 346 of file simd_32.h.

347 {
348 SIMD_4x32 retval(*this);
349 retval ^= other;
350 return retval;
351 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

void Botan::SIMD_4x32::operator^= | ( | const SIMD_4x32 & | other | ) |
| inline

Definition at line 395 of file simd_32.h.

396 {
397 #if defined(BOTAN_SIMD_USE_SSE2)
398 m_simd = _mm_xor_si128(m_simd, other.m_simd);
399
400 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
401 m_simd = vec_xor(m_simd, other.m_simd);
402 #elif defined(BOTAN_SIMD_USE_NEON)
403 m_simd = veorq_u32(m_simd, other.m_simd);
404 #endif
405 }

SIMD_4x32 Botan::SIMD_4x32::operator| | ( | const SIMD_4x32 & | other | ) | const
| inline

Binary OR elements of a SIMD vector

Definition at line 356 of file simd_32.h.

357 {
358 SIMD_4x32 retval(*this);
359 retval |= other;
360 return retval;
361 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

void Botan::SIMD_4x32::operator|= | ( | const SIMD_4x32 & | other | ) |
| inline

Definition at line 407 of file simd_32.h.

408 {
409 #if defined(BOTAN_SIMD_USE_SSE2)
410 m_simd = _mm_or_si128(m_simd, other.m_simd);
411 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
412 m_simd = vec_or(m_simd, other.m_simd);
413 #elif defined(BOTAN_SIMD_USE_NEON)
414 m_simd = vorrq_u32(m_simd, other.m_simd);
415 #endif
416 }

SIMD_4x32 Botan::SIMD_4x32::operator~ | ( |  | ) | const
| inline

Definition at line 460 of file simd_32.h.

References SIMD_4x32().

461 {
462 #if defined(BOTAN_SIMD_USE_SSE2)
463 return SIMD_4x32(_mm_xor_si128(m_simd, _mm_set1_epi32(0xFFFFFFFF)));
464 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
465 return SIMD_4x32(vec_nor(m_simd, m_simd));
466 #elif defined(BOTAN_SIMD_USE_NEON)
467 return SIMD_4x32(vmvnq_u32(m_simd));
468 #endif
469 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

native_simd_type Botan::SIMD_4x32::raw | ( |  | ) | const
| inline

Definition at line 611 of file simd_32.h.

Referenced by shift_elems_left(), shift_elems_right(), and store_le().

611 { return m_simd; }
template<size_t ROT1, size_t ROT2, size_t ROT3>

SIMD_4x32 Botan::SIMD_4x32::rho | ( |  | ) | const
| inline

Definition at line 267 of file simd_32.h.

268 {
269 const SIMD_4x32 rot1 = this->rotr<ROT1>();
270 const SIMD_4x32 rot2 = this->rotr<ROT2>();
271 const SIMD_4x32 rot3 = this->rotr<ROT3>();
272 return (rot1 ^ rot2 ^ rot3);
273 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84
template<size_t ROT>

SIMD_4x32 Botan::SIMD_4x32::rotl | ( |  | ) | const
| inline

Left rotation by a compile time constant

Definition at line 279 of file simd_32.h.

References BOTAN_IF_CONSTEXPR, and SIMD_4x32().

Referenced by rotr().

280 {
281 static_assert(ROT > 0 && ROT < 32, "Invalid rotation constant");
282
283 #if defined(BOTAN_SIMD_USE_SSE2)
284
285 return SIMD_4x32(_mm_or_si128(_mm_slli_epi32(m_simd, static_cast<int>(ROT)),
286 _mm_srli_epi32(m_simd, static_cast<int>(32-ROT))));
287
288 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
289
290 const unsigned int r = static_cast<unsigned int>(ROT);
291 __vector unsigned int rot = {r, r, r, r};
292 return SIMD_4x32(vec_rl(m_simd, rot));
293
294 #elif defined(BOTAN_SIMD_USE_NEON)
295
296 #if defined(BOTAN_TARGET_ARCH_IS_ARM64)
297
298 BOTAN_IF_CONSTEXPR(ROT == 8)
299 {
300 const uint8_t maskb[16] = { 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 };
301 const uint8x16_t mask = vld1q_u8(maskb);
302 return SIMD_4x32(vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(m_simd), mask)));
303 }
304 else BOTAN_IF_CONSTEXPR(ROT == 16)
305 {
306 return SIMD_4x32(vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(m_simd))));
307 }
308 #endif
309 return SIMD_4x32(vorrq_u32(vshlq_n_u32(m_simd, static_cast<int>(ROT)),
310 vshrq_n_u32(m_simd, static_cast<int>(32-ROT))));
311 #endif
312 }
BOTAN_IF_CONSTEXPR
#define BOTAN_IF_CONSTEXPR
Definition: compiler.h:179
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84
template<size_t ROT>

SIMD_4x32 Botan::SIMD_4x32::rotr | ( |  | ) | const
| inline

Right rotation by a compile time constant

Definition at line 318 of file simd_32.h.

References rotl().

319 {
320 return this->rotl<32-ROT>();
321 }
Botan::SIMD_4x32::rotl
SIMD_4x32 rotl() const
Definition: simd_32.h:279
template<size_t I>

SIMD_4x32 Botan::SIMD_4x32::shift_elems_left | ( |  | ) | const
| inline

Definition at line 517 of file simd_32.h.

References raw(), and SIMD_4x32().

518 {
519 static_assert(I <= 3, "Invalid shift count");
520
521 #if defined(BOTAN_SIMD_USE_SSE2)
522 return SIMD_4x32(_mm_slli_si128(raw(), 4*I));
523 #elif defined(BOTAN_SIMD_USE_NEON)
524 return SIMD_4x32(vextq_u32(vdupq_n_u32(0), raw(), 4-I));
525 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
526 const __vector unsigned int zero = vec_splat_u32(0);
527
528 const __vector unsigned char shuf[3] = {
529 { 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
530 { 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7 },
531 { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 1, 2, 3 },
532 };
533
534 return SIMD_4x32(vec_perm(raw(), zero, shuf[I-1]));
535 #endif
536 }
Botan::SIMD_4x32::raw
native_simd_type raw() const BOTAN_FUNC_ISA(BOTAN_SIMD_ISA)
Definition: simd_32.h:611
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84
template<size_t I>

SIMD_4x32 Botan::SIMD_4x32::shift_elems_right | ( |  | ) | const
| inline

Definition at line 539 of file simd_32.h.

References raw(), and SIMD_4x32().

540 {
541 static_assert(I <= 3, "Invalid shift count");
542
543 #if defined(BOTAN_SIMD_USE_SSE2)
544 return SIMD_4x32(_mm_srli_si128(raw(), 4*I));
545 #elif defined(BOTAN_SIMD_USE_NEON)
546 return SIMD_4x32(vextq_u32(raw(), vdupq_n_u32(0), I));
547 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
548 const __vector unsigned int zero = vec_splat_u32(0);
549
550 const __vector unsigned char shuf[3] = {
551 { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 },
552 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 },
553 { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 },
554 };
555
556 return SIMD_4x32(vec_perm(raw(), zero, shuf[I-1]));
557 #endif
558 }
Botan::SIMD_4x32::raw
native_simd_type raw() const BOTAN_FUNC_ISA(BOTAN_SIMD_ISA)
Definition: simd_32.h:611
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84
template<int SHIFT>

SIMD_4x32 Botan::SIMD_4x32::shl | ( |  | ) | const
| inline

Definition at line 430 of file simd_32.h.

References SIMD_4x32().

431 {
432 static_assert(SHIFT > 0 && SHIFT <= 31, "Invalid shift count");
433
434 #if defined(BOTAN_SIMD_USE_SSE2)
435 return SIMD_4x32(_mm_slli_epi32(m_simd, SHIFT));
436
437 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
438 const unsigned int s = static_cast<unsigned int>(SHIFT);
439 const __vector unsigned int shifts = {s, s, s, s};
440 return SIMD_4x32(vec_sl(m_simd, shifts));
441 #elif defined(BOTAN_SIMD_USE_NEON)
442 return SIMD_4x32(vshlq_n_u32(m_simd, SHIFT));
443 #endif
444 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84
template<int SHIFT>

SIMD_4x32 Botan::SIMD_4x32::shr | ( |  | ) | const
| inline

Definition at line 446 of file simd_32.h.

References SIMD_4x32().

447 {
448 #if defined(BOTAN_SIMD_USE_SSE2)
449 return SIMD_4x32(_mm_srli_epi32(m_simd, SHIFT));
450
451 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
452 const unsigned int s = static_cast<unsigned int>(SHIFT);
453 const __vector unsigned int shifts = {s, s, s, s};
454 return SIMD_4x32(vec_sr(m_simd, shifts));
455 #elif defined(BOTAN_SIMD_USE_NEON)
456 return SIMD_4x32(vshrq_n_u32(m_simd, SHIFT));
457 #endif
458 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

static SIMD_4x32 Botan::SIMD_4x32::splat | ( | uint32_t | B | ) |
| inline static

Load SIMD register with one 32-bit element repeated

Definition at line 130 of file simd_32.h.

References SIMD_4x32().

131 {
132 #if defined(BOTAN_SIMD_USE_SSE2)
133 return SIMD_4x32(_mm_set1_epi32(B));
134 #elif defined(BOTAN_SIMD_USE_NEON)
135 return SIMD_4x32(vdupq_n_u32(B));
136 #else
137 return SIMD_4x32(B, B, B, B);
138 #endif
139 }
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

static SIMD_4x32 Botan::SIMD_4x32::splat_u8 | ( | uint8_t | B | ) |
| inline static

Load SIMD register with one 8-bit element repeated

Definition at line 144 of file simd_32.h.

References Botan::make_uint32(), and SIMD_4x32().

145 {
146 #if defined(BOTAN_SIMD_USE_SSE2)
147 return SIMD_4x32(_mm_set1_epi8(B));
148 #elif defined(BOTAN_SIMD_USE_NEON)
149 return SIMD_4x32(vreinterpretq_u32_u8(vdupq_n_u8(B)));
150 #else
151 const uint32_t B4 = make_uint32(B, B, B, B);
152 return SIMD_4x32(B4, B4, B4, B4);
153 #endif
154 }
Botan::make_uint32
constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
Definition: loadstor.h:67
Botan::SIMD_4x32::SIMD_4x32
SIMD_4x32()
Definition: simd_32.h:84

void Botan::SIMD_4x32::store_be | ( | uint8_t | out[] | ) | const
| inline

Load a SIMD register with big-endian convention

Definition at line 235 of file simd_32.h.

References bswap(), Botan::CPUID::is_little_endian(), Botan::store_be(), and store_le().

236 {
237 #if defined(BOTAN_SIMD_USE_SSE2)
238
239 bswap().store_le(out);
240
241 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
242
243 union {
244 __vector unsigned int V;
245 uint32_t R[4];
246 } vec;
247 vec.V = m_simd;
248 Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
249
250 #elif defined(BOTAN_SIMD_USE_NEON)
251 if(CPUID::is_little_endian())
252 {
253 vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
254 }
255 else
256 {
257 vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
258 }
259 #endif
260 }
Botan::SIMD_4x32::bswap
SIMD_4x32 bswap() const
Definition: simd_32.h:491
Botan::store_be
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:438
Botan::CPUID::is_little_endian
static bool is_little_endian()
Definition: cpuid.h:73
Botan::SIMD_4x32::store_le
void store_le(uint32_t out[4]) const
Definition: simd_32.h:192

void Botan::SIMD_4x32::store_le | ( | uint32_t | out[4] | ) | const
| inline

Definition at line 192 of file simd_32.h.

Referenced by Botan::gcm_clmul_precompute(), Botan::gcm_multiply_clmul(), store_be(), and store_le().

193 {
194 this->store_le(reinterpret_cast<uint8_t*>(out));
195 }
Botan::SIMD_4x32::store_le
void store_le(uint32_t out[4]) const
Definition: simd_32.h:192

void Botan::SIMD_4x32::store_le | ( | uint64_t | out[2] | ) | const
| inline

Definition at line 197 of file simd_32.h.

References store_le().

198 {
199 this->store_le(reinterpret_cast<uint8_t*>(out));
200 }
Botan::SIMD_4x32::store_le
void store_le(uint32_t out[4]) const
Definition: simd_32.h:192

void Botan::SIMD_4x32::store_le | ( | uint8_t | out[] | ) | const
| inline

Load a SIMD register with little-endian convention

Definition at line 205 of file simd_32.h.

References bswap(), Botan::CPUID::is_little_endian(), raw(), and Botan::store_le().

206 {
207 #if defined(BOTAN_SIMD_USE_SSE2)
208
209 _mm_storeu_si128(reinterpret_cast<__m128i*>(out), raw());
210
211 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
212
213 union {
214 __vector unsigned int V;
215 uint32_t R[4];
216 } vec;
217 vec.V = raw();
218 Botan::store_le(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
219
220 #elif defined(BOTAN_SIMD_USE_NEON)
221 if(CPUID::is_little_endian())
222 {
223 vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
224 }
225 else
226 {
227 vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
228 }
229 #endif
230 }
Botan::SIMD_4x32::bswap
SIMD_4x32 bswap() const
Definition: simd_32.h:491
Botan::SIMD_4x32::raw
native_simd_type raw() const BOTAN_FUNC_ISA(BOTAN_SIMD_ISA)
Definition: simd_32.h:611
Botan::CPUID::is_little_endian
static bool is_little_endian()
Definition: cpuid.h:73
Botan::store_le
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:454

static void Botan::SIMD_4x32::transpose | ( | SIMD_4x32 & | B0,
|  | SIMD_4x32 & | B1,
|  | SIMD_4x32 & | B2,
|  | SIMD_4x32 & | B3
| ) |  |
| inline static

4x4 Transposition on SIMD registers

Definition at line 563 of file simd_32.h.

565 {
566 #if defined(BOTAN_SIMD_USE_SSE2)
567 const __m128i T0 = _mm_unpacklo_epi32(B0.m_simd, B1.m_simd);
568 const __m128i T1 = _mm_unpacklo_epi32(B2.m_simd, B3.m_simd);
569 const __m128i T2 = _mm_unpackhi_epi32(B0.m_simd, B1.m_simd);
570 const __m128i T3 = _mm_unpackhi_epi32(B2.m_simd, B3.m_simd);
571
572 B0.m_simd = _mm_unpacklo_epi64(T0, T1);
573 B1.m_simd = _mm_unpackhi_epi64(T0, T1);
574 B2.m_simd = _mm_unpacklo_epi64(T2, T3);
575 B3.m_simd = _mm_unpackhi_epi64(T2, T3);
576 #elif defined(BOTAN_SIMD_USE_ALTIVEC)
577 const __vector unsigned int T0 = vec_mergeh(B0.m_simd, B2.m_simd);
578 const __vector unsigned int T1 = vec_mergeh(B1.m_simd, B3.m_simd);
579 const __vector unsigned int T2 = vec_mergel(B0.m_simd, B2.m_simd);
580 const __vector unsigned int T3 = vec_mergel(B1.m_simd, B3.m_simd);
581
582 B0.m_simd = vec_mergeh(T0, T1);
583 B1.m_simd = vec_mergel(T0, T1);
584 B2.m_simd = vec_mergeh(T2, T3);
585 B3.m_simd = vec_mergel(T2, T3);
586
587 #elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM32)
588 const uint32x4x2_t T0 = vzipq_u32(B0.m_simd, B2.m_simd);
589 const uint32x4x2_t T1 = vzipq_u32(B1.m_simd, B3.m_simd);
590 const uint32x4x2_t O0 = vzipq_u32(T0.val[0], T1.val[0]);
591 const uint32x4x2_t O1 = vzipq_u32(T0.val[1], T1.val[1]);
592
593 B0.m_simd = O0.val[0];
594 B1.m_simd = O0.val[1];
595 B2.m_simd = O1.val[0];
596 B3.m_simd = O1.val[1];
597
598 #elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM64)
599 const uint32x4_t T0 = vzip1q_u32(B0.m_simd, B2.m_simd);
600 const uint32x4_t T2 = vzip2q_u32(B0.m_simd, B2.m_simd);
601 const uint32x4_t T1 = vzip1q_u32(B1.m_simd, B3.m_simd);
602 const uint32x4_t T3 = vzip2q_u32(B1.m_simd, B3.m_simd);
603
604 B0.m_simd = vzip1q_u32(T0, T1);
605 B1.m_simd = vzip2q_u32(T0, T1);
606 B2.m_simd = vzip1q_u32(T2, T3);
607 B3.m_simd = vzip2q_u32(T2, T3);
608 #endif
609 }

The documentation for this class was generated from the following file:

- src/lib/utils/simd/simd_32.h