FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dsputil_vis.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 David S. Miller <davem@redhat.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /* The *no_round* functions have been added by James A. Morrison, 2003,2004.
22  The vis code from libmpeg2 was adapted for libavcodec by James A. Morrison.
23  */
24 
25 #include "config.h"
26 
27 #include <inttypes.h>
28 
29 #include "libavutil/attributes.h"
30 #include "libavcodec/dsputil.h"
31 #include "libavutil/mem.h"
32 #include "dsputil_vis.h"
33 
34 #include "vis.h"
35 
36 /* The trick used in some of this file is the formula from the MMX
37  * motion comp code, which is:
38  *
39  * (x+y+1)>>1 == (x|y)-((x^y)>>1)
40  *
41  * This allows us to average 8 bytes at a time in a 64-bit FPU reg.
42  * We avoid overflows by masking before we do the shift, and we
43  * implement the shift by multiplying by 1/2 using mul8x16. So in
44  * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask
45  * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and
46  * the value 0x80808080 is in f8):
47  *
48  * fxor f0, f2, f10
49  * fand f10, f4, f10
50  * fmul8x16 f8, f10, f10
51  * fand f10, f6, f10
52  * for f0, f2, f12
53  * fpsub16 f12, f10, f10
54  */
55 
56 #define DUP4(x) {x, x, x, x}
57 #define DUP8(x) {x, x, x, x, x, x, x, x}
58 DECLARE_ALIGNED(8, static const int16_t, constants1)[] = DUP4 (1);
59 DECLARE_ALIGNED(8, static const int16_t, constants2)[] = DUP4 (2);
60 DECLARE_ALIGNED(8, static const int16_t, constants3)[] = DUP4 (3);
61 DECLARE_ALIGNED(8, static const int16_t, constants6)[] = DUP4 (6);
62 DECLARE_ALIGNED(8, static const int8_t, constants_fe)[] = DUP8 (0xfe);
63 DECLARE_ALIGNED(8, static const int8_t, constants_7f)[] = DUP8 (0x7f);
64 DECLARE_ALIGNED(8, static const int8_t, constants128)[] = DUP8 (128);
65 DECLARE_ALIGNED(8, static const int16_t, constants256_512)[] =
66  {256, 512, 256, 512};
67 DECLARE_ALIGNED(8, static const int16_t, constants256_1024)[] =
68  {256, 1024, 256, 1024};
69 
70 #define REF_0 0
71 #define REF_0_1 1
72 #define REF_2 2
73 #define REF_2_1 3
74 #define REF_4 4
75 #define REF_4_1 5
76 #define REF_6 6
77 #define REF_6_1 7
78 #define REF_S0 8
79 #define REF_S0_1 9
80 #define REF_S2 10
81 #define REF_S2_1 11
82 #define REF_S4 12
83 #define REF_S4_1 13
84 #define REF_S6 14
85 #define REF_S6_1 15
86 #define DST_0 16
87 #define DST_1 17
88 #define DST_2 18
89 #define DST_3 19
90 #define CONST_1 20
91 #define CONST_2 20
92 #define CONST_3 20
93 #define CONST_6 20
94 #define MASK_fe 20
95 #define CONST_128 22
96 #define CONST_256 22
97 #define CONST_512 22
98 #define CONST_1024 22
99 #define TMP0 24
100 #define TMP1 25
101 #define TMP2 26
102 #define TMP3 27
103 #define TMP4 28
104 #define TMP5 29
105 #define ZERO 30
106 #define MASK_7f 30
107 
108 #define TMP6 32
109 #define TMP8 34
110 #define TMP10 36
111 #define TMP12 38
112 #define TMP14 40
113 #define TMP16 42
114 #define TMP18 44
115 #define TMP20 46
116 #define TMP22 48
117 #define TMP24 50
118 #define TMP26 52
119 #define TMP28 54
120 #define TMP30 56
121 #define TMP32 58
122 
123 static void MC_put_o_16_vis (uint8_t * dest, const uint8_t * ref,
124  const ptrdiff_t stride, int height)
125 {
126  ref = vis_alignaddr(ref);
127  do { /* 5 cycles */
128  vis_ld64(ref[0], TMP0);
129 
130  vis_ld64_2(ref, 8, TMP2);
131 
132  vis_ld64_2(ref, 16, TMP4);
133  ref += stride;
134 
136  vis_st64(REF_0, dest[0]);
137 
139  vis_st64_2(REF_2, dest, 8);
140  dest += stride;
141  } while (--height);
142 }
143 
144 static void MC_put_o_8_vis (uint8_t * dest, const uint8_t * ref,
145  const ptrdiff_t stride, int height)
146 {
147  ref = vis_alignaddr(ref);
148  do { /* 4 cycles */
149  vis_ld64(ref[0], TMP0);
150 
151  vis_ld64(ref[8], TMP2);
152  ref += stride;
153 
154  /* stall */
155 
157  vis_st64(REF_0, dest[0]);
158  dest += stride;
159  } while (--height);
160 }
161 
162 
163 static void MC_avg_o_16_vis (uint8_t * dest, const uint8_t * ref,
164  const ptrdiff_t stride, int height)
165 {
166  int stride_8 = stride + 8;
167 
168  ref = vis_alignaddr(ref);
169 
170  vis_ld64(ref[0], TMP0);
171 
172  vis_ld64(ref[8], TMP2);
173 
174  vis_ld64(ref[16], TMP4);
175 
176  vis_ld64(dest[0], DST_0);
177 
178  vis_ld64(dest[8], DST_2);
179 
182 
185 
187 
188  ref += stride;
189  height = (height >> 1) - 1;
190 
191  do { /* 24 cycles */
192  vis_ld64(ref[0], TMP0);
193  vis_xor(DST_0, REF_0, TMP6);
194 
195  vis_ld64_2(ref, 8, TMP2);
197 
198  vis_ld64_2(ref, 16, TMP4);
199  ref += stride;
201  vis_xor(DST_2, REF_2, TMP8);
202 
204 
205  vis_or(DST_0, REF_0, TMP10);
206  vis_ld64_2(dest, stride, DST_0);
208 
209  vis_or(DST_2, REF_2, TMP12);
210  vis_ld64_2(dest, stride_8, DST_2);
211 
212  vis_ld64(ref[0], TMP14);
214 
216 
218  vis_st64(TMP6, dest[0]);
219 
221  vis_st64_2(TMP8, dest, 8);
222 
223  dest += stride;
224  vis_ld64_2(ref, 8, TMP16);
226 
227  vis_ld64_2(ref, 16, TMP18);
229  ref += stride;
230 
232 
234 
237 
239 
240  vis_or(DST_0, REF_0, TMP24);
242 
243  vis_or(DST_2, REF_2, TMP26);
244 
245  vis_ld64_2(dest, stride, DST_0);
247 
248  vis_ld64_2(dest, stride_8, DST_2);
250 
252 
254 
256  vis_st64(TMP20, dest[0]);
257 
259  vis_st64_2(TMP22, dest, 8);
260  dest += stride;
261  } while (--height);
262 
263  vis_ld64(ref[0], TMP0);
264  vis_xor(DST_0, REF_0, TMP6);
265 
266  vis_ld64_2(ref, 8, TMP2);
268 
269  vis_ld64_2(ref, 16, TMP4);
271  vis_xor(DST_2, REF_2, TMP8);
272 
274 
275  vis_or(DST_0, REF_0, TMP10);
276  vis_ld64_2(dest, stride, DST_0);
278 
279  vis_or(DST_2, REF_2, TMP12);
280  vis_ld64_2(dest, stride_8, DST_2);
281 
282  vis_ld64(ref[0], TMP14);
284 
286 
288  vis_st64(TMP6, dest[0]);
289 
291  vis_st64_2(TMP8, dest, 8);
292 
293  dest += stride;
295 
297 
299 
301 
304 
306 
307  vis_or(DST_0, REF_0, TMP24);
309 
310  vis_or(DST_2, REF_2, TMP26);
311 
313 
315 
317  vis_st64(TMP20, dest[0]);
318 
320  vis_st64_2(TMP22, dest, 8);
321 }
322 
323 static void MC_avg_o_8_vis (uint8_t * dest, const uint8_t * ref,
324  const ptrdiff_t stride, int height)
325 {
326  ref = vis_alignaddr(ref);
327 
328  vis_ld64(ref[0], TMP0);
329 
330  vis_ld64(ref[8], TMP2);
331 
332  vis_ld64(dest[0], DST_0);
333 
335 
338 
340 
341  ref += stride;
342  height = (height >> 1) - 1;
343 
344  do { /* 12 cycles */
345  vis_ld64(ref[0], TMP0);
346  vis_xor(DST_0, REF_0, TMP4);
347 
348  vis_ld64(ref[8], TMP2);
350 
351  vis_or(DST_0, REF_0, TMP6);
352  vis_ld64_2(dest, stride, DST_0);
353  ref += stride;
355 
356  vis_ld64(ref[0], TMP12);
358 
359  vis_ld64(ref[8], TMP2);
360  vis_xor(DST_0, REF_0, TMP0);
361  ref += stride;
362 
364 
366 
368  vis_st64(TMP4, dest[0]);
369  dest += stride;
371 
372  vis_or(DST_0, REF_0, TMP6);
373  vis_ld64_2(dest, stride, DST_0);
374 
376 
378 
380  vis_st64(TMP4, dest[0]);
381  dest += stride;
382  } while (--height);
383 
384  vis_ld64(ref[0], TMP0);
385  vis_xor(DST_0, REF_0, TMP4);
386 
387  vis_ld64(ref[8], TMP2);
389 
390  vis_or(DST_0, REF_0, TMP6);
391  vis_ld64_2(dest, stride, DST_0);
393 
395 
396  vis_xor(DST_0, REF_0, TMP0);
397 
399 
401 
403  vis_st64(TMP4, dest[0]);
404  dest += stride;
406 
407  vis_or(DST_0, REF_0, TMP6);
408 
410 
412  vis_st64(TMP4, dest[0]);
413 }
414 
415 static void MC_put_x_16_vis (uint8_t * dest, const uint8_t * ref,
416  const ptrdiff_t stride, int height)
417 {
418  unsigned long off = (unsigned long) ref & 0x7;
419  unsigned long off_plus_1 = off + 1;
420 
421  ref = vis_alignaddr(ref);
422 
423  vis_ld64(ref[0], TMP0);
424 
425  vis_ld64_2(ref, 8, TMP2);
426 
427  vis_ld64_2(ref, 16, TMP4);
428 
430 
433 
436 
437  if (off != 0x7) {
438  vis_alignaddr_g0((void *)off_plus_1);
441  } else {
442  vis_src1(TMP2, REF_2);
443  vis_src1(TMP4, REF_6);
444  }
445 
446  ref += stride;
447  height = (height >> 1) - 1;
448 
449  do { /* 34 cycles */
450  vis_ld64(ref[0], TMP0);
451  vis_xor(REF_0, REF_2, TMP6);
452 
453  vis_ld64_2(ref, 8, TMP2);
454  vis_xor(REF_4, REF_6, TMP8);
455 
456  vis_ld64_2(ref, 16, TMP4);
458  ref += stride;
459 
460  vis_ld64(ref[0], TMP14);
463 
464  vis_ld64_2(ref, 8, TMP16);
466  vis_or(REF_0, REF_2, TMP10);
467 
468  vis_ld64_2(ref, 16, TMP18);
469  ref += stride;
470  vis_or(REF_4, REF_6, TMP12);
471 
472  vis_alignaddr_g0((void *)off);
473 
475 
477 
478  if (off != 0x7) {
479  vis_alignaddr_g0((void *)off_plus_1);
482  } else {
483  vis_src1(TMP2, REF_2);
484  vis_src1(TMP4, REF_6);
485  }
486 
488 
490 
492  vis_st64(TMP6, dest[0]);
493 
495  vis_st64_2(TMP8, dest, 8);
496  dest += stride;
497 
498  vis_xor(REF_0, REF_2, TMP6);
499 
500  vis_xor(REF_4, REF_6, TMP8);
501 
503 
506 
508  vis_or(REF_0, REF_2, TMP10);
509 
510  vis_or(REF_4, REF_6, TMP12);
511 
512  vis_alignaddr_g0((void *)off);
513 
515 
517 
518  if (off != 0x7) {
519  vis_alignaddr_g0((void *)off_plus_1);
522  } else {
523  vis_src1(TMP16, REF_2);
524  vis_src1(TMP18, REF_6);
525  }
526 
528 
530 
532  vis_st64(TMP6, dest[0]);
533 
535  vis_st64_2(TMP8, dest, 8);
536  dest += stride;
537  } while (--height);
538 
539  vis_ld64(ref[0], TMP0);
540  vis_xor(REF_0, REF_2, TMP6);
541 
542  vis_ld64_2(ref, 8, TMP2);
543  vis_xor(REF_4, REF_6, TMP8);
544 
545  vis_ld64_2(ref, 16, TMP4);
547 
550 
552  vis_or(REF_0, REF_2, TMP10);
553 
554  vis_or(REF_4, REF_6, TMP12);
555 
556  vis_alignaddr_g0((void *)off);
557 
559 
561 
562  if (off != 0x7) {
563  vis_alignaddr_g0((void *)off_plus_1);
566  } else {
567  vis_src1(TMP2, REF_2);
568  vis_src1(TMP4, REF_6);
569  }
570 
572 
574 
576  vis_st64(TMP6, dest[0]);
577 
579  vis_st64_2(TMP8, dest, 8);
580  dest += stride;
581 
582  vis_xor(REF_0, REF_2, TMP6);
583 
584  vis_xor(REF_4, REF_6, TMP8);
585 
587 
590 
592  vis_or(REF_0, REF_2, TMP10);
593 
594  vis_or(REF_4, REF_6, TMP12);
595 
597 
599 
601  vis_st64(TMP6, dest[0]);
602 
604  vis_st64_2(TMP8, dest, 8);
605 }
606 
607 static void MC_put_x_8_vis (uint8_t * dest, const uint8_t * ref,
608  const ptrdiff_t stride, int height)
609 {
610  unsigned long off = (unsigned long) ref & 0x7;
611  unsigned long off_plus_1 = off + 1;
612 
613  ref = vis_alignaddr(ref);
614 
615  vis_ld64(ref[0], TMP0);
616 
617  vis_ld64(ref[8], TMP2);
618 
620 
622 
625 
626  if (off != 0x7) {
627  vis_alignaddr_g0((void *)off_plus_1);
629  } else {
630  vis_src1(TMP2, REF_2);
631  }
632 
633  ref += stride;
634  height = (height >> 1) - 1;
635 
636  do { /* 20 cycles */
637  vis_ld64(ref[0], TMP0);
638  vis_xor(REF_0, REF_2, TMP4);
639 
640  vis_ld64_2(ref, 8, TMP2);
642  ref += stride;
643 
644  vis_ld64(ref[0], TMP8);
645  vis_or(REF_0, REF_2, TMP6);
647 
648  vis_alignaddr_g0((void *)off);
649 
650  vis_ld64_2(ref, 8, TMP10);
651  ref += stride;
653 
654  if (off != 0x7) {
655  vis_alignaddr_g0((void *)off_plus_1);
657  } else {
658  vis_src1(TMP2, REF_2);
659  }
660 
662 
664  vis_st64(DST_0, dest[0]);
665  dest += stride;
666 
668 
670 
671  vis_or(REF_0, REF_2, TMP14);
673 
674  vis_alignaddr_g0((void *)off);
676  if (off != 0x7) {
677  vis_alignaddr_g0((void *)off_plus_1);
679  } else {
680  vis_src1(TMP10, REF_2);
681  }
682 
684 
686  vis_st64(DST_0, dest[0]);
687  dest += stride;
688  } while (--height);
689 
690  vis_ld64(ref[0], TMP0);
691  vis_xor(REF_0, REF_2, TMP4);
692 
693  vis_ld64_2(ref, 8, TMP2);
695 
696  vis_or(REF_0, REF_2, TMP6);
698 
699  vis_alignaddr_g0((void *)off);
700 
702 
703  if (off != 0x7) {
704  vis_alignaddr_g0((void *)off_plus_1);
706  } else {
707  vis_src1(TMP2, REF_2);
708  }
709 
711 
713  vis_st64(DST_0, dest[0]);
714  dest += stride;
715 
717 
719 
720  vis_or(REF_0, REF_2, TMP14);
722 
724 
726  vis_st64(DST_0, dest[0]);
727  dest += stride;
728 }
729 
730 static void MC_avg_x_16_vis (uint8_t * dest, const uint8_t * ref,
731  const ptrdiff_t stride, int height)
732 {
733  unsigned long off = (unsigned long) ref & 0x7;
734  unsigned long off_plus_1 = off + 1;
735 
737 
739  vis_fzero(ZERO);
741 
742  ref = vis_alignaddr(ref);
743  do { /* 26 cycles */
744  vis_ld64(ref[0], TMP0);
745 
746  vis_ld64(ref[8], TMP2);
747 
748  vis_alignaddr_g0((void *)off);
749 
750  vis_ld64(ref[16], TMP4);
751 
752  vis_ld64(dest[0], DST_0);
754 
755  vis_ld64(dest[8], DST_2);
757 
758  if (off != 0x7) {
759  vis_alignaddr_g0((void *)off_plus_1);
762  } else {
763  vis_src1(TMP2, REF_2);
764  vis_src1(TMP4, REF_6);
765  }
766 
768 
771 
773 
775 
778 
780 
782 
785 
788 
791 
794 
797 
798  vis_st64(DST_0, dest[0]);
801 
804 
806 
808 
811 
813  vis_st64(DST_2, dest[8]);
814 
815  ref += stride;
816  dest += stride;
817  } while (--height);
818 }
819 
820 static void MC_avg_x_8_vis (uint8_t * dest, const uint8_t * ref,
821  const ptrdiff_t stride, int height)
822 {
823  unsigned long off = (unsigned long) ref & 0x7;
824  unsigned long off_plus_1 = off + 1;
825  int stride_times_2 = stride << 1;
826 
828 
830  vis_fzero(ZERO);
832 
833  ref = vis_alignaddr(ref);
834  height >>= 2;
835  do { /* 47 cycles */
836  vis_ld64(ref[0], TMP0);
837 
838  vis_ld64_2(ref, 8, TMP2);
839  ref += stride;
840 
841  vis_alignaddr_g0((void *)off);
842 
843  vis_ld64(ref[0], TMP4);
845 
846  vis_ld64_2(ref, 8, TMP6);
847  ref += stride;
848 
849  vis_ld64(ref[0], TMP8);
850 
851  vis_ld64_2(ref, 8, TMP10);
852  ref += stride;
854 
855  vis_ld64(ref[0], TMP12);
856 
857  vis_ld64_2(ref, 8, TMP14);
858  ref += stride;
860 
862 
863  if (off != 0x7) {
864  vis_alignaddr_g0((void *)off_plus_1);
865 
866  vis_ld64(dest[0], DST_0);
868 
869  vis_ld64_2(dest, stride, DST_2);
871 
873 
875  } else {
876  vis_ld64(dest[0], DST_0);
877  vis_src1(TMP2, REF_2);
878 
879  vis_ld64_2(dest, stride, DST_2);
880  vis_src1(TMP6, REF_6);
881 
883 
885  }
886 
889 
892 
895 
898 
901 
904 
907 
910 
913 
916 
919 
921  vis_st64(DST_0, dest[0]);
922  dest += stride;
924 
925  vis_ld64_2(dest, stride, DST_0);
927 
928  vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/);
931 
933  vis_st64(DST_2, dest[0]);
934  dest += stride;
935 
938 
941 
944 
947 
950 
953 
956 
959 
961  vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20);
962 
963  vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22);
965 
968 
971  vis_st64(DST_0, dest[0]);
972  dest += stride;
973 
975 
978 
980  vis_st64(DST_2, dest[0]);
981  dest += stride;
982  } while (--height);
983 }
984 
985 static void MC_put_y_16_vis (uint8_t * dest, const uint8_t * ref,
986  const ptrdiff_t stride, int height)
987 {
988  ref = vis_alignaddr(ref);
989  vis_ld64(ref[0], TMP0);
990 
991  vis_ld64_2(ref, 8, TMP2);
992 
993  vis_ld64_2(ref, 16, TMP4);
994  ref += stride;
995 
996  vis_ld64(ref[0], TMP6);
998 
999  vis_ld64_2(ref, 8, TMP8);
1001 
1002  vis_ld64_2(ref, 16, TMP10);
1003  ref += stride;
1004 
1007 
1010 
1012  height = (height >> 1) - 1;
1013  do { /* 24 cycles */
1014  vis_ld64(ref[0], TMP0);
1015  vis_xor(REF_0, REF_2, TMP12);
1016 
1017  vis_ld64_2(ref, 8, TMP2);
1018  vis_xor(REF_4, REF_6, TMP16);
1019 
1020  vis_ld64_2(ref, 16, TMP4);
1021  ref += stride;
1022  vis_or(REF_0, REF_2, TMP14);
1023 
1024  vis_ld64(ref[0], TMP6);
1025  vis_or(REF_4, REF_6, TMP18);
1026 
1027  vis_ld64_2(ref, 8, TMP8);
1029 
1030  vis_ld64_2(ref, 16, TMP10);
1031  ref += stride;
1033 
1035 
1038 
1040  vis_xor(REF_0, REF_2, TMP0);
1041 
1042  vis_xor(REF_4, REF_6, TMP2);
1043 
1044  vis_or(REF_0, REF_2, TMP20);
1045 
1047 
1049 
1051  vis_st64(TMP12, dest[0]);
1052 
1054  vis_st64_2(TMP16, dest, 8);
1055  dest += stride;
1056 
1057  vis_or(REF_4, REF_6, TMP18);
1058 
1059  vis_and(TMP0, MASK_fe, TMP0);
1060 
1061  vis_and(TMP2, MASK_fe, TMP2);
1063 
1066 
1068 
1069  vis_and(TMP0, MASK_7f, TMP0);
1070 
1071  vis_and(TMP2, MASK_7f, TMP2);
1072 
1074  vis_st64(TMP0, dest[0]);
1075 
1077  vis_st64_2(TMP2, dest, 8);
1078  dest += stride;
1079  } while (--height);
1080 
1081  vis_ld64(ref[0], TMP0);
1082  vis_xor(REF_0, REF_2, TMP12);
1083 
1084  vis_ld64_2(ref, 8, TMP2);
1085  vis_xor(REF_4, REF_6, TMP16);
1086 
1087  vis_ld64_2(ref, 16, TMP4);
1088  vis_or(REF_0, REF_2, TMP14);
1089 
1090  vis_or(REF_4, REF_6, TMP18);
1091 
1093 
1095 
1097 
1100 
1102  vis_xor(REF_0, REF_2, TMP0);
1103 
1104  vis_xor(REF_4, REF_6, TMP2);
1105 
1106  vis_or(REF_0, REF_2, TMP20);
1107 
1109 
1111 
1113  vis_st64(TMP12, dest[0]);
1114 
1116  vis_st64_2(TMP16, dest, 8);
1117  dest += stride;
1118 
1119  vis_or(REF_4, REF_6, TMP18);
1120 
1121  vis_and(TMP0, MASK_fe, TMP0);
1122 
1123  vis_and(TMP2, MASK_fe, TMP2);
1125 
1127 
1128  vis_and(TMP0, MASK_7f, TMP0);
1129 
1130  vis_and(TMP2, MASK_7f, TMP2);
1131 
1133  vis_st64(TMP0, dest[0]);
1134 
1136  vis_st64_2(TMP2, dest, 8);
1137 }
1138 
1139 static void MC_put_y_8_vis (uint8_t * dest, const uint8_t * ref,
1140  const ptrdiff_t stride, int height)
1141 {
1142  ref = vis_alignaddr(ref);
1143  vis_ld64(ref[0], TMP0);
1144 
1145  vis_ld64_2(ref, 8, TMP2);
1146  ref += stride;
1147 
1148  vis_ld64(ref[0], TMP4);
1149 
1150  vis_ld64_2(ref, 8, TMP6);
1151  ref += stride;
1152 
1155 
1158 
1160  height = (height >> 1) - 1;
1161  do { /* 12 cycles */
1162  vis_ld64(ref[0], TMP0);
1163  vis_xor(REF_0, REF_2, TMP4);
1164 
1165  vis_ld64_2(ref, 8, TMP2);
1166  ref += stride;
1167  vis_and(TMP4, MASK_fe, TMP4);
1168 
1169  vis_or(REF_0, REF_2, TMP6);
1171 
1173  vis_ld64(ref[0], TMP0);
1174 
1175  vis_ld64_2(ref, 8, TMP2);
1176  ref += stride;
1177  vis_xor(REF_0, REF_2, TMP12);
1178 
1179  vis_and(TMP4, MASK_7f, TMP4);
1180 
1182 
1184  vis_or(REF_0, REF_2, TMP14);
1185 
1187  vis_st64(DST_0, dest[0]);
1188  dest += stride;
1189 
1191 
1193 
1195  vis_st64(DST_0, dest[0]);
1196  dest += stride;
1197  } while (--height);
1198 
1199  vis_ld64(ref[0], TMP0);
1200  vis_xor(REF_0, REF_2, TMP4);
1201 
1202  vis_ld64_2(ref, 8, TMP2);
1203  vis_and(TMP4, MASK_fe, TMP4);
1204 
1205  vis_or(REF_0, REF_2, TMP6);
1207 
1209 
1210  vis_xor(REF_0, REF_2, TMP12);
1211 
1212  vis_and(TMP4, MASK_7f, TMP4);
1213 
1215 
1217  vis_or(REF_0, REF_2, TMP14);
1218 
1220  vis_st64(DST_0, dest[0]);
1221  dest += stride;
1222 
1224 
1226  vis_st64(DST_0, dest[0]);
1227 }
1228 
1229 static void MC_avg_y_16_vis (uint8_t * dest, const uint8_t * ref,
1230  const ptrdiff_t stride, int height)
1231 {
1232  int stride_8 = stride + 8;
1233  int stride_16 = stride + 16;
1234 
1236 
1237  ref = vis_alignaddr(ref);
1238 
1239  vis_ld64(ref[ 0], TMP0);
1240  vis_fzero(ZERO);
1241 
1242  vis_ld64(ref[ 8], TMP2);
1243 
1244  vis_ld64(ref[16], TMP4);
1245 
1248 
1251  height >>= 1;
1252 
1253  do { /* 31 cycles */
1254  vis_ld64_2(ref, stride, TMP0);
1257 
1258  vis_ld64_2(ref, stride_8, TMP2);
1261 
1262  vis_ld64_2(ref, stride_16, TMP4);
1263  ref += stride;
1264 
1265  vis_ld64(dest[0], DST_0);
1267 
1268  vis_ld64_2(dest, 8, DST_2);
1270 
1271  vis_ld64_2(ref, stride, TMP6);
1274 
1275  vis_ld64_2(ref, stride_8, TMP8);
1277 
1278  vis_ld64_2(ref, stride_16, TMP10);
1279  ref += stride;
1280 
1281  vis_ld64_2(dest, stride, REF_S0/*DST_4*/);
1284 
1285  vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/);
1288 
1291 
1294 
1297 
1299 
1302 
1305 
1308 
1311 
1314 
1317 
1320 
1323 
1326 
1328  vis_st64(DST_0, dest[0]);
1330 
1333 
1335  vis_st64_2(DST_2, dest, 8);
1336  dest += stride;
1338 
1340 
1343 
1346  vis_st64(DST_0, dest[0]);
1347 
1350 
1352  vis_st64_2(DST_2, dest, 8);
1353  dest += stride;
1354  } while (--height);
1355 }
1356 
1357 static void MC_avg_y_8_vis (uint8_t * dest, const uint8_t * ref,
1358  const ptrdiff_t stride, int height)
1359 {
1360  int stride_8 = stride + 8;
1361 
1363 
1364  ref = vis_alignaddr(ref);
1365 
1366  vis_ld64(ref[ 0], TMP0);
1367  vis_fzero(ZERO);
1368 
1369  vis_ld64(ref[ 8], TMP2);
1370 
1373 
1375 
1376  height >>= 1;
1377  do { /* 20 cycles */
1378  vis_ld64_2(ref, stride, TMP0);
1381 
1382  vis_ld64_2(ref, stride_8, TMP2);
1383  ref += stride;
1384 
1385  vis_ld64(dest[0], DST_0);
1386 
1387  vis_ld64_2(dest, stride, DST_2);
1389 
1390  vis_ld64_2(ref, stride, TMP4);
1393 
1394  vis_ld64_2(ref, stride_8, TMP6);
1395  ref += stride;
1398 
1401 
1404 
1406 
1408 
1411 
1414 
1416  vis_pack16(TMP0, DST_0);
1417 
1418  vis_pack16(TMP2, DST_1);
1419  vis_st64(DST_0, dest[0]);
1420  dest += stride;
1422 
1424 
1426 
1428  vis_pack16(TMP0, DST_2);
1429 
1430  vis_pack16(TMP2, DST_3);
1431  vis_st64(DST_2, dest[0]);
1432  dest += stride;
1433  } while (--height);
1434 }
1435 
1436 static void MC_put_xy_16_vis (uint8_t * dest, const uint8_t * ref,
1437  const ptrdiff_t stride, int height)
1438 {
1439  unsigned long off = (unsigned long) ref & 0x7;
1440  unsigned long off_plus_1 = off + 1;
1441  int stride_8 = stride + 8;
1442  int stride_16 = stride + 16;
1443 
1445 
1446  ref = vis_alignaddr(ref);
1447 
1448  vis_ld64(ref[ 0], TMP0);
1449  vis_fzero(ZERO);
1450 
1451  vis_ld64(ref[ 8], TMP2);
1452 
1453  vis_ld64(ref[16], TMP4);
1454 
1457 
1460 
1461  if (off != 0x7) {
1462  vis_alignaddr_g0((void *)off_plus_1);
1465  } else {
1466  vis_src1(TMP2, REF_S2);
1467  vis_src1(TMP4, REF_S6);
1468  }
1469 
1470  height >>= 1;
1471  do {
1472  vis_ld64_2(ref, stride, TMP0);
1475 
1476  vis_alignaddr_g0((void *)off);
1477 
1478  vis_ld64_2(ref, stride_8, TMP2);
1481 
1482  vis_ld64_2(ref, stride_16, TMP4);
1483  ref += stride;
1486 
1487  vis_ld64_2(ref, stride, TMP6);
1490 
1491  vis_ld64_2(ref, stride_8, TMP8);
1493 
1494  vis_ld64_2(ref, stride_16, TMP10);
1495  ref += stride;
1497 
1499 
1501 
1502  if (off != 0x7) {
1503  vis_alignaddr_g0((void *)off_plus_1);
1508  } else {
1509  vis_src1(TMP2, REF_2);
1510  vis_src1(TMP4, REF_6);
1511  vis_src1(TMP8, REF_S2);
1512  vis_src1(TMP10, REF_S6);
1513  }
1514 
1517 
1520 
1523 
1526 
1527  vis_padd16(TMP8, TMP4, TMP8);
1529 
1532 
1534 
1536 
1538 
1541 
1543  vis_st64(DST_0, dest[0]);
1545 
1548 
1551 
1554 
1557 
1559 
1561 
1564 
1566  vis_st64_2(DST_2, dest, 8);
1567  dest += stride;
1569 
1572 
1575 
1578 
1580  vis_st64(DST_0, dest[0]);
1582 
1584 
1585  vis_padd16(TMP0, TMP4, TMP0);
1586 
1587  vis_padd16(TMP2, TMP6, TMP2);
1588 
1590 
1592  vis_pack16(TMP0, DST_2);
1593 
1594  vis_pack16(TMP2, DST_3);
1595  vis_st64_2(DST_2, dest, 8);
1596  dest += stride;
1597  } while (--height);
1598 }
1599 
1600 static void MC_put_xy_8_vis (uint8_t * dest, const uint8_t * ref,
1601  const ptrdiff_t stride, int height)
1602 {
1603  unsigned long off = (unsigned long) ref & 0x7;
1604  unsigned long off_plus_1 = off + 1;
1605  int stride_8 = stride + 8;
1606 
1608 
1609  ref = vis_alignaddr(ref);
1610 
1611  vis_ld64(ref[ 0], TMP0);
1612  vis_fzero(ZERO);
1613 
1614  vis_ld64(ref[ 8], TMP2);
1615 
1617 
1620 
1621  if (off != 0x7) {
1622  vis_alignaddr_g0((void *)off_plus_1);
1624  } else {
1625  vis_src1(TMP2, REF_S2);
1626  }
1627 
1628  height >>= 1;
1629  do { /* 26 cycles */
1630  vis_ld64_2(ref, stride, TMP0);
1633 
1634  vis_alignaddr_g0((void *)off);
1635 
1636  vis_ld64_2(ref, stride_8, TMP2);
1637  ref += stride;
1640 
1641  vis_ld64_2(ref, stride, TMP4);
1642 
1643  vis_ld64_2(ref, stride_8, TMP6);
1644  ref += stride;
1646 
1648 
1650 
1652 
1653  if (off != 0x7) {
1654  vis_alignaddr_g0((void *)off_plus_1);
1657  } else {
1658  vis_src1(TMP2, REF_S6);
1659  vis_src1(TMP6, REF_S2);
1660  }
1661 
1664 
1667 
1670 
1673 
1676 
1678 
1680 
1682 
1684  vis_pack16(TMP8, DST_0);
1685 
1687  vis_st64(DST_0, dest[0]);
1688  dest += stride;
1690 
1692 
1694 
1697 
1699  vis_st64(DST_2, dest[0]);
1700  dest += stride;
1701  } while (--height);
1702 }
1703 
1704 static void MC_avg_xy_16_vis (uint8_t * dest, const uint8_t * ref,
1705  const ptrdiff_t stride, int height)
1706 {
1707  unsigned long off = (unsigned long) ref & 0x7;
1708  unsigned long off_plus_1 = off + 1;
1709  int stride_8 = stride + 8;
1710  int stride_16 = stride + 16;
1711 
1713 
1714  ref = vis_alignaddr(ref);
1715 
1716  vis_ld64(ref[ 0], TMP0);
1717  vis_fzero(ZERO);
1718 
1719  vis_ld64(ref[ 8], TMP2);
1720 
1721  vis_ld64(ref[16], TMP4);
1722 
1725 
1728 
1729  if (off != 0x7) {
1730  vis_alignaddr_g0((void *)off_plus_1);
1733  } else {
1734  vis_src1(TMP2, REF_S2);
1735  vis_src1(TMP4, REF_S6);
1736  }
1737 
1738  height >>= 1;
1739  do { /* 55 cycles */
1740  vis_ld64_2(ref, stride, TMP0);
1743 
1744  vis_alignaddr_g0((void *)off);
1745 
1746  vis_ld64_2(ref, stride_8, TMP2);
1749 
1750  vis_ld64_2(ref, stride_16, TMP4);
1751  ref += stride;
1754 
1755  vis_ld64_2(ref, stride, TMP6);
1758 
1759  vis_ld64_2(ref, stride_8, TMP8);
1761 
1762  vis_ld64_2(ref, stride_16, TMP10);
1763  ref += stride;
1765 
1766  vis_ld64(dest[0], DST_0);
1768 
1769  vis_ld64_2(dest, 8, DST_2);
1771 
1772  if (off != 0x7) {
1773  vis_alignaddr_g0((void *)off_plus_1);
1778  } else {
1779  vis_src1(TMP2, REF_2);
1780  vis_src1(TMP4, REF_6);
1781  vis_src1(TMP8, REF_S2);
1782  vis_src1(TMP10, REF_S6);
1783  }
1784 
1787 
1790 
1793 
1796 
1799 
1800  vis_padd16(TMP0, TMP4, TMP0);
1802 
1803  vis_padd16(TMP2, TMP6, TMP2);
1805 
1808 
1811 
1814 
1817 
1819 
1822 
1824  vis_st64(DST_0, dest[0]);
1826 
1827  vis_ld64_2(dest, stride, DST_0);
1830 
1831  vis_padd16(TMP4, TMP8, TMP4);
1833 
1835 
1837 
1839 
1841 
1843 
1846 
1849 
1851  vis_st64_2(DST_2, dest, 8);
1852  dest += stride;
1853 
1854  vis_ld64_2(dest, 8, DST_2);
1857 
1860 
1863 
1866 
1868 
1870 
1872  vis_pack16(TMP8, DST_0);
1873 
1875  vis_st64(DST_0, dest[0]);
1876 
1878 
1881 
1884 
1886 
1888 
1889  /* stall */
1890 
1893 
1895  vis_st64_2(DST_2, dest, 8);
1896  dest += stride;
1897  } while (--height);
1898 }
1899 
1900 static void MC_avg_xy_8_vis (uint8_t * dest, const uint8_t * ref,
1901  const ptrdiff_t stride, int height)
1902 {
1903  unsigned long off = (unsigned long) ref & 0x7;
1904  unsigned long off_plus_1 = off + 1;
1905  int stride_8 = stride + 8;
1906 
1908 
1909  ref = vis_alignaddr(ref);
1910 
1911  vis_ld64(ref[0], TMP0);
1912  vis_fzero(ZERO);
1913 
1914  vis_ld64_2(ref, 8, TMP2);
1915 
1917 
1920 
1921  if (off != 0x7) {
1922  vis_alignaddr_g0((void *)off_plus_1);
1924  } else {
1925  vis_src1(TMP2, REF_S2);
1926  }
1927 
1928  height >>= 1;
1929  do { /* 31 cycles */
1930  vis_ld64_2(ref, stride, TMP0);
1933 
1934  vis_ld64_2(ref, stride_8, TMP2);
1935  ref += stride;
1938 
1939  vis_alignaddr_g0((void *)off);
1940 
1941  vis_ld64_2(ref, stride, TMP4);
1943 
1944  vis_ld64_2(ref, stride_8, TMP6);
1945  ref += stride;
1946 
1947  vis_ld64(dest[0], DST_0);
1949 
1950  vis_ld64_2(dest, stride, DST_2);
1951 
1952  if (off != 0x7) {
1953  vis_alignaddr_g0((void *)off_plus_1);
1956  } else {
1957  vis_src1(TMP2, REF_S6);
1958  vis_src1(TMP6, REF_S2);
1959  }
1960 
1963 
1966 
1969 
1972 
1975 
1978 
1981 
1984 
1987 
1989 
1991 
1993 
1995  vis_pack16(TMP8, DST_0);
1996 
1998  vis_st64(DST_0, dest[0]);
1999  dest += stride;
2000 
2002 
2004 
2006 
2008 
2010 
2013 
2015  vis_st64(DST_2, dest[0]);
2016  dest += stride;
2017  } while (--height);
2018 }
2019 
2020 /* End of rounding code */
2021 
2022 /* Start of no rounding code */
2023 /* The trick used in some of this file is the formula from the MMX
2024  * motion comp code, which is:
2025  *
2026  * (x+y)>>1 == (x&y)+((x^y)>>1)
2027  *
2028  * This allows us to average 8 bytes at a time in a 64-bit FPU reg.
2029  * We avoid overflows by masking before we do the shift, and we
2030  * implement the shift by multiplying by 1/2 using mul8x16. So in
2031  * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask
2032  * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and
2033  * the value 0x80808080 is in f8):
2034  *
2035  * fxor f0, f2, f10
2036  * fand f10, f4, f10
2037  * fmul8x16 f8, f10, f10
2038  * fand f10, f6, f10
2039  * fand f0, f2, f12
2040  * fpadd16 f12, f10, f10
2041  */
2042 
2043 static void MC_put_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
2044  const ptrdiff_t stride, int height)
2045 {
2046  ref = vis_alignaddr(ref);
2047  do { /* 5 cycles */
2048  vis_ld64(ref[0], TMP0);
2049 
2050  vis_ld64_2(ref, 8, TMP2);
2051 
2052  vis_ld64_2(ref, 16, TMP4);
2053  ref += stride;
2054 
2056  vis_st64(REF_0, dest[0]);
2057 
2059  vis_st64_2(REF_2, dest, 8);
2060  dest += stride;
2061  } while (--height);
2062 }
2063 
2064 static void MC_put_no_round_o_8_vis (uint8_t * dest, const uint8_t * ref,
2065  const ptrdiff_t stride, int height)
2066 {
2067  ref = vis_alignaddr(ref);
2068  do { /* 4 cycles */
2069  vis_ld64(ref[0], TMP0);
2070 
2071  vis_ld64(ref[8], TMP2);
2072  ref += stride;
2073 
2074  /* stall */
2075 
2077  vis_st64(REF_0, dest[0]);
2078  dest += stride;
2079  } while (--height);
2080 }
2081 
2082 
2083 static void MC_avg_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
2084  const ptrdiff_t stride, int height)
2085 {
2086  int stride_8 = stride + 8;
2087 
2088  ref = vis_alignaddr(ref);
2089 
2090  vis_ld64(ref[0], TMP0);
2091 
2092  vis_ld64(ref[8], TMP2);
2093 
2094  vis_ld64(ref[16], TMP4);
2095 
2096  vis_ld64(dest[0], DST_0);
2097 
2098  vis_ld64(dest[8], DST_2);
2099 
2102 
2105 
2107 
2108  ref += stride;
2109  height = (height >> 1) - 1;
2110 
2111  do { /* 24 cycles */
2112  vis_ld64(ref[0], TMP0);
2113  vis_xor(DST_0, REF_0, TMP6);
2114 
2115  vis_ld64_2(ref, 8, TMP2);
2116  vis_and(TMP6, MASK_fe, TMP6);
2117 
2118  vis_ld64_2(ref, 16, TMP4);
2119  ref += stride;
2121  vis_xor(DST_2, REF_2, TMP8);
2122 
2123  vis_and(TMP8, MASK_fe, TMP8);
2124 
2125  vis_and(DST_0, REF_0, TMP10);
2126  vis_ld64_2(dest, stride, DST_0);
2128 
2129  vis_and(DST_2, REF_2, TMP12);
2130  vis_ld64_2(dest, stride_8, DST_2);
2131 
2132  vis_ld64(ref[0], TMP14);
2133  vis_and(TMP6, MASK_7f, TMP6);
2134 
2135  vis_and(TMP8, MASK_7f, TMP8);
2136 
2138  vis_st64(TMP6, dest[0]);
2139 
2141  vis_st64_2(TMP8, dest, 8);
2142 
2143  dest += stride;
2144  vis_ld64_2(ref, 8, TMP16);
2146 
2147  vis_ld64_2(ref, 16, TMP18);
2149  ref += stride;
2150 
2151  vis_xor(DST_0, REF_0, TMP20);
2152 
2154 
2155  vis_xor(DST_2, REF_2, TMP22);
2157 
2159 
2160  vis_and(DST_0, REF_0, TMP24);
2162 
2163  vis_and(DST_2, REF_2, TMP26);
2164 
2165  vis_ld64_2(dest, stride, DST_0);
2167 
2168  vis_ld64_2(dest, stride_8, DST_2);
2170 
2172 
2174 
2176  vis_st64(TMP20, dest[0]);
2177 
2179  vis_st64_2(TMP22, dest, 8);
2180  dest += stride;
2181  } while (--height);
2182 
2183  vis_ld64(ref[0], TMP0);
2184  vis_xor(DST_0, REF_0, TMP6);
2185 
2186  vis_ld64_2(ref, 8, TMP2);
2187  vis_and(TMP6, MASK_fe, TMP6);
2188 
2189  vis_ld64_2(ref, 16, TMP4);
2191  vis_xor(DST_2, REF_2, TMP8);
2192 
2193  vis_and(TMP8, MASK_fe, TMP8);
2194 
2195  vis_and(DST_0, REF_0, TMP10);
2196  vis_ld64_2(dest, stride, DST_0);
2198 
2199  vis_and(DST_2, REF_2, TMP12);
2200  vis_ld64_2(dest, stride_8, DST_2);
2201 
2202  vis_ld64(ref[0], TMP14);
2203  vis_and(TMP6, MASK_7f, TMP6);
2204 
2205  vis_and(TMP8, MASK_7f, TMP8);
2206 
2208  vis_st64(TMP6, dest[0]);
2209 
2211  vis_st64_2(TMP8, dest, 8);
2212 
2213  dest += stride;
2215 
2217 
2218  vis_xor(DST_0, REF_0, TMP20);
2219 
2221 
2222  vis_xor(DST_2, REF_2, TMP22);
2224 
2226 
2227  vis_and(DST_0, REF_0, TMP24);
2229 
2230  vis_and(DST_2, REF_2, TMP26);
2231 
2233 
2235 
2237  vis_st64(TMP20, dest[0]);
2238 
2240  vis_st64_2(TMP22, dest, 8);
2241 }
2242 
2243 static void MC_put_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
2244  const ptrdiff_t stride, int height)
2245 {
2246  unsigned long off = (unsigned long) ref & 0x7;
2247  unsigned long off_plus_1 = off + 1;
2248 
2249  ref = vis_alignaddr(ref);
2250 
2251  vis_ld64(ref[0], TMP0);
2252 
2253  vis_ld64_2(ref, 8, TMP2);
2254 
2255  vis_ld64_2(ref, 16, TMP4);
2256 
2258 
2261 
2264 
2265  if (off != 0x7) {
2266  vis_alignaddr_g0((void *)off_plus_1);
2269  } else {
2270  vis_src1(TMP2, REF_2);
2271  vis_src1(TMP4, REF_6);
2272  }
2273 
2274  ref += stride;
2275  height = (height >> 1) - 1;
2276 
2277  do { /* 34 cycles */
2278  vis_ld64(ref[0], TMP0);
2279  vis_xor(REF_0, REF_2, TMP6);
2280 
2281  vis_ld64_2(ref, 8, TMP2);
2282  vis_xor(REF_4, REF_6, TMP8);
2283 
2284  vis_ld64_2(ref, 16, TMP4);
2285  vis_and(TMP6, MASK_fe, TMP6);
2286  ref += stride;
2287 
2288  vis_ld64(ref[0], TMP14);
2290  vis_and(TMP8, MASK_fe, TMP8);
2291 
2292  vis_ld64_2(ref, 8, TMP16);
2294  vis_and(REF_0, REF_2, TMP10);
2295 
2296  vis_ld64_2(ref, 16, TMP18);
2297  ref += stride;
2298  vis_and(REF_4, REF_6, TMP12);
2299 
2300  vis_alignaddr_g0((void *)off);
2301 
2303 
2305 
2306  if (off != 0x7) {
2307  vis_alignaddr_g0((void *)off_plus_1);
2310  } else {
2311  vis_src1(TMP2, REF_2);
2312  vis_src1(TMP4, REF_6);
2313  }
2314 
2315  vis_and(TMP6, MASK_7f, TMP6);
2316 
2317  vis_and(TMP8, MASK_7f, TMP8);
2318 
2320  vis_st64(TMP6, dest[0]);
2321 
2323  vis_st64_2(TMP8, dest, 8);
2324  dest += stride;
2325 
2326  vis_xor(REF_0, REF_2, TMP6);
2327 
2328  vis_xor(REF_4, REF_6, TMP8);
2329 
2330  vis_and(TMP6, MASK_fe, TMP6);
2331 
2333  vis_and(TMP8, MASK_fe, TMP8);
2334 
2336  vis_and(REF_0, REF_2, TMP10);
2337 
2338  vis_and(REF_4, REF_6, TMP12);
2339 
2340  vis_alignaddr_g0((void *)off);
2341 
2343 
2345 
2346  if (off != 0x7) {
2347  vis_alignaddr_g0((void *)off_plus_1);
2350  } else {
2351  vis_src1(TMP16, REF_2);
2352  vis_src1(TMP18, REF_6);
2353  }
2354 
2355  vis_and(TMP6, MASK_7f, TMP6);
2356 
2357  vis_and(TMP8, MASK_7f, TMP8);
2358 
2360  vis_st64(TMP6, dest[0]);
2361 
2363  vis_st64_2(TMP8, dest, 8);
2364  dest += stride;
2365  } while (--height);
2366 
2367  vis_ld64(ref[0], TMP0);
2368  vis_xor(REF_0, REF_2, TMP6);
2369 
2370  vis_ld64_2(ref, 8, TMP2);
2371  vis_xor(REF_4, REF_6, TMP8);
2372 
2373  vis_ld64_2(ref, 16, TMP4);
2374  vis_and(TMP6, MASK_fe, TMP6);
2375 
2377  vis_and(TMP8, MASK_fe, TMP8);
2378 
2380  vis_and(REF_0, REF_2, TMP10);
2381 
2382  vis_and(REF_4, REF_6, TMP12);
2383 
2384  vis_alignaddr_g0((void *)off);
2385 
2387 
2389 
2390  if (off != 0x7) {
2391  vis_alignaddr_g0((void *)off_plus_1);
2394  } else {
2395  vis_src1(TMP2, REF_2);
2396  vis_src1(TMP4, REF_6);
2397  }
2398 
2399  vis_and(TMP6, MASK_7f, TMP6);
2400 
2401  vis_and(TMP8, MASK_7f, TMP8);
2402 
2404  vis_st64(TMP6, dest[0]);
2405 
2407  vis_st64_2(TMP8, dest, 8);
2408  dest += stride;
2409 
2410  vis_xor(REF_0, REF_2, TMP6);
2411 
2412  vis_xor(REF_4, REF_6, TMP8);
2413 
2414  vis_and(TMP6, MASK_fe, TMP6);
2415 
2417  vis_and(TMP8, MASK_fe, TMP8);
2418 
2420  vis_and(REF_0, REF_2, TMP10);
2421 
2422  vis_and(REF_4, REF_6, TMP12);
2423 
2424  vis_and(TMP6, MASK_7f, TMP6);
2425 
2426  vis_and(TMP8, MASK_7f, TMP8);
2427 
2429  vis_st64(TMP6, dest[0]);
2430 
2432  vis_st64_2(TMP8, dest, 8);
2433 }
2434 
2435 static void MC_put_no_round_x_8_vis (uint8_t * dest, const uint8_t * ref,
2436  const ptrdiff_t stride, int height)
2437 {
2438  unsigned long off = (unsigned long) ref & 0x7;
2439  unsigned long off_plus_1 = off + 1;
2440 
2441  ref = vis_alignaddr(ref);
2442 
2443  vis_ld64(ref[0], TMP0);
2444 
2445  vis_ld64(ref[8], TMP2);
2446 
2448 
2450 
2453 
2454  if (off != 0x7) {
2455  vis_alignaddr_g0((void *)off_plus_1);
2457  } else {
2458  vis_src1(TMP2, REF_2);
2459  }
2460 
2461  ref += stride;
2462  height = (height >> 1) - 1;
2463 
2464  do { /* 20 cycles */
2465  vis_ld64(ref[0], TMP0);
2466  vis_xor(REF_0, REF_2, TMP4);
2467 
2468  vis_ld64_2(ref, 8, TMP2);
2469  vis_and(TMP4, MASK_fe, TMP4);
2470  ref += stride;
2471 
2472  vis_ld64(ref[0], TMP8);
2473  vis_and(REF_0, REF_2, TMP6);
2475 
2476  vis_alignaddr_g0((void *)off);
2477 
2478  vis_ld64_2(ref, 8, TMP10);
2479  ref += stride;
2481 
2482  if (off != 0x7) {
2483  vis_alignaddr_g0((void *)off_plus_1);
2485  } else {
2486  vis_src1(TMP2, REF_2);
2487  }
2488 
2489  vis_and(TMP4, MASK_7f, TMP4);
2490 
2492  vis_st64(DST_0, dest[0]);
2493  dest += stride;
2494 
2495  vis_xor(REF_0, REF_2, TMP12);
2496 
2498 
2499  vis_and(REF_0, REF_2, TMP14);
2501 
2502  vis_alignaddr_g0((void *)off);
2504  if (off != 0x7) {
2505  vis_alignaddr_g0((void *)off_plus_1);
2507  } else {
2508  vis_src1(TMP10, REF_2);
2509  }
2510 
2512 
2514  vis_st64(DST_0, dest[0]);
2515  dest += stride;
2516  } while (--height);
2517 
2518  vis_ld64(ref[0], TMP0);
2519  vis_xor(REF_0, REF_2, TMP4);
2520 
2521  vis_ld64_2(ref, 8, TMP2);
2522  vis_and(TMP4, MASK_fe, TMP4);
2523 
2524  vis_and(REF_0, REF_2, TMP6);
2526 
2527  vis_alignaddr_g0((void *)off);
2528 
2530 
2531  if (off != 0x7) {
2532  vis_alignaddr_g0((void *)off_plus_1);
2534  } else {
2535  vis_src1(TMP2, REF_2);
2536  }
2537 
2538  vis_and(TMP4, MASK_7f, TMP4);
2539 
2541  vis_st64(DST_0, dest[0]);
2542  dest += stride;
2543 
2544  vis_xor(REF_0, REF_2, TMP12);
2545 
2547 
2548  vis_and(REF_0, REF_2, TMP14);
2550 
2552 
2554  vis_st64(DST_0, dest[0]);
2555  dest += stride;
2556 }
2557 
2558 static void MC_avg_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
2559  const ptrdiff_t stride, int height)
2560 {
2561  unsigned long off = (unsigned long) ref & 0x7;
2562  unsigned long off_plus_1 = off + 1;
2563 
2565 
2567  vis_fzero(ZERO);
2569 
2570  ref = vis_alignaddr(ref);
2571  do { /* 26 cycles */
2572  vis_ld64(ref[0], TMP0);
2573 
2574  vis_ld64(ref[8], TMP2);
2575 
2576  vis_alignaddr_g0((void *)off);
2577 
2578  vis_ld64(ref[16], TMP4);
2579 
2580  vis_ld64(dest[0], DST_0);
2582 
2583  vis_ld64(dest[8], DST_2);
2585 
2586  if (off != 0x7) {
2587  vis_alignaddr_g0((void *)off_plus_1);
2590  } else {
2591  vis_src1(TMP2, REF_2);
2592  vis_src1(TMP4, REF_6);
2593  }
2594 
2596 
2599 
2601 
2602  vis_padd16(TMP0, TMP4, TMP0);
2603 
2605  vis_padd16(TMP2, TMP6, TMP2);
2606 
2608 
2610 
2611  vis_padd16(TMP0, TMP4, TMP0);
2613 
2614  vis_padd16(TMP2, TMP6, TMP2);
2616 
2619 
2621  vis_pack16(TMP8, DST_0);
2622 
2625 
2626  vis_st64(DST_0, dest[0]);
2629 
2632 
2634 
2635  vis_padd16(TMP0, TMP4, TMP0);
2636 
2637  vis_padd16(TMP2, TMP6, TMP2);
2638  vis_pack16(TMP0, DST_2);
2639 
2640  vis_pack16(TMP2, DST_3);
2641  vis_st64(DST_2, dest[8]);
2642 
2643  ref += stride;
2644  dest += stride;
2645  } while (--height);
2646 }
2647 
2648 static void MC_put_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
2649  const ptrdiff_t stride, int height)
2650 {
2651  ref = vis_alignaddr(ref);
2652  vis_ld64(ref[0], TMP0);
2653 
2654  vis_ld64_2(ref, 8, TMP2);
2655 
2656  vis_ld64_2(ref, 16, TMP4);
2657  ref += stride;
2658 
2659  vis_ld64(ref[0], TMP6);
2661 
2662  vis_ld64_2(ref, 8, TMP8);
2664 
2665  vis_ld64_2(ref, 16, TMP10);
2666  ref += stride;
2667 
2670 
2673 
2675  height = (height >> 1) - 1;
2676  do { /* 24 cycles */
2677  vis_ld64(ref[0], TMP0);
2678  vis_xor(REF_0, REF_2, TMP12);
2679 
2680  vis_ld64_2(ref, 8, TMP2);
2681  vis_xor(REF_4, REF_6, TMP16);
2682 
2683  vis_ld64_2(ref, 16, TMP4);
2684  ref += stride;
2685  vis_and(REF_0, REF_2, TMP14);
2686 
2687  vis_ld64(ref[0], TMP6);
2688  vis_and(REF_4, REF_6, TMP18);
2689 
2690  vis_ld64_2(ref, 8, TMP8);
2692 
2693  vis_ld64_2(ref, 16, TMP10);
2694  ref += stride;
2696 
2698 
2701 
2703  vis_xor(REF_0, REF_2, TMP0);
2704 
2705  vis_xor(REF_4, REF_6, TMP2);
2706 
2707  vis_and(REF_0, REF_2, TMP20);
2708 
2710 
2712 
2714  vis_st64(TMP12, dest[0]);
2715 
2717  vis_st64_2(TMP16, dest, 8);
2718  dest += stride;
2719 
2720  vis_and(REF_4, REF_6, TMP18);
2721 
2722  vis_and(TMP0, MASK_fe, TMP0);
2723 
2724  vis_and(TMP2, MASK_fe, TMP2);
2726 
2729 
2731 
2732  vis_and(TMP0, MASK_7f, TMP0);
2733 
2734  vis_and(TMP2, MASK_7f, TMP2);
2735 
2737  vis_st64(TMP0, dest[0]);
2738 
2740  vis_st64_2(TMP2, dest, 8);
2741  dest += stride;
2742  } while (--height);
2743 
2744  vis_ld64(ref[0], TMP0);
2745  vis_xor(REF_0, REF_2, TMP12);
2746 
2747  vis_ld64_2(ref, 8, TMP2);
2748  vis_xor(REF_4, REF_6, TMP16);
2749 
2750  vis_ld64_2(ref, 16, TMP4);
2751  vis_and(REF_0, REF_2, TMP14);
2752 
2753  vis_and(REF_4, REF_6, TMP18);
2754 
2756 
2758 
2760 
2763 
2765  vis_xor(REF_0, REF_2, TMP0);
2766 
2767  vis_xor(REF_4, REF_6, TMP2);
2768 
2769  vis_and(REF_0, REF_2, TMP20);
2770 
2772 
2774 
2776  vis_st64(TMP12, dest[0]);
2777 
2779  vis_st64_2(TMP16, dest, 8);
2780  dest += stride;
2781 
2782  vis_and(REF_4, REF_6, TMP18);
2783 
2784  vis_and(TMP0, MASK_fe, TMP0);
2785 
2786  vis_and(TMP2, MASK_fe, TMP2);
2788 
2790 
2791  vis_and(TMP0, MASK_7f, TMP0);
2792 
2793  vis_and(TMP2, MASK_7f, TMP2);
2794 
2796  vis_st64(TMP0, dest[0]);
2797 
2799  vis_st64_2(TMP2, dest, 8);
2800 }
2801 
2802 static void MC_put_no_round_y_8_vis (uint8_t * dest, const uint8_t * ref,
2803  const ptrdiff_t stride, int height)
2804 {
2805  ref = vis_alignaddr(ref);
2806  vis_ld64(ref[0], TMP0);
2807 
2808  vis_ld64_2(ref, 8, TMP2);
2809  ref += stride;
2810 
2811  vis_ld64(ref[0], TMP4);
2812 
2813  vis_ld64_2(ref, 8, TMP6);
2814  ref += stride;
2815 
2818 
2821 
2823  height = (height >> 1) - 1;
2824  do { /* 12 cycles */
2825  vis_ld64(ref[0], TMP0);
2826  vis_xor(REF_0, REF_2, TMP4);
2827 
2828  vis_ld64_2(ref, 8, TMP2);
2829  ref += stride;
2830  vis_and(TMP4, MASK_fe, TMP4);
2831 
2832  vis_and(REF_0, REF_2, TMP6);
2834 
2836  vis_ld64(ref[0], TMP0);
2837 
2838  vis_ld64_2(ref, 8, TMP2);
2839  ref += stride;
2840  vis_xor(REF_0, REF_2, TMP12);
2841 
2842  vis_and(TMP4, MASK_7f, TMP4);
2843 
2845 
2847  vis_and(REF_0, REF_2, TMP14);
2848 
2850  vis_st64(DST_0, dest[0]);
2851  dest += stride;
2852 
2854 
2856 
2858  vis_st64(DST_0, dest[0]);
2859  dest += stride;
2860  } while (--height);
2861 
2862  vis_ld64(ref[0], TMP0);
2863  vis_xor(REF_0, REF_2, TMP4);
2864 
2865  vis_ld64_2(ref, 8, TMP2);
2866  vis_and(TMP4, MASK_fe, TMP4);
2867 
2868  vis_and(REF_0, REF_2, TMP6);
2870 
2872 
2873  vis_xor(REF_0, REF_2, TMP12);
2874 
2875  vis_and(TMP4, MASK_7f, TMP4);
2876 
2878 
2880  vis_and(REF_0, REF_2, TMP14);
2881 
2883  vis_st64(DST_0, dest[0]);
2884  dest += stride;
2885 
2887 
2889  vis_st64(DST_0, dest[0]);
2890 }
2891 
2892 static void MC_avg_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
2893  const ptrdiff_t stride, int height)
2894 {
2895  int stride_8 = stride + 8;
2896  int stride_16 = stride + 16;
2897 
2899 
2900  ref = vis_alignaddr(ref);
2901 
2902  vis_ld64(ref[ 0], TMP0);
2903  vis_fzero(ZERO);
2904 
2905  vis_ld64(ref[ 8], TMP2);
2906 
2907  vis_ld64(ref[16], TMP4);
2908 
2911 
2914  height >>= 1;
2915 
2916  do { /* 31 cycles */
2917  vis_ld64_2(ref, stride, TMP0);
2920 
2921  vis_ld64_2(ref, stride_8, TMP2);
2924 
2925  vis_ld64_2(ref, stride_16, TMP4);
2926  ref += stride;
2927 
2928  vis_ld64(dest[0], DST_0);
2930 
2931  vis_ld64_2(dest, 8, DST_2);
2933 
2934  vis_ld64_2(ref, stride, TMP6);
2937 
2938  vis_ld64_2(ref, stride_8, TMP8);
2940 
2941  vis_ld64_2(ref, stride_16, TMP10);
2942  ref += stride;
2943 
2944  vis_ld64_2(dest, stride, REF_S0/*DST_4*/);
2947 
2948  vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/);
2951 
2954 
2957 
2960 
2962 
2965 
2968 
2971 
2974 
2977 
2980 
2983 
2986 
2989 
2991  vis_st64(DST_0, dest[0]);
2993 
2996 
2998  vis_st64_2(DST_2, dest, 8);
2999  dest += stride;
3001 
3003 
3006 
3009  vis_st64(DST_0, dest[0]);
3010 
3013 
3015  vis_st64_2(DST_2, dest, 8);
3016  dest += stride;
3017  } while (--height);
3018 }
3019 
3020 static void MC_put_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
3021  const ptrdiff_t stride, int height)
3022 {
3023  unsigned long off = (unsigned long) ref & 0x7;
3024  unsigned long off_plus_1 = off + 1;
3025  int stride_8 = stride + 8;
3026  int stride_16 = stride + 16;
3027 
3029 
3030  ref = vis_alignaddr(ref);
3031 
3032  vis_ld64(ref[ 0], TMP0);
3033  vis_fzero(ZERO);
3034 
3035  vis_ld64(ref[ 8], TMP2);
3036 
3037  vis_ld64(ref[16], TMP4);
3038 
3041 
3044 
3045  if (off != 0x7) {
3046  vis_alignaddr_g0((void *)off_plus_1);
3049  } else {
3050  vis_src1(TMP2, REF_S2);
3051  vis_src1(TMP4, REF_S6);
3052  }
3053 
3054  height >>= 1;
3055  do {
3056  vis_ld64_2(ref, stride, TMP0);
3059 
3060  vis_alignaddr_g0((void *)off);
3061 
3062  vis_ld64_2(ref, stride_8, TMP2);
3065 
3066  vis_ld64_2(ref, stride_16, TMP4);
3067  ref += stride;
3070 
3071  vis_ld64_2(ref, stride, TMP6);
3074 
3075  vis_ld64_2(ref, stride_8, TMP8);
3077 
3078  vis_ld64_2(ref, stride_16, TMP10);
3079  ref += stride;
3081 
3083 
3085 
3086  if (off != 0x7) {
3087  vis_alignaddr_g0((void *)off_plus_1);
3092  } else {
3093  vis_src1(TMP2, REF_2);
3094  vis_src1(TMP4, REF_6);
3095  vis_src1(TMP8, REF_S2);
3096  vis_src1(TMP10, REF_S6);
3097  }
3098 
3101 
3104 
3107 
3110 
3111  vis_padd16(TMP8, TMP4, TMP8);
3113 
3116 
3118 
3120 
3122 
3125 
3127  vis_st64(DST_0, dest[0]);
3129 
3132 
3135 
3138 
3141 
3143 
3145 
3148 
3150  vis_st64_2(DST_2, dest, 8);
3151  dest += stride;
3153 
3156 
3159 
3162 
3164  vis_st64(DST_0, dest[0]);
3166 
3168 
3169  vis_padd16(TMP0, TMP4, TMP0);
3170 
3171  vis_padd16(TMP2, TMP6, TMP2);
3172 
3174 
3176  vis_pack16(TMP0, DST_2);
3177 
3178  vis_pack16(TMP2, DST_3);
3179  vis_st64_2(DST_2, dest, 8);
3180  dest += stride;
3181  } while (--height);
3182 }
3183 
3184 static void MC_put_no_round_xy_8_vis (uint8_t * dest, const uint8_t * ref,
3185  const ptrdiff_t stride, int height)
3186 {
3187  unsigned long off = (unsigned long) ref & 0x7;
3188  unsigned long off_plus_1 = off + 1;
3189  int stride_8 = stride + 8;
3190 
3192 
3193  ref = vis_alignaddr(ref);
3194 
3195  vis_ld64(ref[ 0], TMP0);
3196  vis_fzero(ZERO);
3197 
3198  vis_ld64(ref[ 8], TMP2);
3199 
3201 
3204 
3205  if (off != 0x7) {
3206  vis_alignaddr_g0((void *)off_plus_1);
3208  } else {
3209  vis_src1(TMP2, REF_S2);
3210  }
3211 
3212  height >>= 1;
3213  do { /* 26 cycles */
3214  vis_ld64_2(ref, stride, TMP0);
3217 
3218  vis_alignaddr_g0((void *)off);
3219 
3220  vis_ld64_2(ref, stride_8, TMP2);
3221  ref += stride;
3224 
3225  vis_ld64_2(ref, stride, TMP4);
3226 
3227  vis_ld64_2(ref, stride_8, TMP6);
3228  ref += stride;
3230 
3232 
3234 
3236 
3237  if (off != 0x7) {
3238  vis_alignaddr_g0((void *)off_plus_1);
3241  } else {
3242  vis_src1(TMP2, REF_S6);
3243  vis_src1(TMP6, REF_S2);
3244  }
3245 
3248 
3251 
3254 
3257 
3260 
3262 
3264 
3266 
3268  vis_pack16(TMP8, DST_0);
3269 
3271  vis_st64(DST_0, dest[0]);
3272  dest += stride;
3274 
3276 
3278 
3281 
3283  vis_st64(DST_2, dest[0]);
3284  dest += stride;
3285  } while (--height);
3286 }
3287 
3288 static void MC_avg_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
3289  const ptrdiff_t stride, int height)
3290 {
3291  unsigned long off = (unsigned long) ref & 0x7;
3292  unsigned long off_plus_1 = off + 1;
3293  int stride_8 = stride + 8;
3294  int stride_16 = stride + 16;
3295 
3297 
3298  ref = vis_alignaddr(ref);
3299 
3300  vis_ld64(ref[ 0], TMP0);
3301  vis_fzero(ZERO);
3302 
3303  vis_ld64(ref[ 8], TMP2);
3304 
3305  vis_ld64(ref[16], TMP4);
3306 
3309 
3312 
3313  if (off != 0x7) {
3314  vis_alignaddr_g0((void *)off_plus_1);
3317  } else {
3318  vis_src1(TMP2, REF_S2);
3319  vis_src1(TMP4, REF_S6);
3320  }
3321 
3322  height >>= 1;
3323  do { /* 55 cycles */
3324  vis_ld64_2(ref, stride, TMP0);
3327 
3328  vis_alignaddr_g0((void *)off);
3329 
3330  vis_ld64_2(ref, stride_8, TMP2);
3333 
3334  vis_ld64_2(ref, stride_16, TMP4);
3335  ref += stride;
3338 
3339  vis_ld64_2(ref, stride, TMP6);
3342 
3343  vis_ld64_2(ref, stride_8, TMP8);
3345 
3346  vis_ld64_2(ref, stride_16, TMP10);
3347  ref += stride;
3349 
3350  vis_ld64(dest[0], DST_0);
3352 
3353  vis_ld64_2(dest, 8, DST_2);
3355 
3356  if (off != 0x7) {
3357  vis_alignaddr_g0((void *)off_plus_1);
3362  } else {
3363  vis_src1(TMP2, REF_2);
3364  vis_src1(TMP4, REF_6);
3365  vis_src1(TMP8, REF_S2);
3366  vis_src1(TMP10, REF_S6);
3367  }
3368 
3371 
3374 
3377 
3380 
3383 
3384  vis_padd16(TMP0, TMP4, TMP0);
3386 
3387  vis_padd16(TMP2, TMP6, TMP2);
3389 
3392 
3395 
3398 
3401 
3403 
3406 
3408  vis_st64(DST_0, dest[0]);
3410 
3411  vis_ld64_2(dest, stride, DST_0);
3414 
3415  vis_padd16(TMP4, TMP8, TMP4);
3417 
3419 
3421 
3423 
3425 
3427 
3430 
3433 
3435  vis_st64_2(DST_2, dest, 8);
3436  dest += stride;
3437 
3438  vis_ld64_2(dest, 8, DST_2);
3441 
3444 
3447 
3450 
3452 
3454 
3456  vis_pack16(TMP8, DST_0);
3457 
3459  vis_st64(DST_0, dest[0]);
3460 
3462 
3465 
3468 
3470 
3472 
3473  /* stall */
3474 
3477 
3479  vis_st64_2(DST_2, dest, 8);
3480  dest += stride;
3481  } while (--height);
3482 }
3483 
3484 /* End of no rounding code */
3485 
3486 #define ACCEL_SPARC_VIS 1
3487 #define ACCEL_SPARC_VIS2 2
3488 
3489 static int vis_level(void)
3490 {
3491  int accel = 0;
3492  accel |= ACCEL_SPARC_VIS;
3493  accel |= ACCEL_SPARC_VIS2;
3494  return accel;
3495 }
3496 
3497 /* libavcodec initialization code */
3499 {
3500  /* VIS-specific optimizations */
3501  int accel = vis_level ();
3502  const int high_bit_depth = avctx->bits_per_raw_sample > 8;
3503 
3504  if (accel & ACCEL_SPARC_VIS && !high_bit_depth) {
3505  if (avctx->idct_algo == FF_IDCT_SIMPLEVIS) {
3508  c->idct = ff_simple_idct_vis;
3510  }
3511 
3512  c->put_pixels_tab[0][0] = MC_put_o_16_vis;
3513  c->put_pixels_tab[0][1] = MC_put_x_16_vis;
3514  c->put_pixels_tab[0][2] = MC_put_y_16_vis;
3515  c->put_pixels_tab[0][3] = MC_put_xy_16_vis;
3516 
3517  c->put_pixels_tab[1][0] = MC_put_o_8_vis;
3518  c->put_pixels_tab[1][1] = MC_put_x_8_vis;
3519  c->put_pixels_tab[1][2] = MC_put_y_8_vis;
3520  c->put_pixels_tab[1][3] = MC_put_xy_8_vis;
3521 
3522  c->avg_pixels_tab[0][0] = MC_avg_o_16_vis;
3523  c->avg_pixels_tab[0][1] = MC_avg_x_16_vis;
3524  c->avg_pixels_tab[0][2] = MC_avg_y_16_vis;
3525  c->avg_pixels_tab[0][3] = MC_avg_xy_16_vis;
3526 
3527  c->avg_pixels_tab[1][0] = MC_avg_o_8_vis;
3528  c->avg_pixels_tab[1][1] = MC_avg_x_8_vis;
3529  c->avg_pixels_tab[1][2] = MC_avg_y_8_vis;
3530  c->avg_pixels_tab[1][3] = MC_avg_xy_8_vis;
3531 
3536 
3541 
3546  }
3547 }