Botan 1.10.17
simd_scalar.h
Go to the documentation of this file.
1/*
2* Scalar emulation of SIMD 32-bit operations
3* (C) 2009 Jack Lloyd
4*
5* Distributed under the terms of the Botan license
6*/
7
8#ifndef BOTAN_SIMD_SCALAR_H__
9#define BOTAN_SIMD_SCALAR_H__
10
11#include <botan/loadstor.h>
12#include <botan/bswap.h>
13
14namespace Botan {
15
16/**
17* Fake SIMD, using plain scalar operations
18* Often still faster than iterative on superscalar machines
19*/
21 {
22 public:
23 static bool enabled() { return true; }
24
25 SIMD_Scalar(const u32bit B[4])
26 {
27 R0 = B[0];
28 R1 = B[1];
29 R2 = B[2];
30 R3 = B[3];
31 }
32
34 {
35 R0 = B0;
36 R1 = B1;
37 R2 = B2;
38 R3 = B3;
39 }
40
42 {
43 R0 = B;
44 R1 = B;
45 R2 = B;
46 R3 = B;
47 }
48
49 static SIMD_Scalar load_le(const void* in)
50 {
51 const byte* in_b = static_cast<const byte*>(in);
52 return SIMD_Scalar(Botan::load_le<u32bit>(in_b, 0),
55 Botan::load_le<u32bit>(in_b, 3));
56 }
57
58 static SIMD_Scalar load_be(const void* in)
59 {
60 const byte* in_b = static_cast<const byte*>(in);
61 return SIMD_Scalar(Botan::load_be<u32bit>(in_b, 0),
64 Botan::load_be<u32bit>(in_b, 3));
65 }
66
67 void store_le(byte out[]) const
68 {
69 Botan::store_le(out, R0, R1, R2, R3);
70 }
71
72 void store_be(byte out[]) const
73 {
74 Botan::store_be(out, R0, R1, R2, R3);
75 }
76
77 void rotate_left(size_t rot)
78 {
79 R0 = Botan::rotate_left(R0, rot);
80 R1 = Botan::rotate_left(R1, rot);
81 R2 = Botan::rotate_left(R2, rot);
82 R3 = Botan::rotate_left(R3, rot);
83 }
84
85 void rotate_right(size_t rot)
86 {
87 R0 = Botan::rotate_right(R0, rot);
88 R1 = Botan::rotate_right(R1, rot);
89 R2 = Botan::rotate_right(R2, rot);
90 R3 = Botan::rotate_right(R3, rot);
91 }
92
93 void operator+=(const SIMD_Scalar& other)
94 {
95 R0 += other.R0;
96 R1 += other.R1;
97 R2 += other.R2;
98 R3 += other.R3;
99 }
100
102 {
103 return SIMD_Scalar(R0 + other.R0,
104 R1 + other.R1,
105 R2 + other.R2,
106 R3 + other.R3);
107 }
108
109 void operator-=(const SIMD_Scalar& other)
110 {
111 R0 -= other.R0;
112 R1 -= other.R1;
113 R2 -= other.R2;
114 R3 -= other.R3;
115 }
116
118 {
119 return SIMD_Scalar(R0 - other.R0,
120 R1 - other.R1,
121 R2 - other.R2,
122 R3 - other.R3);
123 }
124
125 void operator^=(const SIMD_Scalar& other)
126 {
127 R0 ^= other.R0;
128 R1 ^= other.R1;
129 R2 ^= other.R2;
130 R3 ^= other.R3;
131 }
132
134 {
135 return SIMD_Scalar(R0 ^ other.R0,
136 R1 ^ other.R1,
137 R2 ^ other.R2,
138 R3 ^ other.R3);
139 }
140
141 void operator|=(const SIMD_Scalar& other)
142 {
143 R0 |= other.R0;
144 R1 |= other.R1;
145 R2 |= other.R2;
146 R3 |= other.R3;
147 }
148
150 {
151 return SIMD_Scalar(R0 & other.R0,
152 R1 & other.R1,
153 R2 & other.R2,
154 R3 & other.R3);
155 }
156
157 void operator&=(const SIMD_Scalar& other)
158 {
159 R0 &= other.R0;
160 R1 &= other.R1;
161 R2 &= other.R2;
162 R3 &= other.R3;
163 }
164
165 SIMD_Scalar operator<<(size_t shift) const
166 {
167 return SIMD_Scalar(R0 << shift,
168 R1 << shift,
169 R2 << shift,
170 R3 << shift);
171 }
172
173 SIMD_Scalar operator>>(size_t shift) const
174 {
175 return SIMD_Scalar(R0 >> shift,
176 R1 >> shift,
177 R2 >> shift,
178 R3 >> shift);
179 }
180
182 {
183 return SIMD_Scalar(~R0, ~R1, ~R2, ~R3);
184 }
185
186 // (~reg) & other
188 {
189 return SIMD_Scalar(~R0 & other.R0,
190 ~R1 & other.R1,
191 ~R2 & other.R2,
192 ~R3 & other.R3);
193 }
194
196 {
197 return SIMD_Scalar(reverse_bytes(R0),
198 reverse_bytes(R1),
199 reverse_bytes(R2),
200 reverse_bytes(R3));
201 }
202
203 static void transpose(SIMD_Scalar& B0, SIMD_Scalar& B1,
204 SIMD_Scalar& B2, SIMD_Scalar& B3)
205 {
206 SIMD_Scalar T0(B0.R0, B1.R0, B2.R0, B3.R0);
207 SIMD_Scalar T1(B0.R1, B1.R1, B2.R1, B3.R1);
208 SIMD_Scalar T2(B0.R2, B1.R2, B2.R2, B3.R2);
209 SIMD_Scalar T3(B0.R3, B1.R3, B2.R3, B3.R3);
210
211 B0 = T0;
212 B1 = T1;
213 B2 = T2;
214 B3 = T3;
215 }
216
217 private:
218 u32bit R0, R1, R2, R3;
219 };
220
221}
222
223#endif
#define R0
Definition asm_x86_64.h:51
#define R3
Definition asm_x86_64.h:55
#define R2
Definition asm_x86_64.h:53
#define R1
Definition asm_x86_64.h:52
SIMD_Scalar operator<<(size_t shift) const
SIMD_Scalar operator>>(size_t shift) const
SIMD_Scalar operator^(const SIMD_Scalar &other) const
SIMD_Scalar operator&(const SIMD_Scalar &other)
SIMD_Scalar bswap() const
static bool enabled()
Definition simd_scalar.h:23
static SIMD_Scalar load_le(const void *in)
Definition simd_scalar.h:49
void operator+=(const SIMD_Scalar &other)
Definition simd_scalar.h:93
void rotate_left(size_t rot)
Definition simd_scalar.h:77
void store_le(byte out[]) const
Definition simd_scalar.h:67
void operator&=(const SIMD_Scalar &other)
void operator^=(const SIMD_Scalar &other)
static void transpose(SIMD_Scalar &B0, SIMD_Scalar &B1, SIMD_Scalar &B2, SIMD_Scalar &B3)
static SIMD_Scalar load_be(const void *in)
Definition simd_scalar.h:58
SIMD_Scalar operator-(const SIMD_Scalar &other) const
SIMD_Scalar operator+(const SIMD_Scalar &other) const
void rotate_right(size_t rot)
Definition simd_scalar.h:85
SIMD_Scalar(u32bit B)
Definition simd_scalar.h:41
void store_be(byte out[]) const
Definition simd_scalar.h:72
void operator|=(const SIMD_Scalar &other)
SIMD_Scalar(u32bit B0, u32bit B1, u32bit B2, u32bit B3)
Definition simd_scalar.h:33
SIMD_Scalar operator~() const
SIMD_Scalar andc(const SIMD_Scalar &other)
void operator-=(const SIMD_Scalar &other)
SIMD_Scalar(const u32bit B[4])
Definition simd_scalar.h:25
u16bit reverse_bytes(u16bit val)
Definition bswap.h:24
T load_be(const byte in[], size_t off)
Definition loadstor.h:100
T rotate_right(T input, size_t rot)
Definition rotate.h:34
T rotate_left(T input, size_t rot)
Definition rotate.h:21
T load_le(const byte in[], size_t off)
Definition loadstor.h:116
unsigned int u32bit
Definition types.h:32
void store_be(u16bit in, byte out[2])
Definition loadstor.h:412
void store_le(u16bit in, byte out[2])
Definition loadstor.h:427