Botan 2.19.5 Crypto and TLS for C&

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 ()
| SIMD_4x32 (const SIMD_4x32 &other)=default
| SIMD_4x32 (const uint32_t B[4])
| SIMD_4x32 (native_simd_type x)
| SIMD_4x32 (SIMD_4x32 &&other)=default
| SIMD_4x32 (uint32_t B0, uint32_t B1, uint32_t B2, uint32_t B3)
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 72 of file simd_32.h.

## Constructor & Destructor Documentation

## ◆ SIMD_4x32() [1/6]

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

## ◆ SIMD_4x32() [2/6]

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

## ◆ SIMD_4x32() [3/6]

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

Zero initialize SIMD register with 4 32-bit elements

Definition at line 85 of file simd_32.h.

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

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

## ◆ SIMD_4x32() [4/6]

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

Load SIMD register with 4 32-bit elements

Definition at line 99 of file simd_32.h.

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

## ◆ SIMD_4x32() [5/6]

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 114 of file simd_32.h.

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

## ◆ SIMD_4x32() [6/6]

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

Definition at line 614 of file simd_32.h.

614: m_simd(x) {}

## Member Function Documentation

## ◆ andc()

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

Definition at line 473 of file simd_32.h.

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

References SIMD_4x32().

## ◆ bswap()

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

Return copy *this with each word byte swapped

Definition at line 492 of file simd_32.h.

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

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

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

## ◆ load_be()

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

Load a SIMD register with big-endian convention

Definition at line 177 of file simd_32.h.

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

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

## ◆ load_le()

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

Load a SIMD register with little-endian convention

Definition at line 160 of file simd_32.h.

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

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

Referenced by load_be().

## ◆ operator&()

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

Binary AND elements of a SIMD vector

Definition at line 367 of file simd_32.h.

368 {
369 SIMD_4x32 retval(*this);
370 retval &= other;
371 return retval;
372 }

## ◆ operator&=()

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

Definition at line 419 of file simd_32.h.

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

## ◆ operator+()

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

Add elements of a SIMD vector

Definition at line 327 of file simd_32.h.

328 {
329 SIMD_4x32 retval(*this);
330 retval += other;
331 return retval;
332 }

## ◆ operator+=()

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

Definition at line 374 of file simd_32.h.

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

## ◆ operator-()

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

Subtract elements of a SIMD vector

Definition at line 337 of file simd_32.h.

338 {
339 SIMD_4x32 retval(*this);
340 retval -= other;
341 return retval;
342 }

## ◆ operator-=()

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

Definition at line 385 of file simd_32.h.

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

## ◆ operator=() [1/2]

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

## ◆ operator=() [2/2]

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

## ◆ operator^()

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

XOR elements of a SIMD vector

Definition at line 347 of file simd_32.h.

348 {
349 SIMD_4x32 retval(*this);
350 retval ^= other;
351 return retval;
352 }

## ◆ operator^=()

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

Definition at line 396 of file simd_32.h.

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

## ◆ operator|()

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

Binary OR elements of a SIMD vector

Definition at line 357 of file simd_32.h.

358 {
359 SIMD_4x32 retval(*this);
360 retval |= other;
361 return retval;
362 }

## ◆ operator|=()

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

Definition at line 408 of file simd_32.h.

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

## ◆ operator~()

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

Definition at line 461 of file simd_32.h.

462 {
463#if defined(BOTAN_SIMD_USE_SSE2)
464 return SIMD_4x32(_mm_xor_si128(m_simd, _mm_set1_epi32(0xFFFFFFFF)));
465#elif defined(BOTAN_SIMD_USE_ALTIVEC)
466 return SIMD_4x32(vec_nor(m_simd, m_simd));
467#elif defined(BOTAN_SIMD_USE_NEON)
468 return SIMD_4x32(vmvnq_u32(m_simd));
469#endif
470 }

References SIMD_4x32().

## ◆ raw()

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

Definition at line 612 of file simd_32.h.

612{ return m_simd; }

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

## ◆ rho()

template<size_t ROT1, size_t ROT2, size_t ROT3>

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

Definition at line 268 of file simd_32.h.

269 {
270 const SIMD_4x32 rot1 = this->rotr<ROT1>();
271 const SIMD_4x32 rot2 = this->rotr<ROT2>();
272 const SIMD_4x32 rot3 = this->rotr<ROT3>();
273 return (rot1 ^ rot2 ^ rot3);
274 }

## ◆ rotl()

template<size_t ROT>

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

Left rotation by a compile time constant

Definition at line 280 of file simd_32.h.

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

References BOTAN_IF_CONSTEXPR, and SIMD_4x32().

Referenced by rotr().

## ◆ rotr()

template<size_t ROT>

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

Right rotation by a compile time constant

Definition at line 319 of file simd_32.h.

320 {
321 return this->rotl<32-ROT>();
322 }
Botan::SIMD_4x32::rotl
SIMD_4x32 rotl() const
Definition: simd_32.h:280

References rotl().

## ◆ shift_elems_left()

template<size_t I>

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

Definition at line 518 of file simd_32.h.

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

References raw(), and SIMD_4x32().

## ◆ shift_elems_right()

template<size_t I>

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

Definition at line 540 of file simd_32.h.

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

References raw(), and SIMD_4x32().

## ◆ shl()

template<int SHIFT>

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

Definition at line 431 of file simd_32.h.

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

References SIMD_4x32().

## ◆ shr()

template<int SHIFT>

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

Definition at line 447 of file simd_32.h.

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

References SIMD_4x32().

## ◆ splat()

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

Load SIMD register with one 32-bit element repeated

Definition at line 131 of file simd_32.h.

132 {
133#if defined(BOTAN_SIMD_USE_SSE2)
134 return SIMD_4x32(_mm_set1_epi32(B));
135#elif defined(BOTAN_SIMD_USE_NEON)
136 return SIMD_4x32(vdupq_n_u32(B));
137#else
138 return SIMD_4x32(B, B, B, B);
139#endif
140 }

References SIMD_4x32().

## ◆ splat_u8()

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 145 of file simd_32.h.

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

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

## ◆ store_be()

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

Load a SIMD register with big-endian convention

Definition at line 236 of file simd_32.h.

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

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

## ◆ store_le() [1/3]

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

Definition at line 193 of file simd_32.h.

194 {
195 this->store_le(reinterpret_cast<uint8_t*>(out));
196 }

References store_le().

Referenced by store_be(), and store_le().

## ◆ store_le() [2/3]

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

Definition at line 198 of file simd_32.h.

199 {
200 this->store_le(reinterpret_cast<uint8_t*>(out));
201 }

References store_le().

## ◆ store_le() [3/3]

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

Load a SIMD register with little-endian convention

Definition at line 206 of file simd_32.h.

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

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

## ◆ transpose()

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 564 of file simd_32.h.

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

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

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