Botan: src/simd/simd_sse2/simd_sse2.h Source File

Botan 1.10.16

simd_sse2.h
Go to the documentation of this file.
1 /*
2 * Lightweight wrappers for SSE2 intrinsics for 32-bit operations
3 * (C) 2009 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #ifndef BOTAN_SIMD_SSE_H__
9 #define BOTAN_SIMD_SSE_H__
10
11 #if defined(BOTAN_TARGET_CPU_HAS_SSE2)
12
13 #include <botan/cpuid.h>
14 #include <emmintrin.h>
15
16 namespace Botan {
17
18 class SIMD_SSE2
19 {
20 public:
21 static bool enabled() { return CPUID::has_sse2(); }
22
23 SIMD_SSE2(const u32bit B[4])
24 {
25 reg = _mm_loadu_si128(reinterpret_cast<const __m128i*>(B));
26 }
27
28 SIMD_SSE2(u32bit B0, u32bit B1, u32bit B2, u32bit B3)
29 {
30 reg = _mm_set_epi32(B0, B1, B2, B3);
31 }
32
33 SIMD_SSE2(u32bit B)
34 {
35 reg = _mm_set1_epi32(B);
36 }
37
38 static SIMD_SSE2 load_le(const void* in)
39 {
40 return _mm_loadu_si128(reinterpret_cast<const __m128i*>(in));
41 }
42
43 static SIMD_SSE2 load_be(const void* in)
44 {
45 return load_le(in).bswap();
46 }
47
48 void store_le(byte out[]) const
49 {
50 _mm_storeu_si128(reinterpret_cast<__m128i*>(out), reg);
51 }
52
53 void store_be(byte out[]) const
54 {
55 bswap().store_le(out);
56 }
57
58 void rotate_left(size_t rot)
59 {
60 reg = _mm_or_si128(_mm_slli_epi32(reg, static_cast<int>(rot)),
61 _mm_srli_epi32(reg, static_cast<int>(32-rot)));
62 }
63
64 void rotate_right(size_t rot)
65 {
66 rotate_left(32 - rot);
67 }
68
69 void operator+=(const SIMD_SSE2& other)
70 {
71 reg = _mm_add_epi32(reg, other.reg);
72 }
73
74 SIMD_SSE2 operator+(const SIMD_SSE2& other) const
75 {
76 return _mm_add_epi32(reg, other.reg);
77 }
78
79 void operator-=(const SIMD_SSE2& other)
80 {
81 reg = _mm_sub_epi32(reg, other.reg);
82 }
83
84 SIMD_SSE2 operator-(const SIMD_SSE2& other) const
85 {
86 return _mm_sub_epi32(reg, other.reg);
87 }
88
89 void operator^=(const SIMD_SSE2& other)
90 {
91 reg = _mm_xor_si128(reg, other.reg);
92 }
93
94 SIMD_SSE2 operator^(const SIMD_SSE2& other) const
95 {
96 return _mm_xor_si128(reg, other.reg);
97 }
98
99 void operator|=(const SIMD_SSE2& other)
100 {
101 reg = _mm_or_si128(reg, other.reg);
102 }
103
104 SIMD_SSE2 operator&(const SIMD_SSE2& other)
105 {
106 return _mm_and_si128(reg, other.reg);
107 }
108
109 void operator&=(const SIMD_SSE2& other)
110 {
111 reg = _mm_and_si128(reg, other.reg);
112 }
113
114 SIMD_SSE2 operator<<(size_t shift) const
115 {
116 return _mm_slli_epi32(reg, static_cast<int>(shift));
117 }
118
119 SIMD_SSE2 operator>>(size_t shift) const
120 {
121 return _mm_srli_epi32(reg, static_cast<int>(shift));
122 }
123
124 SIMD_SSE2 operator~() const
125 {
126 return _mm_xor_si128(reg, _mm_set1_epi32(0xFFFFFFFF));
127 }
128
129 // (~reg) & other
130 SIMD_SSE2 andc(const SIMD_SSE2& other)
131 {
132 return _mm_andnot_si128(reg, other.reg);
133 }
134
135 SIMD_SSE2 bswap() const
136 {
137 __m128i T = reg;
138
139 T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
140 T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
141
142 return _mm_or_si128(_mm_srli_epi16(T, 8),
143 _mm_slli_epi16(T, 8));
144 }
145
146 static void transpose(SIMD_SSE2& B0, SIMD_SSE2& B1,
147 SIMD_SSE2& B2, SIMD_SSE2& B3)
148 {
149 __m128i T0 = _mm_unpacklo_epi32(B0.reg, B1.reg);
150 __m128i T1 = _mm_unpacklo_epi32(B2.reg, B3.reg);
151 __m128i T2 = _mm_unpackhi_epi32(B0.reg, B1.reg);
152 __m128i T3 = _mm_unpackhi_epi32(B2.reg, B3.reg);
153 B0.reg = _mm_unpacklo_epi64(T0, T1);
154 B1.reg = _mm_unpackhi_epi64(T0, T1);
155 B2.reg = _mm_unpacklo_epi64(T2, T3);
156 B3.reg = _mm_unpackhi_epi64(T2, T3);
157 }
158
159 private:
160 SIMD_SSE2(__m128i in) { reg = in; }
161
162 __m128i reg;
163 };
164
165 }
166
167 #endif
168
169 #endif
Botan::load_be
T load_be(const byte in[], size_t off)
Definition: loadstor.h:100
Botan::load_le
T load_le(const byte in[], size_t off)
Definition: loadstor.h:116
Botan::store_le
void store_le(u16bit in, byte out[2])
Definition: loadstor.h:427
Botan::rotate_left
T rotate_left(T input, size_t rot)
Definition: rotate.h:21
Botan::operator>>
int operator>>(int fd, Pipe &pipe)
Definition: fd_unix.cpp:39
Botan::operator^
OctetString operator^(const OctetString &k1, const OctetString &k2)
Definition: symkey.cpp:125
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::operator<<
int operator<<(int fd, Pipe &pipe)
Definition: fd_unix.cpp:17
Botan::operator+
OctetString operator+(const OctetString &k1, const OctetString &k2)
Definition: symkey.cpp:114
Botan::rotate_right
T rotate_right(T input, size_t rot)
Definition: rotate.h:34
Botan::operator+=
MemoryRegion< T > & operator+=(MemoryRegion< T > &out, const MemoryRegion< T > &in)
Definition: secmem.h:373
Botan
Definition: algo_base.h:14
Botan::CPUID::has_sse2
static bool has_sse2()
Definition: cpuid.h:40
Botan::store_be
void store_be(u16bit in, byte out[2])
Definition: loadstor.h:412
Botan::operator-
BigInt operator-(const BigInt &x, const BigInt &y)
Definition: big_ops3.cpp:48
Botan::u32bit
unsigned int u32bit
Definition: types.h:32