Botan 3.6.1
Crypto and TLS for C&
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 (std::span< uint8_t, 16 > out) const
 
void store_be (uint32_t out[4]) const noexcept
 
void store_be (uint8_t out[]) const noexcept
 
void store_le (std::span< uint8_t, 16 > out) const
 
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_be (std::span< const uint8_t, 16 > in)
 
static SIMD_4x32 load_le (const void *in) noexcept
 
static SIMD_4x32 load_le (std::span< const uint8_t, 16 > in)
 
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 76 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 89 of file simd_32.h.

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

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

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

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

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

◆ SIMD_4x32() [6/6]

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

Definition at line 616 of file simd_32.h.

616: m_simd(x) {}

Member Function Documentation

◆ andc()

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

Definition at line 467 of file simd_32.h.

467 {
468#if defined(BOTAN_SIMD_USE_SSE2)
469 return SIMD_4x32(_mm_andnot_si128(m_simd, other.m_simd));
470#elif defined(BOTAN_SIMD_USE_ALTIVEC)
471 /*
472 AltiVec does arg1 & ~arg2 rather than SSE's ~arg1 & arg2
473 so swap the arguments
474 */
475 return SIMD_4x32(vec_andc(other.m_simd, m_simd));
476#elif defined(BOTAN_SIMD_USE_NEON)
477 // NEON is also a & ~b
478 return SIMD_4x32(vbicq_u32(other.m_simd, m_simd));
479#endif
480 }
SIMD_4x32() noexcept
Definition simd_32.h:89

References SIMD_4x32().

◆ bswap()

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

Return copy *this with each word byte swapped

Definition at line 485 of file simd_32.h.

485 {
486#if defined(BOTAN_SIMD_USE_SSE2)
487
488 __m128i T = m_simd;
489 T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
490 T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
491 return SIMD_4x32(_mm_or_si128(_mm_srli_epi16(T, 8), _mm_slli_epi16(T, 8)));
492
493#elif defined(BOTAN_SIMD_USE_ALTIVEC)
494 #ifdef BOTAN_SIMD_USE_VSX
495 return SIMD_4x32(vec_revb(m_simd));
496 #else
497 const __vector unsigned char rev[1] = {
498 {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12},
499 };
500
501 return SIMD_4x32(vec_perm(m_simd, m_simd, rev[0]));
502 #endif
503
504#elif defined(BOTAN_SIMD_USE_NEON)
505 return SIMD_4x32(vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(m_simd))));
506#endif
507 }
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 600 of file simd_32.h.

600 {
601#if defined(BOTAN_SIMD_USE_ALTIVEC)
602 return SIMD_4x32(vec_sel(b.raw(), a.raw(), mask.raw()));
603#elif defined(BOTAN_SIMD_USE_NEON)
604 return SIMD_4x32(vbslq_u32(mask.raw(), a.raw(), b.raw()));
605#else
606 return (mask & a) ^ mask.andc(b);
607#endif
608 }
const SIMD_8x32 & b

References Botan::b, and SIMD_4x32().

Referenced by majority().

◆ load_be() [1/2]

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

Load a SIMD register with big-endian convention

Definition at line 175 of file simd_32.h.

175 {
176#if defined(BOTAN_SIMD_USE_SSE2)
177 return load_le(in).bswap();
178
179#elif defined(BOTAN_SIMD_USE_ALTIVEC)
180 uint32_t R[4];
181 Botan::load_be(R, static_cast<const uint8_t*>(in), 4);
182 return SIMD_4x32(R);
183
184#elif defined(BOTAN_SIMD_USE_NEON)
185 SIMD_4x32 l(vld1q_u32(static_cast<const uint32_t*>(in)));
186 return CPUID::is_little_endian() ? l.bswap() : l;
187#endif
188 }
static bool is_little_endian()
Definition cpuid.h:60
SIMD_4x32 bswap() const noexcept
Definition simd_32.h:485
static SIMD_4x32 load_le(const void *in) noexcept
Definition simd_32.h:159
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:530

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

Referenced by load_be().

◆ load_be() [2/2]

static SIMD_4x32 Botan::SIMD_4x32::load_be ( std::span< const uint8_t, 16 > in)
inlinestatic

Definition at line 192 of file simd_32.h.

192{ return SIMD_4x32::load_be(in.data()); }
static SIMD_4x32 load_be(const void *in) noexcept
Definition simd_32.h:175

References load_be().

◆ load_le() [1/2]

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

Load a SIMD register with little-endian convention

Definition at line 159 of file simd_32.h.

159 {
160#if defined(BOTAN_SIMD_USE_SSE2)
161 return SIMD_4x32(_mm_loadu_si128(reinterpret_cast<const __m128i*>(in)));
162#elif defined(BOTAN_SIMD_USE_ALTIVEC)
163 uint32_t R[4];
164 Botan::load_le(R, static_cast<const uint8_t*>(in), 4);
165 return SIMD_4x32(R);
166#elif defined(BOTAN_SIMD_USE_NEON)
167 SIMD_4x32 l(vld1q_u32(static_cast<const uint32_t*>(in)));
168 return CPUID::is_big_endian() ? l.bswap() : l;
169#endif
170 }
static bool is_big_endian()
Definition cpuid.h:70
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:521

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

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

◆ load_le() [2/2]

static SIMD_4x32 Botan::SIMD_4x32::load_le ( std::span< const uint8_t, 16 > in)
inlinestatic

Definition at line 190 of file simd_32.h.

190{ return SIMD_4x32::load_le(in.data()); }

References load_le().

◆ majority()

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

Definition at line 610 of file simd_32.h.

610 {
611 return SIMD_4x32::choose(x ^ y, z, y);
612 }
static SIMD_4x32 choose(const SIMD_4x32 &mask, const SIMD_4x32 &a, const SIMD_4x32 &b) noexcept
Definition simd_32.h:600

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 368 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)
inlinenoexcept

Definition at line 416 of file simd_32.h.

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

◆ operator+()

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

Add elements of a SIMD vector

Definition at line 332 of file simd_32.h.

332 {
333 SIMD_4x32 retval(*this);
334 retval += other;
335 return retval;
336 }

◆ operator+=()

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

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

◆ operator-()

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

Subtract elements of a SIMD vector

Definition at line 341 of file simd_32.h.

341 {
342 SIMD_4x32 retval(*this);
343 retval -= other;
344 return retval;
345 }

◆ operator-=()

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

Definition at line 384 of file simd_32.h.

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

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

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

◆ operator^=() [1/2]

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

Definition at line 394 of file simd_32.h.

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

◆ operator^=() [2/2]

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

Definition at line 404 of file simd_32.h.

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

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

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

◆ operator|=()

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

Definition at line 406 of file simd_32.h.

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

◆ operator~()

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

Definition at line 456 of file simd_32.h.

456 {
457#if defined(BOTAN_SIMD_USE_SSE2)
458 return SIMD_4x32(_mm_xor_si128(m_simd, _mm_set1_epi32(0xFFFFFFFF)));
459#elif defined(BOTAN_SIMD_USE_ALTIVEC)
460 return SIMD_4x32(vec_nor(m_simd, m_simd));
461#elif defined(BOTAN_SIMD_USE_NEON)
462 return SIMD_4x32(vmvnq_u32(m_simd));
463#endif
464 }

References SIMD_4x32().

◆ raw()

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

Definition at line 614 of file simd_32.h.

614{ 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 290 of file simd_32.h.

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

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

325 {
326 return this->rotl<32 - ROT>();
327 }
SIMD_4x32 rotl() const noexcept
Definition simd_32.h:290

References rotl().

Referenced by Botan::rotr(), sigma0(), and sigma1().

◆ shift_elems_left()

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

Definition at line 510 of file simd_32.h.

512 {
513#if defined(BOTAN_SIMD_USE_SSE2)
514 return SIMD_4x32(_mm_slli_si128(raw(), 4 * I));
515#elif defined(BOTAN_SIMD_USE_NEON)
516 return SIMD_4x32(vextq_u32(vdupq_n_u32(0), raw(), 4 - I));
517#elif defined(BOTAN_SIMD_USE_ALTIVEC)
518 const __vector unsigned int zero = vec_splat_u32(0);
519
520 const __vector unsigned char shuf[3] = {
521 {16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
522 {16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7},
523 {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 1, 2, 3},
524 };
525
526 return SIMD_4x32(vec_perm(raw(), zero, shuf[I - 1]));
527#endif
528 }
native_simd_type raw() const noexcept
Definition simd_32.h:614

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

533 {
534#if defined(BOTAN_SIMD_USE_SSE2)
535 return SIMD_4x32(_mm_srli_si128(raw(), 4 * I));
536#elif defined(BOTAN_SIMD_USE_NEON)
537 return SIMD_4x32(vextq_u32(raw(), vdupq_n_u32(0), I));
538#elif defined(BOTAN_SIMD_USE_ALTIVEC)
539 const __vector unsigned int zero = vec_splat_u32(0);
540
541 const __vector unsigned char shuf[3] = {
542 {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
543 {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
544 {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27},
545 };
546
547 return SIMD_4x32(vec_perm(raw(), zero, shuf[I - 1]));
548#endif
549 }

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

429 {
430#if defined(BOTAN_SIMD_USE_SSE2)
431 return SIMD_4x32(_mm_slli_epi32(m_simd, SHIFT));
432
433#elif defined(BOTAN_SIMD_USE_ALTIVEC)
434 const unsigned int s = static_cast<unsigned int>(SHIFT);
435 const __vector unsigned int shifts = {s, s, s, s};
436 return SIMD_4x32(vec_sl(m_simd, shifts));
437#elif defined(BOTAN_SIMD_USE_NEON)
438 return SIMD_4x32(vshlq_n_u32(m_simd, SHIFT));
439#endif
440 }

References SIMD_4x32().

Referenced by Botan::shl().

◆ shr()

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

Definition at line 443 of file simd_32.h.

443 {
444#if defined(BOTAN_SIMD_USE_SSE2)
445 return SIMD_4x32(_mm_srli_epi32(m_simd, SHIFT));
446
447#elif defined(BOTAN_SIMD_USE_ALTIVEC)
448 const unsigned int s = static_cast<unsigned int>(SHIFT);
449 const __vector unsigned int shifts = {s, s, s, s};
450 return SIMD_4x32(vec_sr(m_simd, shifts));
451#elif defined(BOTAN_SIMD_USE_NEON)
452 return SIMD_4x32(vshrq_n_u32(m_simd, SHIFT));
453#endif
454 }

References SIMD_4x32().

◆ sigma0()

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

Definition at line 261 of file simd_32.h.

261 {
262#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_crypto_vshasigmaw) && defined(_ARCH_PWR8)
263 return SIMD_4x32(__builtin_crypto_vshasigmaw(raw(), 1, 0));
264#else
265 const SIMD_4x32 rot1 = this->rotr<2>();
266 const SIMD_4x32 rot2 = this->rotr<13>();
267 const SIMD_4x32 rot3 = this->rotr<22>();
268 return (rot1 ^ rot2 ^ rot3);
269#endif
270 }
SIMD_4x32 rotr() const noexcept
Definition simd_32.h:325

References raw(), rotr(), and SIMD_4x32().

◆ sigma1()

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

Definition at line 275 of file simd_32.h.

275 {
276#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_crypto_vshasigmaw) && defined(_ARCH_PWR8)
277 return SIMD_4x32(__builtin_crypto_vshasigmaw(raw(), 1, 0xF));
278#else
279 const SIMD_4x32 rot1 = this->rotr<6>();
280 const SIMD_4x32 rot2 = this->rotr<11>();
281 const SIMD_4x32 rot3 = this->rotr<25>();
282 return (rot1 ^ rot2 ^ rot3);
283#endif
284 }

References raw(), rotr(), 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 132 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)
inlinestaticnoexcept

Load SIMD register with one 8-bit element repeated

Definition at line 145 of file simd_32.h.

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

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

Referenced by Botan::BOTAN_FUNC_ISA().

◆ store_be() [1/3]

void Botan::SIMD_4x32::store_be ( std::span< uint8_t, 16 > out) const
inline

Definition at line 254 of file simd_32.h.

254{ this->store_be(out.data()); }
void store_be(uint32_t out[4]) const noexcept
Definition simd_32.h:196

References store_be().

Referenced by store_be().

◆ store_be() [2/3]

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

Definition at line 196 of file simd_32.h.

196{ this->store_be(reinterpret_cast<uint8_t*>(out)); }

References store_be().

Referenced by store_be().

◆ store_be() [3/3]

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

Load a SIMD register with big-endian convention

Definition at line 230 of file simd_32.h.

230 {
231#if defined(BOTAN_SIMD_USE_SSE2)
232
233 bswap().store_le(out);
234
235#elif defined(BOTAN_SIMD_USE_ALTIVEC)
236
237 union {
238 __vector unsigned int V;
239 uint32_t R[4];
240 } vec;
241
242 vec.V = m_simd;
243 Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
244
245#elif defined(BOTAN_SIMD_USE_NEON)
247 vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
248 } else {
249 vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
250 }
251#endif
252 }
void store_le(uint32_t out[4]) const noexcept
Definition simd_32.h:194
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:773

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

◆ store_le() [1/4]

void Botan::SIMD_4x32::store_le ( std::span< uint8_t, 16 > out) const
inline

Definition at line 256 of file simd_32.h.

256{ this->store_le(out.data()); }

References store_le().

Referenced by store_le().

◆ store_le() [2/4]

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

Definition at line 194 of file simd_32.h.

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

References store_le().

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

◆ store_le() [3/4]

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

Definition at line 198 of file simd_32.h.

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

References store_le().

Referenced by store_le().

◆ store_le() [4/4]

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

Load a SIMD register with little-endian convention

Definition at line 203 of file simd_32.h.

203 {
204#if defined(BOTAN_SIMD_USE_SSE2)
205
206 _mm_storeu_si128(reinterpret_cast<__m128i*>(out), raw());
207
208#elif defined(BOTAN_SIMD_USE_ALTIVEC)
209
210 union {
211 __vector unsigned int V;
212 uint32_t R[4];
213 } vec;
214
215 vec.V = raw();
216 Botan::store_le(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
217
218#elif defined(BOTAN_SIMD_USE_NEON)
220 vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
221 } else {
222 vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
223 }
224#endif
225 }
constexpr auto store_le(ParamTs &&... params)
Definition loadstor.h:764

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

554 {
555#if defined(BOTAN_SIMD_USE_SSE2)
556 const __m128i T0 = _mm_unpacklo_epi32(B0.m_simd, B1.m_simd);
557 const __m128i T1 = _mm_unpacklo_epi32(B2.m_simd, B3.m_simd);
558 const __m128i T2 = _mm_unpackhi_epi32(B0.m_simd, B1.m_simd);
559 const __m128i T3 = _mm_unpackhi_epi32(B2.m_simd, B3.m_simd);
560
561 B0.m_simd = _mm_unpacklo_epi64(T0, T1);
562 B1.m_simd = _mm_unpackhi_epi64(T0, T1);
563 B2.m_simd = _mm_unpacklo_epi64(T2, T3);
564 B3.m_simd = _mm_unpackhi_epi64(T2, T3);
565#elif defined(BOTAN_SIMD_USE_ALTIVEC)
566 const __vector unsigned int T0 = vec_mergeh(B0.m_simd, B2.m_simd);
567 const __vector unsigned int T1 = vec_mergeh(B1.m_simd, B3.m_simd);
568 const __vector unsigned int T2 = vec_mergel(B0.m_simd, B2.m_simd);
569 const __vector unsigned int T3 = vec_mergel(B1.m_simd, B3.m_simd);
570
571 B0.m_simd = vec_mergeh(T0, T1);
572 B1.m_simd = vec_mergel(T0, T1);
573 B2.m_simd = vec_mergeh(T2, T3);
574 B3.m_simd = vec_mergel(T2, T3);
575
576#elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM32)
577 const uint32x4x2_t T0 = vzipq_u32(B0.m_simd, B2.m_simd);
578 const uint32x4x2_t T1 = vzipq_u32(B1.m_simd, B3.m_simd);
579 const uint32x4x2_t O0 = vzipq_u32(T0.val[0], T1.val[0]);
580 const uint32x4x2_t O1 = vzipq_u32(T0.val[1], T1.val[1]);
581
582 B0.m_simd = O0.val[0];
583 B1.m_simd = O0.val[1];
584 B2.m_simd = O1.val[0];
585 B3.m_simd = O1.val[1];
586
587#elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM64)
588 const uint32x4_t T0 = vzip1q_u32(B0.m_simd, B2.m_simd);
589 const uint32x4_t T2 = vzip2q_u32(B0.m_simd, B2.m_simd);
590 const uint32x4_t T1 = vzip1q_u32(B1.m_simd, B3.m_simd);
591 const uint32x4_t T3 = vzip2q_u32(B1.m_simd, B3.m_simd);
592
593 B0.m_simd = vzip1q_u32(T0, T1);
594 B1.m_simd = vzip2q_u32(T0, T1);
595 B2.m_simd = vzip1q_u32(T2, T3);
596 B3.m_simd = vzip2q_u32(T2, T3);
597#endif
598 }

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