moved firmext code into the backend dir
[libfirm] / ir / be / grgen / simd / C_Patterns / C_Patterns.c
1 /*****************************************************************************
2  * Program:  C_Patterns.c
3  * Function: C specification of complex operations for the simd optimization.
4  *                       The order in this file of the functions is IMPORTANT since an
5  *                       earlier defined function has a higher scheduling priority!
6  * Author:   Andreas Schoesser
7  * Date:     2007-02-13
8  *****************************************************************************/
9
10
11 #include <stdio.h>
12 #include "define_operation.h"
13
14 typedef int sse_32_2;
15
16 /* Vektor Load, 4 Komponents, single precision float */
17 void vload_4f_32(void)
18 {
19         float *param = Arg_0("vector", "memory", "gp");
20         float *result = Res("vector", "register", "xmm");
21         Emit(". movaps (%S0), %D0");
22         Priority(0);
23
24         result[0] = param[0];
25         result[1] = param[1];
26         result[2] = param[2];
27         result[3] = param[3];
28 }
29
30
31
32 void vload_16b(void)
33 {
34         unsigned char *param  = Arg_0("vector", "memory", "gp");
35         unsigned char *result = Res("vector", "register", "xmm");
36         Emit(". lddqu (%S0), %D0");
37         Priority(0);
38         CostSavings(10);
39
40         result[0] = param[0];
41         result[1] = param[1];
42         result[2] = param[2];
43         result[3] = param[3];
44         result[4] = param[4];
45         result[5] = param[5];
46         result[6] = param[6];
47         result[7] = param[7];
48         result[8] = param[8];
49         result[9] = param[9];
50         result[10] = param[10];
51         result[11] = param[11];
52         result[12] = param[12];
53         result[13] = param[13];
54         result[14] = param[14];
55         result[15] = param[15];
56 }
57
58
59
60 #if 0
61 /* Vektor Load, 4 Komponents, 32 Bit integer */
62 void vload_4_32(void)
63 {
64         sse_32_2 *param = Arg_0("vector", "memory", "gp");
65         sse_32_2 *result = Res("vector", "register", "xmm");
66         Emit(". movdqu (%S0), %D0");
67         Priority(0);
68
69         result[0] = param[0];
70         result[1] = param[1];
71         result[2] = param[2];
72         result[3] = param[3];
73 }
74
75
76 void vload_2_32(void)
77 {
78         sse_32_2 *param = Arg_0("vector", "memory", "gp");
79         sse_32_2 *result = Res("vector", "register", "xmm");
80         Emit(". movq (%S0), %D0");
81         Priority(1);
82
83         result[0] = param[0];
84         result[1] = param[1];
85 }
86
87
88 void vadd_2_32(void)
89 {
90         sse_32_2 *param0 = Arg_0("vector", "register", "xmm");
91         sse_32_2 *param1 = Arg_1("vector", "register", "xmm");
92         sse_32_2 *result = Res("vector", "register", "in_r0");
93         Emit(". paddd %S1, %S0");
94         Priority(2);
95
96
97         result[0] = param0[0] + param1[0];
98         result[1] = param0[1] + param1[1];
99 }
100 #endif
101
102 /** Register mode **/
103 void mulps_4_32(void)
104 {
105         float *param0 = Arg_0("vector", "register", "xmm");
106         float *param1 = Arg_1("vector", "register", "xmm");
107         float *result = Res("vector", "register", "in_r1");
108         Emit(". mulps %S1, %S0");
109         Priority(2);
110
111         result[0] = param0[0] * param1[0];
112         result[1] = param0[1] * param1[1];
113         result[2] = param0[2] * param1[2];
114         result[3] = param0[3] * param1[3];
115 }
116
117 /** Mem mode right **/
118 void mulps_4_32_am(void)
119 {
120         float *param0 = Arg_0("vector", "register", "xmm");
121         float *param1 = Arg_1("vector", "memory",   "gp");
122         float *result = Res("vector", "register", "in_r1");
123         Emit(". mulps %S1, %S0");
124         Priority(0);
125         CostSavings(5);
126
127         result[0] = param0[0] * param1[0];
128         result[1] = param0[1] * param1[1];
129         result[2] = param0[2] * param1[2];
130         result[3] = param0[3] * param1[3];
131 }
132
133
134
135 void add_horz_4_32(void)
136 {
137         float *param = Arg_0("vector", "register", "xmm");
138         float *result = Res("vector", "register", "in_r1");
139         Emit(". haddps %S0, %S0\\n. haddps %S0, %S0");
140         Priority(2);
141
142         result[0] = param[0] + param[1] + param[2] + param[3];
143 }
144
145
146  /************************************************************************/
147  /*                                                                      */
148  /************************************************************************/
149
150 void maxps(void)
151 {
152         float *a = Arg_0("vector", "register", "xmm");
153         float *b = Arg_1("vector", "register", "xmm");
154         float *r =   Res("vector", "register", "in_r1");
155         Emit(". maxps %S1, %S0");
156         Priority(2);
157
158         if(a[0] < b[0])
159                 r[0] = b[0];
160         else
161                 r[0] = a[0];
162
163         if(a[1] < b[1])
164                 r[1] = b[1];
165         else
166                 r[1] = a[1];
167
168         if(a[2] < b[2])
169                 r[2] = b[2];
170         else
171                 r[2] = a[2];
172
173         if(a[3] < b[3])
174                 r[3] = b[3];
175         else
176                 r[3] = a[3];
177 }
178
179 void psadbw()
180 {
181         unsigned char *a = Arg_0("vector", "register", "xmm");
182         unsigned char *b = Arg_1("vector", "register", "xmm");
183         unsigned int  *r =   Res("vector", "register", "in_r1");
184         Emit(". psadbw %S1, %S0\\n. phaddd %S0, %S0\\n. phaddd %S0, %S0");
185         Priority(2);
186
187         r[0] = ((a[0] > b[0]) ? (a[0] - b[0]) : (b[0] - a[0])) +
188                ((a[1] > b[1]) ? (a[1] - b[1]) : (b[1] - a[1])) +
189                ((a[2] > b[2]) ? (a[2] - b[2]) : (b[2] - a[2])) +
190                    ((a[3] > b[3]) ? (a[3] - b[3]) : (b[3] - a[3])) +
191                    ((a[4] > b[4]) ? (a[4] - b[4]) : (b[4] - a[4])) +
192                ((a[5] > b[5]) ? (a[5] - b[5]) : (b[5] - a[5])) +
193                ((a[6] > b[6]) ? (a[6] - b[6]) : (b[6] - a[6])) +
194                ((a[7] > b[7]) ? (a[7] - b[7]) : (b[7] - a[7])) +
195                ((a[8] > b[8]) ? (a[8] - b[8]) : (b[8] - a[8])) +
196                ((a[9] > b[9]) ? (a[9] - b[9]) : (b[9] - a[9])) +
197                ((a[10] > b[10]) ? (a[10] - b[10]) : (b[10] - a[10])) +
198                ((a[11] > b[11]) ? (a[11] - b[11]) : (b[11] - a[11])) +
199                ((a[12] > b[12]) ? (a[12] - b[12]) : (b[12] - a[12])) +
200                ((a[13] > b[13]) ? (a[13] - b[13]) : (b[13] - a[13])) +
201                ((a[14] > b[14]) ? (a[14] - b[14]) : (b[14] - a[14])) +
202                ((a[15] > b[15]) ? (a[15] - b[15]) : (b[15] - a[15]));
203 }
204
205 /*void sadps(void)
206 {
207         float *a = Arg_0("vector", "register", "xmm");
208         float *b = Arg_1("vector", "register", "xmm");
209         float *r =   Res("vector", "register", "in_r1");
210
211         r[0] = (a[0] - b[0]) + (a[1] - b[1]) + (a[2] - b[2]) + (a[3] - b[3]);
212
213
214 } */
215
216
217 void vstore_4f(void)
218 {
219         float *param =   Arg_0("vector", "register", "xmm");
220         float *result =  Arg_1("vector", "memory", "gp");
221         Emit(". movaps %S0, (%S1)");
222         Priority(4);
223
224         result[0] = param[0];
225         result[1] = param[1];
226         result[2] = param[2];
227         result[3] = param[3];
228 }
229
230
231
232 #if 0
233 /************************************************************************/
234 /* vstore                                                               */
235 /* Input:     Vector register 1 v1, memory pointer p1                   */
236 /* Output:    None.                                                     */
237 /* Operation: Store the components of v1 at memory location p1.         */
238 /************************************************************************/
239
240 void vstore_4_32(void)
241 {
242         sse_32_2 *param = Arg_0("vector", "register", "xmm");
243         sse_32_2 *result = Arg_1("vector", "memory", "gp");
244         Emit(". movq %S0, (%S1)");
245         Priority(4);
246
247         result[0] = param[0];
248         result[1] = param[1];
249         result[2] = param[2];
250         result[3] = param[3];
251 }
252
253
254 void vstore_2_32(void)
255 {
256         sse_32_2 *param = Arg_0("vector", "register", "xmm");
257         sse_32_2 *result = Arg_1("vector", "memory", "gp");
258         Emit(". movq %S0, (%S1)");
259         Priority(5);
260
261         result[0] = param[0];
262         result[1] = param[1];
263 }
264
265 #endif
266
267 void component_0f(void)
268 {
269         float *b = Arg_0("vector", "register", "xmm");
270         float *r = Res("scalar", "register", "xmm");
271         Priority(PRIORITY_CLEANUP);
272         Emit("");//. movd %S0, %D0");
273
274         *r = b[0];
275 }
276
277
278
279
280 void component_0Iu(void)
281 {
282         int *b = Arg_0("vector", "register", "xmm");
283         int *r = Res("scalar", "register", "gp");
284         Priority(PRIORITY_CLEANUP);
285         Emit(". movd %S0, %D0");
286
287         *r = b[0];
288 }
289 #if 0
290 void component_0(void)
291 {
292         sse_32_2 *b = Arg_0("vector", "register", "xmm");
293         sse_32_2 *r = Res("scalar", "register", "gp");
294         Priority(PRIORITY_CLEANUP);
295         Emit(". movd %S0, %D0");
296
297         *r = b[0];
298 }
299
300 void component_1(void)
301 {
302         sse_32_2 *b = Arg_0("vector", "register", "xmm");
303         sse_32_2 *r = Res("scalar", "register", "gp");
304         Destroys("in_r0");
305         Priority(PRIORITY_CLEANUP);
306         Emit(". psrldq \\$4, %S0 \\n. movd %S0, %D0");
307
308         *r = b[1];
309 }
310
311 void component_2(void)
312 {
313         sse_32_2 *b = Arg_0("vector", "register", "xmm");
314         sse_32_2 *r = Res("scalar", "register", "gp");
315         Destroys("in_r0");
316         Priority(PRIORITY_CLEANUP);
317         Emit(". psrldq \\$8, %S0 \\n. movd %S0, %D0");
318
319         *r = b[2];
320 }
321
322 void component_3(void)
323 {
324         sse_32_2 *b = Arg_0("vector", "register", "xmm");
325         sse_32_2 *r = Res("scalar", "register", "gp");
326         Destroys("in_r0");
327         Priority(PRIORITY_CLEANUP);
328         Emit(". psrldq \\$12, %S0 \\n. movd %S0, %D0");
329
330         *r = b[3];
331 }
332
333
334 /********************************
335  * THIS IS SSE3!
336  ********************************/
337
338
339 void packed_add_8_32(void)
340 {
341         sse_32_2 *a = Arg_0("vector", "register", "xmm");
342         sse_32_2 *b = Arg_1("vector", "register", "xmm");
343         sse_32_2 *r = Res("vector",   "register", "in_r0");
344         Priority(3);
345         Emit(". haddps %S1, %S0");
346
347         r[0] = a[0] + a[1];
348         r[1] = a[2] + b[3];
349         r[2] = b[0] + b[1];
350         r[3] = b[2] + b[3];
351 }
352 #endif