Git init
[profile/ivi/liboil.git] / liboil / i386_amd64 / mas.c
1
2 #include <liboil/liboilfunction.h>
3 #include <liboil/liboilclasses.h>
4
5
6 void
7 mas10_u8_mmx (uint8_t *d, const uint8_t *s1_np9, const int16_t *s2_10,
8         const int16_t *s3_2, int n)
9 {
10   int j;
11   int x;
12
13   while(n&3) {
14     x = 0;
15     for(j=0;j<10;j++){
16       x += s1_np9[j] * s2_10[j];
17     }
18     *d = CLAMP((x + s3_2[0])>>s3_2[1],0,255);
19     d++;
20     s1_np9++;
21     n--;
22   }
23
24   if (n == 0) return;
25   n>>=2;
26   __asm__ __volatile__("\n"
27       "  pxor %%mm7, %%mm7\n"
28
29       "  movd (%[s3_2]), %%mm6\n"
30
31       "  movzwl 2(%[s3_2]), %%ecx\n"
32       "  movd %%ecx, %%mm5\n"
33
34       "1:\n"
35       /* load 128 */
36       "  pshufw $0x00, %%mm6, %%mm2\n"
37
38 #define LOOP(x) \
39       "  movd " #x "(%[s1_np9]), %%mm0\n" \
40       "  punpcklbw %%mm7, %%mm0\n" \
41       "  movq 2*" #x "(%[s2_10]), %%mm1\n" \
42       "  pshufw $0x00, %%mm1, %%mm1\n" \
43       "  pmullw %%mm1, %%mm0\n" \
44       "  paddw %%mm0, %%mm2\n"
45
46       LOOP(0)
47       LOOP(1)
48       LOOP(2)
49       LOOP(3)
50       LOOP(4)
51       LOOP(5)
52       LOOP(6)
53       LOOP(7)
54       LOOP(8)
55       LOOP(9)
56 #undef LOOP
57
58       "  psraw %%mm5, %%mm2\n"
59       "  pmaxsw %%mm7, %%mm2\n"
60       "  packuswb %%mm2, %%mm2\n"
61       "  movd %%mm2, 0(%[d])\n"
62       "  add $4, %[d]\n"
63       "  add $4, %[s1_np9]\n"
64       "  decl %[n]\n"
65       "  jnz 1b\n"
66       "  emms\n"
67       : [d] "+r" (d),
68         [s1_np9] "+r" (s1_np9),
69         [n] "+m" (n)
70       : [s2_10] "r" (s2_10),
71         [s3_2] "r" (s3_2)
72       : "ecx");
73 }
74 OIL_DEFINE_IMPL_FULL (mas10_u8_mmx, mas10_u8_l15, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
75
76 #if 0
77 void
78 mas10_u8_mmx_2 (uint8_t *d, const uint8_t *s1_np9, const int16_t *s2_10,
79         const int16_t *s3_2, int n)
80 {
81   int j;
82   int x;
83   int16_t coeff[4*10];
84   int16_t *ptr;
85
86   ptr = coeff;
87
88   while(n&3) {
89     x = 0;
90     for(j=0;j<10;j++){
91       x += s1_np9[j] * s2_10[j];
92     }
93     *d = CLAMP((x + s3_2[0])>>s3_2[1],0,255);
94     d++;
95     s1_np9++;
96     n--;
97   }
98
99   for(j=0;j<10;j++){
100     ptr[4*j + 0] = s2_10[j];
101     ptr[4*j + 1] = s2_10[j];
102     ptr[4*j + 2] = s2_10[j];
103     ptr[4*j + 3] = s2_10[j];
104   }
105
106   if (n == 0) return;
107   n>>=2;
108   __asm__ __volatile__("\n"
109       "  pxor %%mm7, %%mm7\n"
110
111       "  movd (%[s3_2]), %%mm6\n"
112
113       "  movzwl 2(%[s3_2]), %%ecx\n"
114       "  movd %%ecx, %%mm5\n"
115
116       "1:\n"
117       /* load 128 */
118       "  pshufw $0x00, %%mm6, %%mm2\n"
119
120 #define LOOP(x) \
121       "  movd " #x "(%[s1_np9]), %%mm0\n" \
122       "  punpcklbw %%mm7, %%mm0\n" \
123       "  pmullw 8*" #x "(%[coeff]), %%mm0\n" \
124       "  paddw %%mm0, %%mm2\n"
125
126       LOOP(0)
127       LOOP(1)
128       LOOP(2)
129       LOOP(3)
130       LOOP(4)
131       LOOP(5)
132       LOOP(6)
133       LOOP(7)
134       LOOP(8)
135       LOOP(9)
136 #undef LOOP
137
138       "  psraw %%mm5, %%mm2\n"
139       "  pmaxsw %%mm7, %%mm2\n"
140       "  packuswb %%mm2, %%mm2\n"
141       "  movd %%mm2, 0(%[d])\n"
142       "  add $4, %[d]\n"
143       "  add $4, %[s1_np9]\n"
144       "  decl %[n]\n"
145       "  jnz 1b\n"
146       "  emms\n"
147       : [d] "+r" (d),
148         [s1_np9] "+r" (s1_np9),
149         [n] "+m" (n)
150       : [coeff] "r" (ptr),
151         [s3_2] "r" (s3_2)
152       : "ecx");
153 }
154 OIL_DEFINE_IMPL_FULL (mas10_u8_mmx_2, mas10_u8_l15, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
155 #endif
156
157 void
158 mas10_u8_mmx_3 (uint8_t *d, const uint8_t *s1_np9, const int16_t *s2_10,
159         const int16_t *s3_2, int n)
160 {
161   int j;
162   int x;
163
164   while(n&3) {
165     x = 0;
166     for(j=0;j<10;j++){
167       x += s1_np9[j] * s2_10[j];
168     }
169     *d = CLAMP((x + s3_2[0])>>s3_2[1],0,255);
170     d++;
171     s1_np9++;
172     n--;
173   }
174
175   if (n == 0) return;
176   n>>=2;
177   __asm__ __volatile__("\n"
178       "  pxor %%mm7, %%mm7\n"
179
180       "  movd (%[s3_2]), %%mm6\n"
181
182       "  movzwl 2(%[s3_2]), %%ecx\n"
183       "  movd %%ecx, %%mm5\n"
184
185       "  movq 0(%[s2_10]), %%mm3\n"
186       "  movq 8(%[s2_10]), %%mm4\n"
187
188       "1:\n"
189       /* load 128 */
190       "  pshufw $0x00, %%mm6, %%mm2\n"
191
192 #define LOOP(x) \
193       "  movd " #x "(%[s1_np9]), %%mm0\n" \
194       "  punpcklbw %%mm7, %%mm0\n" \
195       "  movq 2*" #x "(%[s2_10]), %%mm1\n" \
196       "  pshufw $0x00, %%mm1, %%mm1\n" \
197       "  pmullw %%mm1, %%mm0\n" \
198       "  paddw %%mm0, %%mm2\n"
199
200       //LOOP(0)
201       "  movd 0(%[s1_np9]), %%mm0\n"
202       "  punpcklbw %%mm7, %%mm0\n"
203       "  pshufw $0x00, %%mm3, %%mm1\n"
204       "  pmullw %%mm1, %%mm0\n"
205       "  paddw %%mm0, %%mm2\n"
206
207       //LOOP(1)
208       "  movd 1(%[s1_np9]), %%mm0\n"
209       "  punpcklbw %%mm7, %%mm0\n"
210       "  pshufw $0x55*1, %%mm3, %%mm1\n"
211       "  pmullw %%mm1, %%mm0\n"
212       "  paddw %%mm0, %%mm2\n"
213
214       //LOOP(2)
215       "  movd 2(%[s1_np9]), %%mm0\n"
216       "  punpcklbw %%mm7, %%mm0\n"
217       "  pshufw $0x55*2, %%mm3, %%mm1\n"
218       "  pmullw %%mm1, %%mm0\n"
219       "  paddw %%mm0, %%mm2\n"
220
221       //LOOP(3)
222       "  movd 3(%[s1_np9]), %%mm0\n"
223       "  punpcklbw %%mm7, %%mm0\n"
224       "  pshufw $0x55*3, %%mm3, %%mm1\n"
225       "  pmullw %%mm1, %%mm0\n"
226       "  paddw %%mm0, %%mm2\n"
227
228       //LOOP(4)
229       "  movd 4(%[s1_np9]), %%mm0\n"
230       "  punpcklbw %%mm7, %%mm0\n"
231       "  pshufw $0x00, %%mm4, %%mm1\n"
232       "  pmullw %%mm1, %%mm0\n"
233       "  paddw %%mm0, %%mm2\n"
234
235       //LOOP(5)
236       "  movd 5(%[s1_np9]), %%mm0\n"
237       "  punpcklbw %%mm7, %%mm0\n"
238       "  pshufw $0x55*1, %%mm4, %%mm1\n"
239       "  pmullw %%mm1, %%mm0\n"
240       "  paddw %%mm0, %%mm2\n"
241
242       //LOOP(6)
243       "  movd 6(%[s1_np9]), %%mm0\n"
244       "  punpcklbw %%mm7, %%mm0\n"
245       "  pshufw $0x55*2, %%mm4, %%mm1\n"
246       "  pmullw %%mm1, %%mm0\n"
247       "  paddw %%mm0, %%mm2\n"
248
249       //LOOP(7)
250       "  movd 7(%[s1_np9]), %%mm0\n"
251       "  punpcklbw %%mm7, %%mm0\n"
252       "  pshufw $0x55*3, %%mm4, %%mm1\n"
253       "  pmullw %%mm1, %%mm0\n"
254       "  paddw %%mm0, %%mm2\n"
255
256       LOOP(8)
257       LOOP(9)
258 #undef LOOP
259
260       "  psraw %%mm5, %%mm2\n"
261       "  pmaxsw %%mm7, %%mm2\n"
262       "  packuswb %%mm2, %%mm2\n"
263       "  movd %%mm2, 0(%[d])\n"
264       "  add $4, %[d]\n"
265       "  add $4, %[s1_np9]\n"
266       "  decl %[n]\n"
267       "  jnz 1b\n"
268       "  emms\n"
269       : [d] "+r" (d),
270         [s1_np9] "+r" (s1_np9),
271         [n] "+m" (n)
272       : [s2_10] "r" (s2_10),
273         [s3_2] "r" (s3_2)
274       : "ecx");
275 }
276 OIL_DEFINE_IMPL_FULL (mas10_u8_mmx_3, mas10_u8_l15, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
277
278 void
279 mas10_u8_mmx_4 (uint8_t *d, const uint8_t *s1_np9, const int16_t *s2_10,
280         const int16_t *s3_2, int n)
281 {
282   if (n == 0) return;
283   __asm__ __volatile__("\n"
284       "  pxor %%mm7, %%mm7\n"
285
286       "  movzwl 0(%[s3_2]), %%ecx\n"
287       "  movd %%ecx, %%mm6\n"
288
289       "  movzwl 2(%[s3_2]), %%ecx\n"
290       "  movd %%ecx, %%mm5\n"
291
292       "1:\n"
293       "  movd 0(%[s1_np9]), %%mm0\n"
294       "  punpcklbw %%mm7, %%mm0\n"
295       "  pmaddwd 0(%[s2_10]), %%mm0\n"
296
297       "  movd 4(%[s1_np9]), %%mm1\n"
298       "  punpcklbw %%mm7, %%mm1\n"
299       "  pmaddwd 8(%[s2_10]), %%mm1\n"
300
301       "  movd 8(%[s1_np9]), %%mm2\n"
302       "  punpcklbw %%mm7, %%mm2\n"
303       "  pmaddwd 16(%[s2_10]), %%mm2\n"
304
305       "  paddd %%mm1, %%mm0\n"
306       "  movq %%mm0, %%mm1\n"
307       "  psrlq $32, %%mm0\n"
308       "  paddd %%mm1, %%mm0\n"
309       "  paddd %%mm2, %%mm0\n"
310       "  paddd %%mm6, %%mm0\n"
311
312       "  psrad %%mm5, %%mm0\n"
313       "  pmaxsw %%mm7, %%mm0\n"
314       "  packuswb %%mm0, %%mm0\n"
315       "  movd %%mm0, %%ecx\n"
316       "  movb %%cl,0(%[d])\n"
317
318       "  add $1, %[d]\n"
319       "  add $1, %[s1_np9]\n"
320       "  decl %[n]\n"
321       "  jnz 1b\n"
322       "  emms\n"
323       : [d] "+r" (d),
324         [s1_np9] "+r" (s1_np9),
325         [n] "+m" (n)
326       : [s2_10] "r" (s2_10),
327         [s3_2] "r" (s3_2)
328       : "ecx");
329 }
330 OIL_DEFINE_IMPL_FULL (mas10_u8_mmx_4, mas10_u8, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
331
332
333 void
334 mas8_u8_mmx_3 (uint8_t *d, const uint8_t *s1_np7, const int16_t *s2_8,
335         const int16_t *s3_2, int n)
336 {
337   int j;
338   int x;
339
340   while(n&3) {
341     x = 0;
342     for(j=0;j<8;j++){
343       x += s1_np7[j] * s2_8[j];
344     }
345     *d = CLAMP((x + s3_2[0])>>s3_2[1],0,255);
346     d++;
347     s1_np7++;
348     n--;
349   }
350
351   if (n == 0) return;
352   n>>=2;
353   __asm__ __volatile__("\n"
354       "  pxor %%mm7, %%mm7\n"
355
356       "  movd (%[s3_2]), %%mm6\n"
357
358       "  movzwl 2(%[s3_2]), %%ecx\n"
359       "  movd %%ecx, %%mm5\n"
360
361       "  movq 0(%[s2_8]), %%mm3\n"
362       "  movq 8(%[s2_8]), %%mm4\n"
363
364       "1:\n"
365       /* load 128 */
366       "  pshufw $0x00, %%mm6, %%mm2\n"
367
368       "  movd 0(%[s1_np7]), %%mm0\n"
369       "  punpcklbw %%mm7, %%mm0\n"
370       "  pshufw $0x00, %%mm3, %%mm1\n"
371       "  pmullw %%mm1, %%mm0\n"
372       "  paddw %%mm0, %%mm2\n"
373
374       "  movd 1(%[s1_np7]), %%mm0\n"
375       "  punpcklbw %%mm7, %%mm0\n"
376       "  pshufw $0x55*1, %%mm3, %%mm1\n"
377       "  pmullw %%mm1, %%mm0\n"
378       "  paddw %%mm0, %%mm2\n"
379
380       "  movd 2(%[s1_np7]), %%mm0\n"
381       "  punpcklbw %%mm7, %%mm0\n"
382       "  pshufw $0x55*2, %%mm3, %%mm1\n"
383       "  pmullw %%mm1, %%mm0\n"
384       "  paddw %%mm0, %%mm2\n"
385
386       "  movd 3(%[s1_np7]), %%mm0\n"
387       "  punpcklbw %%mm7, %%mm0\n"
388       "  pshufw $0x55*3, %%mm3, %%mm1\n"
389       "  pmullw %%mm1, %%mm0\n"
390       "  paddw %%mm0, %%mm2\n"
391
392       "  movd 4(%[s1_np7]), %%mm0\n"
393       "  punpcklbw %%mm7, %%mm0\n"
394       "  pshufw $0x00, %%mm4, %%mm1\n"
395       "  pmullw %%mm1, %%mm0\n"
396       "  paddw %%mm0, %%mm2\n"
397
398       "  movd 5(%[s1_np7]), %%mm0\n"
399       "  punpcklbw %%mm7, %%mm0\n"
400       "  pshufw $0x55*1, %%mm4, %%mm1\n"
401       "  pmullw %%mm1, %%mm0\n"
402       "  paddw %%mm0, %%mm2\n"
403
404       "  movd 6(%[s1_np7]), %%mm0\n"
405       "  punpcklbw %%mm7, %%mm0\n"
406       "  pshufw $0x55*2, %%mm4, %%mm1\n"
407       "  pmullw %%mm1, %%mm0\n"
408       "  paddw %%mm0, %%mm2\n"
409
410       "  movd 7(%[s1_np7]), %%mm0\n"
411       "  punpcklbw %%mm7, %%mm0\n"
412       "  pshufw $0x55*3, %%mm4, %%mm1\n"
413       "  pmullw %%mm1, %%mm0\n"
414       "  paddw %%mm0, %%mm2\n"
415
416       "  psraw %%mm5, %%mm2\n"
417       "  pmaxsw %%mm7, %%mm2\n"
418       "  packuswb %%mm2, %%mm2\n"
419       "  movd %%mm2, 0(%[d])\n"
420       "  add $4, %[d]\n"
421       "  add $4, %[s1_np7]\n"
422       "  decl %[n]\n"
423       "  jnz 1b\n"
424       "  emms\n"
425       : [d] "+r" (d),
426         [s1_np7] "+r" (s1_np7),
427         [n] "+m" (n)
428       : [s2_8] "r" (s2_8),
429         [s3_2] "r" (s3_2)
430       : "ecx");
431 }
432 OIL_DEFINE_IMPL_FULL (mas8_u8_mmx_3, mas8_u8_l15, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
433
434 void
435 mas8_u8_mmx_4 (uint8_t *d, const uint8_t *s1_np7, const int16_t *s2_8,
436         const int16_t *s3_2, int n)
437 {
438   if (n == 0) return;
439   __asm__ __volatile__("\n"
440       "  pxor %%mm7, %%mm7\n"
441
442       "  movzwl 0(%[s3_2]), %%ecx\n"
443       "  movd %%ecx, %%mm6\n"
444
445       "  movzwl 2(%[s3_2]), %%ecx\n"
446       "  movd %%ecx, %%mm5\n"
447
448       "1:\n"
449       "  movd 0(%[s1_np7]), %%mm0\n"
450       "  punpcklbw %%mm7, %%mm0\n"
451       "  pmaddwd 0(%[s2_8]), %%mm0\n"
452
453       "  movd 4(%[s1_np7]), %%mm1\n"
454       "  punpcklbw %%mm7, %%mm1\n"
455       "  pmaddwd 8(%[s2_8]), %%mm1\n"
456
457       "  paddd %%mm1, %%mm0\n"
458       "  movq %%mm0, %%mm1\n"
459       "  psrlq $32, %%mm0\n"
460       "  paddd %%mm1, %%mm0\n"
461       "  paddd %%mm6, %%mm0\n"
462
463       "  psrad %%mm5, %%mm0\n"
464       "  pmaxsw %%mm7, %%mm0\n"
465       "  packuswb %%mm0, %%mm0\n"
466       "  movd %%mm0, %%ecx\n"
467       "  movb %%cl,0(%[d])\n"
468
469       "  add $1, %[d]\n"
470       "  add $1, %[s1_np7]\n"
471       "  decl %[n]\n"
472       "  jnz 1b\n"
473       "  emms\n"
474       : [d] "+r" (d),
475         [s1_np7] "+r" (s1_np7),
476         [n] "+m" (n)
477       : [s2_8] "r" (s2_8),
478         [s3_2] "r" (s3_2)
479       : "ecx");
480 }
481 OIL_DEFINE_IMPL_FULL (mas8_u8_mmx_4, mas8_u8, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
482
483 void
484 mas8_u8_sym_mmx_3 (uint8_t *d, const uint8_t *s1_np7, const int16_t *s2_8,
485         const int16_t *s3_2, int n)
486 {
487   int j;
488   int x;
489
490   while(n&3) {
491     x = 0;
492     for(j=0;j<8;j++){
493       x += s1_np7[j] * s2_8[j];
494     }
495     *d = CLAMP((x + s3_2[0])>>s3_2[1],0,255);
496     d++;
497     s1_np7++;
498     n--;
499   }
500
501   if (n == 0) return;
502   n>>=2;
503   __asm__ __volatile__("\n"
504       "  pxor %%mm7, %%mm7\n"
505
506       "  movd (%[s3_2]), %%mm6\n"
507
508       "  movzwl 2(%[s3_2]), %%ecx\n"
509       "  movd %%ecx, %%mm5\n"
510
511       "  movq 0(%[s2_8]), %%mm3\n"
512       "  movq 8(%[s2_8]), %%mm4\n"
513
514       " .p2align 4,,15                  \n"
515       "1:\n"
516       /* load 128 */
517       "  pshufw $0x00, %%mm6, %%mm2\n"
518
519       "  movd 0(%[s1_np7]), %%mm0\n"
520       "  punpcklbw %%mm7, %%mm0\n"
521       "  movd 7(%[s1_np7]), %%mm1\n"
522       "  punpcklbw %%mm7, %%mm1\n"
523       "  paddw %%mm1, %%mm0\n"
524       //"  pshufw $0x00, %%mm3, %%mm1\n"
525       //"  pmullw %%mm1, %%mm0\n"
526       //"  paddw %%mm0, %%mm2\n"
527       "  psubw %%mm0, %%mm2\n"
528
529       "  movd 1(%[s1_np7]), %%mm0\n"
530       "  punpcklbw %%mm7, %%mm0\n"
531       "  movd 6(%[s1_np7]), %%mm1\n"
532       "  punpcklbw %%mm7, %%mm1\n"
533       "  paddw %%mm1, %%mm0\n"
534       "  pshufw $0x55*1, %%mm3, %%mm1\n"
535       "  pmullw %%mm1, %%mm0\n"
536       "  paddw %%mm0, %%mm2\n"
537
538       "  movd 2(%[s1_np7]), %%mm0\n"
539       "  punpcklbw %%mm7, %%mm0\n"
540       "  movd 5(%[s1_np7]), %%mm1\n"
541       "  punpcklbw %%mm7, %%mm1\n"
542       "  paddw %%mm1, %%mm0\n"
543       "  pshufw $0x55*2, %%mm3, %%mm1\n"
544       "  pmullw %%mm1, %%mm0\n"
545       "  paddw %%mm0, %%mm2\n"
546
547       "  movd 3(%[s1_np7]), %%mm0\n"
548       "  punpcklbw %%mm7, %%mm0\n"
549       "  movd 4(%[s1_np7]), %%mm1\n"
550       "  punpcklbw %%mm7, %%mm1\n"
551       "  paddw %%mm1, %%mm0\n"
552       "  pshufw $0x55*3, %%mm3, %%mm1\n"
553       "  pmullw %%mm1, %%mm0\n"
554       "  paddw %%mm0, %%mm2\n"
555
556       "  psraw %%mm5, %%mm2\n"
557       "  pmaxsw %%mm7, %%mm2\n"
558       "  packuswb %%mm2, %%mm2\n"
559       "  movd %%mm2, 0(%[d])\n"
560       "  add $4, %[d]\n"
561       "  add $4, %[s1_np7]\n"
562       "  decl %[n]\n"
563       "  jnz 1b\n"
564       "  emms\n"
565       : [d] "+r" (d),
566         [s1_np7] "+r" (s1_np7),
567         [n] "+m" (n)
568       : [s2_8] "r" (s2_8),
569         [s3_2] "r" (s3_2)
570       : "ecx");
571 }
572 OIL_DEFINE_IMPL_FULL (mas8_u8_sym_mmx_3, mas8_u8_sym_l15, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
573
574 void
575 mas8_u8_sym_mmx_41 (uint8_t *d, const uint8_t *s1_np7, const int16_t *s2_8,
576         const int16_t *s3_2, int n)
577 {
578   int j;
579   int x;
580   int16_t tmp[16];
581
582   while(n&3) {
583     x = 0;
584     for(j=0;j<8;j++){
585       x += s1_np7[j] * s2_8[j];
586     }
587     *d = CLAMP((x + s3_2[0])>>s3_2[1],0,255);
588     d++;
589     s1_np7++;
590     n--;
591   }
592
593   if (n == 0) return;
594   n>>=2;
595   __asm__ __volatile__("\n"
596       "  pxor %%mm7, %%mm7\n"
597
598       "  movd (%[s3_2]), %%mm6\n"
599
600       "  movzwl 2(%[s3_2]), %%ecx\n"
601       "  movd %%ecx, %%mm5\n"
602
603       "  movq 0(%[s2_8]), %%mm3\n"
604       "  pshufw $0x55*0, %%mm3, %%mm1\n"
605       "  movq %%mm1, 0(%[coeff])\n"
606       "  pshufw $0x55*1, %%mm3, %%mm1\n"
607       "  movq %%mm1, 8(%[coeff])\n"
608       "  pshufw $0x55*2, %%mm3, %%mm1\n"
609       "  movq %%mm1, 16(%[coeff])\n"
610       "  pshufw $0x55*3, %%mm3, %%mm1\n"
611       "  movq %%mm1, 24(%[coeff])\n"
612       :
613       : [s2_8] "r" (s2_8),
614         [s3_2] "r" (s3_2),
615         [coeff] "r" (tmp)
616       : "ecx");
617
618   __asm__ __volatile__("\n"
619       " .p2align 4,,15                  \n"
620       "1:\n"
621       /* load 128 */
622       "  pshufw $0x00, %%mm6, %%mm2\n"
623
624       "  movd 0(%[s1_np7]), %%mm0\n"
625       "  punpcklbw %%mm7, %%mm0\n"
626       "  movd 7(%[s1_np7]), %%mm1\n"
627       "  punpcklbw %%mm7, %%mm1\n"
628       "  paddw %%mm1, %%mm0\n"
629       "  pmullw 0(%[coeff]), %%mm0\n"
630       "  paddw %%mm0, %%mm2\n"
631
632       "  movd 1(%[s1_np7]), %%mm0\n"
633       "  punpcklbw %%mm7, %%mm0\n"
634       "  movd 6(%[s1_np7]), %%mm1\n"
635       "  punpcklbw %%mm7, %%mm1\n"
636       "  paddw %%mm1, %%mm0\n"
637       "  pmullw 8(%[coeff]), %%mm0\n"
638       "  paddw %%mm0, %%mm2\n"
639
640       "  movd 2(%[s1_np7]), %%mm0\n"
641       "  punpcklbw %%mm7, %%mm0\n"
642       "  movd 5(%[s1_np7]), %%mm1\n"
643       "  punpcklbw %%mm7, %%mm1\n"
644       "  paddw %%mm1, %%mm0\n"
645       "  pmullw 16(%[coeff]), %%mm0\n"
646       "  paddw %%mm0, %%mm2\n"
647
648       "  movd 3(%[s1_np7]), %%mm0\n"
649       "  punpcklbw %%mm7, %%mm0\n"
650       "  movd 4(%[s1_np7]), %%mm1\n"
651       "  punpcklbw %%mm7, %%mm1\n"
652       "  paddw %%mm1, %%mm0\n"
653       "  pmullw 24(%[coeff]), %%mm0\n"
654       "  paddw %%mm0, %%mm2\n"
655
656       "  psraw %%mm5, %%mm2\n"
657       "  pmaxsw %%mm7, %%mm2\n"
658       "  packuswb %%mm2, %%mm2\n"
659       "  movd %%mm2, 0(%[d])\n"
660       "  add $4, %[d]\n"
661       "  add $4, %[s1_np7]\n"
662       "  decl %[n]\n"
663       "  jnz 1b\n"
664       "  emms\n"
665       : [d] "+r" (d),
666         [s1_np7] "+r" (s1_np7),
667         [n] "+m" (n)
668       : [s2_8] "r" (s2_8),
669         [coeff] "r" (tmp)
670       : "ecx");
671 }
672 OIL_DEFINE_IMPL_FULL (mas8_u8_sym_mmx_41, mas8_u8_sym_l15, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
673
674
675 #define PSHUFW_3210 "0xe4"
676 #define PSHUFW_0123 "0x1b"
677
678 void
679 mas8_u8_sym_mmx_5 (uint8_t *d, const uint8_t *s1_np7, const int16_t *s2_8,
680         const int16_t *s3_2, int n)
681 {
682   if (n==0) return;
683   __asm__ __volatile__("\n"
684       "  pxor %%mm7, %%mm7\n"
685
686       "  movzwl 0(%[s3_2]), %%ecx\n"
687       "  movd %%ecx, %%mm6\n"
688       "  pshufw $0x44, %%mm6, %%mm6\n" // 01 00 01 00
689
690       "  movzwl 2(%[s3_2]), %%ecx\n"
691       "  movd %%ecx, %%mm5\n"
692
693       "  cmpl $0, %[n]\n"
694       "  jz 2f\n"
695
696       "1:\n"
697       "  movd 0(%[s1_np7]), %%mm0\n"
698       "  punpcklbw %%mm7, %%mm0\n"
699 #if 1
700       "  movd 4(%[s1_np7]), %%mm1\n"
701       "  punpcklbw %%mm7, %%mm1\n"
702       "  pshufw $0x1b, %%mm1, %%mm1\n" // 00 01 10 11
703       "  paddw %%mm1, %%mm0\n"
704       "  pmaddwd 0(%[s2_8]), %%mm0\n"
705 #else
706       "  pmaddwd 0(%[s2_8]), %%mm0\n"
707
708       "  movd 4(%[s1_np7]), %%mm1\n"
709       "  punpcklbw %%mm7, %%mm1\n"
710       "  pmaddwd 8(%[s2_8]), %%mm1\n"
711       "  paddd %%mm1, %%mm0\n"
712 #endif
713       
714       "  pshufw $0xee, %%mm0, %%mm1\n" // 11 10 11 10
715       "  paddd %%mm1, %%mm0\n"
716       "  paddd %%mm6, %%mm0\n"
717
718       "  psrad %%mm5, %%mm0\n"
719       "  pmaxsw %%mm7, %%mm0\n"
720       "  packuswb %%mm0, %%mm0\n"
721       "  movd %%mm0, %%ecx\n"
722       "  movb %%cl,0(%[d])\n"
723
724       "  add $1, %[d]\n"
725       "  add $1, %[s1_np7]\n"
726       "  decl %[n]\n"
727       "  jnz 1b\n"
728
729       "2:\n"
730       "  emms\n"
731       : [d] "+r" (d),
732         [s1_np7] "+r" (s1_np7),
733         [n] "+m" (n)
734       : [s2_8] "r" (s2_8),
735         [s3_2] "r" (s3_2)
736       : "ecx");
737 }
738 OIL_DEFINE_IMPL_FULL (mas8_u8_sym_mmx_5, mas8_u8_sym_l15, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
739
740 #ifdef HAVE_SSSE3_ASM
741 void
742 mas8_u8_sym_mmx_6 (uint8_t *d, const uint8_t *s1_np7, const int16_t *s2_8,
743         const int16_t *s3_2, int n)
744 {
745   int8_t coeff[8];
746   int8_t *ack;
747   int i;
748
749   for(i=0;i<8;i++){
750     //coeff[i] = s2_8[i];
751     coeff[i] = i;
752   }
753   ack = coeff;
754
755   if (n==0) return;
756   __asm__ __volatile__("\n"
757       "  pxor %%mm7, %%mm7\n"
758
759       "  movzwl 0(%[s3_2]), %%ecx\n"
760       "  movd %%ecx, %%mm6\n"
761       "  pshufw $0x44, %%mm6, %%mm6\n" // 01 00 01 00
762
763       "  movzwl 2(%[s3_2]), %%ecx\n"
764       "  movd %%ecx, %%mm5\n"
765
766       "  movq 0(%[s2_8]), %%mm4\n"
767       "  packsswb 8(%[s2_8]), %%mm4\n"
768
769       "1:\n"
770       "  movq 0(%[s1_np7]), %%mm0\n"
771       "  pmaddubsw %%mm4, %%mm0\n"
772
773 #if 1
774       "  pshufw $0xee, %%mm0, %%mm1\n" // 11 10 11 10
775       "  paddw %%mm1, %%mm0\n"
776       "  pshufw $0x55, %%mm0, %%mm1\n" // 01 01 01 01
777       "  paddw %%mm1, %%mm0\n"
778 #else
779       "  phaddw %%mm0, %%mm0\n"
780       "  phaddw %%mm0, %%mm0\n"
781 #endif
782
783       "  paddw %%mm6, %%mm0\n"
784       "  psraw %%mm5, %%mm0\n"
785       "  pmaxsw %%mm7, %%mm0\n"
786       "  packuswb %%mm0, %%mm0\n"
787       "  movd %%mm0, %%ecx\n"
788       "  movb %%cl,0(%[d])\n"
789
790       "  add $1, %[d]\n"
791       "  add $1, %[s1_np7]\n"
792       "  decl %[n]\n"
793       "  jnz 1b\n"
794
795       "  emms\n"
796       : [d] "+r" (d),
797         [s1_np7] "+r" (s1_np7),
798         [n] "+m" (n)
799       : [s2_8] "r" (s2_8),
800         [s3_2] "r" (s3_2)
801       : "ecx");
802 }
803 OIL_DEFINE_IMPL_FULL (mas8_u8_sym_mmx_6, mas8_u8_sym_l15, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT|OIL_IMPL_FLAG_SSSE3);
804 #endif
805
806 #ifdef ENABLE_BROKEN_IMPLS
807 /* This only works for the taps array: -1, 3, -7, 21, 21, -7, 3, -1 */
808 void
809 mas8_u8_supersym_mmx (uint8_t *d, const uint8_t *s1_np7, const int16_t *s2_8,
810         const int16_t *s3_2, int n)
811 {
812   int j;
813   int x;
814
815   while(n&3) {
816     x = 0;
817     for(j=0;j<8;j++){
818       x += s1_np7[j] * s2_8[j];
819     }
820     *d = CLAMP((x + s3_2[0])>>s3_2[1],0,255);
821     d++;
822     s1_np7++;
823     n--;
824   }
825
826   n>>=2;
827   __asm__ __volatile__("\n"
828       "  pxor %%mm7, %%mm7\n"
829
830       "  movd (%[s3_2]), %%mm6\n"
831       "  pshufw $0x00, %%mm6, %%mm6\n"
832
833       "  movzwl 2(%[s3_2]), %%ecx\n"
834       "  movd %%ecx, %%mm5\n"
835
836       "  movq 0(%[s2_8]), %%mm3\n"
837       "  movq 8(%[s2_8]), %%mm4\n"
838
839       "1:\n"
840       "  movd 0(%[s1_np7]), %%mm0\n"
841       "  punpcklbw %%mm7, %%mm0\n"
842       "  movd 7(%[s1_np7]), %%mm1\n"
843       "  punpcklbw %%mm7, %%mm1\n"
844       "  paddw %%mm1, %%mm0\n"
845
846       "  movd 1(%[s1_np7]), %%mm2\n"
847       "  punpcklbw %%mm7, %%mm2\n"
848       "  movd 6(%[s1_np7]), %%mm3\n"
849       "  punpcklbw %%mm7, %%mm3\n"
850       "  paddw %%mm3, %%mm2\n"
851
852       "  paddw %%mm2, %%mm0\n"
853       "  psllw $2, %%mm2\n"
854       "  psubw %%mm0, %%mm2\n"
855       "      movq %%mm2, %%mm4\n"
856
857       "  movd 2(%[s1_np7]), %%mm0\n"
858       "  punpcklbw %%mm7, %%mm0\n"
859       "  movd 5(%[s1_np7]), %%mm1\n"
860       "  punpcklbw %%mm7, %%mm1\n"
861       "  paddw %%mm1, %%mm0\n"
862
863       "  movd 3(%[s1_np7]), %%mm2\n"
864       "  punpcklbw %%mm7, %%mm2\n"
865       "  movd 4(%[s1_np7]), %%mm3\n"
866       "  punpcklbw %%mm7, %%mm3\n"
867       "  paddw %%mm3, %%mm2\n"
868
869       "  paddw %%mm2, %%mm0\n"
870       "  psllw $2, %%mm2\n"
871       "  psubw %%mm0, %%mm2\n"
872
873       "  psubw %%mm2, %%mm4\n"
874       "  psllw $3, %%mm2\n"
875       "  paddw %%mm4, %%mm2\n"
876
877       "  paddw %%mm6, %%mm2\n"
878
879       "  psraw %%mm5, %%mm2\n"
880       "  pmaxsw %%mm7, %%mm2\n"
881       "  packuswb %%mm2, %%mm2\n"
882       "  movd %%mm2, 0(%[d])\n"
883       "  add $4, %[d]\n"
884       "  add $4, %[s1_np7]\n"
885       "  decl %[n]\n"
886       "  jnz 1b\n"
887       "  emms\n"
888       : [d] "+r" (d),
889         [s1_np7] "+r" (s1_np7),
890         [n] "+m" (n)
891       : [s2_8] "r" (s2_8),
892         [s3_2] "r" (s3_2)
893       : "ecx");
894 }
895 OIL_DEFINE_IMPL_FULL (mas8_u8_supersym_mmx, mas8_u8_sym_l15, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
896 #endif
897
898 void
899 mas12_addc_rshift_decim2_u8_mmx_4 (uint8_t *d, const uint8_t *s1_2xnp11,
900     const int16_t *s2_12, const int16_t *s3_2, int n)
901 {
902   if (n == 0) return;
903   __asm__ __volatile__("\n"
904       "  pxor %%mm7, %%mm7\n"
905
906       "  movzwl 0(%[s3_2]), %%ecx\n"
907       "  movd %%ecx, %%mm6\n"
908
909       "  movzwl 2(%[s3_2]), %%ecx\n"
910       "  movd %%ecx, %%mm5\n"
911
912       "1:\n"
913       "  movd 0(%[s1_2xnp11]), %%mm0\n"
914       "  punpcklbw %%mm7, %%mm0\n"
915       "  pmaddwd 0(%[s2_12]), %%mm0\n"
916
917       "  movd 4(%[s1_2xnp11]), %%mm1\n"
918       "  punpcklbw %%mm7, %%mm1\n"
919       "  pmaddwd 8(%[s2_12]), %%mm1\n"
920       "  paddd %%mm1, %%mm0\n"
921
922       "  movd 8(%[s1_2xnp11]), %%mm1\n"
923       "  punpcklbw %%mm7, %%mm1\n"
924       "  pmaddwd 16(%[s2_12]), %%mm1\n"
925       "  paddd %%mm1, %%mm0\n"
926
927       "  movq %%mm0, %%mm1\n"
928       "  psrlq $32, %%mm0\n"
929       "  paddd %%mm1, %%mm0\n"
930       "  paddd %%mm6, %%mm0\n"
931
932       "  psrad %%mm5, %%mm0\n"
933       "  pmaxsw %%mm7, %%mm0\n"
934       "  packuswb %%mm0, %%mm0\n"
935       "  movd %%mm0, %%ecx\n"
936       "  movb %%cl,0(%[d])\n"
937
938       "  add $1, %[d]\n"
939       "  add $2, %[s1_2xnp11]\n"
940       "  decl %[n]\n"
941       "  jnz 1b\n"
942       "  emms\n"
943       : [d] "+r" (d),
944         [s1_2xnp11] "+r" (s1_2xnp11),
945         [n] "+m" (n)
946       : [s2_12] "r" (s2_12),
947         [s3_2] "r" (s3_2)
948       : "ecx");
949 }
950 OIL_DEFINE_IMPL_FULL (mas12_addc_rshift_decim2_u8_mmx_4,
951     mas12_addc_rshift_decim2_u8, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
952
953 #if 0
954 void
955 mas8_addc_rshift_decim2_u8_mmx_4 (uint8_t *d, const uint8_t *s1_2xnp9,
956     const int16_t *s2_8, const int16_t *s3_2, int n)
957 {
958   if (n == 0) return;
959   __asm__ __volatile__("\n"
960       "  pxor %%mm7, %%mm7\n"
961
962       "  movzwl 0(%[s3_2]), %%ecx\n"
963       "  movd %%ecx, %%mm6\n"
964
965       "  movzwl 2(%[s3_2]), %%ecx\n"
966       "  movd %%ecx, %%mm5\n"
967
968       "1:\n"
969       "  movd 0(%[s1_2xnp9]), %%mm0\n"
970       "  punpcklbw %%mm7, %%mm0\n"
971       "  pmaddwd 0(%[s2_8]), %%mm0\n"
972
973       "  movd 4(%[s1_2xnp9]), %%mm1\n"
974       "  punpcklbw %%mm7, %%mm1\n"
975       "  pmaddwd 8(%[s2_8]), %%mm1\n"
976       "  paddd %%mm1, %%mm0\n"
977
978       "  movq %%mm0, %%mm1\n"
979       "  psrlq $32, %%mm0\n"
980       "  paddd %%mm1, %%mm0\n"
981       "  paddd %%mm6, %%mm0\n"
982
983       "  psrad %%mm5, %%mm0\n"
984       "  pmaxsw %%mm7, %%mm0\n"
985       "  packuswb %%mm0, %%mm0\n"
986       "  movd %%mm0, %%ecx\n"
987       "  movb %%cl,0(%[d])\n"
988
989       "  add $1, %[d]\n"
990       "  add $2, %[s1_2xnp9]\n"
991       "  decl %[n]\n"
992       "  jnz 1b\n"
993       "  emms\n"
994       : [d] "+r" (d),
995         [s1_2xnp9] "+r" (s1_2xnp9),
996         [n] "+m" (n)
997       : [s2_8] "r" (s2_8),
998         [s3_2] "r" (s3_2)
999       : "ecx");
1000 }
1001 OIL_DEFINE_IMPL_FULL (mas8_addc_rshift_decim2_u8_mmx_4,
1002     mas8_addc_rshift_decim2_u8, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
1003
1004 #endif
1005
1006 void
1007 mas8_across_u8_mmx_3 (uint8_t *d, const uint8_t *s1_nx8, int ss1,
1008     const int16_t *s2_8, const int16_t *s3_2, int n)
1009 {
1010   int i;
1011   int x;
1012
1013   while(n&3) {
1014     x = 0;
1015     for(i=0;i<8;i++){
1016       x += OIL_GET(s1_nx8, i*ss1, uint8_t)*s2_8[i];
1017     }
1018     *d = CLAMP((x + s3_2[0])>>s3_2[1],0,255);
1019     d++;
1020     s1_nx8++;
1021     n--;
1022   }
1023
1024   if (n == 0) return;
1025   n>>=2;
1026   __asm__ __volatile__("\n"
1027       "  pxor %%mm7, %%mm7\n"
1028
1029       "  movd (%[s3_2]), %%mm6\n"
1030
1031       "  movzwl 2(%[s3_2]), %%ecx\n"
1032       "  movd %%ecx, %%mm5\n"
1033
1034       "  movq 0(%[s2_8]), %%mm3\n"
1035       "  movq 8(%[s2_8]), %%mm4\n"
1036       :
1037       : [s2_8] "r" (s2_8),
1038         [s3_2] "r" (s3_2)
1039       : "ecx");
1040
1041   while (n > 0) {
1042     const uint8_t *p = s1_nx8;
1043   __asm__ __volatile__("\n"
1044       "1:\n"
1045       /* load 128 */
1046       "  pshufw $0x00, %%mm6, %%mm2\n"
1047
1048       "  movd 0(%[p]), %%mm0\n"
1049       "  add %[ss1], %[p]\n"
1050       "  punpcklbw %%mm7, %%mm0\n"
1051       "  pshufw $0x00, %%mm3, %%mm1\n"
1052       "  pmullw %%mm1, %%mm0\n"
1053       "  paddw %%mm0, %%mm2\n"
1054
1055       "  movd 0(%[p]), %%mm0\n"
1056       "  add %[ss1], %[p]\n"
1057       "  punpcklbw %%mm7, %%mm0\n"
1058       "  pshufw $0x55*1, %%mm3, %%mm1\n"
1059       "  pmullw %%mm1, %%mm0\n"
1060       "  paddw %%mm0, %%mm2\n"
1061
1062       "  movd 0(%[p]), %%mm0\n"
1063       "  add %[ss1], %[p]\n"
1064       "  punpcklbw %%mm7, %%mm0\n"
1065       "  pshufw $0x55*2, %%mm3, %%mm1\n"
1066       "  pmullw %%mm1, %%mm0\n"
1067       "  paddw %%mm0, %%mm2\n"
1068
1069       "  movd 0(%[p]), %%mm0\n"
1070       "  add %[ss1], %[p]\n"
1071       "  punpcklbw %%mm7, %%mm0\n"
1072       "  pshufw $0x55*3, %%mm3, %%mm1\n"
1073       "  pmullw %%mm1, %%mm0\n"
1074       "  paddw %%mm0, %%mm2\n"
1075
1076       "  movd 0(%[p]), %%mm0\n"
1077       "  add %[ss1], %[p]\n"
1078       "  punpcklbw %%mm7, %%mm0\n"
1079       "  pshufw $0x00, %%mm4, %%mm1\n"
1080       "  pmullw %%mm1, %%mm0\n"
1081       "  paddw %%mm0, %%mm2\n"
1082
1083       "  movd 0(%[p]), %%mm0\n"
1084       "  add %[ss1], %[p]\n"
1085       "  punpcklbw %%mm7, %%mm0\n"
1086       "  pshufw $0x55*1, %%mm4, %%mm1\n"
1087       "  pmullw %%mm1, %%mm0\n"
1088       "  paddw %%mm0, %%mm2\n"
1089
1090       "  movd 0(%[p]), %%mm0\n"
1091       "  add %[ss1], %[p]\n"
1092       "  punpcklbw %%mm7, %%mm0\n"
1093       "  pshufw $0x55*2, %%mm4, %%mm1\n"
1094       "  pmullw %%mm1, %%mm0\n"
1095       "  paddw %%mm0, %%mm2\n"
1096
1097       "  movd 0(%[p]), %%mm0\n"
1098       "  add %[ss1], %[p]\n"
1099       "  punpcklbw %%mm7, %%mm0\n"
1100       "  pshufw $0x55*3, %%mm4, %%mm1\n"
1101       "  pmullw %%mm1, %%mm0\n"
1102       "  paddw %%mm0, %%mm2\n"
1103
1104       "  psraw %%mm5, %%mm2\n"
1105       "  pmaxsw %%mm7, %%mm2\n"
1106       "  packuswb %%mm2, %%mm2\n"
1107       "  movd %%mm2, 0(%[d])\n"
1108       : [p] "+r" (p)
1109       : [d] "r" (d), [ss1] "r" ((long)ss1));
1110     d+=4;
1111     s1_nx8+=4;
1112     n--;
1113   }
1114
1115   asm volatile ("emms");
1116 }
1117 OIL_DEFINE_IMPL_FULL (mas8_across_u8_mmx_3, mas8_across_u8, OIL_IMPL_FLAG_MMX|OIL_IMPL_FLAG_MMXEXT);
1118