Botan 3.2.0
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 noexcept
 
SIMD_4x32 bswap () const noexcept
 
SIMD_4x32 operator& (const SIMD_4x32 &other) const noexcept
 
void operator&= (const SIMD_4x32 &other) noexcept
 
SIMD_4x32 operator+ (const SIMD_4x32 &other) const noexcept
 
void operator+= (const SIMD_4x32 &other) noexcept
 
SIMD_4x32 operator- (const SIMD_4x32 &other) const noexcept
 
void operator-= (const SIMD_4x32 &other) noexcept
 
SIMD_4x32operator= (const SIMD_4x32 &other)=default
 
SIMD_4x32operator= (SIMD_4x32 &&other)=default
 
SIMD_4x32 operator^ (const SIMD_4x32 &other) const noexcept
 
void operator^= (const SIMD_4x32 &other) noexcept
 
void operator^= (uint32_t other) noexcept
 
SIMD_4x32 operator| (const SIMD_4x32 &other) const noexcept
 
void operator|= (const SIMD_4x32 &other) noexcept
 
SIMD_4x32 operator~ () const noexcept
 
native_simd_type raw () const noexcept
 
template<size_t ROT>
requires (ROT > 0 && ROT < 32)
SIMD_4x32 rotl () const noexcept
 
template<size_t ROT>
SIMD_4x32 rotr () const noexcept
 
template<size_t I>
requires (I <= 3)
SIMD_4x32 shift_elems_left () const noexcept
 
template<size_t I>
requires (I <= 3)
SIMD_4x32 shift_elems_right () const noexcept
 
template<int SHIFT>
requires (SHIFT > 0 && SHIFT < 32)
SIMD_4x32 shl () const noexcept
 
template<int SHIFT>
SIMD_4x32 shr () const noexcept
 
SIMD_4x32 sigma0 () const noexcept
 
SIMD_4x32 sigma1 () const noexcept
 
 SIMD_4x32 () noexcept
 
 SIMD_4x32 (const SIMD_4x32 &other)=default
 
 SIMD_4x32 (const uint32_t B[4]) noexcept
 
 SIMD_4x32 (native_simd_type x) noexcept
 
 SIMD_4x32 (SIMD_4x32 &&other)=default
 
 SIMD_4x32 (uint32_t B0, uint32_t B1, uint32_t B2, uint32_t B3) noexcept
 
void store_be (uint32_t out[4]) const noexcept
 
void store_be (uint8_t out[]) const noexcept
 
void store_le (uint32_t out[4]) const noexcept
 
void store_le (uint64_t out[2]) const noexcept
 
void store_le (uint8_t out[]) const noexcept
 
 ~SIMD_4x32 ()=default
 

Static Public Member Functions

static SIMD_4x32 choose (const SIMD_4x32 &mask, const SIMD_4x32 &a, const SIMD_4x32 &b) noexcept
 
static SIMD_4x32 load_be (const void *in) noexcept
 
static SIMD_4x32 load_le (const void *in) noexcept
 
static SIMD_4x32 majority (const SIMD_4x32 &x, const SIMD_4x32 &y, const SIMD_4x32 &z) noexcept
 
static SIMD_4x32 splat (uint32_t B) noexcept
 
static SIMD_4x32 splat_u8 (uint8_t B) noexcept
 
static void transpose (SIMD_4x32 &B0, SIMD_4x32 &B1, SIMD_4x32 &B2, SIMD_4x32 &B3) noexcept
 

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

Botan::SIMD_4x32::~SIMD_4x32 ( )
default

◆ SIMD_4x32() [3/6]

Botan::SIMD_4x32::SIMD_4x32 ( )
inlinenoexcept

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])
inlineexplicitnoexcept

Load SIMD register with 4 32-bit elements

Definition at line 99 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 }

◆ SIMD_4x32() [5/6]

Botan::SIMD_4x32::SIMD_4x32 ( uint32_t  B0,
uint32_t  B1,
uint32_t  B2,
uint32_t  B3 
)
inlinenoexcept

Load SIMD register with 4 32-bit elements

Definition at line 113 of file simd_32.h.

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

◆ SIMD_4x32() [6/6]

Botan::SIMD_4x32::SIMD_4x32 ( native_simd_type  x)
inlineexplicitnoexcept

Definition at line 597 of file simd_32.h.

597: m_simd(x) {}

Member Function Documentation

◆ andc()

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

Definition at line 456 of file simd_32.h.

456 {
457#if defined(BOTAN_SIMD_USE_SSE2)
458 return SIMD_4x32(_mm_andnot_si128(m_simd, other.m_simd));
459#elif defined(BOTAN_SIMD_USE_ALTIVEC)
460 /*
461 AltiVec does arg1 & ~arg2 rather than SSE's ~arg1 & arg2
462 so swap the arguments
463 */
464 return SIMD_4x32(vec_andc(other.m_simd, m_simd));
465#elif defined(BOTAN_SIMD_USE_NEON)
466 // NEON is also a & ~b
467 return SIMD_4x32(vbicq_u32(other.m_simd, m_simd));
468#endif
469 }
SIMD_4x32() noexcept
Definition simd_32.h:85

References SIMD_4x32().

◆ bswap()

SIMD_4x32 Botan::SIMD_4x32::bswap ( ) const
inlinenoexcept

Return copy *this with each word byte swapped

Definition at line 474 of file simd_32.h.

474 {
475#if defined(BOTAN_SIMD_USE_SSE2)
476
477 __m128i T = m_simd;
478 T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
479 T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
480 return SIMD_4x32(_mm_or_si128(_mm_srli_epi16(T, 8), _mm_slli_epi16(T, 8)));
481
482#elif defined(BOTAN_SIMD_USE_ALTIVEC)
483 return SIMD_4x32(vec_revb(m_simd));
484
485#elif defined(BOTAN_SIMD_USE_NEON)
486 return SIMD_4x32(vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(m_simd))));
487#endif
488 }
FE_25519 T
Definition ge.cpp:34

References 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 
)
inlinestaticnoexcept

Definition at line 581 of file simd_32.h.

581 {
582#if defined(BOTAN_SIMD_USE_ALTIVEC)
583 return SIMD_4x32(vec_sel(b.raw(), a.raw(), mask.raw()));
584#elif defined(BOTAN_SIMD_USE_NEON)
585 return SIMD_4x32(vbslq_u32(mask.raw(), a.raw(), b.raw()));
586#else
587 return (mask & a) ^ mask.andc(b);
588#endif
589 }

References SIMD_4x32().

Referenced by majority().

◆ load_be()

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

Load a SIMD register with big-endian convention

Definition at line 172 of file simd_32.h.

172 {
173#if defined(BOTAN_SIMD_USE_SSE2)
174 return load_le(in).bswap();
175
176#elif defined(BOTAN_SIMD_USE_ALTIVEC)
177 uint32_t R[4];
178 Botan::load_be(R, static_cast<const uint8_t*>(in), 4);
179 return SIMD_4x32(R);
180
181#elif defined(BOTAN_SIMD_USE_NEON)
182 SIMD_4x32 l(vld1q_u32(static_cast<const uint32_t*>(in)));
183 return CPUID::is_little_endian() ? l.bswap() : l;
184#endif
185 }
static bool is_little_endian()
Definition cpuid.h:59
SIMD_4x32 bswap() const noexcept
Definition simd_32.h:474
static SIMD_4x32 load_le(const void *in) noexcept
Definition simd_32.h:156
constexpr T load_be(const uint8_t in[], size_t off)
Definition loadstor.h:92

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

Load a SIMD register with little-endian convention

Definition at line 156 of file simd_32.h.

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

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

Referenced by Botan::BOTAN_FUNC_ISA(), Botan::BOTAN_FUNC_ISA(), and load_be().

◆ majority()

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

Definition at line 591 of file simd_32.h.

591 {
592 return SIMD_4x32::choose(x ^ y, z, y);
593 }
static SIMD_4x32 choose(const SIMD_4x32 &mask, const SIMD_4x32 &a, const SIMD_4x32 &b) noexcept
Definition simd_32.h:581

References choose().

◆ operator&()

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

Binary AND elements of a SIMD vector

Definition at line 357 of file simd_32.h.

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

◆ operator&=()

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

Definition at line 405 of file simd_32.h.

405 {
406#if defined(BOTAN_SIMD_USE_SSE2)
407 m_simd = _mm_and_si128(m_simd, other.m_simd);
408#elif defined(BOTAN_SIMD_USE_ALTIVEC)
409 m_simd = vec_and(m_simd, other.m_simd);
410#elif defined(BOTAN_SIMD_USE_NEON)
411 m_simd = vandq_u32(m_simd, other.m_simd);
412#endif
413 }

◆ operator+()

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

Add elements of a SIMD vector

Definition at line 321 of file simd_32.h.

321 {
322 SIMD_4x32 retval(*this);
323 retval += other;
324 return retval;
325 }

◆ operator+=()

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

Definition at line 363 of file simd_32.h.

363 {
364#if defined(BOTAN_SIMD_USE_SSE2)
365 m_simd = _mm_add_epi32(m_simd, other.m_simd);
366#elif defined(BOTAN_SIMD_USE_ALTIVEC)
367 m_simd = vec_add(m_simd, other.m_simd);
368#elif defined(BOTAN_SIMD_USE_NEON)
369 m_simd = vaddq_u32(m_simd, other.m_simd);
370#endif
371 }

◆ operator-()

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

Subtract elements of a SIMD vector

Definition at line 330 of file simd_32.h.

330 {
331 SIMD_4x32 retval(*this);
332 retval -= other;
333 return retval;
334 }

◆ operator-=()

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

Definition at line 373 of file simd_32.h.

373 {
374#if defined(BOTAN_SIMD_USE_SSE2)
375 m_simd = _mm_sub_epi32(m_simd, other.m_simd);
376#elif defined(BOTAN_SIMD_USE_ALTIVEC)
377 m_simd = vec_sub(m_simd, other.m_simd);
378#elif defined(BOTAN_SIMD_USE_NEON)
379 m_simd = vsubq_u32(m_simd, other.m_simd);
380#endif
381 }

◆ 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
inlinenoexcept

XOR elements of a SIMD vector

Definition at line 339 of file simd_32.h.

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

◆ operator^=() [1/2]

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

Definition at line 383 of file simd_32.h.

383 {
384#if defined(BOTAN_SIMD_USE_SSE2)
385 m_simd = _mm_xor_si128(m_simd, other.m_simd);
386#elif defined(BOTAN_SIMD_USE_ALTIVEC)
387 m_simd = vec_xor(m_simd, other.m_simd);
388#elif defined(BOTAN_SIMD_USE_NEON)
389 m_simd = veorq_u32(m_simd, other.m_simd);
390#endif
391 }

◆ operator^=() [2/2]

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

Definition at line 393 of file simd_32.h.

393{ *this ^= SIMD_4x32::splat(other); }
static SIMD_4x32 splat(uint32_t B) noexcept
Definition simd_32.h:129

References splat().

◆ operator|()

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

Binary OR elements of a SIMD vector

Definition at line 348 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)
inlinenoexcept

Definition at line 395 of file simd_32.h.

395 {
396#if defined(BOTAN_SIMD_USE_SSE2)
397 m_simd = _mm_or_si128(m_simd, other.m_simd);
398#elif defined(BOTAN_SIMD_USE_ALTIVEC)
399 m_simd = vec_or(m_simd, other.m_simd);
400#elif defined(BOTAN_SIMD_USE_NEON)
401 m_simd = vorrq_u32(m_simd, other.m_simd);
402#endif
403 }

◆ operator~()

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

Definition at line 445 of file simd_32.h.

445 {
446#if defined(BOTAN_SIMD_USE_SSE2)
447 return SIMD_4x32(_mm_xor_si128(m_simd, _mm_set1_epi32(0xFFFFFFFF)));
448#elif defined(BOTAN_SIMD_USE_ALTIVEC)
449 return SIMD_4x32(vec_nor(m_simd, m_simd));
450#elif defined(BOTAN_SIMD_USE_NEON)
451 return SIMD_4x32(vmvnq_u32(m_simd));
452#endif
453 }

References SIMD_4x32().

◆ raw()

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

Definition at line 595 of file simd_32.h.

595{ return m_simd; }

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

◆ rotl()

template<size_t ROT>
requires (ROT > 0 && ROT < 32)
SIMD_4x32 Botan::SIMD_4x32::rotl ( ) const
inlinenoexcept

Left rotation by a compile time constant

Definition at line 279 of file simd_32.h.

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

References SIMD_4x32().

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

◆ rotr()

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

Right rotation by a compile time constant

Definition at line 314 of file simd_32.h.

314 {
315 return this->rotl<32 - ROT>();
316 }
SIMD_4x32 rotl() const noexcept
Definition simd_32.h:279

References rotl().

Referenced by Botan::rotr().

◆ shift_elems_left()

template<size_t I>
requires (I <= 3)
SIMD_4x32 Botan::SIMD_4x32::shift_elems_left ( ) const
inlinenoexcept

Definition at line 491 of file simd_32.h.

493 {
494#if defined(BOTAN_SIMD_USE_SSE2)
495 return SIMD_4x32(_mm_slli_si128(raw(), 4 * I));
496#elif defined(BOTAN_SIMD_USE_NEON)
497 return SIMD_4x32(vextq_u32(vdupq_n_u32(0), raw(), 4 - I));
498#elif defined(BOTAN_SIMD_USE_ALTIVEC)
499 const __vector unsigned int zero = vec_splat_u32(0);
500
501 const __vector unsigned char shuf[3] = {
502 {16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
503 {16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7},
504 {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 1, 2, 3},
505 };
506
507 return SIMD_4x32(vec_perm(raw(), zero, shuf[I - 1]));
508#endif
509 }
native_simd_type raw() const noexcept
Definition simd_32.h:595

References raw(), and SIMD_4x32().

◆ shift_elems_right()

template<size_t I>
requires (I <= 3)
SIMD_4x32 Botan::SIMD_4x32::shift_elems_right ( ) const
inlinenoexcept

Definition at line 512 of file simd_32.h.

514 {
515#if defined(BOTAN_SIMD_USE_SSE2)
516 return SIMD_4x32(_mm_srli_si128(raw(), 4 * I));
517#elif defined(BOTAN_SIMD_USE_NEON)
518 return SIMD_4x32(vextq_u32(raw(), vdupq_n_u32(0), I));
519#elif defined(BOTAN_SIMD_USE_ALTIVEC)
520 const __vector unsigned int zero = vec_splat_u32(0);
521
522 const __vector unsigned char shuf[3] = {
523 {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
524 {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
525 {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27},
526 };
527
528 return SIMD_4x32(vec_perm(raw(), zero, shuf[I - 1]));
529#endif
530 }

References raw(), and SIMD_4x32().

◆ shl()

template<int SHIFT>
requires (SHIFT > 0 && SHIFT < 32)
SIMD_4x32 Botan::SIMD_4x32::shl ( ) const
inlinenoexcept

Definition at line 416 of file simd_32.h.

418 {
419#if defined(BOTAN_SIMD_USE_SSE2)
420 return SIMD_4x32(_mm_slli_epi32(m_simd, SHIFT));
421
422#elif defined(BOTAN_SIMD_USE_ALTIVEC)
423 const unsigned int s = static_cast<unsigned int>(SHIFT);
424 const __vector unsigned int shifts = {s, s, s, s};
425 return SIMD_4x32(vec_sl(m_simd, shifts));
426#elif defined(BOTAN_SIMD_USE_NEON)
427 return SIMD_4x32(vshlq_n_u32(m_simd, SHIFT));
428#endif
429 }

References SIMD_4x32().

Referenced by Botan::shl().

◆ shr()

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

Definition at line 432 of file simd_32.h.

432 {
433#if defined(BOTAN_SIMD_USE_SSE2)
434 return SIMD_4x32(_mm_srli_epi32(m_simd, SHIFT));
435
436#elif defined(BOTAN_SIMD_USE_ALTIVEC)
437 const unsigned int s = static_cast<unsigned int>(SHIFT);
438 const __vector unsigned int shifts = {s, s, s, s};
439 return SIMD_4x32(vec_sr(m_simd, shifts));
440#elif defined(BOTAN_SIMD_USE_NEON)
441 return SIMD_4x32(vshrq_n_u32(m_simd, SHIFT));
442#endif
443 }

References SIMD_4x32().

◆ sigma0()

SIMD_4x32 Botan::SIMD_4x32::sigma0 ( ) const
inlinenoexcept

Definition at line 250 of file simd_32.h.

250 {
251#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_crypto_vshasigmaw) && defined(_ARCH_PWR8)
252 return SIMD_4x32(__builtin_crypto_vshasigmaw(raw(), 1, 0));
253#else
254 const SIMD_4x32 rot1 = this->rotr<2>();
255 const SIMD_4x32 rot2 = this->rotr<13>();
256 const SIMD_4x32 rot3 = this->rotr<22>();
257 return (rot1 ^ rot2 ^ rot3);
258#endif
259 }

References raw(), and SIMD_4x32().

◆ sigma1()

SIMD_4x32 Botan::SIMD_4x32::sigma1 ( ) const
inlinenoexcept

Definition at line 264 of file simd_32.h.

264 {
265#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_crypto_vshasigmaw) && defined(_ARCH_PWR8)
266 return SIMD_4x32(__builtin_crypto_vshasigmaw(raw(), 1, 0xF));
267#else
268 const SIMD_4x32 rot1 = this->rotr<6>();
269 const SIMD_4x32 rot2 = this->rotr<11>();
270 const SIMD_4x32 rot3 = this->rotr<25>();
271 return (rot1 ^ rot2 ^ rot3);
272#endif
273 }

References raw(), and SIMD_4x32().

◆ splat()

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

Load SIMD register with one 32-bit element repeated

Definition at line 129 of file simd_32.h.

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

References SIMD_4x32().

Referenced by operator^=().

◆ splat_u8()

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

Load SIMD register with one 8-bit element repeated

Definition at line 142 of file simd_32.h.

142 {
143#if defined(BOTAN_SIMD_USE_SSE2)
144 return SIMD_4x32(_mm_set1_epi8(B));
145#elif defined(BOTAN_SIMD_USE_NEON)
146 return SIMD_4x32(vreinterpretq_u32_u8(vdupq_n_u8(B)));
147#else
148 const uint32_t B4 = make_uint32(B, B, B, B);
149 return SIMD_4x32(B4, B4, B4, B4);
150#endif
151 }
constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
Definition loadstor.h:61

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

Referenced by Botan::BOTAN_FUNC_ISA().

◆ store_be() [1/2]

void Botan::SIMD_4x32::store_be ( uint32_t  out[4]) const
inlinenoexcept

Definition at line 189 of file simd_32.h.

189{ this->store_be(reinterpret_cast<uint8_t*>(out)); }
void store_be(uint32_t out[4]) const noexcept
Definition simd_32.h:189

References store_be().

Referenced by store_be().

◆ store_be() [2/2]

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

Load a SIMD register with big-endian convention

Definition at line 223 of file simd_32.h.

223 {
224#if defined(BOTAN_SIMD_USE_SSE2)
225
226 bswap().store_le(out);
227
228#elif defined(BOTAN_SIMD_USE_ALTIVEC)
229
230 union {
231 __vector unsigned int V;
232 uint32_t R[4];
233 } vec;
234
235 vec.V = m_simd;
236 Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
237
238#elif defined(BOTAN_SIMD_USE_NEON)
240 vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
241 } else {
242 vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
243 }
244#endif
245 }
void store_le(uint32_t out[4]) const noexcept
Definition simd_32.h:187
constexpr void store_be(uint16_t in, uint8_t out[2])
Definition loadstor.h:389

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
inlinenoexcept

Definition at line 187 of file simd_32.h.

187{ this->store_le(reinterpret_cast<uint8_t*>(out)); }

References store_le().

Referenced by Botan::BOTAN_FUNC_ISA(), store_be(), and store_le().

◆ store_le() [2/3]

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

Definition at line 191 of file simd_32.h.

191{ this->store_le(reinterpret_cast<uint8_t*>(out)); }

References store_le().

Referenced by store_le().

◆ store_le() [3/3]

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

Load a SIMD register with little-endian convention

Definition at line 196 of file simd_32.h.

196 {
197#if defined(BOTAN_SIMD_USE_SSE2)
198
199 _mm_storeu_si128(reinterpret_cast<__m128i*>(out), raw());
200
201#elif defined(BOTAN_SIMD_USE_ALTIVEC)
202
203 union {
204 __vector unsigned int V;
205 uint32_t R[4];
206 } vec;
207
208 vec.V = raw();
209 Botan::store_le(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
210
211#elif defined(BOTAN_SIMD_USE_NEON)
213 vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
214 } else {
215 vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
216 }
217#endif
218 }
constexpr void store_le(uint16_t in, uint8_t out[2])
Definition loadstor.h:405

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

4x4 Transposition on SIMD registers

Definition at line 535 of file simd_32.h.

535 {
536#if defined(BOTAN_SIMD_USE_SSE2)
537 const __m128i T0 = _mm_unpacklo_epi32(B0.m_simd, B1.m_simd);
538 const __m128i T1 = _mm_unpacklo_epi32(B2.m_simd, B3.m_simd);
539 const __m128i T2 = _mm_unpackhi_epi32(B0.m_simd, B1.m_simd);
540 const __m128i T3 = _mm_unpackhi_epi32(B2.m_simd, B3.m_simd);
541
542 B0.m_simd = _mm_unpacklo_epi64(T0, T1);
543 B1.m_simd = _mm_unpackhi_epi64(T0, T1);
544 B2.m_simd = _mm_unpacklo_epi64(T2, T3);
545 B3.m_simd = _mm_unpackhi_epi64(T2, T3);
546#elif defined(BOTAN_SIMD_USE_ALTIVEC)
547 const __vector unsigned int T0 = vec_mergeh(B0.m_simd, B2.m_simd);
548 const __vector unsigned int T1 = vec_mergeh(B1.m_simd, B3.m_simd);
549 const __vector unsigned int T2 = vec_mergel(B0.m_simd, B2.m_simd);
550 const __vector unsigned int T3 = vec_mergel(B1.m_simd, B3.m_simd);
551
552 B0.m_simd = vec_mergeh(T0, T1);
553 B1.m_simd = vec_mergel(T0, T1);
554 B2.m_simd = vec_mergeh(T2, T3);
555 B3.m_simd = vec_mergel(T2, T3);
556
557#elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM32)
558 const uint32x4x2_t T0 = vzipq_u32(B0.m_simd, B2.m_simd);
559 const uint32x4x2_t T1 = vzipq_u32(B1.m_simd, B3.m_simd);
560 const uint32x4x2_t O0 = vzipq_u32(T0.val[0], T1.val[0]);
561 const uint32x4x2_t O1 = vzipq_u32(T0.val[1], T1.val[1]);
562
563 B0.m_simd = O0.val[0];
564 B1.m_simd = O0.val[1];
565 B2.m_simd = O1.val[0];
566 B3.m_simd = O1.val[1];
567
568#elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM64)
569 const uint32x4_t T0 = vzip1q_u32(B0.m_simd, B2.m_simd);
570 const uint32x4_t T2 = vzip2q_u32(B0.m_simd, B2.m_simd);
571 const uint32x4_t T1 = vzip1q_u32(B1.m_simd, B3.m_simd);
572 const uint32x4_t T3 = vzip2q_u32(B1.m_simd, B3.m_simd);
573
574 B0.m_simd = vzip1q_u32(T0, T1);
575 B1.m_simd = vzip2q_u32(T0, T1);
576 B2.m_simd = vzip1q_u32(T2, T3);
577 B3.m_simd = vzip2q_u32(T2, T3);
578#endif
579 }

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