2 * MMX optimized DSP utils
3 * Copyright (c) 2000, 2001 Gerard Lantau.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
22 #include "../dsputil.h"
24 int mm_flags; /* multimedia extension flags */
26 int pix_abs16x16_mmx(UINT8 *blk1, UINT8 *blk2, int lx, int h);
27 int pix_abs16x16_sse(UINT8 *blk1, UINT8 *blk2, int lx, int h);
28 int pix_abs16x16_x2_mmx(UINT8 *blk1, UINT8 *blk2, int lx, int h);
29 int pix_abs16x16_y2_mmx(UINT8 *blk1, UINT8 *blk2, int lx, int h);
30 int pix_abs16x16_xy2_mmx(UINT8 *blk1, UINT8 *blk2, int lx, int h);
33 /* external functions, defined in libmpeg2 */
34 void mmx_idct(DCTELEM *block);
35 void mmxext_idct(DCTELEM *block);
36 /* this should be in dsputil.h? -- A'rpi */
37 extern UINT8 ff_alternate_horizontal_scan[64];
38 extern UINT8 ff_alternate_vertical_scan[64];
39 extern UINT8 zigzag_direct[64];
42 /* pixel operations */
43 static const unsigned long long int mm_wone __attribute__ ((aligned(8))) = 0x0001000100010001;
44 static const unsigned long long int mm_wtwo __attribute__ ((aligned(8))) = 0x0002000200020002;
45 //static const unsigned short mm_wone[4] __attribute__ ((aligned(8))) = { 0x1, 0x1, 0x1, 0x1 };
46 //static const unsigned short mm_wtwo[4] __attribute__ ((aligned(8))) = { 0x2, 0x2, 0x2, 0x2 };
48 /***********************************/
51 #define DEF(x) x ## _3dnow
52 /* for Athlons PAVGUSB is prefered */
53 #define PAVGB "pavgusb"
55 #include "dsputil_mmx_avg.h"
60 /***********************************/
63 #define DEF(x) x ## _sse
65 /* Introduced only in MMX2 set */
68 #include "dsputil_mmx_avg.h"
73 /***********************************/
76 static void get_pixels_mmx(DCTELEM *block, const UINT8 *pixels, int line_size)
85 __asm __volatile("pxor %%mm7, %%mm7":::"memory");
90 "movq %%mm0, %%mm2\n\t"
91 "movq %%mm1, %%mm3\n\t"
92 "punpcklbw %%mm7, %%mm0\n\t"
93 "punpckhbw %%mm7, %%mm2\n\t"
94 "punpcklbw %%mm7, %%mm1\n\t"
95 "punpckhbw %%mm7, %%mm3\n\t"
98 "movq %%mm1, 16%0\n\t"
99 "movq %%mm3, 24%0\n\t"
101 :"m"(*pix), "m"(*(pix+line_size))
108 static void put_pixels_clamped_mmx(const DCTELEM *block, UINT8 *pixels, int line_size)
114 /* read the pixels */
120 "movq 8%4, %%mm1\n\t"
121 "movq 16%4, %%mm2\n\t"
122 "movq 24%4, %%mm3\n\t"
123 "movq 32%4, %%mm4\n\t"
124 "movq 40%4, %%mm5\n\t"
125 "movq 48%4, %%mm6\n\t"
126 "movq 56%4, %%mm7\n\t"
127 "packuswb %%mm1, %%mm0\n\t"
128 "packuswb %%mm3, %%mm2\n\t"
129 "packuswb %%mm5, %%mm4\n\t"
130 "packuswb %%mm7, %%mm6\n\t"
135 :"=m"(*pix), "=m"(*(pix+line_size))
136 ,"=m"(*(pix+line_size*2)), "=m"(*(pix+line_size*3))
144 static void add_pixels_clamped_mmx(const DCTELEM *block, UINT8 *pixels, int line_size)
150 /* read the pixels */
153 __asm __volatile("pxor %%mm7, %%mm7":::"memory");
157 "movq 8%2, %%mm1\n\t"
158 "movq 16%2, %%mm2\n\t"
159 "movq 24%2, %%mm3\n\t"
162 "movq %%mm4, %%mm5\n\t"
163 "punpcklbw %%mm7, %%mm4\n\t"
164 "punpckhbw %%mm7, %%mm5\n\t"
165 "paddsw %%mm4, %%mm0\n\t"
166 "paddsw %%mm5, %%mm1\n\t"
167 "movq %%mm6, %%mm5\n\t"
168 "punpcklbw %%mm7, %%mm6\n\t"
169 "punpckhbw %%mm7, %%mm5\n\t"
170 "paddsw %%mm6, %%mm2\n\t"
171 "paddsw %%mm5, %%mm3\n\t"
172 "packuswb %%mm1, %%mm0\n\t"
173 "packuswb %%mm3, %%mm2\n\t"
176 :"=m"(*pix), "=m"(*(pix+line_size))
184 static void put_pixels_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
203 :"=m"(*p), "=m"(*(p+line_size)), "=m"(*(p+line_size*2)), "=m"(*(p+line_size*3))
204 :"m"(*pix), "m"(*(pix+line_size)), "m"(*(pix+line_size*2)), "m"(*(pix+line_size*3))
206 pix = pix + line_size*4;
216 pix = pix + line_size;
221 static void put_pixels_x2_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
228 "pxor %%mm7, %%mm7\n\t"
230 ::"m"(mm_wone):"memory");
234 "movq 1%1, %%mm1\n\t"
235 "movq %%mm0, %%mm2\n\t"
236 "movq %%mm1, %%mm3\n\t"
237 "punpcklbw %%mm7, %%mm0\n\t"
238 "punpcklbw %%mm7, %%mm1\n\t"
239 "punpckhbw %%mm7, %%mm2\n\t"
240 "punpckhbw %%mm7, %%mm3\n\t"
241 "paddusw %%mm1, %%mm0\n\t"
242 "paddusw %%mm3, %%mm2\n\t"
243 "paddusw %%mm4, %%mm0\n\t"
244 "paddusw %%mm4, %%mm2\n\t"
245 "psrlw $1, %%mm0\n\t"
246 "psrlw $1, %%mm2\n\t"
247 "packuswb %%mm2, %%mm0\n\t"
252 pix += line_size; p += line_size;
256 static void put_pixels_y2_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
263 "pxor %%mm7, %%mm7\n\t"
265 ::"m"(mm_wone):"memory");
270 "movq %%mm0, %%mm2\n\t"
271 "movq %%mm1, %%mm3\n\t"
272 "punpcklbw %%mm7, %%mm0\n\t"
273 "punpcklbw %%mm7, %%mm1\n\t"
274 "punpckhbw %%mm7, %%mm2\n\t"
275 "punpckhbw %%mm7, %%mm3\n\t"
276 "paddusw %%mm1, %%mm0\n\t"
277 "paddusw %%mm3, %%mm2\n\t"
278 "paddusw %%mm4, %%mm0\n\t"
279 "paddusw %%mm4, %%mm2\n\t"
280 "psrlw $1, %%mm0\n\t"
281 "psrlw $1, %%mm2\n\t"
282 "packuswb %%mm2, %%mm0\n\t"
286 "m"(*(pix+line_size))
293 static void put_pixels_xy2_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
300 "pxor %%mm7, %%mm7\n\t"
302 ::"m"(mm_wtwo):"memory");
307 "movq 1%1, %%mm4\n\t"
308 "movq 1%2, %%mm5\n\t"
309 "movq %%mm0, %%mm2\n\t"
310 "movq %%mm1, %%mm3\n\t"
311 "punpcklbw %%mm7, %%mm0\n\t"
312 "punpcklbw %%mm7, %%mm1\n\t"
313 "punpckhbw %%mm7, %%mm2\n\t"
314 "punpckhbw %%mm7, %%mm3\n\t"
315 "paddusw %%mm1, %%mm0\n\t"
316 "paddusw %%mm3, %%mm2\n\t"
317 "movq %%mm4, %%mm1\n\t"
318 "movq %%mm5, %%mm3\n\t"
319 "punpcklbw %%mm7, %%mm4\n\t"
320 "punpcklbw %%mm7, %%mm5\n\t"
321 "punpckhbw %%mm7, %%mm1\n\t"
322 "punpckhbw %%mm7, %%mm3\n\t"
323 "paddusw %%mm5, %%mm4\n\t"
324 "paddusw %%mm3, %%mm1\n\t"
325 "paddusw %%mm6, %%mm4\n\t"
326 "paddusw %%mm6, %%mm1\n\t"
327 "paddusw %%mm4, %%mm0\n\t"
328 "paddusw %%mm1, %%mm2\n\t"
329 "psrlw $2, %%mm0\n\t"
330 "psrlw $2, %%mm2\n\t"
331 "packuswb %%mm2, %%mm0\n\t"
335 "m"(*(pix+line_size))
342 static void put_no_rnd_pixels_x2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
348 __asm __volatile("pxor %%mm7, %%mm7\n\t":::"memory");
352 "movq 1%1, %%mm1\n\t"
353 "movq %%mm0, %%mm2\n\t"
354 "movq %%mm1, %%mm3\n\t"
355 "punpcklbw %%mm7, %%mm0\n\t"
356 "punpcklbw %%mm7, %%mm1\n\t"
357 "punpckhbw %%mm7, %%mm2\n\t"
358 "punpckhbw %%mm7, %%mm3\n\t"
359 "paddusw %%mm1, %%mm0\n\t"
360 "paddusw %%mm3, %%mm2\n\t"
361 "psrlw $1, %%mm0\n\t"
362 "psrlw $1, %%mm2\n\t"
363 "packuswb %%mm2, %%mm0\n\t"
373 static void put_no_rnd_pixels_y2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
379 __asm __volatile("pxor %%mm7, %%mm7\n\t":::"memory");
384 "movq %%mm0, %%mm2\n\t"
385 "movq %%mm1, %%mm3\n\t"
386 "punpcklbw %%mm7, %%mm0\n\t"
387 "punpcklbw %%mm7, %%mm1\n\t"
388 "punpckhbw %%mm7, %%mm2\n\t"
389 "punpckhbw %%mm7, %%mm3\n\t"
390 "paddusw %%mm1, %%mm0\n\t"
391 "paddusw %%mm3, %%mm2\n\t"
392 "psrlw $1, %%mm0\n\t"
393 "psrlw $1, %%mm2\n\t"
394 "packuswb %%mm2, %%mm0\n\t"
398 "m"(*(pix+line_size))
405 static void put_no_rnd_pixels_xy2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
412 "pxor %%mm7, %%mm7\n\t"
414 ::"m"(mm_wone):"memory");
419 "movq 1%1, %%mm4\n\t"
420 "movq 1%2, %%mm5\n\t"
421 "movq %%mm0, %%mm2\n\t"
422 "movq %%mm1, %%mm3\n\t"
423 "punpcklbw %%mm7, %%mm0\n\t"
424 "punpcklbw %%mm7, %%mm1\n\t"
425 "punpckhbw %%mm7, %%mm2\n\t"
426 "punpckhbw %%mm7, %%mm3\n\t"
427 "paddusw %%mm1, %%mm0\n\t"
428 "paddusw %%mm3, %%mm2\n\t"
429 "movq %%mm4, %%mm1\n\t"
430 "movq %%mm5, %%mm3\n\t"
431 "punpcklbw %%mm7, %%mm4\n\t"
432 "punpcklbw %%mm7, %%mm5\n\t"
433 "punpckhbw %%mm7, %%mm1\n\t"
434 "punpckhbw %%mm7, %%mm3\n\t"
435 "paddusw %%mm5, %%mm4\n\t"
436 "paddusw %%mm3, %%mm1\n\t"
437 "paddusw %%mm6, %%mm4\n\t"
438 "paddusw %%mm6, %%mm1\n\t"
439 "paddusw %%mm4, %%mm0\n\t"
440 "paddusw %%mm1, %%mm2\n\t"
441 "psrlw $2, %%mm0\n\t"
442 "psrlw $2, %%mm2\n\t"
443 "packuswb %%mm2, %%mm0\n\t"
447 "m"(*(pix+line_size))
454 static void avg_pixels_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
461 "pxor %%mm7, %%mm7\n\t"
463 ::"m"(mm_wone):"memory");
468 "movq %%mm0, %%mm2\n\t"
469 "movq %%mm1, %%mm3\n\t"
470 "punpcklbw %%mm7, %%mm0\n\t"
471 "punpcklbw %%mm7, %%mm1\n\t"
472 "punpckhbw %%mm7, %%mm2\n\t"
473 "punpckhbw %%mm7, %%mm3\n\t"
474 "paddusw %%mm1, %%mm0\n\t"
475 "paddusw %%mm3, %%mm2\n\t"
476 "paddusw %%mm6, %%mm0\n\t"
477 "paddusw %%mm6, %%mm2\n\t"
478 "psrlw $1, %%mm0\n\t"
479 "psrlw $1, %%mm2\n\t"
480 "packuswb %%mm2, %%mm0\n\t"
491 static void avg_pixels_x2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
498 "pxor %%mm7, %%mm7\n\t"
500 ::"m"(mm_wone):"memory");
505 "movq 1%1, %%mm4\n\t"
506 "movq %%mm0, %%mm2\n\t"
507 "movq %%mm1, %%mm3\n\t"
508 "movq %%mm4, %%mm5\n\t"
509 "punpcklbw %%mm7, %%mm1\n\t"
510 "punpckhbw %%mm7, %%mm3\n\t"
511 "punpcklbw %%mm7, %%mm4\n\t"
512 "punpckhbw %%mm7, %%mm5\n\t"
513 "punpcklbw %%mm7, %%mm0\n\t"
514 "punpckhbw %%mm7, %%mm2\n\t"
515 "paddusw %%mm4, %%mm1\n\t"
516 "paddusw %%mm5, %%mm3\n\t"
517 "paddusw %%mm6, %%mm1\n\t"
518 "paddusw %%mm6, %%mm3\n\t"
519 "psrlw $1, %%mm1\n\t"
520 "psrlw $1, %%mm3\n\t"
521 "paddusw %%mm6, %%mm0\n\t"
522 "paddusw %%mm6, %%mm2\n\t"
523 "paddusw %%mm1, %%mm0\n\t"
524 "paddusw %%mm3, %%mm2\n\t"
525 "psrlw $1, %%mm0\n\t"
526 "psrlw $1, %%mm2\n\t"
527 "packuswb %%mm2, %%mm0\n\t"
537 static void avg_pixels_y2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
544 "pxor %%mm7, %%mm7\n\t"
546 ::"m"(mm_wone):"memory");
552 "movq %%mm0, %%mm2\n\t"
553 "movq %%mm1, %%mm3\n\t"
554 "movq %%mm4, %%mm5\n\t"
555 "punpcklbw %%mm7, %%mm1\n\t"
556 "punpckhbw %%mm7, %%mm3\n\t"
557 "punpcklbw %%mm7, %%mm4\n\t"
558 "punpckhbw %%mm7, %%mm5\n\t"
559 "punpcklbw %%mm7, %%mm0\n\t"
560 "punpckhbw %%mm7, %%mm2\n\t"
561 "paddusw %%mm4, %%mm1\n\t"
562 "paddusw %%mm5, %%mm3\n\t"
563 "paddusw %%mm6, %%mm1\n\t"
564 "paddusw %%mm6, %%mm3\n\t"
565 "psrlw $1, %%mm1\n\t"
566 "psrlw $1, %%mm3\n\t"
567 "paddusw %%mm6, %%mm0\n\t"
568 "paddusw %%mm6, %%mm2\n\t"
569 "paddusw %%mm1, %%mm0\n\t"
570 "paddusw %%mm3, %%mm2\n\t"
571 "psrlw $1, %%mm0\n\t"
572 "psrlw $1, %%mm2\n\t"
573 "packuswb %%mm2, %%mm0\n\t"
576 :"m"(*pix), "m"(*(pix+line_size))
583 static void avg_pixels_xy2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
590 "pxor %%mm7, %%mm7\n\t"
592 ::"m"(mm_wtwo):"memory");
597 "movq 1%1, %%mm4\n\t"
598 "movq 1%2, %%mm5\n\t"
599 "movq %%mm0, %%mm2\n\t"
600 "movq %%mm1, %%mm3\n\t"
601 "punpcklbw %%mm7, %%mm0\n\t"
602 "punpcklbw %%mm7, %%mm1\n\t"
603 "punpckhbw %%mm7, %%mm2\n\t"
604 "punpckhbw %%mm7, %%mm3\n\t"
605 "paddusw %%mm1, %%mm0\n\t"
606 "paddusw %%mm3, %%mm2\n\t"
607 "movq %%mm4, %%mm1\n\t"
608 "movq %%mm5, %%mm3\n\t"
609 "punpcklbw %%mm7, %%mm4\n\t"
610 "punpcklbw %%mm7, %%mm5\n\t"
611 "punpckhbw %%mm7, %%mm1\n\t"
612 "punpckhbw %%mm7, %%mm3\n\t"
613 "paddusw %%mm5, %%mm4\n\t"
614 "paddusw %%mm3, %%mm1\n\t"
615 "paddusw %%mm6, %%mm4\n\t"
616 "paddusw %%mm6, %%mm1\n\t"
617 "paddusw %%mm4, %%mm0\n\t"
618 "paddusw %%mm1, %%mm2\n\t"
620 "psrlw $2, %%mm0\n\t"
622 "psrlw $2, %%mm2\n\t"
623 "movq %%mm1, %%mm3\n\t"
624 "punpcklbw %%mm7, %%mm1\n\t"
625 "punpckhbw %%mm7, %%mm3\n\t"
626 "paddusw %%mm1, %%mm0\n\t"
627 "paddusw %%mm3, %%mm2\n\t"
628 "paddusw %%mm5, %%mm0\n\t"
629 "paddusw %%mm5, %%mm2\n\t"
630 "psrlw $1, %%mm0\n\t"
631 "psrlw $1, %%mm2\n\t"
632 "packuswb %%mm2, %%mm0\n\t"
636 "m"(*(pix+line_size)), "m"(mm_wone)
643 static void avg_no_rnd_pixels_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
649 __asm __volatile("pxor %%mm7, %%mm7\n\t":::"memory");
654 "movq %%mm0, %%mm2\n\t"
655 "movq %%mm1, %%mm3\n\t"
656 "punpcklbw %%mm7, %%mm0\n\t"
657 "punpcklbw %%mm7, %%mm1\n\t"
658 "punpckhbw %%mm7, %%mm2\n\t"
659 "punpckhbw %%mm7, %%mm3\n\t"
660 "paddusw %%mm1, %%mm0\n\t"
661 "paddusw %%mm3, %%mm2\n\t"
662 "psrlw $1, %%mm0\n\t"
663 "psrlw $1, %%mm2\n\t"
664 "packuswb %%mm2, %%mm0\n\t"
674 static void avg_no_rnd_pixels_x2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
681 "pxor %%mm7, %%mm7\n\t":::"memory");
685 "movq 1%1, %%mm1\n\t"
687 "movq %%mm0, %%mm2\n\t"
688 "movq %%mm1, %%mm3\n\t"
689 "movq %%mm4, %%mm5\n\t"
690 "punpcklbw %%mm7, %%mm0\n\t"
691 "punpcklbw %%mm7, %%mm1\n\t"
692 "punpckhbw %%mm7, %%mm2\n\t"
693 "punpckhbw %%mm7, %%mm3\n\t"
694 "punpcklbw %%mm7, %%mm4\n\t"
695 "punpckhbw %%mm7, %%mm5\n\t"
696 "paddusw %%mm1, %%mm0\n\t"
697 "paddusw %%mm3, %%mm2\n\t"
698 "psrlw $1, %%mm0\n\t"
699 "psrlw $1, %%mm2\n\t"
700 "paddusw %%mm4, %%mm0\n\t"
701 "paddusw %%mm5, %%mm2\n\t"
702 "psrlw $1, %%mm0\n\t"
703 "psrlw $1, %%mm2\n\t"
704 "packuswb %%mm2, %%mm0\n\t"
714 static void avg_no_rnd_pixels_y2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
721 "pxor %%mm7, %%mm7\n\t":::"memory");
727 "movq %%mm0, %%mm2\n\t"
728 "movq %%mm1, %%mm3\n\t"
729 "movq %%mm4, %%mm5\n\t"
730 "punpcklbw %%mm7, %%mm0\n\t"
731 "punpcklbw %%mm7, %%mm1\n\t"
732 "punpckhbw %%mm7, %%mm2\n\t"
733 "punpckhbw %%mm7, %%mm3\n\t"
734 "punpcklbw %%mm7, %%mm4\n\t"
735 "punpckhbw %%mm7, %%mm5\n\t"
736 "paddusw %%mm1, %%mm0\n\t"
737 "paddusw %%mm3, %%mm2\n\t"
738 "psrlw $1, %%mm0\n\t"
739 "psrlw $1, %%mm2\n\t"
740 "paddusw %%mm4, %%mm0\n\t"
741 "paddusw %%mm5, %%mm2\n\t"
742 "psrlw $1, %%mm0\n\t"
743 "psrlw $1, %%mm2\n\t"
744 "packuswb %%mm2, %%mm0\n\t"
747 :"m"(*pix), "m"(*(pix+line_size))
754 static void avg_no_rnd_pixels_xy2_mmx( UINT8 *block, const UINT8 *pixels, int line_size, int h)
761 "pxor %%mm7, %%mm7\n\t"
763 ::"m"(mm_wone):"memory");
768 "movq 1%1, %%mm4\n\t"
769 "movq 1%2, %%mm5\n\t"
770 "movq %%mm0, %%mm2\n\t"
771 "movq %%mm1, %%mm3\n\t"
772 "punpcklbw %%mm7, %%mm0\n\t"
773 "punpcklbw %%mm7, %%mm1\n\t"
774 "punpckhbw %%mm7, %%mm2\n\t"
775 "punpckhbw %%mm7, %%mm3\n\t"
776 "paddusw %%mm1, %%mm0\n\t"
777 "paddusw %%mm3, %%mm2\n\t"
778 "movq %%mm4, %%mm1\n\t"
779 "movq %%mm5, %%mm3\n\t"
780 "punpcklbw %%mm7, %%mm4\n\t"
781 "punpcklbw %%mm7, %%mm5\n\t"
782 "punpckhbw %%mm7, %%mm1\n\t"
783 "punpckhbw %%mm7, %%mm3\n\t"
784 "paddusw %%mm5, %%mm4\n\t"
785 "paddusw %%mm3, %%mm1\n\t"
786 "paddusw %%mm6, %%mm4\n\t"
787 "paddusw %%mm6, %%mm1\n\t"
788 "paddusw %%mm4, %%mm0\n\t"
789 "paddusw %%mm1, %%mm2\n\t"
791 "psrlw $2, %%mm0\n\t"
792 "movq %%mm1, %%mm3\n\t"
793 "psrlw $2, %%mm2\n\t"
794 "punpcklbw %%mm7, %%mm1\n\t"
795 "punpckhbw %%mm7, %%mm3\n\t"
796 "paddusw %%mm1, %%mm0\n\t"
797 "paddusw %%mm3, %%mm2\n\t"
798 "psrlw $1, %%mm0\n\t"
799 "psrlw $1, %%mm2\n\t"
800 "packuswb %%mm2, %%mm0\n\t"
804 "m"(*(pix+line_size))
811 static void sub_pixels_mmx( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
817 __asm __volatile("pxor %%mm7, %%mm7":::"memory");
822 "movq 8%0, %%mm1\n\t"
823 "movq %%mm2, %%mm3\n\t"
824 "punpcklbw %%mm7, %%mm2\n\t"
825 "punpckhbw %%mm7, %%mm3\n\t"
826 "psubsw %%mm2, %%mm0\n\t"
827 "psubsw %%mm3, %%mm1\n\t"
829 "movq %%mm1, 8%0\n\t"
838 static void sub_pixels_x2_mmx( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
845 "pxor %%mm7, %%mm7\n\t"
847 ::"m"(mm_wone):"memory");
852 "movq 8%0, %%mm1\n\t"
853 "movq 1%1, %%mm4\n\t"
854 "movq %%mm2, %%mm3\n\t"
855 "movq %%mm4, %%mm5\n\t"
856 "punpcklbw %%mm7, %%mm2\n\t"
857 "punpckhbw %%mm7, %%mm3\n\t"
858 "punpcklbw %%mm7, %%mm4\n\t"
859 "punpckhbw %%mm7, %%mm5\n\t"
860 "paddusw %%mm4, %%mm2\n\t"
861 "paddusw %%mm5, %%mm3\n\t"
862 "paddusw %%mm6, %%mm2\n\t"
863 "paddusw %%mm6, %%mm3\n\t"
864 "psrlw $1, %%mm2\n\t"
865 "psrlw $1, %%mm3\n\t"
866 "psubsw %%mm2, %%mm0\n\t"
867 "psubsw %%mm3, %%mm1\n\t"
869 "movq %%mm1, 8%0\n\t"
878 static void sub_pixels_y2_mmx( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
885 "pxor %%mm7, %%mm7\n\t"
887 ::"m"(mm_wone):"memory");
892 "movq 8%0, %%mm1\n\t"
894 "movq %%mm2, %%mm3\n\t"
895 "movq %%mm4, %%mm5\n\t"
896 "punpcklbw %%mm7, %%mm2\n\t"
897 "punpckhbw %%mm7, %%mm3\n\t"
898 "punpcklbw %%mm7, %%mm4\n\t"
899 "punpckhbw %%mm7, %%mm5\n\t"
900 "paddusw %%mm4, %%mm2\n\t"
901 "paddusw %%mm5, %%mm3\n\t"
902 "paddusw %%mm6, %%mm2\n\t"
903 "paddusw %%mm6, %%mm3\n\t"
904 "psrlw $1, %%mm2\n\t"
905 "psrlw $1, %%mm3\n\t"
906 "psubsw %%mm2, %%mm0\n\t"
907 "psubsw %%mm3, %%mm1\n\t"
909 "movq %%mm1, 8%0\n\t"
911 :"m"(*pix), "m"(*(pix+line_size))
918 static void sub_pixels_xy2_mmx( DCTELEM *block, const UINT8 *pixels, int line_size, int h)
925 "pxor %%mm7, %%mm7\n\t"
927 ::"m"(mm_wtwo):"memory");
932 "movq 1%1, %%mm4\n\t"
933 "movq 1%2, %%mm5\n\t"
934 "movq %%mm0, %%mm2\n\t"
935 "movq %%mm1, %%mm3\n\t"
936 "punpcklbw %%mm7, %%mm0\n\t"
937 "punpcklbw %%mm7, %%mm1\n\t"
938 "punpckhbw %%mm7, %%mm2\n\t"
939 "punpckhbw %%mm7, %%mm3\n\t"
940 "paddusw %%mm1, %%mm0\n\t"
941 "paddusw %%mm3, %%mm2\n\t"
942 "movq %%mm4, %%mm1\n\t"
943 "movq %%mm5, %%mm3\n\t"
944 "punpcklbw %%mm7, %%mm4\n\t"
945 "punpcklbw %%mm7, %%mm5\n\t"
946 "punpckhbw %%mm7, %%mm1\n\t"
947 "punpckhbw %%mm7, %%mm3\n\t"
948 "paddusw %%mm5, %%mm4\n\t"
949 "paddusw %%mm3, %%mm1\n\t"
950 "paddusw %%mm6, %%mm4\n\t"
951 "paddusw %%mm6, %%mm1\n\t"
952 "paddusw %%mm4, %%mm0\n\t"
953 "paddusw %%mm1, %%mm2\n\t"
955 "movq 8%0, %%mm3\n\t"
956 "psrlw $2, %%mm0\n\t"
957 "psrlw $2, %%mm2\n\t"
958 "psubsw %%mm0, %%mm1\n\t"
959 "psubsw %%mm2, %%mm3\n\t"
961 "movq %%mm3, 8%0\n\t"
964 "m"(*(pix+line_size))
971 void dsputil_init_mmx(void)
973 mm_flags = mm_support();
975 printf("CPU flags:");
976 if (mm_flags & MM_MMX)
978 if (mm_flags & MM_MMXEXT)
980 if (mm_flags & MM_3DNOW)
982 if (mm_flags & MM_SSE)
984 if (mm_flags & MM_SSE2)
989 if (mm_flags & MM_MMX) {
990 get_pixels = get_pixels_mmx;
991 put_pixels_clamped = put_pixels_clamped_mmx;
992 add_pixels_clamped = add_pixels_clamped_mmx;
994 pix_abs16x16 = pix_abs16x16_mmx;
995 pix_abs16x16_x2 = pix_abs16x16_x2_mmx;
996 pix_abs16x16_y2 = pix_abs16x16_y2_mmx;
997 pix_abs16x16_xy2 = pix_abs16x16_xy2_mmx;
1000 put_pixels_tab[0] = put_pixels_mmx;
1001 put_pixels_tab[1] = put_pixels_x2_mmx;
1002 put_pixels_tab[2] = put_pixels_y2_mmx;
1003 put_pixels_tab[3] = put_pixels_xy2_mmx;
1005 put_no_rnd_pixels_tab[0] = put_pixels_mmx;
1006 put_no_rnd_pixels_tab[1] = put_no_rnd_pixels_x2_mmx;
1007 put_no_rnd_pixels_tab[2] = put_no_rnd_pixels_y2_mmx;
1008 put_no_rnd_pixels_tab[3] = put_no_rnd_pixels_xy2_mmx;
1010 avg_pixels_tab[0] = avg_pixels_mmx;
1011 avg_pixels_tab[1] = avg_pixels_x2_mmx;
1012 avg_pixels_tab[2] = avg_pixels_y2_mmx;
1013 avg_pixels_tab[3] = avg_pixels_xy2_mmx;
1015 avg_no_rnd_pixels_tab[0] = avg_no_rnd_pixels_mmx;
1016 avg_no_rnd_pixels_tab[1] = avg_no_rnd_pixels_x2_mmx;
1017 avg_no_rnd_pixels_tab[2] = avg_no_rnd_pixels_y2_mmx;
1018 avg_no_rnd_pixels_tab[3] = avg_no_rnd_pixels_xy2_mmx;
1020 sub_pixels_tab[0] = sub_pixels_mmx;
1021 sub_pixels_tab[1] = sub_pixels_x2_mmx;
1022 sub_pixels_tab[2] = sub_pixels_y2_mmx;
1023 sub_pixels_tab[3] = sub_pixels_xy2_mmx;
1025 if (mm_flags & MM_MMXEXT) {
1026 pix_abs16x16 = pix_abs16x16_sse;
1029 if (mm_flags & MM_SSE) {
1030 put_pixels_tab[1] = put_pixels_x2_sse;
1031 put_pixels_tab[2] = put_pixels_y2_sse;
1033 avg_pixels_tab[0] = avg_pixels_sse;
1034 avg_pixels_tab[1] = avg_pixels_x2_sse;
1035 avg_pixels_tab[2] = avg_pixels_y2_sse;
1036 avg_pixels_tab[3] = avg_pixels_xy2_sse;
1038 sub_pixels_tab[1] = sub_pixels_x2_sse;
1039 sub_pixels_tab[2] = sub_pixels_y2_sse;
1040 } else if (mm_flags & MM_3DNOW) {
1041 put_pixels_tab[1] = put_pixels_x2_3dnow;
1042 put_pixels_tab[2] = put_pixels_y2_3dnow;
1044 avg_pixels_tab[0] = avg_pixels_3dnow;
1045 avg_pixels_tab[1] = avg_pixels_x2_3dnow;
1046 avg_pixels_tab[2] = avg_pixels_y2_3dnow;
1047 avg_pixels_tab[3] = avg_pixels_xy2_3dnow;
1049 sub_pixels_tab[1] = sub_pixels_x2_3dnow;
1050 sub_pixels_tab[2] = sub_pixels_y2_3dnow;
1054 /* use MMX / MMXEXT iDCT code from libmpeg2 */
1055 //printf("LIBAVCODEC: Using MMX%s iDCT code\n",(mm_flags & MM_MMXEXT)?"EXT":"");
1056 ff_idct = (mm_flags & MM_MMXEXT) ? mmxext_idct : mmx_idct;
1057 /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
1059 for (i = 0; i < 64; i++) {
1060 j = zigzag_direct[i];
1061 zigzag_direct[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);
1062 j = ff_alternate_horizontal_scan[i];
1063 ff_alternate_horizontal_scan[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);
1064 j = ff_alternate_vertical_scan[i];
1065 ff_alternate_vertical_scan[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);