1 /* Vectorized routines for PowerPC, using Altivec/VMX.
2 */
3 #ifndef eslVMX_INCLUDED
4 #define eslVMX_INCLUDED
5
6 #include "esl_config.h"
7 #ifdef eslENABLE_VMX
8
9 #include "easel.h"
10
11 #include <stdio.h>
12 #include <altivec.h>
13
14
15 extern vector float esl_vmx_logf(vector float x);
16 extern vector float esl_vmx_expf(vector float x);
17 extern void esl_vmx_dump_vecfloat(FILE *fp, vector float v);
18
19 /* Function: esl_vmx_set_float()
20 * Synopsis: Fills float vector with x.
21 *
22 * Purpose: Sets all elements in the vector <float> to x.
23 */
24 static inline vector float
esl_vmx_set_float(float x)25 esl_vmx_set_float(float x)
26 {
27 vector float v;
28 // vector unsigned char p;
29
30 v = vec_splats(x);
31 /* v = vec_lde(0, &x);
32 p = vec_lvsl(0, &x);
33 v = vec_perm(v, v, p);
34 v = vec_splat(v, 0); */
35 return v;
36 }
37
38 /* Function: esl_vmx_set_s16()
39 * Synopsis: Fills short vector with x.
40 *
41 * Purpose: Sets all elements in the vector <signed short> to x.
42 */
43 static inline vector signed short
esl_vmx_set_s16(signed short x)44 esl_vmx_set_s16(signed short x)
45 {
46 vector signed short v;
47 //vector unsigned char p;
48 v = vec_splats(x);
49 /*v = vec_lde(0, &x);
50 p = vec_lvsl(0, &x);
51 v = vec_perm(v, v, p);
52 v = vec_splat(v, 0); */
53 return v;
54 }
55
56 /* Function: esl_vmx_set_u8()
57 * Synopsis: Fills byte vector with x.
58 *
59 * Purpose: Sets all elements in the vector <unsigned char> to x.
60 */
61 static inline vector unsigned char
esl_vmx_set_u8(unsigned char x)62 esl_vmx_set_u8(unsigned char x)
63 {
64 vector unsigned char v;
65 //vector unsigned char p;
66 v = vec_splats(x);
67
68 /*v = vec_lde(0, &x);
69 p = vec_lvsl(0, &x);
70 v = vec_perm(v, v, p);
71 v = vec_splat(v, 0);*/
72 return v;
73 }
74
75 /* Function: esl_vmx_hsum_float()
76 * Synopsis: Returns sum of all floats.
77 *
78 * Purpose: Resturns the sum of all elements in the vector <float>.
79 */
80 static inline float
esl_vmx_hsum_float(vector float v)81 esl_vmx_hsum_float(vector float v)
82 {
83 float f;
84
85 v = vec_add(v, vec_sld(v, v, 4));
86 v = vec_add(v, vec_sld(v, v, 8));
87 vec_ste(v, 0, &f);
88
89 return f;
90 }
91
92 /* Function: esl_vmx_hsum_s16()
93 * Synopsis: Returns sum of all shorts.
94 *
95 * Purpose: Resturns the sum of all elements in the vector <signed short>.
96 */
97 static inline signed short
esl_vmx_hsum_s16(vector signed short v)98 esl_vmx_hsum_s16(vector signed short v)
99 {
100 signed short s;
101
102 v = vec_add(v, vec_sld(v, v, 2));
103 v = vec_add(v, vec_sld(v, v, 4));
104 v = vec_add(v, vec_sld(v, v, 8));
105 vec_ste(v, 0, &s);
106
107 return s;
108 }
109
110 /* Function: esl_vmx_hmax_float()
111 * Synopsis: Returns max of all floats.
112 *
113 * Purpose: Resturns the maximum element in the vector <float>.
114 */
115 static inline float
esl_vmx_hmax_float(vector float v)116 esl_vmx_hmax_float(vector float v)
117 {
118 float f;
119
120 v = vec_max(v, vec_sld(v, v, 4));
121 v = vec_max(v, vec_sld(v, v, 8));
122 vec_ste(v, 0, &f);
123
124 return f;
125 }
126
127 /* Function: esl_vmx_hmax_s16()
128 * Synopsis: Returns max of all shorts.
129 *
130 * Purpose: Resturns the maximum element in the vector <signed short>.
131 */
132 static inline signed short
esl_vmx_hmax_s16(vector signed short v)133 esl_vmx_hmax_s16(vector signed short v)
134 {
135 signed short s;
136
137 v = vec_max(v, vec_sld(v, v, 2));
138 v = vec_max(v, vec_sld(v, v, 4));
139 v = vec_max(v, vec_sld(v, v, 8));
140 vec_ste(v, 0, &s);
141
142 return s;
143 }
144
145 /* Function: esl_vmx_hmax_u8()
146 * Synopsis: Returns max of all bytes.
147 *
148 * Purpose: Resturns the maximum element in the vector <unsigned char>.
149 */
150 static inline unsigned char
esl_vmx_hmax_s8(vector signed char v)151 esl_vmx_hmax_s8(vector signed char v)
152 {
153 signed char s;
154
155 v = vec_vmaxsb(v, vec_sld(v, v, 1));
156 v = vec_vmaxsb(v, vec_sld(v, v, 2));
157 v = vec_vmaxsb(v, vec_sld(v, v, 4));
158 v = vec_vmaxsb(v, vec_sld(v, v, 8));
159 vec_ste(v, 0, &s);
160
161 return s;
162 }
163
164 /* Function: esl_vmx_rightshift_int8()
165 * Synopsis: Shift int8 vector elements to the right, shifting -inf on
166 * Incept: NPC, Thurs Jun 15 2017
167 *
168 * Purpose: Given an int8 vector <{ a0 .. a16}>, and a mask <{-inf,
169 * 0*15 }> with the desired value of -inf in slot 0
170 * (and zeros elsewhere), return <{ -inf, a0..a14 }>;
171 * i.e. shift the values in <a> to the right, while
172 * shifting $-\infty$ on.
173 *
174 * By our convention, "right" and "left" refer to memory
175 * order (low addresses on the left). On a little-endian
176 * (x86) architecture, this is a left shift in the hardware
177 * register.
178 *
179 * This can be used both for signed (epi8) and unsigned
180 * (epu8) int8 vectors.
181 *
182 * Xref: HMMER's simdvec.md: on our left/right convention.
183 */
184 static inline vector signed char
esl_vmx_rightshift_int8(vector signed char a,vector signed char neginfmask)185 esl_vmx_rightshift_int8(vector signed char a, vector signed char neginfmask)
186 {
187 vector signed char v2 = vec_sld(a, neginfmask, 1);
188 return v2;
189 }
190
191
192 /* Function: esl_vmx_rightshift_int16()
193 * Synopsis: Shift int16 vector elements to the right, shifting -inf on
194 * Incept: NPC, Thurs Jun 15 2017
195 *
196 * Purpose: Same as <esl_vmx_rightshift_int8()> but for int16.
197 */
198 static inline vector short
esl_vmx_rightshift_int16(vector short a,vector short neginfmask)199 esl_vmx_rightshift_int16(vector short a, vector short neginfmask)
200 {
201 vector short v2 = vec_sld(a, neginfmask, 2);
202 return v2;
203 }
204
205 /* Function: esl_sse_rightshiftz_float()
206 * Synopsis: Shift float vector elements to the right, shifting zero on.
207 *
208 * Purpose: Same as <esl_sse_rightshift_int8()> but for floats,
209 * and the value that is shifted on is a zero.
210 */
211 static inline vector float
esl_vmx_rightshiftz_float(vector float a)212 esl_vmx_rightshiftz_float(vector float a)
213 {
214 vector float v = {0.0, 0.0, 0.0, 0.0};
215 vector float v2 = vec_sld(a, v, 4);
216 return v2;
217 }
218
219 /* Function: esl_sse_leftshiftz_float()
220 * Synopsis: Shift float vector elements to the left, shifting zero on.
221 *
222 * Purpose: Same as <esl_sse_rightshift_float()> but leftwise: <[ a0 a1 a2
223 * a3 ]> becomes <[ a1 a2 a3 0 ]>. Used in Backwards.
224 */
225 static inline vector float
esl_vmx_leftshiftz_float(vector float a)226 esl_vmx_leftshiftz_float(vector float a)
227 {
228 vector float v = {0.0, 0.0, 0.0, 0.0};
229 vector float v2 = vec_sld(v, a, 12); // left-shifting the three high elements of a into a vector of zeroes
230 // gives the same result as right-shifting a by one element
231 return v2;
232 }
233
234
235 #endif /* eslENABLE_VMX */
236 #endif /*eslVMX_INCLUDED*/
237
238