Botan  2.15.0
Crypto and TLS for C++11
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)
 
SIMD_4x32 operator| (const SIMD_4x32 &other) const
 
void operator|= (const SIMD_4x32 &other)
 
SIMD_4x32 operator~ () const
 
native_simd_type raw () const BOTAN_FUNC_ISA(BOTAN_SIMD_ISA)
 
template<size_t ROT1, size_t ROT2, size_t ROT3>
SIMD_4x32 rho () const
 
template<size_t ROT>
SIMD_4x32 rotl () const
 
template<size_t ROT>
SIMD_4x32 rotr () const
 
template<size_t I>
SIMD_4x32 shift_elems_left () const
 
template<size_t I>
SIMD_4x32 shift_elems_right () const
 
template<int SHIFT>
SIMD_4x32 shl () const
 
template<int SHIFT>
SIMD_4x32 shr () const
 
 SIMD_4x32 (const SIMD_4x32 &other)=default
 
 SIMD_4x32 (SIMD_4x32 &&other)=default
 
 SIMD_4x32 ()
 
 SIMD_4x32 (const uint32_t B[4])
 
 SIMD_4x32 (uint32_t B0, uint32_t B1, uint32_t B2, uint32_t B3)
 
 SIMD_4x32 (native_simd_type x)
 
void store_be (uint8_t out[]) const
 
void store_le (uint32_t out[4]) const
 
void store_le (uint64_t out[2]) const
 
void store_le (uint8_t out[]) const
 

Static Public Member Functions

static SIMD_4x32 load_be (const void *in)
 
static SIMD_4x32 load_le (const void *in)
 
static SIMD_4x32 splat (uint32_t B)
 
static SIMD_4x32 splat_u8 (uint8_t B)
 
static void transpose (SIMD_4x32 &B0, SIMD_4x32 &B1, SIMD_4x32 &B2, SIMD_4x32 &B3)
 

Detailed Description

4x32 bit SIMD register

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

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

Definition at line 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.

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

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  }

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

References SIMD_4x32().

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  }

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

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

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

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  }
void bswap_4(T x[4])
Definition: bswap.h:98
fe T
Definition: ge.cpp:37

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

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

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

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

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

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

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

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

References SIMD_4x32().

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  }

◆ raw()

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

Definition at line 612 of file simd_32.h.

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

612 { return m_simd; }

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

References BOTAN_IF_CONSTEXPR, and SIMD_4x32().

Referenced by rotr().

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  }
#define BOTAN_IF_CONSTEXPR
Definition: compiler.h:185

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

References rotl().

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

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

References raw(), and SIMD_4x32().

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  }
native_simd_type raw() const BOTAN_FUNC_ISA(BOTAN_SIMD_ISA)
Definition: simd_32.h:612

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

References raw(), and SIMD_4x32().

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  }
native_simd_type raw() const BOTAN_FUNC_ISA(BOTAN_SIMD_ISA)
Definition: simd_32.h:612

◆ shl()

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

Definition at line 431 of file simd_32.h.

References SIMD_4x32().

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  }

◆ shr()

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

Definition at line 447 of file simd_32.h.

References SIMD_4x32().

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  }

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

References SIMD_4x32().

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  }

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

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

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:67

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

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

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  }
SIMD_4x32 bswap() const
Definition: simd_32.h:492
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:438
static bool is_little_endian()
Definition: cpuid.h:73
void store_le(uint32_t out[4]) const
Definition: simd_32.h:193

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

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

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

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

References store_le().

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

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

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

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  }
SIMD_4x32 bswap() const
Definition: simd_32.h:492
native_simd_type raw() const BOTAN_FUNC_ISA(BOTAN_SIMD_ISA)
Definition: simd_32.h:612
static bool is_little_endian()
Definition: cpuid.h:73
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:454

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