Botan 3.0.0-alpha0
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_4x32operator= (const SIMD_4x32 &other)=default
 
SIMD_4x32operator= (SIMD_4x32 &&other)=default
 
SIMD_4x32 operator^ (const SIMD_4x32 &other) const
 
void operator^= (const SIMD_4x32 &other)
 
void operator^= (uint32_t other)
 
SIMD_4x32 operator| (const SIMD_4x32 &other) const
 
void operator|= (const SIMD_4x32 &other)
 
SIMD_4x32 operator~ () const
 
native_simd_type raw () 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 sigma0 () const
 
SIMD_4x32 sigma1 () 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 choose (const SIMD_4x32 &mask, const SIMD_4x32 &a, const SIMD_4x32 &b)
 
static SIMD_4x32 load_be (const void *in)
 
static SIMD_4x32 load_le (const void *in)
 
static SIMD_4x32 majority (const SIMD_4x32 &x, const SIMD_4x32 &y, const SIMD_4x32 &z)
 
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(), choose(), load_be(), load_le(), operator~(), rotl(), shift_elems_left(), shift_elems_right(), shl(), shr(), sigma0(), sigma1(), splat(), and splat_u8().

◆ SIMD_4x32() [4/6]

Botan::SIMD_4x32::SIMD_4x32 ( const uint32_t  B[4])
inlineexplicit

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)
inlineexplicit

Definition at line 651 of file simd_32.h.

651: m_simd(x) {}

Member Function Documentation

◆ andc()

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

Definition at line 494 of file simd_32.h.

495 {
496#if defined(BOTAN_SIMD_USE_SSE2)
497 return SIMD_4x32(_mm_andnot_si128(m_simd, other.m_simd));
498#elif defined(BOTAN_SIMD_USE_ALTIVEC)
499 /*
500 AltiVec does arg1 & ~arg2 rather than SSE's ~arg1 & arg2
501 so swap the arguments
502 */
503 return SIMD_4x32(vec_andc(other.m_simd, m_simd));
504#elif defined(BOTAN_SIMD_USE_NEON)
505 // NEON is also a & ~b
506 return SIMD_4x32(vbicq_u32(other.m_simd, m_simd));
507#endif
508 }

References SIMD_4x32().

Referenced by choose().

◆ bswap()

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

Return copy *this with each word byte swapped

Definition at line 513 of file simd_32.h.

514 {
515#if defined(BOTAN_SIMD_USE_SSE2)
516
517 __m128i T = m_simd;
518 T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
519 T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
520 return SIMD_4x32(_mm_or_si128(_mm_srli_epi16(T, 8), _mm_slli_epi16(T, 8)));
521
522#elif defined(BOTAN_SIMD_USE_ALTIVEC)
523
524 union {
525 __vector unsigned int V;
526 uint32_t R[4];
527 } vec;
528
529 vec.V = m_simd;
530 bswap_4(vec.R);
531 return SIMD_4x32(vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
532
533#elif defined(BOTAN_SIMD_USE_NEON)
534 return SIMD_4x32(vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(m_simd))));
535#endif
536 }
fe T
Definition: ge.cpp:36
constexpr void bswap_4(T x[4])
Definition: bswap.h:72

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

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

◆ choose()

static SIMD_4x32 Botan::SIMD_4x32::choose ( const SIMD_4x32 mask,
const SIMD_4x32 a,
const SIMD_4x32 b 
)
inlinestatic

Definition at line 633 of file simd_32.h.

634 {
635#if defined(BOTAN_SIMD_USE_ALTIVEC)
636 return SIMD_4x32(vec_sel(b.raw(), a.raw(), mask.raw()));
637#elif defined(BOTAN_SIMD_USE_NEON)
638 return SIMD_4x32(vbslq_u32(mask.raw(), a.raw(), b.raw()));
639#else
640 return (mask & a) ^ mask.andc(b);
641#endif
642 }
PolynomialVector b
Definition: kyber.cpp:821

References andc(), b, raw(), and SIMD_4x32().

Referenced by majority().

◆ load_be()

static SIMD_4x32 Botan::SIMD_4x32::load_be ( const void *  in)
inlinestatic

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 }
static bool is_little_endian()
Definition: cpuid.h:64
SIMD_4x32 bswap() const
Definition: simd_32.h:513
static SIMD_4x32 load_le(const void *in)
Definition: simd_32.h:160
constexpr T load_be(const uint8_t in[], size_t off)
Definition: loadstor.h:118

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)
inlinestatic

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 }
static bool is_big_endian()
Definition: cpuid.h:75
constexpr T load_le(const uint8_t in[], size_t off)
Definition: loadstor.h:134

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

Referenced by load_be().

◆ majority()

static SIMD_4x32 Botan::SIMD_4x32::majority ( const SIMD_4x32 x,
const SIMD_4x32 y,
const SIMD_4x32 z 
)
inlinestatic

Definition at line 644 of file simd_32.h.

645 {
646 return SIMD_4x32::choose(x ^ y, z, y);
647 }
static SIMD_4x32 choose(const SIMD_4x32 &mask, const SIMD_4x32 &a, const SIMD_4x32 &b)
Definition: simd_32.h:633

References choose().

◆ operator&()

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

Binary AND elements of a SIMD vector

Definition at line 384 of file simd_32.h.

385 {
386 SIMD_4x32 retval(*this);
387 retval &= other;
388 return retval;
389 }

◆ operator&=()

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

Definition at line 440 of file simd_32.h.

441 {
442#if defined(BOTAN_SIMD_USE_SSE2)
443 m_simd = _mm_and_si128(m_simd, other.m_simd);
444#elif defined(BOTAN_SIMD_USE_ALTIVEC)
445 m_simd = vec_and(m_simd, other.m_simd);
446#elif defined(BOTAN_SIMD_USE_NEON)
447 m_simd = vandq_u32(m_simd, other.m_simd);
448#endif
449 }

◆ operator+()

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

Add elements of a SIMD vector

Definition at line 344 of file simd_32.h.

345 {
346 SIMD_4x32 retval(*this);
347 retval += other;
348 return retval;
349 }

◆ operator+=()

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

Definition at line 391 of file simd_32.h.

392 {
393#if defined(BOTAN_SIMD_USE_SSE2)
394 m_simd = _mm_add_epi32(m_simd, other.m_simd);
395#elif defined(BOTAN_SIMD_USE_ALTIVEC)
396 m_simd = vec_add(m_simd, other.m_simd);
397#elif defined(BOTAN_SIMD_USE_NEON)
398 m_simd = vaddq_u32(m_simd, other.m_simd);
399#endif
400 }

◆ operator-()

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

Subtract elements of a SIMD vector

Definition at line 354 of file simd_32.h.

355 {
356 SIMD_4x32 retval(*this);
357 retval -= other;
358 return retval;
359 }

◆ operator-=()

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

Definition at line 402 of file simd_32.h.

403 {
404#if defined(BOTAN_SIMD_USE_SSE2)
405 m_simd = _mm_sub_epi32(m_simd, other.m_simd);
406#elif defined(BOTAN_SIMD_USE_ALTIVEC)
407 m_simd = vec_sub(m_simd, other.m_simd);
408#elif defined(BOTAN_SIMD_USE_NEON)
409 m_simd = vsubq_u32(m_simd, other.m_simd);
410#endif
411 }

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

365 {
366 SIMD_4x32 retval(*this);
367 retval ^= other;
368 return retval;
369 }

◆ operator^=() [1/2]

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

Definition at line 413 of file simd_32.h.

414 {
415#if defined(BOTAN_SIMD_USE_SSE2)
416 m_simd = _mm_xor_si128(m_simd, other.m_simd);
417#elif defined(BOTAN_SIMD_USE_ALTIVEC)
418 m_simd = vec_xor(m_simd, other.m_simd);
419#elif defined(BOTAN_SIMD_USE_NEON)
420 m_simd = veorq_u32(m_simd, other.m_simd);
421#endif
422 }

◆ operator^=() [2/2]

void Botan::SIMD_4x32::operator^= ( uint32_t  other)
inline

Definition at line 424 of file simd_32.h.

425 {
426 *this ^= SIMD_4x32::splat(other);
427 }
static SIMD_4x32 splat(uint32_t B)
Definition: simd_32.h:131

References splat().

◆ operator|()

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

Binary OR elements of a SIMD vector

Definition at line 374 of file simd_32.h.

375 {
376 SIMD_4x32 retval(*this);
377 retval |= other;
378 return retval;
379 }

◆ operator|=()

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

Definition at line 429 of file simd_32.h.

430 {
431#if defined(BOTAN_SIMD_USE_SSE2)
432 m_simd = _mm_or_si128(m_simd, other.m_simd);
433#elif defined(BOTAN_SIMD_USE_ALTIVEC)
434 m_simd = vec_or(m_simd, other.m_simd);
435#elif defined(BOTAN_SIMD_USE_NEON)
436 m_simd = vorrq_u32(m_simd, other.m_simd);
437#endif
438 }

◆ operator~()

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

Definition at line 482 of file simd_32.h.

483 {
484#if defined(BOTAN_SIMD_USE_SSE2)
485 return SIMD_4x32(_mm_xor_si128(m_simd, _mm_set1_epi32(0xFFFFFFFF)));
486#elif defined(BOTAN_SIMD_USE_ALTIVEC)
487 return SIMD_4x32(vec_nor(m_simd, m_simd));
488#elif defined(BOTAN_SIMD_USE_NEON)
489 return SIMD_4x32(vmvnq_u32(m_simd));
490#endif
491 }

References SIMD_4x32().

◆ raw()

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

Definition at line 649 of file simd_32.h.

649{ return m_simd; }

Referenced by choose(), shift_elems_left(), shift_elems_right(), sigma0(), sigma1(), and store_le().

◆ rotl()

template<size_t ROT>
SIMD_4x32 Botan::SIMD_4x32::rotl ( ) const
inline

Left rotation by a compile time constant

Definition at line 297 of file simd_32.h.

298 {
299 static_assert(ROT > 0 && ROT < 32, "Invalid rotation constant");
300
301#if defined(BOTAN_SIMD_USE_SSE2)
302
303 return SIMD_4x32(_mm_or_si128(_mm_slli_epi32(m_simd, static_cast<int>(ROT)),
304 _mm_srli_epi32(m_simd, static_cast<int>(32-ROT))));
305
306#elif defined(BOTAN_SIMD_USE_ALTIVEC)
307
308 const unsigned int r = static_cast<unsigned int>(ROT);
309 __vector unsigned int rot = {r, r, r, r};
310 return SIMD_4x32(vec_rl(m_simd, rot));
311
312#elif defined(BOTAN_SIMD_USE_NEON)
313
314#if defined(BOTAN_TARGET_ARCH_IS_ARM64)
315
316 if constexpr(ROT == 8)
317 {
318 const uint8_t maskb[16] = { 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 };
319 const uint8x16_t mask = vld1q_u8(maskb);
320 return SIMD_4x32(vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(m_simd), mask)));
321 }
322 else if constexpr(ROT == 16)
323 {
324 return SIMD_4x32(vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(m_simd))));
325 }
326#endif
327 return SIMD_4x32(vorrq_u32(vshlq_n_u32(m_simd, static_cast<int>(ROT)),
328 vshrq_n_u32(m_simd, static_cast<int>(32-ROT))));
329#endif
330 }

References SIMD_4x32().

Referenced by Botan::rotl(), and rotr().

◆ rotr()

template<size_t ROT>
SIMD_4x32 Botan::SIMD_4x32::rotr ( ) const
inline

Right rotation by a compile time constant

Definition at line 336 of file simd_32.h.

337 {
338 return this->rotl<32-ROT>();
339 }
SIMD_4x32 rotl() const
Definition: simd_32.h:297

References rotl().

Referenced by Botan::rotr().

◆ shift_elems_left()

template<size_t I>
SIMD_4x32 Botan::SIMD_4x32::shift_elems_left ( ) const
inline

Definition at line 539 of file simd_32.h.

540 {
541 static_assert(I <= 3, "Invalid shift count");
542
543#if defined(BOTAN_SIMD_USE_SSE2)
544 return SIMD_4x32(_mm_slli_si128(raw(), 4*I));
545#elif defined(BOTAN_SIMD_USE_NEON)
546 return SIMD_4x32(vextq_u32(vdupq_n_u32(0), raw(), 4-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 { 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
552 { 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7 },
553 { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 1, 2, 3 },
554 };
555
556 return SIMD_4x32(vec_perm(raw(), zero, shuf[I-1]));
557#endif
558 }
native_simd_type raw() const
Definition: simd_32.h:649

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

562 {
563 static_assert(I <= 3, "Invalid shift count");
564
565#if defined(BOTAN_SIMD_USE_SSE2)
566 return SIMD_4x32(_mm_srli_si128(raw(), 4*I));
567#elif defined(BOTAN_SIMD_USE_NEON)
568 return SIMD_4x32(vextq_u32(raw(), vdupq_n_u32(0), I));
569#elif defined(BOTAN_SIMD_USE_ALTIVEC)
570 const __vector unsigned int zero = vec_splat_u32(0);
571
572 const __vector unsigned char shuf[3] = {
573 { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 },
574 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 },
575 { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 },
576 };
577
578 return SIMD_4x32(vec_perm(raw(), zero, shuf[I-1]));
579#endif
580 }

References raw(), and SIMD_4x32().

◆ shl()

template<int SHIFT>
SIMD_4x32 Botan::SIMD_4x32::shl ( ) const
inline

Definition at line 452 of file simd_32.h.

453 {
454 static_assert(SHIFT > 0 && SHIFT <= 31, "Invalid shift count");
455
456#if defined(BOTAN_SIMD_USE_SSE2)
457 return SIMD_4x32(_mm_slli_epi32(m_simd, SHIFT));
458
459#elif defined(BOTAN_SIMD_USE_ALTIVEC)
460 const unsigned int s = static_cast<unsigned int>(SHIFT);
461 const __vector unsigned int shifts = {s, s, s, s};
462 return SIMD_4x32(vec_sl(m_simd, shifts));
463#elif defined(BOTAN_SIMD_USE_NEON)
464 return SIMD_4x32(vshlq_n_u32(m_simd, SHIFT));
465#endif
466 }

References SIMD_4x32().

Referenced by Botan::shl().

◆ shr()

template<int SHIFT>
SIMD_4x32 Botan::SIMD_4x32::shr ( ) const
inline

Definition at line 468 of file simd_32.h.

469 {
470#if defined(BOTAN_SIMD_USE_SSE2)
471 return SIMD_4x32(_mm_srli_epi32(m_simd, SHIFT));
472
473#elif defined(BOTAN_SIMD_USE_ALTIVEC)
474 const unsigned int s = static_cast<unsigned int>(SHIFT);
475 const __vector unsigned int shifts = {s, s, s, s};
476 return SIMD_4x32(vec_sr(m_simd, shifts));
477#elif defined(BOTAN_SIMD_USE_NEON)
478 return SIMD_4x32(vshrq_n_u32(m_simd, SHIFT));
479#endif
480 }

References SIMD_4x32().

◆ sigma0()

SIMD_4x32 Botan::SIMD_4x32::sigma0 ( ) const
inline

Definition at line 266 of file simd_32.h.

267 {
268#if defined(__GNUC__) && defined(_ARCH_PWR8)
269 return SIMD_4x32(__builtin_crypto_vshasigmaw(raw(), 1, 0));
270#else
271 const SIMD_4x32 rot1 = this->rotr<2>();
272 const SIMD_4x32 rot2 = this->rotr<13>();
273 const SIMD_4x32 rot3 = this->rotr<22>();
274 return (rot1 ^ rot2 ^ rot3);
275#endif
276 }

References raw(), and SIMD_4x32().

◆ sigma1()

SIMD_4x32 Botan::SIMD_4x32::sigma1 ( ) const
inline

Definition at line 281 of file simd_32.h.

282 {
283#if defined(__GNUC__) && defined(_ARCH_PWR8)
284 return SIMD_4x32(__builtin_crypto_vshasigmaw(raw(), 1, 0xF));
285#else
286 const SIMD_4x32 rot1 = this->rotr<6>();
287 const SIMD_4x32 rot2 = this->rotr<11>();
288 const SIMD_4x32 rot3 = this->rotr<25>();
289 return (rot1 ^ rot2 ^ rot3);
290#endif
291 }

References raw(), and SIMD_4x32().

◆ splat()

static SIMD_4x32 Botan::SIMD_4x32::splat ( uint32_t  B)
inlinestatic

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().

Referenced by operator^=().

◆ splat_u8()

static SIMD_4x32 Botan::SIMD_4x32::splat_u8 ( uint8_t  B)
inlinestatic

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 }
constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
Definition: loadstor.h:78

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)
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 }
void store_le(uint32_t out[4]) const
Definition: simd_32.h:193
constexpr void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:449

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)
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 }
constexpr void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:465

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 
)
inlinestatic

4x4 Transposition on SIMD registers

Definition at line 585 of file simd_32.h.

587 {
588#if defined(BOTAN_SIMD_USE_SSE2)
589 const __m128i T0 = _mm_unpacklo_epi32(B0.m_simd, B1.m_simd);
590 const __m128i T1 = _mm_unpacklo_epi32(B2.m_simd, B3.m_simd);
591 const __m128i T2 = _mm_unpackhi_epi32(B0.m_simd, B1.m_simd);
592 const __m128i T3 = _mm_unpackhi_epi32(B2.m_simd, B3.m_simd);
593
594 B0.m_simd = _mm_unpacklo_epi64(T0, T1);
595 B1.m_simd = _mm_unpackhi_epi64(T0, T1);
596 B2.m_simd = _mm_unpacklo_epi64(T2, T3);
597 B3.m_simd = _mm_unpackhi_epi64(T2, T3);
598#elif defined(BOTAN_SIMD_USE_ALTIVEC)
599 const __vector unsigned int T0 = vec_mergeh(B0.m_simd, B2.m_simd);
600 const __vector unsigned int T1 = vec_mergeh(B1.m_simd, B3.m_simd);
601 const __vector unsigned int T2 = vec_mergel(B0.m_simd, B2.m_simd);
602 const __vector unsigned int T3 = vec_mergel(B1.m_simd, B3.m_simd);
603
604 B0.m_simd = vec_mergeh(T0, T1);
605 B1.m_simd = vec_mergel(T0, T1);
606 B2.m_simd = vec_mergeh(T2, T3);
607 B3.m_simd = vec_mergel(T2, T3);
608
609#elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM32)
610 const uint32x4x2_t T0 = vzipq_u32(B0.m_simd, B2.m_simd);
611 const uint32x4x2_t T1 = vzipq_u32(B1.m_simd, B3.m_simd);
612 const uint32x4x2_t O0 = vzipq_u32(T0.val[0], T1.val[0]);
613 const uint32x4x2_t O1 = vzipq_u32(T0.val[1], T1.val[1]);
614
615 B0.m_simd = O0.val[0];
616 B1.m_simd = O0.val[1];
617 B2.m_simd = O1.val[0];
618 B3.m_simd = O1.val[1];
619
620#elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM64)
621 const uint32x4_t T0 = vzip1q_u32(B0.m_simd, B2.m_simd);
622 const uint32x4_t T2 = vzip2q_u32(B0.m_simd, B2.m_simd);
623 const uint32x4_t T1 = vzip1q_u32(B1.m_simd, B3.m_simd);
624 const uint32x4_t T3 = vzip2q_u32(B1.m_simd, B3.m_simd);
625
626 B0.m_simd = vzip1q_u32(T0, T1);
627 B1.m_simd = vzip2q_u32(T0, T1);
628 B2.m_simd = vzip1q_u32(T2, T3);
629 B3.m_simd = vzip2q_u32(T2, T3);
630#endif
631 }

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