QDP++
sse_dcomplex_mult_macros.h
Go to the documentation of this file.
1#ifndef SSE_DCOMPLEX_MULT_MACROS
2#define SSE_DCOMPLEX_MULT_MACROS
3
4#include "qdp_diagnostics.h"
5
6/* This selects the configuration */
7#include "qdp_config.h"
8
9/* SSE 2 Headers */
10#include<xmmintrin.h>
11
12/* A useful union type allows me to set values into the
13 vector from code */
14
15#ifndef QDP_USE_SSE3
16
17/* SSE2 macros */
18/* z = x*y z, x, y are SSE registers containing complex numbers
19 ordered with the real part in the low half, imag part
20 in the upper half */
21#define CMUL(z,x,y) \
22 { \
23 __m128d t1,t2,t3,t4; \
24 t1 = _mm_mul_pd(x,y); \
25 t2 = _mm_shuffle_pd(t1,t1,0x1); \
26 t3 = _mm_shuffle_pd(y,y,0x1);\
27 z = _mm_sub_pd(t1,t2); \
28 t2 = _mm_mul_pd(x,t3); \
29 t3 = _mm_shuffle_pd(t2,t2,0x1); \
30 t3 = _mm_add_pd(t2,t3); \
31 z= _mm_shuffle_pd(z,t3,0x2); \
32 }
33
34/* z += x*y z, x, y are SSE registers containing complex numbers
35 ordered with the real part in the low half, imag part
36 in the upper half */
37#define CMADD(z,x,y) \
38 { \
39 __m128d t1,t2,t3,t4; \
40 t1 = _mm_mul_pd(x,y); \
41 t2 = _mm_shuffle_pd(t1,t1,0x1); \
42 t3 = _mm_shuffle_pd(y,y,0x1);\
43 t4 = _mm_sub_pd(t1,t2); \
44 t2 = _mm_mul_pd(x,t3); \
45 t3 = _mm_shuffle_pd(t2,t2,0x1); \
46 t3 = _mm_add_pd(t2,t3); \
47 t4= _mm_shuffle_pd(t4,t3,0x2); \
48 z = _mm_add_pd(z,t4); \
49 }
50
51/* z = conj(x)*conj(y) z, x, y are SSE registers containing complex numbers
52 ordered with the real part in the low half, imag part
53 in the upper half */
54#define CCMUL(z,x,y) \
55 { \
56 __m128d t1,t2,t3; \
57 __m128d t4 = _mm_set_pd( (double)(-1), (double)1 ); \
58 t1 = _mm_mul_pd(x,y); \
59 t2 = _mm_shuffle_pd(t1,t1,0x1); \
60 t3 = _mm_shuffle_pd(y,y,0x1);\
61 z = _mm_sub_pd(t1,t2); \
62 t2 = _mm_mul_pd(x,t3); \
63 t3 = _mm_shuffle_pd(t2,t2,0x1); \
64 t3 = _mm_add_pd(t2,t3); \
65 z= _mm_shuffle_pd(z,t3,0x2); \
66 z= _mm_mul_pd(z,t4); \
67 }
68
69/* z += conj(x)*conj(y) z, x, y are SSE registers containing complex numbers
70 ordered with the real part in the low half, imag part
71 in the upper half */
72#define CCMADD(z,x,y) \
73 { \
74 __m128d t1,t2,t3,t4; \
75 __m128d t5 = _mm_set_pd( (double)(-1), (double)1 ); \
76 t1 = _mm_mul_pd(x,y); \
77 t2 = _mm_shuffle_pd(t1,t1,0x1); \
78 t3 = _mm_shuffle_pd(y,y,0x1);\
79 t4 = _mm_sub_pd(t1,t2); \
80 t2 = _mm_mul_pd(x,t3); \
81 t3 = _mm_shuffle_pd(t2,t2,0x1); \
82 t3 = _mm_add_pd(t2,t3); \
83 t4= _mm_shuffle_pd(t4,t3,0x2); \
84 t4= _mm_mul_pd(t5, t4); \
85 z = _mm_add_pd(z,t4); \
86 }
87
88
89/* z = x*conj(y) z, x, y are SSE registers containing complex numbers
90 ordered with the real part in the low half, imag part
91 in the upper half */
92#define CONJMUL(z,x,y) \
93 { \
94 __m128d t1,t2,t3,t4; \
95 t1 = _mm_mul_pd(x,y); \
96 t2 = _mm_shuffle_pd(t1,t1,0x1); \
97 t3 = _mm_shuffle_pd(y,y,0x1);\
98 z = _mm_add_pd(t1,t2); \
99 t2 = _mm_mul_pd(x,t3); \
100 t3 = _mm_shuffle_pd(t2,t2,0x1); \
101 t3 = _mm_sub_pd(t2,t3); \
102 z= _mm_shuffle_pd(z,t3,0x2); \
103 }
104
105/* z += x*conj(y) z, x, y are SSE registers containing complex numbers
106 ordered with the real part in the low half, imag part
107 in the upper half */
108#define CONJMADD(z,x,y) \
109 { \
110 __m128d t1,t2,t3,t4; \
111 t1 = _mm_mul_pd(x,y); \
112 t2 = _mm_shuffle_pd(t1,t1,0x1); \
113 t3 = _mm_shuffle_pd(y,y,0x1);\
114 t4 = _mm_add_pd(t1,t2); \
115 t2 = _mm_mul_pd(x,t3); \
116 t3 = _mm_shuffle_pd(t2,t2,0x1); \
117 t3 = _mm_sub_pd(t2,t3); \
118 t4= _mm_shuffle_pd(t4,t3,0x2); \
119 z = _mm_add_pd(z,t4); \
120 }
121
122
123
124#else
125QDPXX_MESSAGE("Using SSE3")
126/* SSE 3 */
127#include <pmmintrin.h>
128
129/* z = x*y z, x, y are SSE registers containing complex numbers
130 ordered with the real part in the low half, imag part
131 in the upper half */
132#define CMUL(z,x,y) \
133 { \
134 __m128d t1; \
135 t1 = _mm_mul_pd((x),(y)); \
136 (z) = _mm_hsub_pd(t1,t1); \
137 t1 = _mm_shuffle_pd((y),(y),0x1);\
138 t1 = _mm_mul_pd((x),t1); \
139 t1 = _mm_hadd_pd(t1,t1); \
140 (z)= _mm_shuffle_pd((z),t1,0x2); \
141 }
142
143/* z = conj(x)*conj(y) z, x, y are SSE registers containing complex numbers
144 ordered with the real part in the low half, imag part
145 in the upper half */
146#define CCMUL(z,x,y) \
147 { \
148 __m128d t1; \
149 __m128d t2 = _mm_set_pd((double)(-1), (double)1 ); \
150 t1 = _mm_mul_pd((x),(y)); \
151 (z) = _mm_hsub_pd(t1,t1); \
152 t1 = _mm_shuffle_pd((y),(y),0x1);\
153 t1 = _mm_mul_pd((x),t1); \
154 t1 = _mm_hadd_pd(t1,t1); \
155 (z)= _mm_shuffle_pd((z),t1,0x2); \
156 (z)= _mm_mul_pd((z),t2); \
157 }
158
159/* z += x*y z, x, y are SSE registers containing complex numbers
160 ordered with the real part in the low half, imag part
161 in the upper half */
162#define CMADD(z,x,y) \
163 { \
164 __m128d t1,t2; \
165 t1 = _mm_mul_pd((x),(y)); \
166 t1 = _mm_hsub_pd(t1,t1); \
167 t2 = _mm_shuffle_pd((y),(y),0x1);\
168 t2 = _mm_mul_pd((x),t2); \
169 t2 = _mm_hadd_pd(t2,t2); \
170 t1= _mm_shuffle_pd(t1,t2,0x2); \
171 (z) = _mm_add_pd((z),t1); \
172 }
173
174/* z += conj(x)*conj(y) z, x, y are SSE registers containing complex numbers
175 ordered with the real part in the low half, imag part
176 in the upper half */
177#define CCMADD(z,x,y) \
178 { \
179 __m128d t1,t2; \
180 __m128d t3 = _mm_set_pd( (double)(-1), (double)1 ); \
181 t1 = _mm_mul_pd((x),(y)); \
182 t1 = _mm_hsub_pd(t1,t1); \
183 t2 = _mm_shuffle_pd((y),(y),0x1);\
184 t2 = _mm_mul_pd((x),t2); \
185 t2 = _mm_hadd_pd(t2,t2); \
186 t1= _mm_shuffle_pd(t1,t2,0x2); \
187 t1= _mm_mul_pd(t3,t1); \
188 (z) = _mm_add_pd((z),t1); \
189 }
190
191/* z = x*conj(y) z, x, y are SSE registers containing complex numbers
192 ordered with the real part in the low half, imag part
193 in the upper half */
194#define CONJMUL(z,x,y) \
195 { \
196 __m128d t1; \
197 t1 = _mm_mul_pd((x),(y)); \
198 (z) = _mm_hadd_pd(t1,t1); \
199 t1 = _mm_shuffle_pd((x),(x),0x1);\
200 t1 = _mm_mul_pd((y),t1); \
201 t1 = _mm_hsub_pd(t1,t1); \
202 (z)= _mm_shuffle_pd((z),t1,0x2); \
203 }
204
205/* z += x*conj(y) z, x, y are SSE registers containing complex numbers
206 ordered with the real part in the low half, imag part
207 in the upper half */
208#define CONJMADD(z,x,y) \
209 { \
210 __m128d t1,t2; \
211 t1 = _mm_mul_pd((x),(y)); \
212 t1 = _mm_hadd_pd(t1,t1); \
213 t2 = _mm_shuffle_pd((x),(x),0x1);\
214 t2 = _mm_mul_pd((y),t2); \
215 t2 = _mm_hsub_pd(t2,t2); \
216 t1= _mm_shuffle_pd(t1,t2,0x2); \
217 (z) = _mm_add_pd((z),t1); \
218 }
219
220
221
222
223#endif
224#endif
#define QDPXX_MESSAGE(s)