Botan  1.10.9
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
T load_be(const byte in[], size_t off)
Definition: loadstor.h:100
T load_le(const byte in[], size_t off)
Definition: loadstor.h:116
void store_le(u16bit in, byte out[2])
Definition: loadstor.h:427
T rotate_left(T input, size_t rot)
Definition: rotate.h:21
int operator>>(int fd, Pipe &pipe)
Definition: fd_unix.cpp:39
OctetString operator^(const OctetString &k1, const OctetString &k2)
Definition: symkey.cpp:125
unsigned char byte
Definition: types.h:22
int operator<<(int fd, Pipe &pipe)
Definition: fd_unix.cpp:17
OctetString operator+(const OctetString &k1, const OctetString &k2)
Definition: symkey.cpp:114
T rotate_right(T input, size_t rot)
Definition: rotate.h:34
MemoryRegion< T > & operator+=(MemoryRegion< T > &out, const MemoryRegion< T > &in)
Definition: secmem.h:373
static bool has_sse2()
Definition: cpuid.h:40
void store_be(u16bit in, byte out[2])
Definition: loadstor.h:412
BigInt operator-(const BigInt &x, const BigInt &y)
Definition: big_ops3.cpp:48
unsigned int u32bit
Definition: types.h:32