Botan 3.11.0
Crypto and TLS for C&
Botan::SIMD_4x32 Class Referencefinal

#include <simd_4x32.h>

Public Member Functions

SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 andc (const SIMD_4x32 &other) const noexcept
BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32 bswap () const noexcept
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 operator& (const SIMD_4x32 &other) const noexcept
void BOTAN_FN_ISA_SIMD_4X32 operator&= (const SIMD_4x32 &other) noexcept
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 operator+ (const SIMD_4x32 &other) const noexcept
void BOTAN_FN_ISA_SIMD_4X32 operator+= (const SIMD_4x32 &other) noexcept
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 operator- (const SIMD_4x32 &other) const noexcept
void BOTAN_FN_ISA_SIMD_4X32 operator-= (const SIMD_4x32 &other) noexcept
SIMD_4x32operator= (const SIMD_4x32 &other)=default
SIMD_4x32operator= (SIMD_4x32 &&other)=default
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 operator^ (const SIMD_4x32 &other) const noexcept
void BOTAN_FN_ISA_SIMD_4X32 operator^= (const SIMD_4x32 &other) noexcept
void BOTAN_FN_ISA_SIMD_4X32 operator^= (uint32_t other) noexcept
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 operator| (const SIMD_4x32 &other) const noexcept
void BOTAN_FN_ISA_SIMD_4X32 operator|= (const SIMD_4x32 &other) noexcept
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 operator~ () const noexcept
native_simd_type BOTAN_FN_ISA_SIMD_4X32 raw () const noexcept
template<size_t ROT>
requires (ROT > 0 && ROT < 32)
BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32 rotl () const noexcept
template<size_t ROT>
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 rotr () const noexcept
template<size_t I>
requires (I <= 3)
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 shift_elems_left () const noexcept
template<size_t I>
requires (I <= 3)
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 shift_elems_right () const noexcept
template<int SHIFT>
requires (SHIFT > 0 && SHIFT < 32)
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 shl () const noexcept
template<int SHIFT>
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 shr () const noexcept
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 sigma0 () const noexcept
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 sigma1 () const noexcept
BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32 () noexcept
 SIMD_4x32 (const SIMD_4x32 &other)=default
BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32 (native_simd_type x) noexcept
 SIMD_4x32 (SIMD_4x32 &&other)=default
BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32 (uint32_t B0, uint32_t B1, uint32_t B2, uint32_t B3) noexcept
void BOTAN_FN_ISA_SIMD_4X32 store_be (std::span< uint8_t, 16 > out) const
void BOTAN_FN_ISA_SIMD_4X32 store_be (uint32_t out[4]) const noexcept
BOTAN_FN_ISA_SIMD_4X32 void store_be (uint8_t out[]) const noexcept
void BOTAN_FN_ISA_SIMD_4X32 store_le (std::span< uint8_t, 16 > out) const
void BOTAN_FN_ISA_SIMD_4X32 store_le (uint32_t out[4]) const noexcept
void BOTAN_FN_ISA_SIMD_4X32 store_le (uint64_t out[2]) const noexcept
void BOTAN_FN_ISA_SIMD_4X32 store_le (uint8_t out[]) const noexcept
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 swap_halves () const
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 top_bit_mask () const
 ~SIMD_4x32 ()=default

Static Public Member Functions

static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 alignr4 (const SIMD_4x32 &a, const SIMD_4x32 &b)
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 alignr8 (const SIMD_4x32 &a, const SIMD_4x32 &b)
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 byte_shuffle (const SIMD_4x32 &tbl, const SIMD_4x32 &idx)
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 choose (const SIMD_4x32 &mask, const SIMD_4x32 &a, const SIMD_4x32 &b) noexcept
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 load_be (const void *in) noexcept
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 load_be (std::span< const uint8_t, 16 > in)
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 load_le (const void *in) noexcept
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 load_le (std::span< const uint8_t, 16 > in)
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 majority (const SIMD_4x32 &x, const SIMD_4x32 &y, const SIMD_4x32 &z) noexcept
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 masked_byte_shuffle (const SIMD_4x32 &tbl, const SIMD_4x32 &idx)
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 splat (uint32_t B) noexcept
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 splat_u8 (uint8_t B) noexcept
static void BOTAN_FN_ISA_SIMD_4X32 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), ARMv7/Aarch64 NEON, LoongArch LSX and Wasm SIMD128

Definition at line 61 of file simd_4x32.h.

Constructor & Destructor Documentation

◆ SIMD_4x32() [1/5]

◆ SIMD_4x32() [2/5]

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

References SIMD_4x32().

◆ ~SIMD_4x32()

Botan::SIMD_4x32::~SIMD_4x32 ( )
default

◆ SIMD_4x32() [3/5]

BOTAN_FN_ISA_SIMD_4X32 Botan::SIMD_4x32::SIMD_4x32 ( )
inlinenoexcept

Zero initialize SIMD register with 4 32-bit elements

Definition at line 86 of file simd_4x32.h.

86 {
87#if defined(BOTAN_SIMD_USE_SSSE3)
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#elif defined(BOTAN_SIMD_USE_LSX)
94 m_simd = __lsx_vldi(0);
95#elif defined(BOTAN_SIMD_USE_SIMD128)
96 m_simd = wasm_u32x4_const_splat(0);
97#endif
98 }

Referenced by alignr4(), alignr8(), andc(), bswap(), byte_shuffle(), choose(), load_be(), load_le(), masked_byte_shuffle(), operator~(), rotl(), shift_elems_left(), shift_elems_right(), shl(), shr(), sigma0(), sigma1(), splat(), splat_u8(), swap_halves(), and top_bit_mask().

◆ SIMD_4x32() [4/5]

BOTAN_FN_ISA_SIMD_4X32 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 103 of file simd_4x32.h.

103 {
104#if defined(BOTAN_SIMD_USE_SSSE3)
105 m_simd = _mm_set_epi32(B3, B2, B1, B0);
106#elif defined(BOTAN_SIMD_USE_ALTIVEC)
107 __vector unsigned int val = {B0, B1, B2, B3};
108 m_simd = val;
109#elif defined(BOTAN_SIMD_USE_NEON)
110 // Better way to do this?
111 const uint32_t B[4] = {B0, B1, B2, B3};
112 m_simd = vld1q_u32(B);
113#elif defined(BOTAN_SIMD_USE_LSX)
114 // Better way to do this?
115 const uint32_t B[4] = {B0, B1, B2, B3};
116 m_simd = __lsx_vld(B, 0);
117#elif defined(BOTAN_SIMD_USE_SIMD128)
118 m_simd = wasm_u32x4_make(B0, B1, B2, B3);
119#endif
120 }

◆ SIMD_4x32() [5/5]

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

Definition at line 918 of file simd_4x32.h.

918: m_simd(x) {}

Member Function Documentation

◆ alignr4()

SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 Botan::SIMD_4x32::alignr4 ( const SIMD_4x32 & a,
const SIMD_4x32 & b )
inlinestatic

Definition at line 843 of file simd_4x32.h.

843 {
844#if defined(BOTAN_SIMD_USE_SSSE3)
845 return SIMD_4x32(_mm_alignr_epi8(a.raw(), b.raw(), 4));
846#elif defined(BOTAN_SIMD_USE_NEON)
847 return SIMD_4x32(vextq_u32(b.raw(), a.raw(), 1));
848#elif defined(BOTAN_SIMD_USE_ALTIVEC)
849 const __vector unsigned char mask = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
850 return SIMD_4x32(vec_perm(b.raw(), a.raw(), mask));
851#elif defined(BOTAN_SIMD_USE_LSX)
852 const auto mask = SIMD_4x32(0x07060504, 0x0B0A0908, 0x0F0E0D0C, 0x13121110);
853 return SIMD_4x32(__lsx_vshuf_b(a.raw(), b.raw(), mask.raw()));
854#elif defined(BOTAN_SIMD_USE_SIMD128)
855 return SIMD_4x32(
856 wasm_i8x16_shuffle(b.raw(), a.raw(), 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19));
857#endif
858 }
BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32() noexcept
Definition simd_4x32.h:86

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

◆ alignr8()

SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 Botan::SIMD_4x32::alignr8 ( const SIMD_4x32 & a,
const SIMD_4x32 & b )
inlinestatic

Definition at line 860 of file simd_4x32.h.

860 {
861#if defined(BOTAN_SIMD_USE_SSSE3)
862 return SIMD_4x32(_mm_alignr_epi8(a.raw(), b.raw(), 8));
863#elif defined(BOTAN_SIMD_USE_NEON)
864 return SIMD_4x32(vextq_u32(b.raw(), a.raw(), 2));
865#elif defined(BOTAN_SIMD_USE_ALTIVEC)
866 const __vector unsigned char mask = {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
867 return SIMD_4x32(vec_perm(b.raw(), a.raw(), mask));
868#elif defined(BOTAN_SIMD_USE_LSX)
869 return SIMD_4x32(__lsx_vshuf4i_d(a.raw(), b.raw(), 0b0011));
870#elif defined(BOTAN_SIMD_USE_SIMD128)
871 return SIMD_4x32(
872 wasm_i8x16_shuffle(b.raw(), a.raw(), 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23));
873#endif
874 }

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

Referenced by swap_halves().

◆ andc()

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

Definition at line 552 of file simd_4x32.h.

552 {
553#if defined(BOTAN_SIMD_USE_SSSE3)
554 return SIMD_4x32(_mm_andnot_si128(m_simd, other.m_simd));
555#elif defined(BOTAN_SIMD_USE_ALTIVEC)
556 /*
557 AltiVec does arg1 & ~arg2 rather than SSE's ~arg1 & arg2
558 so swap the arguments
559 */
560 return SIMD_4x32(vec_andc(other.m_simd, m_simd));
561#elif defined(BOTAN_SIMD_USE_NEON)
562 // NEON is also a & ~b
563 return SIMD_4x32(vbicq_u32(other.m_simd, m_simd));
564#elif defined(BOTAN_SIMD_USE_LSX)
565 // LSX is ~a & b
566 return SIMD_4x32(__lsx_vandn_v(m_simd, other.m_simd));
567#elif defined(BOTAN_SIMD_USE_SIMD128)
568 // SIMD128 is a & ~b
569 return SIMD_4x32(wasm_v128_andnot(other.m_simd, m_simd));
570#endif
571 }

References SIMD_4x32(), and SIMD_4x32().

Referenced by Botan::clmul().

◆ bswap()

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

Return copy *this with each word byte swapped

Definition at line 576 of file simd_4x32.h.

576 {
577#if defined(BOTAN_SIMD_USE_SSSE3)
578 const auto idx = _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
579
580 return SIMD_4x32(_mm_shuffle_epi8(raw(), idx));
581#elif defined(BOTAN_SIMD_USE_ALTIVEC)
582 #ifdef BOTAN_SIMD_USE_VSX
583 return SIMD_4x32(vec_revb(m_simd));
584 #else
585 const __vector unsigned char rev[1] = {
586 {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12},
587 };
588
589 return SIMD_4x32(vec_perm(m_simd, m_simd, rev[0]));
590 #endif
591
592#elif defined(BOTAN_SIMD_USE_NEON)
593 return SIMD_4x32(vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(m_simd))));
594#elif defined(BOTAN_SIMD_USE_LSX)
595 return SIMD_4x32(__lsx_vshuf4i_b(m_simd, 0b00011011));
596#elif defined(BOTAN_SIMD_USE_SIMD128)
597 return SIMD_4x32(wasm_i8x16_shuffle(m_simd, m_simd, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12));
598#endif
599 }
native_simd_type BOTAN_FN_ISA_SIMD_4X32 raw() const noexcept
Definition simd_4x32.h:916

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

Referenced by Botan::clmul(), load_be(), load_le(), store_be(), and store_le().

◆ byte_shuffle()

SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 Botan::SIMD_4x32::byte_shuffle ( const SIMD_4x32 & tbl,
const SIMD_4x32 & idx )
inlinestatic

Byte shuffle

This function assumes that each byte of idx is <= 16; it may produce incorrect results if this does not hold.

Definition at line 777 of file simd_4x32.h.

777 {
778#if defined(BOTAN_SIMD_USE_SSSE3)
779 return SIMD_4x32(_mm_shuffle_epi8(tbl.raw(), idx.raw()));
780#elif defined(BOTAN_SIMD_USE_NEON)
781 const uint8x16_t tbl8 = vreinterpretq_u8_u32(tbl.raw());
782 const uint8x16_t idx8 = vreinterpretq_u8_u32(idx.raw());
783
784 #if defined(BOTAN_TARGET_ARCH_IS_ARM32)
785 const uint8x8x2_t tbl2 = {vget_low_u8(tbl8), vget_high_u8(tbl8)};
786
787 return SIMD_4x32(
788 vreinterpretq_u32_u8(vcombine_u8(vtbl2_u8(tbl2, vget_low_u8(idx8)), vtbl2_u8(tbl2, vget_high_u8(idx8)))));
789 #else
790 return SIMD_4x32(vreinterpretq_u32_u8(vqtbl1q_u8(tbl8, idx8)));
791 #endif
792
793#elif defined(BOTAN_SIMD_USE_ALTIVEC)
794 const auto r = vec_perm(reinterpret_cast<__vector signed char>(tbl.raw()),
795 reinterpret_cast<__vector signed char>(tbl.raw()),
796 reinterpret_cast<__vector unsigned char>(idx.raw()));
797 return SIMD_4x32(reinterpret_cast<__vector unsigned int>(r));
798#elif defined(BOTAN_SIMD_USE_LSX)
799 return SIMD_4x32(__lsx_vshuf_b(tbl.raw(), tbl.raw(), idx.raw()));
800#elif defined(BOTAN_SIMD_USE_SIMD128)
801 return SIMD_4x32(wasm_i8x16_swizzle(tbl.raw(), idx.raw()));
802#endif
803 }

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

Referenced by masked_byte_shuffle().

◆ choose()

SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 Botan::SIMD_4x32::choose ( const SIMD_4x32 & mask,
const SIMD_4x32 & a,
const SIMD_4x32 & b )
inlinestaticnoexcept

Definition at line 749 of file simd_4x32.h.

751 {
752#if defined(BOTAN_SIMD_USE_ALTIVEC)
753 return SIMD_4x32(vec_sel(b.raw(), a.raw(), mask.raw()));
754#elif defined(BOTAN_SIMD_USE_NEON)
755 return SIMD_4x32(vbslq_u32(mask.raw(), a.raw(), b.raw()));
756#elif defined(BOTAN_SIMD_USE_LSX)
757 return SIMD_4x32(__lsx_vbitsel_v(b.raw(), a.raw(), mask.raw()));
758#elif defined(BOTAN_SIMD_USE_SIMD128)
759 return SIMD_4x32(wasm_v128_bitselect(a.raw(), b.raw(), mask.raw()));
760#else
761 return (mask & a) ^ mask.andc(b);
762#endif
763 }

References SIMD_4x32(), and SIMD_4x32().

Referenced by majority().

◆ load_be() [1/2]

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

Load a SIMD register with big-endian convention

Definition at line 189 of file simd_4x32.h.

189 {
190#if defined(BOTAN_SIMD_USE_SSSE3) || defined(BOTAN_SIMD_USE_LSX) || defined(BOTAN_SIMD_USE_SIMD128)
191 return load_le(in).bswap();
192
193#elif defined(BOTAN_SIMD_USE_ALTIVEC)
194 uint32_t R0 = Botan::load_be<uint32_t>(reinterpret_cast<const uint8_t*>(in), 0);
195 uint32_t R1 = Botan::load_be<uint32_t>(reinterpret_cast<const uint8_t*>(in), 1);
196 uint32_t R2 = Botan::load_be<uint32_t>(reinterpret_cast<const uint8_t*>(in), 2);
197 uint32_t R3 = Botan::load_be<uint32_t>(reinterpret_cast<const uint8_t*>(in), 3);
198 __vector unsigned int val = {R0, R1, R2, R3};
199 return SIMD_4x32(val);
200
201#elif defined(BOTAN_SIMD_USE_NEON)
202 SIMD_4x32 l(vld1q_u32(static_cast<const uint32_t*>(in)));
203 if constexpr(std::endian::native == std::endian::little) {
204 return l.bswap();
205 } else {
206 return l;
207 }
208#endif
209 }
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 load_le(const void *in) noexcept
Definition simd_4x32.h:162
SIMD_4x32(const SIMD_4x32 &other)=default
BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32 bswap() const noexcept
Definition simd_4x32.h:576
void R2(uint32_t A, uint32_t &B, uint32_t C, uint32_t &D, uint32_t E, uint32_t &F, uint32_t G, uint32_t &H, uint32_t TJ, uint32_t Wi, uint32_t Wj)
Definition sm3_fn.h:43
void R1(uint32_t A, uint32_t &B, uint32_t C, uint32_t &D, uint32_t E, uint32_t &F, uint32_t G, uint32_t &H, uint32_t TJ, uint32_t Wi, uint32_t Wj)
Definition sm3_fn.h:21
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504

References bswap(), Botan::load_be(), load_le(), Botan::R1(), Botan::R2(), SIMD_4x32(), and SIMD_4x32().

Referenced by Botan::SHA_256::compress_digest_armv8(), Botan::SHA_256::compress_digest_x86(), load_be(), and Botan::SHA_1::sha1_compress_x86().

◆ load_be() [2/2]

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

Definition at line 215 of file simd_4x32.h.

215 {
216 return SIMD_4x32::load_be(in.data());
217 }
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 load_be(const void *in) noexcept
Definition simd_4x32.h:189

References load_be(), and SIMD_4x32().

◆ load_le() [1/2]

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

Load a SIMD register with little-endian convention

Definition at line 162 of file simd_4x32.h.

162 {
163#if defined(BOTAN_SIMD_USE_SSSE3)
164 return SIMD_4x32(_mm_loadu_si128(reinterpret_cast<const __m128i*>(in)));
165#elif defined(BOTAN_SIMD_USE_ALTIVEC)
166 uint32_t R0 = Botan::load_le<uint32_t>(reinterpret_cast<const uint8_t*>(in), 0);
167 uint32_t R1 = Botan::load_le<uint32_t>(reinterpret_cast<const uint8_t*>(in), 1);
168 uint32_t R2 = Botan::load_le<uint32_t>(reinterpret_cast<const uint8_t*>(in), 2);
169 uint32_t R3 = Botan::load_le<uint32_t>(reinterpret_cast<const uint8_t*>(in), 3);
170 __vector unsigned int val = {R0, R1, R2, R3};
171 return SIMD_4x32(val);
172#elif defined(BOTAN_SIMD_USE_NEON)
173 SIMD_4x32 l(vld1q_u32(static_cast<const uint32_t*>(in)));
174 if constexpr(std::endian::native == std::endian::big) {
175 return l.bswap();
176 } else {
177 return l;
178 }
179#elif defined(BOTAN_SIMD_USE_LSX)
180 return SIMD_4x32(__lsx_vld(in, 0));
181#elif defined(BOTAN_SIMD_USE_SIMD128)
182 return SIMD_4x32(wasm_v128_load(in));
183#endif
184 }
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:495

References bswap(), Botan::load_le(), Botan::R1(), Botan::R2(), SIMD_4x32(), and SIMD_4x32().

Referenced by Botan::SHA_256::compress_digest_armv8(), Botan::SHA_256::compress_digest_x86(), load_be(), load_le(), and Botan::SHA_1::sha1_compress_x86().

◆ load_le() [2/2]

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

Definition at line 211 of file simd_4x32.h.

211 {
212 return SIMD_4x32::load_le(in.data());
213 }

References load_le(), and SIMD_4x32().

◆ majority()

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

Definition at line 765 of file simd_4x32.h.

767 {
768 return SIMD_4x32::choose(x ^ y, z, y);
769 }
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 choose(const SIMD_4x32 &mask, const SIMD_4x32 &a, const SIMD_4x32 &b) noexcept
Definition simd_4x32.h:749

References choose(), and SIMD_4x32().

◆ masked_byte_shuffle()

SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 Botan::SIMD_4x32::masked_byte_shuffle ( const SIMD_4x32 & tbl,
const SIMD_4x32 & idx )
inlinestatic

Byte shuffle with masking

If the index is >= 128 then the output byte is set to zero.

Warning: for indices between 16 and 128 this function may have different behaviors depending on the CPU; possibly the output is zero, tbl[idx % 16], or even undefined.

Definition at line 814 of file simd_4x32.h.

814 {
815#if defined(BOTAN_SIMD_USE_ALTIVEC)
816 const auto zero = vec_splat_s8(0x00);
817 const auto mask = vec_cmplt(reinterpret_cast<__vector signed char>(idx.raw()), zero);
818 const auto r = vec_perm(reinterpret_cast<__vector signed char>(tbl.raw()),
819 reinterpret_cast<__vector signed char>(tbl.raw()),
820 reinterpret_cast<__vector unsigned char>(idx.raw()));
821 return SIMD_4x32(reinterpret_cast<__vector unsigned int>(vec_sel(r, zero, mask)));
822#elif defined(BOTAN_SIMD_USE_LSX)
823 /*
824 * The behavior of vshuf.b unfortunately differs among microarchitectures
825 * when the index is larger than the available elements. In LA664 CPUs,
826 * larger indices result in a zero byte, which is exactly what we want.
827 * Unfortunately on LA464 machines, the output is instead undefined.
828 *
829 * So we must use a slower sequence that handles the larger indices.
830 * If we had a way of knowing at compile time that we are on an LA664
831 * or later, we could use __lsx_vshuf_b without the comparison or select.
832 */
833 const auto zero = __lsx_vldi(0);
834 const auto r = __lsx_vshuf_b(zero, tbl.raw(), idx.raw());
835 const auto mask = __lsx_vslti_bu(idx.raw(), 16);
836 return SIMD_4x32(__lsx_vbitsel_v(zero, r, mask));
837#else
838 // ARM, x86 and Wasm byte shuffles have the behavior we want for out of range idx
839 return SIMD_4x32::byte_shuffle(tbl, idx);
840#endif
841 }
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 byte_shuffle(const SIMD_4x32 &tbl, const SIMD_4x32 &idx)
Definition simd_4x32.h:777

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

◆ operator&()

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

Binary AND elements of a SIMD vector

Definition at line 421 of file simd_4x32.h.

421 {
422 SIMD_4x32 retval(*this);
423 retval &= other;
424 return retval;
425 }

References SIMD_4x32().

◆ operator&=()

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

Definition at line 485 of file simd_4x32.h.

485 {
486#if defined(BOTAN_SIMD_USE_SSSE3)
487 m_simd = _mm_and_si128(m_simd, other.m_simd);
488#elif defined(BOTAN_SIMD_USE_ALTIVEC)
489 m_simd = vec_and(m_simd, other.m_simd);
490#elif defined(BOTAN_SIMD_USE_NEON)
491 m_simd = vandq_u32(m_simd, other.m_simd);
492#elif defined(BOTAN_SIMD_USE_LSX)
493 m_simd = __lsx_vand_v(m_simd, other.m_simd);
494#elif defined(BOTAN_SIMD_USE_SIMD128)
495 m_simd = wasm_v128_and(m_simd, other.m_simd);
496#endif
497 }

References SIMD_4x32().

◆ operator+()

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

Add elements of a SIMD vector

Definition at line 385 of file simd_4x32.h.

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

References SIMD_4x32().

◆ operator+=()

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

Definition at line 427 of file simd_4x32.h.

427 {
428#if defined(BOTAN_SIMD_USE_SSSE3)
429 m_simd = _mm_add_epi32(m_simd, other.m_simd);
430#elif defined(BOTAN_SIMD_USE_ALTIVEC)
431 m_simd = vec_add(m_simd, other.m_simd);
432#elif defined(BOTAN_SIMD_USE_NEON)
433 m_simd = vaddq_u32(m_simd, other.m_simd);
434#elif defined(BOTAN_SIMD_USE_LSX)
435 m_simd = __lsx_vadd_w(m_simd, other.m_simd);
436#elif defined(BOTAN_SIMD_USE_SIMD128)
437 m_simd = wasm_i32x4_add(m_simd, other.m_simd);
438#endif
439 }

References SIMD_4x32().

◆ operator-()

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

Subtract elements of a SIMD vector

Definition at line 394 of file simd_4x32.h.

394 {
395 SIMD_4x32 retval(*this);
396 retval -= other;
397 return retval;
398 }

References SIMD_4x32().

◆ operator-=()

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

Definition at line 441 of file simd_4x32.h.

441 {
442#if defined(BOTAN_SIMD_USE_SSSE3)
443 m_simd = _mm_sub_epi32(m_simd, other.m_simd);
444#elif defined(BOTAN_SIMD_USE_ALTIVEC)
445 m_simd = vec_sub(m_simd, other.m_simd);
446#elif defined(BOTAN_SIMD_USE_NEON)
447 m_simd = vsubq_u32(m_simd, other.m_simd);
448#elif defined(BOTAN_SIMD_USE_LSX)
449 m_simd = __lsx_vsub_w(m_simd, other.m_simd);
450#elif defined(BOTAN_SIMD_USE_SIMD128)
451 m_simd = wasm_i32x4_sub(m_simd, other.m_simd);
452#endif
453 }

References SIMD_4x32().

◆ operator=() [1/2]

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

References SIMD_4x32().

◆ operator=() [2/2]

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

References SIMD_4x32().

◆ operator^()

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

XOR elements of a SIMD vector

Definition at line 403 of file simd_4x32.h.

403 {
404 SIMD_4x32 retval(*this);
405 retval ^= other;
406 return retval;
407 }

References SIMD_4x32().

◆ operator^=() [1/2]

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

Definition at line 455 of file simd_4x32.h.

455 {
456#if defined(BOTAN_SIMD_USE_SSSE3)
457 m_simd = _mm_xor_si128(m_simd, other.m_simd);
458#elif defined(BOTAN_SIMD_USE_ALTIVEC)
459 m_simd = vec_xor(m_simd, other.m_simd);
460#elif defined(BOTAN_SIMD_USE_NEON)
461 m_simd = veorq_u32(m_simd, other.m_simd);
462#elif defined(BOTAN_SIMD_USE_LSX)
463 m_simd = __lsx_vxor_v(m_simd, other.m_simd);
464#elif defined(BOTAN_SIMD_USE_SIMD128)
465 m_simd = wasm_v128_xor(m_simd, other.m_simd);
466#endif
467 }

References SIMD_4x32().

◆ operator^=() [2/2]

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

Definition at line 469 of file simd_4x32.h.

469{ *this ^= SIMD_4x32::splat(other); }
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 splat(uint32_t B) noexcept
Definition simd_4x32.h:127

References splat().

◆ operator|()

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

Binary OR elements of a SIMD vector

Definition at line 412 of file simd_4x32.h.

412 {
413 SIMD_4x32 retval(*this);
414 retval |= other;
415 return retval;
416 }

References SIMD_4x32().

◆ operator|=()

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

Definition at line 471 of file simd_4x32.h.

471 {
472#if defined(BOTAN_SIMD_USE_SSSE3)
473 m_simd = _mm_or_si128(m_simd, other.m_simd);
474#elif defined(BOTAN_SIMD_USE_ALTIVEC)
475 m_simd = vec_or(m_simd, other.m_simd);
476#elif defined(BOTAN_SIMD_USE_NEON)
477 m_simd = vorrq_u32(m_simd, other.m_simd);
478#elif defined(BOTAN_SIMD_USE_LSX)
479 m_simd = __lsx_vor_v(m_simd, other.m_simd);
480#elif defined(BOTAN_SIMD_USE_SIMD128)
481 m_simd = wasm_v128_or(m_simd, other.m_simd);
482#endif
483 }

References SIMD_4x32().

◆ operator~()

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

Definition at line 537 of file simd_4x32.h.

537 {
538#if defined(BOTAN_SIMD_USE_SSSE3)
539 return SIMD_4x32(_mm_xor_si128(m_simd, _mm_set1_epi32(0xFFFFFFFF)));
540#elif defined(BOTAN_SIMD_USE_ALTIVEC)
541 return SIMD_4x32(vec_nor(m_simd, m_simd));
542#elif defined(BOTAN_SIMD_USE_NEON)
543 return SIMD_4x32(vmvnq_u32(m_simd));
544#elif defined(BOTAN_SIMD_USE_LSX)
545 return SIMD_4x32(__lsx_vnor_v(m_simd, m_simd));
546#elif defined(BOTAN_SIMD_USE_SIMD128)
547 return SIMD_4x32(wasm_v128_not(m_simd));
548#endif
549 }

References SIMD_4x32(), and SIMD_4x32().

◆ raw()

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

◆ rotl()

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

Left rotation by a compile time constant

Definition at line 329 of file simd_4x32.h.

331 {
332#if defined(BOTAN_SIMD_USE_SSSE3)
333 if constexpr(ROT == 8) {
334 const auto shuf_rotl_8 = _mm_set_epi64x(0x0e0d0c0f0a09080b, 0x0605040702010003);
335 return SIMD_4x32(_mm_shuffle_epi8(raw(), shuf_rotl_8));
336 } else if constexpr(ROT == 16) {
337 const auto shuf_rotl_16 = _mm_set_epi64x(0x0d0c0f0e09080b0a, 0x0504070601000302);
338 return SIMD_4x32(_mm_shuffle_epi8(raw(), shuf_rotl_16));
339 } else if constexpr(ROT == 24) {
340 const auto shuf_rotl_24 = _mm_set_epi64x(0x0c0f0e0d080b0a09, 0x0407060500030201);
341 return SIMD_4x32(_mm_shuffle_epi8(raw(), shuf_rotl_24));
342 } else {
343 return SIMD_4x32(_mm_xor_si128(_mm_slli_epi32(raw(), static_cast<int>(ROT)),
344 _mm_srli_epi32(raw(), static_cast<int>(32 - ROT))));
345 }
346
347#elif defined(BOTAN_SIMD_USE_ALTIVEC)
348
349 const unsigned int r = static_cast<unsigned int>(ROT);
350 __vector unsigned int rot = {r, r, r, r};
351 return SIMD_4x32(vec_rl(m_simd, rot));
352
353#elif defined(BOTAN_SIMD_USE_NEON)
354
355 #if defined(BOTAN_TARGET_ARCH_IS_ARM64)
356
357 if constexpr(ROT == 8) {
358 const uint8_t maskb[16] = {3, 0, 1, 2, 7, 4, 5, 6, 11, 8, 9, 10, 15, 12, 13, 14};
359 const uint8x16_t mask = vld1q_u8(maskb);
360 return SIMD_4x32(vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(m_simd), mask)));
361 } else if constexpr(ROT == 16) {
362 return SIMD_4x32(vreinterpretq_u32_u16(vrev32q_u16(vreinterpretq_u16_u32(m_simd))));
363 }
364 #endif
365 return SIMD_4x32(
366 vorrq_u32(vshlq_n_u32(m_simd, static_cast<int>(ROT)), vshrq_n_u32(m_simd, static_cast<int>(32 - ROT))));
367#elif defined(BOTAN_SIMD_USE_LSX)
368 return SIMD_4x32(__lsx_vrotri_w(raw(), 32 - ROT));
369#elif defined(BOTAN_SIMD_USE_SIMD128)
370 return SIMD_4x32(wasm_v128_or(wasm_i32x4_shl(m_simd, ROT), wasm_u32x4_shr(m_simd, 32 - ROT)));
371#endif
372 }

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

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

◆ rotr()

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

Right rotation by a compile time constant

Definition at line 378 of file simd_4x32.h.

378 {
379 return this->rotl<32 - ROT>();
380 }
BOTAN_FN_ISA_SIMD_4X32 SIMD_4x32 rotl() const noexcept
Definition simd_4x32.h:329

References rotl(), and SIMD_4x32().

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

◆ shift_elems_left()

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

Definition at line 602 of file simd_4x32.h.

604 {
605#if defined(BOTAN_SIMD_USE_SSSE3)
606 return SIMD_4x32(_mm_slli_si128(raw(), 4 * I));
607#elif defined(BOTAN_SIMD_USE_NEON)
608 return SIMD_4x32(vextq_u32(vdupq_n_u32(0), raw(), 4 - I));
609#elif defined(BOTAN_SIMD_USE_ALTIVEC)
610 const __vector unsigned int zero = vec_splat_u32(0);
611
612 const __vector unsigned char shuf[3] = {
613 {16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
614 {16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7},
615 {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 1, 2, 3},
616 };
617
618 return SIMD_4x32(vec_perm(raw(), zero, shuf[I - 1]));
619#elif defined(BOTAN_SIMD_USE_LSX)
620 return SIMD_4x32(__lsx_vbsll_v(raw(), 4 * I));
621#elif defined(BOTAN_SIMD_USE_SIMD128)
622 if constexpr(I == 0) {
623 return SIMD_4x32(m_simd);
624 }
625
626 const auto zero = wasm_u32x4_const_splat(0);
627 if constexpr(I == 1) {
628 return SIMD_4x32(wasm_i8x16_shuffle(m_simd, zero, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
629 }
630 if constexpr(I == 2) {
631 return SIMD_4x32(wasm_i8x16_shuffle(m_simd, zero, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7));
632 }
633
634 return SIMD_4x32(wasm_i8x16_shuffle(m_simd, zero, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3));
635#endif
636 }

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

Referenced by Botan::clmul(), and Botan::polyval_multiply().

◆ shift_elems_right()

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

Definition at line 639 of file simd_4x32.h.

641 {
642#if defined(BOTAN_SIMD_USE_SSSE3)
643 return SIMD_4x32(_mm_srli_si128(raw(), 4 * I));
644#elif defined(BOTAN_SIMD_USE_NEON)
645 return SIMD_4x32(vextq_u32(raw(), vdupq_n_u32(0), I));
646#elif defined(BOTAN_SIMD_USE_ALTIVEC)
647 const __vector unsigned int zero = vec_splat_u32(0);
648
649 const __vector unsigned char shuf[3] = {
650 {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
651 {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
652 {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27},
653 };
654
655 return SIMD_4x32(vec_perm(raw(), zero, shuf[I - 1]));
656#elif defined(BOTAN_SIMD_USE_LSX)
657 return SIMD_4x32(__lsx_vbsrl_v(raw(), 4 * I));
658#elif defined(BOTAN_SIMD_USE_SIMD128)
659 if constexpr(I == 0) {
660 return SIMD_4x32(m_simd);
661 }
662
663 const auto zero = wasm_u32x4_const_splat(0);
664 if constexpr(I == 1) {
665 return SIMD_4x32(
666 wasm_i8x16_shuffle(m_simd, zero, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16));
667 }
668 if constexpr(I == 2) {
669 return SIMD_4x32(
670 wasm_i8x16_shuffle(m_simd, zero, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16));
671 }
672
673 return SIMD_4x32(
674 wasm_i8x16_shuffle(m_simd, zero, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16));
675#endif
676 }

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

Referenced by Botan::polyval_multiply().

◆ shl()

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

Definition at line 500 of file simd_4x32.h.

502 {
503#if defined(BOTAN_SIMD_USE_SSSE3)
504 return SIMD_4x32(_mm_slli_epi32(m_simd, SHIFT));
505
506#elif defined(BOTAN_SIMD_USE_ALTIVEC)
507 const unsigned int s = static_cast<unsigned int>(SHIFT);
508 const __vector unsigned int shifts = {s, s, s, s};
509 return SIMD_4x32(vec_sl(m_simd, shifts));
510#elif defined(BOTAN_SIMD_USE_NEON)
511 return SIMD_4x32(vshlq_n_u32(m_simd, SHIFT));
512#elif defined(BOTAN_SIMD_USE_LSX)
513 return SIMD_4x32(__lsx_vslli_w(m_simd, SHIFT));
514#elif defined(BOTAN_SIMD_USE_SIMD128)
515 return SIMD_4x32(wasm_i32x4_shl(m_simd, SHIFT));
516#endif
517 }

References SIMD_4x32(), and SIMD_4x32().

Referenced by Botan::mulx_polyval(), and Botan::shl().

◆ shr()

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

Definition at line 520 of file simd_4x32.h.

520 {
521#if defined(BOTAN_SIMD_USE_SSSE3)
522 return SIMD_4x32(_mm_srli_epi32(m_simd, SHIFT));
523
524#elif defined(BOTAN_SIMD_USE_ALTIVEC)
525 const unsigned int s = static_cast<unsigned int>(SHIFT);
526 const __vector unsigned int shifts = {s, s, s, s};
527 return SIMD_4x32(vec_sr(m_simd, shifts));
528#elif defined(BOTAN_SIMD_USE_NEON)
529 return SIMD_4x32(vshrq_n_u32(m_simd, SHIFT));
530#elif defined(BOTAN_SIMD_USE_LSX)
531 return SIMD_4x32(__lsx_vsrli_w(m_simd, SHIFT));
532#elif defined(BOTAN_SIMD_USE_SIMD128)
533 return SIMD_4x32(wasm_u32x4_shr(m_simd, SHIFT));
534#endif
535 }

References SIMD_4x32(), and SIMD_4x32().

Referenced by Botan::mulx_polyval().

◆ sigma0()

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

Definition at line 300 of file simd_4x32.h.

300 {
301#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_crypto_vshasigmaw) && defined(_ARCH_PWR8)
302 return SIMD_4x32(__builtin_crypto_vshasigmaw(raw(), 1, 0));
303#else
304 const SIMD_4x32 r1 = this->rotr<2>();
305 const SIMD_4x32 r2 = this->rotr<13>();
306 const SIMD_4x32 r3 = this->rotr<22>();
307 return (r1 ^ r2 ^ r3);
308#endif
309 }
SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 rotr() const noexcept
Definition simd_4x32.h:378

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

◆ sigma1()

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

Definition at line 314 of file simd_4x32.h.

314 {
315#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_crypto_vshasigmaw) && defined(_ARCH_PWR8)
316 return SIMD_4x32(__builtin_crypto_vshasigmaw(raw(), 1, 0xF));
317#else
318 const SIMD_4x32 r1 = this->rotr<6>();
319 const SIMD_4x32 r2 = this->rotr<11>();
320 const SIMD_4x32 r3 = this->rotr<25>();
321 return (r1 ^ r2 ^ r3);
322#endif
323 }

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

◆ splat()

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

Load SIMD register with one 32-bit element repeated

Definition at line 127 of file simd_4x32.h.

127 {
128#if defined(BOTAN_SIMD_USE_SSSE3)
129 return SIMD_4x32(_mm_set1_epi32(B));
130#elif defined(BOTAN_SIMD_USE_NEON)
131 return SIMD_4x32(vdupq_n_u32(B));
132#elif defined(BOTAN_SIMD_USE_LSX)
133 return SIMD_4x32(__lsx_vreplgr2vr_w(B));
134#elif defined(BOTAN_SIMD_USE_SIMD128)
135 return SIMD_4x32(wasm_u32x4_splat(B));
136#else
137 return SIMD_4x32(B, B, B, B);
138#endif
139 }

References SIMD_4x32(), and SIMD_4x32().

Referenced by operator^=().

◆ splat_u8()

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

Load SIMD register with one 8-bit element repeated

Definition at line 144 of file simd_4x32.h.

144 {
145#if defined(BOTAN_SIMD_USE_SSSE3)
146 return SIMD_4x32(_mm_set1_epi8(B));
147#elif defined(BOTAN_SIMD_USE_NEON)
148 return SIMD_4x32(vreinterpretq_u32_u8(vdupq_n_u8(B)));
149#elif defined(BOTAN_SIMD_USE_LSX)
150 return SIMD_4x32(__lsx_vreplgr2vr_b(B));
151#elif defined(BOTAN_SIMD_USE_SIMD128)
152 return SIMD_4x32(wasm_u8x16_splat(B));
153#else
154 const uint32_t B4 = make_uint32(B, B, B, B);
155 return SIMD_4x32(B4, B4, B4, B4);
156#endif
157 }
constexpr uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3)
Definition loadstor.h:104

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

◆ store_be() [1/3]

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

Definition at line 293 of file simd_4x32.h.

293{ this->store_be(out.data()); }
void BOTAN_FN_ISA_SIMD_4X32 store_be(uint32_t out[4]) const noexcept
Definition simd_4x32.h:223

References store_be().

Referenced by store_be().

◆ store_be() [2/3]

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

Definition at line 223 of file simd_4x32.h.

223 {
224 this->store_be(reinterpret_cast<uint8_t*>(out));
225 }

References store_be().

Referenced by store_be().

◆ store_be() [3/3]

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

Load a SIMD register with big-endian convention

Definition at line 267 of file simd_4x32.h.

267 {
268#if defined(BOTAN_SIMD_USE_SSSE3) || defined(BOTAN_SIMD_USE_LSX) || defined(BOTAN_SIMD_USE_SIMD128)
269
270 bswap().store_le(out);
271
272#elif defined(BOTAN_SIMD_USE_ALTIVEC)
273
274 union {
275 __vector unsigned int V;
276 uint32_t R[4];
277 } vec{};
278
279 // NOLINTNEXTLINE(*-union-access)
280 vec.V = m_simd;
281 // NOLINTNEXTLINE(*-union-access)
282 Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
283
284#elif defined(BOTAN_SIMD_USE_NEON)
285 if constexpr(std::endian::native == std::endian::little) {
286 vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
287 } else {
288 vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
289 }
290#endif
291 }
void BOTAN_FN_ISA_SIMD_4X32 store_le(uint32_t out[4]) const noexcept
Definition simd_4x32.h:219
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:745

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

◆ store_le() [1/4]

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

Definition at line 295 of file simd_4x32.h.

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

References store_le().

Referenced by store_le().

◆ store_le() [2/4]

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

Definition at line 219 of file simd_4x32.h.

219 {
220 this->store_le(reinterpret_cast<uint8_t*>(out));
221 }

References store_le().

Referenced by Botan::SHA_256::compress_digest_armv8(), Botan::SHA_256::compress_digest_x86(), store_be(), store_le(), and store_le().

◆ store_le() [3/4]

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

Definition at line 227 of file simd_4x32.h.

227 {
228 this->store_le(reinterpret_cast<uint8_t*>(out));
229 }

References store_le().

◆ store_le() [4/4]

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

Load a SIMD register with little-endian convention

Definition at line 234 of file simd_4x32.h.

234 {
235#if defined(BOTAN_SIMD_USE_SSSE3)
236
237 _mm_storeu_si128(reinterpret_cast<__m128i*>(out), raw());
238
239#elif defined(BOTAN_SIMD_USE_ALTIVEC)
240
241 union {
242 __vector unsigned int V;
243 uint32_t R[4];
244 } vec{};
245
246 // NOLINTNEXTLINE(*-union-access)
247 vec.V = raw();
248 // NOLINTNEXTLINE(*-union-access)
249 Botan::store_le(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
250
251#elif defined(BOTAN_SIMD_USE_NEON)
252 if constexpr(std::endian::native == std::endian::little) {
253 vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
254 } else {
255 vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
256 }
257#elif defined(BOTAN_SIMD_USE_LSX)
258 __lsx_vst(raw(), out, 0);
259#elif defined(BOTAN_SIMD_USE_SIMD128)
260 wasm_v128_store(out, m_simd);
261#endif
262 }
constexpr auto store_le(ParamTs &&... params)
Definition loadstor.h:736

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

◆ swap_halves()

SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 Botan::SIMD_4x32::swap_halves ( ) const
inline

Swap the upper and lower 64-bit halves of the vector

Definition at line 908 of file simd_4x32.h.

908 {
909#if defined(BOTAN_SIMD_USE_SSSE3)
910 return SIMD_4x32(_mm_shuffle_epi32(raw(), 0b01001110));
911#else
912 return SIMD_4x32::alignr8(*this, *this);
913#endif
914 }
static SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 alignr8(const SIMD_4x32 &a, const SIMD_4x32 &b)
Definition simd_4x32.h:860

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

Referenced by Botan::polyval_reduce().

◆ top_bit_mask()

SIMD_4x32 BOTAN_FN_ISA_SIMD_4X32 Botan::SIMD_4x32::top_bit_mask ( ) const
inline

If the topmost bit of x is set, return a vector of all ones, otherwise a vector of all zeros ie: (v >> 127) ? splat(0xFFFFFFFF) : zero;

Most of the implementations work by doing an arithmetic shift of 31 to smear the top bits of each word, followed by a broadcast of the top word.

Definition at line 883 of file simd_4x32.h.

883 {
884#if defined(BOTAN_SIMD_USE_SSSE3)
885 return SIMD_4x32(_mm_shuffle_epi32(_mm_srai_epi32(raw(), 31), 0b11111111));
886#elif defined(BOTAN_SIMD_USE_NEON)
887 #if defined(BOTAN_TARGET_ARCH_IS_ARM32)
888 int32x4_t v = vshrq_n_s32(vreinterpretq_s32_u32(raw()), 31);
889 int32x2_t hi = vget_high_s32(v);
890 return SIMD_4x32(vreinterpretq_u32_s32(vdupq_lane_s32(hi, 1)));
891 #else
892 return SIMD_4x32(vreinterpretq_u32_s32(vdupq_laneq_s32(vshrq_n_s32(vreinterpretq_s32_u32(raw()), 31), 3)));
893 #endif
894#elif defined(BOTAN_SIMD_USE_ALTIVEC)
895 const __vector unsigned int shift = vec_splats(31U);
896 const __vector signed int shifted = vec_sra(reinterpret_cast<__vector signed int>(raw()), shift);
897 return SIMD_4x32(reinterpret_cast<__vector unsigned int>(vec_splat(shifted, 3)));
898#elif defined(BOTAN_SIMD_USE_LSX)
899 return SIMD_4x32(__lsx_vshuf4i_w(__lsx_vsrai_w(raw(), 31), 0xFF));
900#elif defined(BOTAN_SIMD_USE_SIMD128)
901 return SIMD_4x32(wasm_i32x4_splat(wasm_i32x4_extract_lane(wasm_i32x4_shr(raw(), 31), 3)));
902#endif
903 }

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

Referenced by Botan::mulx_polyval().

◆ transpose()

void BOTAN_FN_ISA_SIMD_4X32 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 681 of file simd_4x32.h.

684 {
685#if defined(BOTAN_SIMD_USE_SSSE3)
686 const __m128i T0 = _mm_unpacklo_epi32(B0.m_simd, B1.m_simd);
687 const __m128i T1 = _mm_unpacklo_epi32(B2.m_simd, B3.m_simd);
688 const __m128i T2 = _mm_unpackhi_epi32(B0.m_simd, B1.m_simd);
689 const __m128i T3 = _mm_unpackhi_epi32(B2.m_simd, B3.m_simd);
690
691 B0.m_simd = _mm_unpacklo_epi64(T0, T1);
692 B1.m_simd = _mm_unpackhi_epi64(T0, T1);
693 B2.m_simd = _mm_unpacklo_epi64(T2, T3);
694 B3.m_simd = _mm_unpackhi_epi64(T2, T3);
695#elif defined(BOTAN_SIMD_USE_ALTIVEC)
696 const __vector unsigned int T0 = vec_mergeh(B0.m_simd, B2.m_simd);
697 const __vector unsigned int T1 = vec_mergeh(B1.m_simd, B3.m_simd);
698 const __vector unsigned int T2 = vec_mergel(B0.m_simd, B2.m_simd);
699 const __vector unsigned int T3 = vec_mergel(B1.m_simd, B3.m_simd);
700
701 B0.m_simd = vec_mergeh(T0, T1);
702 B1.m_simd = vec_mergel(T0, T1);
703 B2.m_simd = vec_mergeh(T2, T3);
704 B3.m_simd = vec_mergel(T2, T3);
705
706#elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM32)
707 const uint32x4x2_t T0 = vzipq_u32(B0.m_simd, B2.m_simd);
708 const uint32x4x2_t T1 = vzipq_u32(B1.m_simd, B3.m_simd);
709 const uint32x4x2_t O0 = vzipq_u32(T0.val[0], T1.val[0]);
710 const uint32x4x2_t O1 = vzipq_u32(T0.val[1], T1.val[1]);
711
712 B0.m_simd = O0.val[0];
713 B1.m_simd = O0.val[1];
714 B2.m_simd = O1.val[0];
715 B3.m_simd = O1.val[1];
716
717#elif defined(BOTAN_SIMD_USE_NEON) && defined(BOTAN_TARGET_ARCH_IS_ARM64)
718 const uint32x4_t T0 = vzip1q_u32(B0.m_simd, B2.m_simd);
719 const uint32x4_t T2 = vzip2q_u32(B0.m_simd, B2.m_simd);
720 const uint32x4_t T1 = vzip1q_u32(B1.m_simd, B3.m_simd);
721 const uint32x4_t T3 = vzip2q_u32(B1.m_simd, B3.m_simd);
722
723 B0.m_simd = vzip1q_u32(T0, T1);
724 B1.m_simd = vzip2q_u32(T0, T1);
725 B2.m_simd = vzip1q_u32(T2, T3);
726 B3.m_simd = vzip2q_u32(T2, T3);
727#elif defined(BOTAN_SIMD_USE_LSX)
728 const __m128i T0 = __lsx_vilvl_w(B2.raw(), B0.raw());
729 const __m128i T1 = __lsx_vilvh_w(B2.raw(), B0.raw());
730 const __m128i T2 = __lsx_vilvl_w(B3.raw(), B1.raw());
731 const __m128i T3 = __lsx_vilvh_w(B3.raw(), B1.raw());
732 B0.m_simd = __lsx_vilvl_w(T2, T0);
733 B1.m_simd = __lsx_vilvh_w(T2, T0);
734 B2.m_simd = __lsx_vilvl_w(T3, T1);
735 B3.m_simd = __lsx_vilvh_w(T3, T1);
736#elif defined(BOTAN_SIMD_USE_SIMD128)
737 const auto T0 = wasm_i32x4_shuffle(B0.m_simd, B2.m_simd, 0, 4, 1, 5);
738 const auto T2 = wasm_i32x4_shuffle(B0.m_simd, B2.m_simd, 2, 6, 3, 7);
739 const auto T1 = wasm_i32x4_shuffle(B1.m_simd, B3.m_simd, 0, 4, 1, 5);
740 const auto T3 = wasm_i32x4_shuffle(B1.m_simd, B3.m_simd, 2, 6, 3, 7);
741
742 B0.m_simd = wasm_i32x4_shuffle(T0, T1, 0, 4, 1, 5);
743 B1.m_simd = wasm_i32x4_shuffle(T0, T1, 2, 6, 3, 7);
744 B2.m_simd = wasm_i32x4_shuffle(T2, T3, 0, 4, 1, 5);
745 B3.m_simd = wasm_i32x4_shuffle(T2, T3, 2, 6, 3, 7);
746#endif
747 }

References SIMD_4x32().


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