FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hpeldsp_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 <stddef.h>
26 #include <stdint.h>
27 
28 #include "libavutil/attributes.h"
29 #include "libavutil/mem.h"
30 #include "libavcodec/hpeldsp.h"
31 #include "vis.h"
32 
33 /* The trick used in some of this file is the formula from the MMX
34  * motion comp code, which is:
35  *
36  * (x+y+1)>>1 == (x|y)-((x^y)>>1)
37  *
38  * This allows us to average 8 bytes at a time in a 64-bit FPU reg.
39  * We avoid overflows by masking before we do the shift, and we
40  * implement the shift by multiplying by 1/2 using mul8x16. So in
41  * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask
42  * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and
43  * the value 0x80808080 is in f8):
44  *
45  * fxor f0, f2, f10
46  * fand f10, f4, f10
47  * fmul8x16 f8, f10, f10
48  * fand f10, f6, f10
49  * for f0, f2, f12
50  * fpsub16 f12, f10, f10
51  */
52 
53 #define DUP4(x) {x, x, x, x}
54 #define DUP8(x) {x, x, x, x, x, x, x, x}
55 DECLARE_ALIGNED(8, static const int16_t, constants1)[] = DUP4 (1);
56 DECLARE_ALIGNED(8, static const int16_t, constants2)[] = DUP4 (2);
57 DECLARE_ALIGNED(8, static const int16_t, constants3)[] = DUP4 (3);
58 DECLARE_ALIGNED(8, static const int16_t, constants6)[] = DUP4 (6);
59 DECLARE_ALIGNED(8, static const int8_t, constants_fe)[] = DUP8 (0xfe);
60 DECLARE_ALIGNED(8, static const int8_t, constants_7f)[] = DUP8 (0x7f);
61 DECLARE_ALIGNED(8, static const int8_t, constants128)[] = DUP8 (128);
62 DECLARE_ALIGNED(8, static const int16_t, constants256_512)[] =
63  {256, 512, 256, 512};
64 DECLARE_ALIGNED(8, static const int16_t, constants256_1024)[] =
65  {256, 1024, 256, 1024};
66 
67 #define REF_0 0
68 #define REF_0_1 1
69 #define REF_2 2
70 #define REF_2_1 3
71 #define REF_4 4
72 #define REF_4_1 5
73 #define REF_6 6
74 #define REF_6_1 7
75 #define REF_S0 8
76 #define REF_S0_1 9
77 #define REF_S2 10
78 #define REF_S2_1 11
79 #define REF_S4 12
80 #define REF_S4_1 13
81 #define REF_S6 14
82 #define REF_S6_1 15
83 #define DST_0 16
84 #define DST_1 17
85 #define DST_2 18
86 #define DST_3 19
87 #define CONST_1 20
88 #define CONST_2 20
89 #define CONST_3 20
90 #define CONST_6 20
91 #define MASK_fe 20
92 #define CONST_128 22
93 #define CONST_256 22
94 #define CONST_512 22
95 #define CONST_1024 22
96 #define TMP0 24
97 #define TMP1 25
98 #define TMP2 26
99 #define TMP3 27
100 #define TMP4 28
101 #define TMP5 29
102 #define ZERO 30
103 #define MASK_7f 30
104 
105 #define TMP6 32
106 #define TMP8 34
107 #define TMP10 36
108 #define TMP12 38
109 #define TMP14 40
110 #define TMP16 42
111 #define TMP18 44
112 #define TMP20 46
113 #define TMP22 48
114 #define TMP24 50
115 #define TMP26 52
116 #define TMP28 54
117 #define TMP30 56
118 #define TMP32 58
119 
120 static void MC_put_o_16_vis (uint8_t * dest, const uint8_t * ref,
121  const ptrdiff_t stride, int height)
122 {
123  ref = vis_alignaddr(ref);
124  do { /* 5 cycles */
125  vis_ld64(ref[0], TMP0);
126 
127  vis_ld64_2(ref, 8, TMP2);
128 
129  vis_ld64_2(ref, 16, TMP4);
130  ref += stride;
131 
133  vis_st64(REF_0, dest[0]);
134 
136  vis_st64_2(REF_2, dest, 8);
137  dest += stride;
138  } while (--height);
139 }
140 
141 static void MC_put_o_8_vis (uint8_t * dest, const uint8_t * ref,
142  const ptrdiff_t stride, int height)
143 {
144  ref = vis_alignaddr(ref);
145  do { /* 4 cycles */
146  vis_ld64(ref[0], TMP0);
147 
148  vis_ld64(ref[8], TMP2);
149  ref += stride;
150 
151  /* stall */
152 
154  vis_st64(REF_0, dest[0]);
155  dest += stride;
156  } while (--height);
157 }
158 
159 
160 static void MC_avg_o_16_vis (uint8_t * dest, const uint8_t * ref,
161  const ptrdiff_t stride, int height)
162 {
163  int stride_8 = stride + 8;
164 
165  ref = vis_alignaddr(ref);
166 
167  vis_ld64(ref[0], TMP0);
168 
169  vis_ld64(ref[8], TMP2);
170 
171  vis_ld64(ref[16], TMP4);
172 
173  vis_ld64(dest[0], DST_0);
174 
175  vis_ld64(dest[8], DST_2);
176 
179 
182 
184 
185  ref += stride;
186  height = (height >> 1) - 1;
187 
188  do { /* 24 cycles */
189  vis_ld64(ref[0], TMP0);
190  vis_xor(DST_0, REF_0, TMP6);
191 
192  vis_ld64_2(ref, 8, TMP2);
194 
195  vis_ld64_2(ref, 16, TMP4);
196  ref += stride;
198  vis_xor(DST_2, REF_2, TMP8);
199 
201 
202  vis_or(DST_0, REF_0, TMP10);
203  vis_ld64_2(dest, stride, DST_0);
205 
206  vis_or(DST_2, REF_2, TMP12);
207  vis_ld64_2(dest, stride_8, DST_2);
208 
209  vis_ld64(ref[0], TMP14);
211 
213 
215  vis_st64(TMP6, dest[0]);
216 
218  vis_st64_2(TMP8, dest, 8);
219 
220  dest += stride;
221  vis_ld64_2(ref, 8, TMP16);
223 
224  vis_ld64_2(ref, 16, TMP18);
226  ref += stride;
227 
229 
231 
234 
236 
237  vis_or(DST_0, REF_0, TMP24);
239 
240  vis_or(DST_2, REF_2, TMP26);
241 
242  vis_ld64_2(dest, stride, DST_0);
244 
245  vis_ld64_2(dest, stride_8, DST_2);
247 
249 
251 
253  vis_st64(TMP20, dest[0]);
254 
256  vis_st64_2(TMP22, dest, 8);
257  dest += stride;
258  } while (--height);
259 
260  vis_ld64(ref[0], TMP0);
261  vis_xor(DST_0, REF_0, TMP6);
262 
263  vis_ld64_2(ref, 8, TMP2);
265 
266  vis_ld64_2(ref, 16, TMP4);
268  vis_xor(DST_2, REF_2, TMP8);
269 
271 
272  vis_or(DST_0, REF_0, TMP10);
273  vis_ld64_2(dest, stride, DST_0);
275 
276  vis_or(DST_2, REF_2, TMP12);
277  vis_ld64_2(dest, stride_8, DST_2);
278 
279  vis_ld64(ref[0], TMP14);
281 
283 
285  vis_st64(TMP6, dest[0]);
286 
288  vis_st64_2(TMP8, dest, 8);
289 
290  dest += stride;
292 
294 
296 
298 
301 
303 
304  vis_or(DST_0, REF_0, TMP24);
306 
307  vis_or(DST_2, REF_2, TMP26);
308 
310 
312 
314  vis_st64(TMP20, dest[0]);
315 
317  vis_st64_2(TMP22, dest, 8);
318 }
319 
320 static void MC_avg_o_8_vis (uint8_t * dest, const uint8_t * ref,
321  const ptrdiff_t stride, int height)
322 {
323  ref = vis_alignaddr(ref);
324 
325  vis_ld64(ref[0], TMP0);
326 
327  vis_ld64(ref[8], TMP2);
328 
329  vis_ld64(dest[0], DST_0);
330 
332 
335 
337 
338  ref += stride;
339  height = (height >> 1) - 1;
340 
341  do { /* 12 cycles */
342  vis_ld64(ref[0], TMP0);
343  vis_xor(DST_0, REF_0, TMP4);
344 
345  vis_ld64(ref[8], TMP2);
347 
348  vis_or(DST_0, REF_0, TMP6);
349  vis_ld64_2(dest, stride, DST_0);
350  ref += stride;
352 
353  vis_ld64(ref[0], TMP12);
355 
356  vis_ld64(ref[8], TMP2);
357  vis_xor(DST_0, REF_0, TMP0);
358  ref += stride;
359 
361 
363 
365  vis_st64(TMP4, dest[0]);
366  dest += stride;
368 
369  vis_or(DST_0, REF_0, TMP6);
370  vis_ld64_2(dest, stride, DST_0);
371 
373 
375 
377  vis_st64(TMP4, dest[0]);
378  dest += stride;
379  } while (--height);
380 
381  vis_ld64(ref[0], TMP0);
382  vis_xor(DST_0, REF_0, TMP4);
383 
384  vis_ld64(ref[8], TMP2);
386 
387  vis_or(DST_0, REF_0, TMP6);
388  vis_ld64_2(dest, stride, DST_0);
390 
392 
393  vis_xor(DST_0, REF_0, TMP0);
394 
396 
398 
400  vis_st64(TMP4, dest[0]);
401  dest += stride;
403 
404  vis_or(DST_0, REF_0, TMP6);
405 
407 
409  vis_st64(TMP4, dest[0]);
410 }
411 
412 static void MC_put_x_16_vis (uint8_t * dest, const uint8_t * ref,
413  const ptrdiff_t stride, int height)
414 {
415  unsigned long off = (unsigned long) ref & 0x7;
416  unsigned long off_plus_1 = off + 1;
417 
418  ref = vis_alignaddr(ref);
419 
420  vis_ld64(ref[0], TMP0);
421 
422  vis_ld64_2(ref, 8, TMP2);
423 
424  vis_ld64_2(ref, 16, TMP4);
425 
427 
430 
433 
434  if (off != 0x7) {
435  vis_alignaddr_g0((void *)off_plus_1);
438  } else {
439  vis_src1(TMP2, REF_2);
440  vis_src1(TMP4, REF_6);
441  }
442 
443  ref += stride;
444  height = (height >> 1) - 1;
445 
446  do { /* 34 cycles */
447  vis_ld64(ref[0], TMP0);
448  vis_xor(REF_0, REF_2, TMP6);
449 
450  vis_ld64_2(ref, 8, TMP2);
451  vis_xor(REF_4, REF_6, TMP8);
452 
453  vis_ld64_2(ref, 16, TMP4);
455  ref += stride;
456 
457  vis_ld64(ref[0], TMP14);
460 
461  vis_ld64_2(ref, 8, TMP16);
463  vis_or(REF_0, REF_2, TMP10);
464 
465  vis_ld64_2(ref, 16, TMP18);
466  ref += stride;
467  vis_or(REF_4, REF_6, TMP12);
468 
469  vis_alignaddr_g0((void *)off);
470 
472 
474 
475  if (off != 0x7) {
476  vis_alignaddr_g0((void *)off_plus_1);
479  } else {
480  vis_src1(TMP2, REF_2);
481  vis_src1(TMP4, REF_6);
482  }
483 
485 
487 
489  vis_st64(TMP6, dest[0]);
490 
492  vis_st64_2(TMP8, dest, 8);
493  dest += stride;
494 
495  vis_xor(REF_0, REF_2, TMP6);
496 
497  vis_xor(REF_4, REF_6, TMP8);
498 
500 
503 
505  vis_or(REF_0, REF_2, TMP10);
506 
507  vis_or(REF_4, REF_6, TMP12);
508 
509  vis_alignaddr_g0((void *)off);
510 
512 
514 
515  if (off != 0x7) {
516  vis_alignaddr_g0((void *)off_plus_1);
519  } else {
520  vis_src1(TMP16, REF_2);
521  vis_src1(TMP18, REF_6);
522  }
523 
525 
527 
529  vis_st64(TMP6, dest[0]);
530 
532  vis_st64_2(TMP8, dest, 8);
533  dest += stride;
534  } while (--height);
535 
536  vis_ld64(ref[0], TMP0);
537  vis_xor(REF_0, REF_2, TMP6);
538 
539  vis_ld64_2(ref, 8, TMP2);
540  vis_xor(REF_4, REF_6, TMP8);
541 
542  vis_ld64_2(ref, 16, TMP4);
544 
547 
549  vis_or(REF_0, REF_2, TMP10);
550 
551  vis_or(REF_4, REF_6, TMP12);
552 
553  vis_alignaddr_g0((void *)off);
554 
556 
558 
559  if (off != 0x7) {
560  vis_alignaddr_g0((void *)off_plus_1);
563  } else {
564  vis_src1(TMP2, REF_2);
565  vis_src1(TMP4, REF_6);
566  }
567 
569 
571 
573  vis_st64(TMP6, dest[0]);
574 
576  vis_st64_2(TMP8, dest, 8);
577  dest += stride;
578 
579  vis_xor(REF_0, REF_2, TMP6);
580 
581  vis_xor(REF_4, REF_6, TMP8);
582 
584 
587 
589  vis_or(REF_0, REF_2, TMP10);
590 
591  vis_or(REF_4, REF_6, TMP12);
592 
594 
596 
598  vis_st64(TMP6, dest[0]);
599 
601  vis_st64_2(TMP8, dest, 8);
602 }
603 
604 static void MC_put_x_8_vis (uint8_t * dest, const uint8_t * ref,
605  const ptrdiff_t stride, int height)
606 {
607  unsigned long off = (unsigned long) ref & 0x7;
608  unsigned long off_plus_1 = off + 1;
609 
610  ref = vis_alignaddr(ref);
611 
612  vis_ld64(ref[0], TMP0);
613 
614  vis_ld64(ref[8], TMP2);
615 
617 
619 
622 
623  if (off != 0x7) {
624  vis_alignaddr_g0((void *)off_plus_1);
626  } else {
627  vis_src1(TMP2, REF_2);
628  }
629 
630  ref += stride;
631  height = (height >> 1) - 1;
632 
633  do { /* 20 cycles */
634  vis_ld64(ref[0], TMP0);
635  vis_xor(REF_0, REF_2, TMP4);
636 
637  vis_ld64_2(ref, 8, TMP2);
639  ref += stride;
640 
641  vis_ld64(ref[0], TMP8);
642  vis_or(REF_0, REF_2, TMP6);
644 
645  vis_alignaddr_g0((void *)off);
646 
647  vis_ld64_2(ref, 8, TMP10);
648  ref += stride;
650 
651  if (off != 0x7) {
652  vis_alignaddr_g0((void *)off_plus_1);
654  } else {
655  vis_src1(TMP2, REF_2);
656  }
657 
659 
661  vis_st64(DST_0, dest[0]);
662  dest += stride;
663 
665 
667 
668  vis_or(REF_0, REF_2, TMP14);
670 
671  vis_alignaddr_g0((void *)off);
673  if (off != 0x7) {
674  vis_alignaddr_g0((void *)off_plus_1);
676  } else {
677  vis_src1(TMP10, REF_2);
678  }
679 
681 
683  vis_st64(DST_0, dest[0]);
684  dest += stride;
685  } while (--height);
686 
687  vis_ld64(ref[0], TMP0);
688  vis_xor(REF_0, REF_2, TMP4);
689 
690  vis_ld64_2(ref, 8, TMP2);
692 
693  vis_or(REF_0, REF_2, TMP6);
695 
696  vis_alignaddr_g0((void *)off);
697 
699 
700  if (off != 0x7) {
701  vis_alignaddr_g0((void *)off_plus_1);
703  } else {
704  vis_src1(TMP2, REF_2);
705  }
706 
708 
710  vis_st64(DST_0, dest[0]);
711  dest += stride;
712 
714 
716 
717  vis_or(REF_0, REF_2, TMP14);
719 
721 
723  vis_st64(DST_0, dest[0]);
724  dest += stride;
725 }
726 
727 static void MC_avg_x_16_vis (uint8_t * dest, const uint8_t * ref,
728  const ptrdiff_t stride, int height)
729 {
730  unsigned long off = (unsigned long) ref & 0x7;
731  unsigned long off_plus_1 = off + 1;
732 
734 
736  vis_fzero(ZERO);
738 
739  ref = vis_alignaddr(ref);
740  do { /* 26 cycles */
741  vis_ld64(ref[0], TMP0);
742 
743  vis_ld64(ref[8], TMP2);
744 
745  vis_alignaddr_g0((void *)off);
746 
747  vis_ld64(ref[16], TMP4);
748 
749  vis_ld64(dest[0], DST_0);
751 
752  vis_ld64(dest[8], DST_2);
754 
755  if (off != 0x7) {
756  vis_alignaddr_g0((void *)off_plus_1);
759  } else {
760  vis_src1(TMP2, REF_2);
761  vis_src1(TMP4, REF_6);
762  }
763 
765 
768 
770 
772 
775 
777 
779 
782 
785 
788 
791 
794 
795  vis_st64(DST_0, dest[0]);
798 
801 
803 
805 
808 
810  vis_st64(DST_2, dest[8]);
811 
812  ref += stride;
813  dest += stride;
814  } while (--height);
815 }
816 
817 static void MC_avg_x_8_vis (uint8_t * dest, const uint8_t * ref,
818  const ptrdiff_t stride, int height)
819 {
820  unsigned long off = (unsigned long) ref & 0x7;
821  unsigned long off_plus_1 = off + 1;
822  int stride_times_2 = stride << 1;
823 
825 
827  vis_fzero(ZERO);
829 
830  ref = vis_alignaddr(ref);
831  height >>= 2;
832  do { /* 47 cycles */
833  vis_ld64(ref[0], TMP0);
834 
835  vis_ld64_2(ref, 8, TMP2);
836  ref += stride;
837 
838  vis_alignaddr_g0((void *)off);
839 
840  vis_ld64(ref[0], TMP4);
842 
843  vis_ld64_2(ref, 8, TMP6);
844  ref += stride;
845 
846  vis_ld64(ref[0], TMP8);
847 
848  vis_ld64_2(ref, 8, TMP10);
849  ref += stride;
851 
852  vis_ld64(ref[0], TMP12);
853 
854  vis_ld64_2(ref, 8, TMP14);
855  ref += stride;
857 
859 
860  if (off != 0x7) {
861  vis_alignaddr_g0((void *)off_plus_1);
862 
863  vis_ld64(dest[0], DST_0);
865 
866  vis_ld64_2(dest, stride, DST_2);
868 
870 
872  } else {
873  vis_ld64(dest[0], DST_0);
874  vis_src1(TMP2, REF_2);
875 
876  vis_ld64_2(dest, stride, DST_2);
877  vis_src1(TMP6, REF_6);
878 
880 
882  }
883 
886 
889 
892 
895 
898 
901 
904 
907 
910 
913 
916 
918  vis_st64(DST_0, dest[0]);
919  dest += stride;
921 
922  vis_ld64_2(dest, stride, DST_0);
924 
925  vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/);
928 
930  vis_st64(DST_2, dest[0]);
931  dest += stride;
932 
935 
938 
941 
944 
947 
950 
953 
956 
958  vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20);
959 
960  vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22);
962 
965 
968  vis_st64(DST_0, dest[0]);
969  dest += stride;
970 
972 
975 
977  vis_st64(DST_2, dest[0]);
978  dest += stride;
979  } while (--height);
980 }
981 
982 static void MC_put_y_16_vis (uint8_t * dest, const uint8_t * ref,
983  const ptrdiff_t stride, int height)
984 {
985  ref = vis_alignaddr(ref);
986  vis_ld64(ref[0], TMP0);
987 
988  vis_ld64_2(ref, 8, TMP2);
989 
990  vis_ld64_2(ref, 16, TMP4);
991  ref += stride;
992 
993  vis_ld64(ref[0], TMP6);
995 
996  vis_ld64_2(ref, 8, TMP8);
998 
999  vis_ld64_2(ref, 16, TMP10);
1000  ref += stride;
1001 
1004 
1007 
1009  height = (height >> 1) - 1;
1010  do { /* 24 cycles */
1011  vis_ld64(ref[0], TMP0);
1012  vis_xor(REF_0, REF_2, TMP12);
1013 
1014  vis_ld64_2(ref, 8, TMP2);
1015  vis_xor(REF_4, REF_6, TMP16);
1016 
1017  vis_ld64_2(ref, 16, TMP4);
1018  ref += stride;
1019  vis_or(REF_0, REF_2, TMP14);
1020 
1021  vis_ld64(ref[0], TMP6);
1022  vis_or(REF_4, REF_6, TMP18);
1023 
1024  vis_ld64_2(ref, 8, TMP8);
1026 
1027  vis_ld64_2(ref, 16, TMP10);
1028  ref += stride;
1030 
1032 
1035 
1037  vis_xor(REF_0, REF_2, TMP0);
1038 
1039  vis_xor(REF_4, REF_6, TMP2);
1040 
1041  vis_or(REF_0, REF_2, TMP20);
1042 
1044 
1046 
1048  vis_st64(TMP12, dest[0]);
1049 
1051  vis_st64_2(TMP16, dest, 8);
1052  dest += stride;
1053 
1054  vis_or(REF_4, REF_6, TMP18);
1055 
1056  vis_and(TMP0, MASK_fe, TMP0);
1057 
1058  vis_and(TMP2, MASK_fe, TMP2);
1060 
1063 
1065 
1066  vis_and(TMP0, MASK_7f, TMP0);
1067 
1068  vis_and(TMP2, MASK_7f, TMP2);
1069 
1071  vis_st64(TMP0, dest[0]);
1072 
1074  vis_st64_2(TMP2, dest, 8);
1075  dest += stride;
1076  } while (--height);
1077 
1078  vis_ld64(ref[0], TMP0);
1079  vis_xor(REF_0, REF_2, TMP12);
1080 
1081  vis_ld64_2(ref, 8, TMP2);
1082  vis_xor(REF_4, REF_6, TMP16);
1083 
1084  vis_ld64_2(ref, 16, TMP4);
1085  vis_or(REF_0, REF_2, TMP14);
1086 
1087  vis_or(REF_4, REF_6, TMP18);
1088 
1090 
1092 
1094 
1097 
1099  vis_xor(REF_0, REF_2, TMP0);
1100 
1101  vis_xor(REF_4, REF_6, TMP2);
1102 
1103  vis_or(REF_0, REF_2, TMP20);
1104 
1106 
1108 
1110  vis_st64(TMP12, dest[0]);
1111 
1113  vis_st64_2(TMP16, dest, 8);
1114  dest += stride;
1115 
1116  vis_or(REF_4, REF_6, TMP18);
1117 
1118  vis_and(TMP0, MASK_fe, TMP0);
1119 
1120  vis_and(TMP2, MASK_fe, TMP2);
1122 
1124 
1125  vis_and(TMP0, MASK_7f, TMP0);
1126 
1127  vis_and(TMP2, MASK_7f, TMP2);
1128 
1130  vis_st64(TMP0, dest[0]);
1131 
1133  vis_st64_2(TMP2, dest, 8);
1134 }
1135 
1136 static void MC_put_y_8_vis (uint8_t * dest, const uint8_t * ref,
1137  const ptrdiff_t stride, int height)
1138 {
1139  ref = vis_alignaddr(ref);
1140  vis_ld64(ref[0], TMP0);
1141 
1142  vis_ld64_2(ref, 8, TMP2);
1143  ref += stride;
1144 
1145  vis_ld64(ref[0], TMP4);
1146 
1147  vis_ld64_2(ref, 8, TMP6);
1148  ref += stride;
1149 
1152 
1155 
1157  height = (height >> 1) - 1;
1158  do { /* 12 cycles */
1159  vis_ld64(ref[0], TMP0);
1160  vis_xor(REF_0, REF_2, TMP4);
1161 
1162  vis_ld64_2(ref, 8, TMP2);
1163  ref += stride;
1164  vis_and(TMP4, MASK_fe, TMP4);
1165 
1166  vis_or(REF_0, REF_2, TMP6);
1168 
1170  vis_ld64(ref[0], TMP0);
1171 
1172  vis_ld64_2(ref, 8, TMP2);
1173  ref += stride;
1174  vis_xor(REF_0, REF_2, TMP12);
1175 
1176  vis_and(TMP4, MASK_7f, TMP4);
1177 
1179 
1181  vis_or(REF_0, REF_2, TMP14);
1182 
1184  vis_st64(DST_0, dest[0]);
1185  dest += stride;
1186 
1188 
1190 
1192  vis_st64(DST_0, dest[0]);
1193  dest += stride;
1194  } while (--height);
1195 
1196  vis_ld64(ref[0], TMP0);
1197  vis_xor(REF_0, REF_2, TMP4);
1198 
1199  vis_ld64_2(ref, 8, TMP2);
1200  vis_and(TMP4, MASK_fe, TMP4);
1201 
1202  vis_or(REF_0, REF_2, TMP6);
1204 
1206 
1207  vis_xor(REF_0, REF_2, TMP12);
1208 
1209  vis_and(TMP4, MASK_7f, TMP4);
1210 
1212 
1214  vis_or(REF_0, REF_2, TMP14);
1215 
1217  vis_st64(DST_0, dest[0]);
1218  dest += stride;
1219 
1221 
1223  vis_st64(DST_0, dest[0]);
1224 }
1225 
1226 static void MC_avg_y_16_vis (uint8_t * dest, const uint8_t * ref,
1227  const ptrdiff_t stride, int height)
1228 {
1229  int stride_8 = stride + 8;
1230  int stride_16 = stride + 16;
1231 
1233 
1234  ref = vis_alignaddr(ref);
1235 
1236  vis_ld64(ref[ 0], TMP0);
1237  vis_fzero(ZERO);
1238 
1239  vis_ld64(ref[ 8], TMP2);
1240 
1241  vis_ld64(ref[16], TMP4);
1242 
1245 
1248  height >>= 1;
1249 
1250  do { /* 31 cycles */
1251  vis_ld64_2(ref, stride, TMP0);
1254 
1255  vis_ld64_2(ref, stride_8, TMP2);
1258 
1259  vis_ld64_2(ref, stride_16, TMP4);
1260  ref += stride;
1261 
1262  vis_ld64(dest[0], DST_0);
1264 
1265  vis_ld64_2(dest, 8, DST_2);
1267 
1268  vis_ld64_2(ref, stride, TMP6);
1271 
1272  vis_ld64_2(ref, stride_8, TMP8);
1274 
1275  vis_ld64_2(ref, stride_16, TMP10);
1276  ref += stride;
1277 
1278  vis_ld64_2(dest, stride, REF_S0/*DST_4*/);
1281 
1282  vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/);
1285 
1288 
1291 
1294 
1296 
1299 
1302 
1305 
1308 
1311 
1314 
1317 
1320 
1323 
1325  vis_st64(DST_0, dest[0]);
1327 
1330 
1332  vis_st64_2(DST_2, dest, 8);
1333  dest += stride;
1335 
1337 
1340 
1343  vis_st64(DST_0, dest[0]);
1344 
1347 
1349  vis_st64_2(DST_2, dest, 8);
1350  dest += stride;
1351  } while (--height);
1352 }
1353 
1354 static void MC_avg_y_8_vis (uint8_t * dest, const uint8_t * ref,
1355  const ptrdiff_t stride, int height)
1356 {
1357  int stride_8 = stride + 8;
1358 
1360 
1361  ref = vis_alignaddr(ref);
1362 
1363  vis_ld64(ref[ 0], TMP0);
1364  vis_fzero(ZERO);
1365 
1366  vis_ld64(ref[ 8], TMP2);
1367 
1370 
1372 
1373  height >>= 1;
1374  do { /* 20 cycles */
1375  vis_ld64_2(ref, stride, TMP0);
1378 
1379  vis_ld64_2(ref, stride_8, TMP2);
1380  ref += stride;
1381 
1382  vis_ld64(dest[0], DST_0);
1383 
1384  vis_ld64_2(dest, stride, DST_2);
1386 
1387  vis_ld64_2(ref, stride, TMP4);
1390 
1391  vis_ld64_2(ref, stride_8, TMP6);
1392  ref += stride;
1395 
1398 
1401 
1403 
1405 
1408 
1411 
1413  vis_pack16(TMP0, DST_0);
1414 
1415  vis_pack16(TMP2, DST_1);
1416  vis_st64(DST_0, dest[0]);
1417  dest += stride;
1419 
1421 
1423 
1425  vis_pack16(TMP0, DST_2);
1426 
1427  vis_pack16(TMP2, DST_3);
1428  vis_st64(DST_2, dest[0]);
1429  dest += stride;
1430  } while (--height);
1431 }
1432 
1433 static void MC_put_xy_16_vis (uint8_t * dest, const uint8_t * ref,
1434  const ptrdiff_t stride, int height)
1435 {
1436  unsigned long off = (unsigned long) ref & 0x7;
1437  unsigned long off_plus_1 = off + 1;
1438  int stride_8 = stride + 8;
1439  int stride_16 = stride + 16;
1440 
1442 
1443  ref = vis_alignaddr(ref);
1444 
1445  vis_ld64(ref[ 0], TMP0);
1446  vis_fzero(ZERO);
1447 
1448  vis_ld64(ref[ 8], TMP2);
1449 
1450  vis_ld64(ref[16], TMP4);
1451 
1454 
1457 
1458  if (off != 0x7) {
1459  vis_alignaddr_g0((void *)off_plus_1);
1462  } else {
1463  vis_src1(TMP2, REF_S2);
1464  vis_src1(TMP4, REF_S6);
1465  }
1466 
1467  height >>= 1;
1468  do {
1469  vis_ld64_2(ref, stride, TMP0);
1472 
1473  vis_alignaddr_g0((void *)off);
1474 
1475  vis_ld64_2(ref, stride_8, TMP2);
1478 
1479  vis_ld64_2(ref, stride_16, TMP4);
1480  ref += stride;
1483 
1484  vis_ld64_2(ref, stride, TMP6);
1487 
1488  vis_ld64_2(ref, stride_8, TMP8);
1490 
1491  vis_ld64_2(ref, stride_16, TMP10);
1492  ref += stride;
1494 
1496 
1498 
1499  if (off != 0x7) {
1500  vis_alignaddr_g0((void *)off_plus_1);
1505  } else {
1506  vis_src1(TMP2, REF_2);
1507  vis_src1(TMP4, REF_6);
1508  vis_src1(TMP8, REF_S2);
1509  vis_src1(TMP10, REF_S6);
1510  }
1511 
1514 
1517 
1520 
1523 
1524  vis_padd16(TMP8, TMP4, TMP8);
1526 
1529 
1531 
1533 
1535 
1538 
1540  vis_st64(DST_0, dest[0]);
1542 
1545 
1548 
1551 
1554 
1556 
1558 
1561 
1563  vis_st64_2(DST_2, dest, 8);
1564  dest += stride;
1566 
1569 
1572 
1575 
1577  vis_st64(DST_0, dest[0]);
1579 
1581 
1582  vis_padd16(TMP0, TMP4, TMP0);
1583 
1584  vis_padd16(TMP2, TMP6, TMP2);
1585 
1587 
1589  vis_pack16(TMP0, DST_2);
1590 
1591  vis_pack16(TMP2, DST_3);
1592  vis_st64_2(DST_2, dest, 8);
1593  dest += stride;
1594  } while (--height);
1595 }
1596 
1597 static void MC_put_xy_8_vis (uint8_t * dest, const uint8_t * ref,
1598  const ptrdiff_t stride, int height)
1599 {
1600  unsigned long off = (unsigned long) ref & 0x7;
1601  unsigned long off_plus_1 = off + 1;
1602  int stride_8 = stride + 8;
1603 
1605 
1606  ref = vis_alignaddr(ref);
1607 
1608  vis_ld64(ref[ 0], TMP0);
1609  vis_fzero(ZERO);
1610 
1611  vis_ld64(ref[ 8], TMP2);
1612 
1614 
1617 
1618  if (off != 0x7) {
1619  vis_alignaddr_g0((void *)off_plus_1);
1621  } else {
1622  vis_src1(TMP2, REF_S2);
1623  }
1624 
1625  height >>= 1;
1626  do { /* 26 cycles */
1627  vis_ld64_2(ref, stride, TMP0);
1630 
1631  vis_alignaddr_g0((void *)off);
1632 
1633  vis_ld64_2(ref, stride_8, TMP2);
1634  ref += stride;
1637 
1638  vis_ld64_2(ref, stride, TMP4);
1639 
1640  vis_ld64_2(ref, stride_8, TMP6);
1641  ref += stride;
1643 
1645 
1647 
1649 
1650  if (off != 0x7) {
1651  vis_alignaddr_g0((void *)off_plus_1);
1654  } else {
1655  vis_src1(TMP2, REF_S6);
1656  vis_src1(TMP6, REF_S2);
1657  }
1658 
1661 
1664 
1667 
1670 
1673 
1675 
1677 
1679 
1681  vis_pack16(TMP8, DST_0);
1682 
1684  vis_st64(DST_0, dest[0]);
1685  dest += stride;
1687 
1689 
1691 
1694 
1696  vis_st64(DST_2, dest[0]);
1697  dest += stride;
1698  } while (--height);
1699 }
1700 
1701 static void MC_avg_xy_16_vis (uint8_t * dest, const uint8_t * ref,
1702  const ptrdiff_t stride, int height)
1703 {
1704  unsigned long off = (unsigned long) ref & 0x7;
1705  unsigned long off_plus_1 = off + 1;
1706  int stride_8 = stride + 8;
1707  int stride_16 = stride + 16;
1708 
1710 
1711  ref = vis_alignaddr(ref);
1712 
1713  vis_ld64(ref[ 0], TMP0);
1714  vis_fzero(ZERO);
1715 
1716  vis_ld64(ref[ 8], TMP2);
1717 
1718  vis_ld64(ref[16], TMP4);
1719 
1722 
1725 
1726  if (off != 0x7) {
1727  vis_alignaddr_g0((void *)off_plus_1);
1730  } else {
1731  vis_src1(TMP2, REF_S2);
1732  vis_src1(TMP4, REF_S6);
1733  }
1734 
1735  height >>= 1;
1736  do { /* 55 cycles */
1737  vis_ld64_2(ref, stride, TMP0);
1740 
1741  vis_alignaddr_g0((void *)off);
1742 
1743  vis_ld64_2(ref, stride_8, TMP2);
1746 
1747  vis_ld64_2(ref, stride_16, TMP4);
1748  ref += stride;
1751 
1752  vis_ld64_2(ref, stride, TMP6);
1755 
1756  vis_ld64_2(ref, stride_8, TMP8);
1758 
1759  vis_ld64_2(ref, stride_16, TMP10);
1760  ref += stride;
1762 
1763  vis_ld64(dest[0], DST_0);
1765 
1766  vis_ld64_2(dest, 8, DST_2);
1768 
1769  if (off != 0x7) {
1770  vis_alignaddr_g0((void *)off_plus_1);
1775  } else {
1776  vis_src1(TMP2, REF_2);
1777  vis_src1(TMP4, REF_6);
1778  vis_src1(TMP8, REF_S2);
1779  vis_src1(TMP10, REF_S6);
1780  }
1781 
1784 
1787 
1790 
1793 
1796 
1797  vis_padd16(TMP0, TMP4, TMP0);
1799 
1800  vis_padd16(TMP2, TMP6, TMP2);
1802 
1805 
1808 
1811 
1814 
1816 
1819 
1821  vis_st64(DST_0, dest[0]);
1823 
1824  vis_ld64_2(dest, stride, DST_0);
1827 
1828  vis_padd16(TMP4, TMP8, TMP4);
1830 
1832 
1834 
1836 
1838 
1840 
1843 
1846 
1848  vis_st64_2(DST_2, dest, 8);
1849  dest += stride;
1850 
1851  vis_ld64_2(dest, 8, DST_2);
1854 
1857 
1860 
1863 
1865 
1867 
1869  vis_pack16(TMP8, DST_0);
1870 
1872  vis_st64(DST_0, dest[0]);
1873 
1875 
1878 
1881 
1883 
1885 
1886  /* stall */
1887 
1890 
1892  vis_st64_2(DST_2, dest, 8);
1893  dest += stride;
1894  } while (--height);
1895 }
1896 
1897 static void MC_avg_xy_8_vis (uint8_t * dest, const uint8_t * ref,
1898  const ptrdiff_t stride, int height)
1899 {
1900  unsigned long off = (unsigned long) ref & 0x7;
1901  unsigned long off_plus_1 = off + 1;
1902  int stride_8 = stride + 8;
1903 
1905 
1906  ref = vis_alignaddr(ref);
1907 
1908  vis_ld64(ref[0], TMP0);
1909  vis_fzero(ZERO);
1910 
1911  vis_ld64_2(ref, 8, TMP2);
1912 
1914 
1917 
1918  if (off != 0x7) {
1919  vis_alignaddr_g0((void *)off_plus_1);
1921  } else {
1922  vis_src1(TMP2, REF_S2);
1923  }
1924 
1925  height >>= 1;
1926  do { /* 31 cycles */
1927  vis_ld64_2(ref, stride, TMP0);
1930 
1931  vis_ld64_2(ref, stride_8, TMP2);
1932  ref += stride;
1935 
1936  vis_alignaddr_g0((void *)off);
1937 
1938  vis_ld64_2(ref, stride, TMP4);
1940 
1941  vis_ld64_2(ref, stride_8, TMP6);
1942  ref += stride;
1943 
1944  vis_ld64(dest[0], DST_0);
1946 
1947  vis_ld64_2(dest, stride, DST_2);
1948 
1949  if (off != 0x7) {
1950  vis_alignaddr_g0((void *)off_plus_1);
1953  } else {
1954  vis_src1(TMP2, REF_S6);
1955  vis_src1(TMP6, REF_S2);
1956  }
1957 
1960 
1963 
1966 
1969 
1972 
1975 
1978 
1981 
1984 
1986 
1988 
1990 
1992  vis_pack16(TMP8, DST_0);
1993 
1995  vis_st64(DST_0, dest[0]);
1996  dest += stride;
1997 
1999 
2001 
2003 
2005 
2007 
2010 
2012  vis_st64(DST_2, dest[0]);
2013  dest += stride;
2014  } while (--height);
2015 }
2016 
2017 /* End of rounding code */
2018 
2019 /* Start of no rounding code */
2020 /* The trick used in some of this file is the formula from the MMX
2021  * motion comp code, which is:
2022  *
2023  * (x+y)>>1 == (x&y)+((x^y)>>1)
2024  *
2025  * This allows us to average 8 bytes at a time in a 64-bit FPU reg.
2026  * We avoid overflows by masking before we do the shift, and we
2027  * implement the shift by multiplying by 1/2 using mul8x16. So in
2028  * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask
2029  * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and
2030  * the value 0x80808080 is in f8):
2031  *
2032  * fxor f0, f2, f10
2033  * fand f10, f4, f10
2034  * fmul8x16 f8, f10, f10
2035  * fand f10, f6, f10
2036  * fand f0, f2, f12
2037  * fpadd16 f12, f10, f10
2038  */
2039 
2040 static void MC_put_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
2041  const ptrdiff_t stride, int height)
2042 {
2043  ref = vis_alignaddr(ref);
2044  do { /* 5 cycles */
2045  vis_ld64(ref[0], TMP0);
2046 
2047  vis_ld64_2(ref, 8, TMP2);
2048 
2049  vis_ld64_2(ref, 16, TMP4);
2050  ref += stride;
2051 
2053  vis_st64(REF_0, dest[0]);
2054 
2056  vis_st64_2(REF_2, dest, 8);
2057  dest += stride;
2058  } while (--height);
2059 }
2060 
2061 static void MC_put_no_round_o_8_vis (uint8_t * dest, const uint8_t * ref,
2062  const ptrdiff_t stride, int height)
2063 {
2064  ref = vis_alignaddr(ref);
2065  do { /* 4 cycles */
2066  vis_ld64(ref[0], TMP0);
2067 
2068  vis_ld64(ref[8], TMP2);
2069  ref += stride;
2070 
2071  /* stall */
2072 
2074  vis_st64(REF_0, dest[0]);
2075  dest += stride;
2076  } while (--height);
2077 }
2078 
2079 
2080 static void MC_avg_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
2081  const ptrdiff_t stride, int height)
2082 {
2083  int stride_8 = stride + 8;
2084 
2085  ref = vis_alignaddr(ref);
2086 
2087  vis_ld64(ref[0], TMP0);
2088 
2089  vis_ld64(ref[8], TMP2);
2090 
2091  vis_ld64(ref[16], TMP4);
2092 
2093  vis_ld64(dest[0], DST_0);
2094 
2095  vis_ld64(dest[8], DST_2);
2096 
2099 
2102 
2104 
2105  ref += stride;
2106  height = (height >> 1) - 1;
2107 
2108  do { /* 24 cycles */
2109  vis_ld64(ref[0], TMP0);
2110  vis_xor(DST_0, REF_0, TMP6);
2111 
2112  vis_ld64_2(ref, 8, TMP2);
2113  vis_and(TMP6, MASK_fe, TMP6);
2114 
2115  vis_ld64_2(ref, 16, TMP4);
2116  ref += stride;
2118  vis_xor(DST_2, REF_2, TMP8);
2119 
2120  vis_and(TMP8, MASK_fe, TMP8);
2121 
2122  vis_and(DST_0, REF_0, TMP10);
2123  vis_ld64_2(dest, stride, DST_0);
2125 
2126  vis_and(DST_2, REF_2, TMP12);
2127  vis_ld64_2(dest, stride_8, DST_2);
2128 
2129  vis_ld64(ref[0], TMP14);
2130  vis_and(TMP6, MASK_7f, TMP6);
2131 
2132  vis_and(TMP8, MASK_7f, TMP8);
2133 
2135  vis_st64(TMP6, dest[0]);
2136 
2138  vis_st64_2(TMP8, dest, 8);
2139 
2140  dest += stride;
2141  vis_ld64_2(ref, 8, TMP16);
2143 
2144  vis_ld64_2(ref, 16, TMP18);
2146  ref += stride;
2147 
2148  vis_xor(DST_0, REF_0, TMP20);
2149 
2151 
2152  vis_xor(DST_2, REF_2, TMP22);
2154 
2156 
2157  vis_and(DST_0, REF_0, TMP24);
2159 
2160  vis_and(DST_2, REF_2, TMP26);
2161 
2162  vis_ld64_2(dest, stride, DST_0);
2164 
2165  vis_ld64_2(dest, stride_8, DST_2);
2167 
2169 
2171 
2173  vis_st64(TMP20, dest[0]);
2174 
2176  vis_st64_2(TMP22, dest, 8);
2177  dest += stride;
2178  } while (--height);
2179 
2180  vis_ld64(ref[0], TMP0);
2181  vis_xor(DST_0, REF_0, TMP6);
2182 
2183  vis_ld64_2(ref, 8, TMP2);
2184  vis_and(TMP6, MASK_fe, TMP6);
2185 
2186  vis_ld64_2(ref, 16, TMP4);
2188  vis_xor(DST_2, REF_2, TMP8);
2189 
2190  vis_and(TMP8, MASK_fe, TMP8);
2191 
2192  vis_and(DST_0, REF_0, TMP10);
2193  vis_ld64_2(dest, stride, DST_0);
2195 
2196  vis_and(DST_2, REF_2, TMP12);
2197  vis_ld64_2(dest, stride_8, DST_2);
2198 
2199  vis_ld64(ref[0], TMP14);
2200  vis_and(TMP6, MASK_7f, TMP6);
2201 
2202  vis_and(TMP8, MASK_7f, TMP8);
2203 
2205  vis_st64(TMP6, dest[0]);
2206 
2208  vis_st64_2(TMP8, dest, 8);
2209 
2210  dest += stride;
2212 
2214 
2215  vis_xor(DST_0, REF_0, TMP20);
2216 
2218 
2219  vis_xor(DST_2, REF_2, TMP22);
2221 
2223 
2224  vis_and(DST_0, REF_0, TMP24);
2226 
2227  vis_and(DST_2, REF_2, TMP26);
2228 
2230 
2232 
2234  vis_st64(TMP20, dest[0]);
2235 
2237  vis_st64_2(TMP22, dest, 8);
2238 }
2239 
2240 static void MC_put_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
2241  const ptrdiff_t stride, int height)
2242 {
2243  unsigned long off = (unsigned long) ref & 0x7;
2244  unsigned long off_plus_1 = off + 1;
2245 
2246  ref = vis_alignaddr(ref);
2247 
2248  vis_ld64(ref[0], TMP0);
2249 
2250  vis_ld64_2(ref, 8, TMP2);
2251 
2252  vis_ld64_2(ref, 16, TMP4);
2253 
2255 
2258 
2261 
2262  if (off != 0x7) {
2263  vis_alignaddr_g0((void *)off_plus_1);
2266  } else {
2267  vis_src1(TMP2, REF_2);
2268  vis_src1(TMP4, REF_6);
2269  }
2270 
2271  ref += stride;
2272  height = (height >> 1) - 1;
2273 
2274  do { /* 34 cycles */
2275  vis_ld64(ref[0], TMP0);
2276  vis_xor(REF_0, REF_2, TMP6);
2277 
2278  vis_ld64_2(ref, 8, TMP2);
2279  vis_xor(REF_4, REF_6, TMP8);
2280 
2281  vis_ld64_2(ref, 16, TMP4);
2282  vis_and(TMP6, MASK_fe, TMP6);
2283  ref += stride;
2284 
2285  vis_ld64(ref[0], TMP14);
2287  vis_and(TMP8, MASK_fe, TMP8);
2288 
2289  vis_ld64_2(ref, 8, TMP16);
2291  vis_and(REF_0, REF_2, TMP10);
2292 
2293  vis_ld64_2(ref, 16, TMP18);
2294  ref += stride;
2295  vis_and(REF_4, REF_6, TMP12);
2296 
2297  vis_alignaddr_g0((void *)off);
2298 
2300 
2302 
2303  if (off != 0x7) {
2304  vis_alignaddr_g0((void *)off_plus_1);
2307  } else {
2308  vis_src1(TMP2, REF_2);
2309  vis_src1(TMP4, REF_6);
2310  }
2311 
2312  vis_and(TMP6, MASK_7f, TMP6);
2313 
2314  vis_and(TMP8, MASK_7f, TMP8);
2315 
2317  vis_st64(TMP6, dest[0]);
2318 
2320  vis_st64_2(TMP8, dest, 8);
2321  dest += stride;
2322 
2323  vis_xor(REF_0, REF_2, TMP6);
2324 
2325  vis_xor(REF_4, REF_6, TMP8);
2326 
2327  vis_and(TMP6, MASK_fe, TMP6);
2328 
2330  vis_and(TMP8, MASK_fe, TMP8);
2331 
2333  vis_and(REF_0, REF_2, TMP10);
2334 
2335  vis_and(REF_4, REF_6, TMP12);
2336 
2337  vis_alignaddr_g0((void *)off);
2338 
2340 
2342 
2343  if (off != 0x7) {
2344  vis_alignaddr_g0((void *)off_plus_1);
2347  } else {
2348  vis_src1(TMP16, REF_2);
2349  vis_src1(TMP18, REF_6);
2350  }
2351 
2352  vis_and(TMP6, MASK_7f, TMP6);
2353 
2354  vis_and(TMP8, MASK_7f, TMP8);
2355 
2357  vis_st64(TMP6, dest[0]);
2358 
2360  vis_st64_2(TMP8, dest, 8);
2361  dest += stride;
2362  } while (--height);
2363 
2364  vis_ld64(ref[0], TMP0);
2365  vis_xor(REF_0, REF_2, TMP6);
2366 
2367  vis_ld64_2(ref, 8, TMP2);
2368  vis_xor(REF_4, REF_6, TMP8);
2369 
2370  vis_ld64_2(ref, 16, TMP4);
2371  vis_and(TMP6, MASK_fe, TMP6);
2372 
2374  vis_and(TMP8, MASK_fe, TMP8);
2375 
2377  vis_and(REF_0, REF_2, TMP10);
2378 
2379  vis_and(REF_4, REF_6, TMP12);
2380 
2381  vis_alignaddr_g0((void *)off);
2382 
2384 
2386 
2387  if (off != 0x7) {
2388  vis_alignaddr_g0((void *)off_plus_1);
2391  } else {
2392  vis_src1(TMP2, REF_2);
2393  vis_src1(TMP4, REF_6);
2394  }
2395 
2396  vis_and(TMP6, MASK_7f, TMP6);
2397 
2398  vis_and(TMP8, MASK_7f, TMP8);
2399 
2401  vis_st64(TMP6, dest[0]);
2402 
2404  vis_st64_2(TMP8, dest, 8);
2405  dest += stride;
2406 
2407  vis_xor(REF_0, REF_2, TMP6);
2408 
2409  vis_xor(REF_4, REF_6, TMP8);
2410 
2411  vis_and(TMP6, MASK_fe, TMP6);
2412 
2414  vis_and(TMP8, MASK_fe, TMP8);
2415 
2417  vis_and(REF_0, REF_2, TMP10);
2418 
2419  vis_and(REF_4, REF_6, TMP12);
2420 
2421  vis_and(TMP6, MASK_7f, TMP6);
2422 
2423  vis_and(TMP8, MASK_7f, TMP8);
2424 
2426  vis_st64(TMP6, dest[0]);
2427 
2429  vis_st64_2(TMP8, dest, 8);
2430 }
2431 
2432 static void MC_put_no_round_x_8_vis (uint8_t * dest, const uint8_t * ref,
2433  const ptrdiff_t stride, int height)
2434 {
2435  unsigned long off = (unsigned long) ref & 0x7;
2436  unsigned long off_plus_1 = off + 1;
2437 
2438  ref = vis_alignaddr(ref);
2439 
2440  vis_ld64(ref[0], TMP0);
2441 
2442  vis_ld64(ref[8], TMP2);
2443 
2445 
2447 
2450 
2451  if (off != 0x7) {
2452  vis_alignaddr_g0((void *)off_plus_1);
2454  } else {
2455  vis_src1(TMP2, REF_2);
2456  }
2457 
2458  ref += stride;
2459  height = (height >> 1) - 1;
2460 
2461  do { /* 20 cycles */
2462  vis_ld64(ref[0], TMP0);
2463  vis_xor(REF_0, REF_2, TMP4);
2464 
2465  vis_ld64_2(ref, 8, TMP2);
2466  vis_and(TMP4, MASK_fe, TMP4);
2467  ref += stride;
2468 
2469  vis_ld64(ref[0], TMP8);
2470  vis_and(REF_0, REF_2, TMP6);
2472 
2473  vis_alignaddr_g0((void *)off);
2474 
2475  vis_ld64_2(ref, 8, TMP10);
2476  ref += stride;
2478 
2479  if (off != 0x7) {
2480  vis_alignaddr_g0((void *)off_plus_1);
2482  } else {
2483  vis_src1(TMP2, REF_2);
2484  }
2485 
2486  vis_and(TMP4, MASK_7f, TMP4);
2487 
2489  vis_st64(DST_0, dest[0]);
2490  dest += stride;
2491 
2492  vis_xor(REF_0, REF_2, TMP12);
2493 
2495 
2496  vis_and(REF_0, REF_2, TMP14);
2498 
2499  vis_alignaddr_g0((void *)off);
2501  if (off != 0x7) {
2502  vis_alignaddr_g0((void *)off_plus_1);
2504  } else {
2505  vis_src1(TMP10, REF_2);
2506  }
2507 
2509 
2511  vis_st64(DST_0, dest[0]);
2512  dest += stride;
2513  } while (--height);
2514 
2515  vis_ld64(ref[0], TMP0);
2516  vis_xor(REF_0, REF_2, TMP4);
2517 
2518  vis_ld64_2(ref, 8, TMP2);
2519  vis_and(TMP4, MASK_fe, TMP4);
2520 
2521  vis_and(REF_0, REF_2, TMP6);
2523 
2524  vis_alignaddr_g0((void *)off);
2525 
2527 
2528  if (off != 0x7) {
2529  vis_alignaddr_g0((void *)off_plus_1);
2531  } else {
2532  vis_src1(TMP2, REF_2);
2533  }
2534 
2535  vis_and(TMP4, MASK_7f, TMP4);
2536 
2538  vis_st64(DST_0, dest[0]);
2539  dest += stride;
2540 
2541  vis_xor(REF_0, REF_2, TMP12);
2542 
2544 
2545  vis_and(REF_0, REF_2, TMP14);
2547 
2549 
2551  vis_st64(DST_0, dest[0]);
2552  dest += stride;
2553 }
2554 
2555 static void MC_avg_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
2556  const ptrdiff_t stride, int height)
2557 {
2558  unsigned long off = (unsigned long) ref & 0x7;
2559  unsigned long off_plus_1 = off + 1;
2560 
2562 
2564  vis_fzero(ZERO);
2566 
2567  ref = vis_alignaddr(ref);
2568  do { /* 26 cycles */
2569  vis_ld64(ref[0], TMP0);
2570 
2571  vis_ld64(ref[8], TMP2);
2572 
2573  vis_alignaddr_g0((void *)off);
2574 
2575  vis_ld64(ref[16], TMP4);
2576 
2577  vis_ld64(dest[0], DST_0);
2579 
2580  vis_ld64(dest[8], DST_2);
2582 
2583  if (off != 0x7) {
2584  vis_alignaddr_g0((void *)off_plus_1);
2587  } else {
2588  vis_src1(TMP2, REF_2);
2589  vis_src1(TMP4, REF_6);
2590  }
2591 
2593 
2596 
2598 
2599  vis_padd16(TMP0, TMP4, TMP0);
2600 
2602  vis_padd16(TMP2, TMP6, TMP2);
2603 
2605 
2607 
2608  vis_padd16(TMP0, TMP4, TMP0);
2610 
2611  vis_padd16(TMP2, TMP6, TMP2);
2613 
2616 
2618  vis_pack16(TMP8, DST_0);
2619 
2622 
2623  vis_st64(DST_0, dest[0]);
2626 
2629 
2631 
2632  vis_padd16(TMP0, TMP4, TMP0);
2633 
2634  vis_padd16(TMP2, TMP6, TMP2);
2635  vis_pack16(TMP0, DST_2);
2636 
2637  vis_pack16(TMP2, DST_3);
2638  vis_st64(DST_2, dest[8]);
2639 
2640  ref += stride;
2641  dest += stride;
2642  } while (--height);
2643 }
2644 
2645 static void MC_put_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
2646  const ptrdiff_t stride, int height)
2647 {
2648  ref = vis_alignaddr(ref);
2649  vis_ld64(ref[0], TMP0);
2650 
2651  vis_ld64_2(ref, 8, TMP2);
2652 
2653  vis_ld64_2(ref, 16, TMP4);
2654  ref += stride;
2655 
2656  vis_ld64(ref[0], TMP6);
2658 
2659  vis_ld64_2(ref, 8, TMP8);
2661 
2662  vis_ld64_2(ref, 16, TMP10);
2663  ref += stride;
2664 
2667 
2670 
2672  height = (height >> 1) - 1;
2673  do { /* 24 cycles */
2674  vis_ld64(ref[0], TMP0);
2675  vis_xor(REF_0, REF_2, TMP12);
2676 
2677  vis_ld64_2(ref, 8, TMP2);
2678  vis_xor(REF_4, REF_6, TMP16);
2679 
2680  vis_ld64_2(ref, 16, TMP4);
2681  ref += stride;
2682  vis_and(REF_0, REF_2, TMP14);
2683 
2684  vis_ld64(ref[0], TMP6);
2685  vis_and(REF_4, REF_6, TMP18);
2686 
2687  vis_ld64_2(ref, 8, TMP8);
2689 
2690  vis_ld64_2(ref, 16, TMP10);
2691  ref += stride;
2693 
2695 
2698 
2700  vis_xor(REF_0, REF_2, TMP0);
2701 
2702  vis_xor(REF_4, REF_6, TMP2);
2703 
2704  vis_and(REF_0, REF_2, TMP20);
2705 
2707 
2709 
2711  vis_st64(TMP12, dest[0]);
2712 
2714  vis_st64_2(TMP16, dest, 8);
2715  dest += stride;
2716 
2717  vis_and(REF_4, REF_6, TMP18);
2718 
2719  vis_and(TMP0, MASK_fe, TMP0);
2720 
2721  vis_and(TMP2, MASK_fe, TMP2);
2723 
2726 
2728 
2729  vis_and(TMP0, MASK_7f, TMP0);
2730 
2731  vis_and(TMP2, MASK_7f, TMP2);
2732 
2734  vis_st64(TMP0, dest[0]);
2735 
2737  vis_st64_2(TMP2, dest, 8);
2738  dest += stride;
2739  } while (--height);
2740 
2741  vis_ld64(ref[0], TMP0);
2742  vis_xor(REF_0, REF_2, TMP12);
2743 
2744  vis_ld64_2(ref, 8, TMP2);
2745  vis_xor(REF_4, REF_6, TMP16);
2746 
2747  vis_ld64_2(ref, 16, TMP4);
2748  vis_and(REF_0, REF_2, TMP14);
2749 
2750  vis_and(REF_4, REF_6, TMP18);
2751 
2753 
2755 
2757 
2760 
2762  vis_xor(REF_0, REF_2, TMP0);
2763 
2764  vis_xor(REF_4, REF_6, TMP2);
2765 
2766  vis_and(REF_0, REF_2, TMP20);
2767 
2769 
2771 
2773  vis_st64(TMP12, dest[0]);
2774 
2776  vis_st64_2(TMP16, dest, 8);
2777  dest += stride;
2778 
2779  vis_and(REF_4, REF_6, TMP18);
2780 
2781  vis_and(TMP0, MASK_fe, TMP0);
2782 
2783  vis_and(TMP2, MASK_fe, TMP2);
2785 
2787 
2788  vis_and(TMP0, MASK_7f, TMP0);
2789 
2790  vis_and(TMP2, MASK_7f, TMP2);
2791 
2793  vis_st64(TMP0, dest[0]);
2794 
2796  vis_st64_2(TMP2, dest, 8);
2797 }
2798 
2799 static void MC_put_no_round_y_8_vis (uint8_t * dest, const uint8_t * ref,
2800  const ptrdiff_t stride, int height)
2801 {
2802  ref = vis_alignaddr(ref);
2803  vis_ld64(ref[0], TMP0);
2804 
2805  vis_ld64_2(ref, 8, TMP2);
2806  ref += stride;
2807 
2808  vis_ld64(ref[0], TMP4);
2809 
2810  vis_ld64_2(ref, 8, TMP6);
2811  ref += stride;
2812 
2815 
2818 
2820  height = (height >> 1) - 1;
2821  do { /* 12 cycles */
2822  vis_ld64(ref[0], TMP0);
2823  vis_xor(REF_0, REF_2, TMP4);
2824 
2825  vis_ld64_2(ref, 8, TMP2);
2826  ref += stride;
2827  vis_and(TMP4, MASK_fe, TMP4);
2828 
2829  vis_and(REF_0, REF_2, TMP6);
2831 
2833  vis_ld64(ref[0], TMP0);
2834 
2835  vis_ld64_2(ref, 8, TMP2);
2836  ref += stride;
2837  vis_xor(REF_0, REF_2, TMP12);
2838 
2839  vis_and(TMP4, MASK_7f, TMP4);
2840 
2842 
2844  vis_and(REF_0, REF_2, TMP14);
2845 
2847  vis_st64(DST_0, dest[0]);
2848  dest += stride;
2849 
2851 
2853 
2855  vis_st64(DST_0, dest[0]);
2856  dest += stride;
2857  } while (--height);
2858 
2859  vis_ld64(ref[0], TMP0);
2860  vis_xor(REF_0, REF_2, TMP4);
2861 
2862  vis_ld64_2(ref, 8, TMP2);
2863  vis_and(TMP4, MASK_fe, TMP4);
2864 
2865  vis_and(REF_0, REF_2, TMP6);
2867 
2869 
2870  vis_xor(REF_0, REF_2, TMP12);
2871 
2872  vis_and(TMP4, MASK_7f, TMP4);
2873 
2875 
2877  vis_and(REF_0, REF_2, TMP14);
2878 
2880  vis_st64(DST_0, dest[0]);
2881  dest += stride;
2882 
2884 
2886  vis_st64(DST_0, dest[0]);
2887 }
2888 
2889 static void MC_avg_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
2890  const ptrdiff_t stride, int height)
2891 {
2892  int stride_8 = stride + 8;
2893  int stride_16 = stride + 16;
2894 
2896 
2897  ref = vis_alignaddr(ref);
2898 
2899  vis_ld64(ref[ 0], TMP0);
2900  vis_fzero(ZERO);
2901 
2902  vis_ld64(ref[ 8], TMP2);
2903 
2904  vis_ld64(ref[16], TMP4);
2905 
2908 
2911  height >>= 1;
2912 
2913  do { /* 31 cycles */
2914  vis_ld64_2(ref, stride, TMP0);
2917 
2918  vis_ld64_2(ref, stride_8, TMP2);
2921 
2922  vis_ld64_2(ref, stride_16, TMP4);
2923  ref += stride;
2924 
2925  vis_ld64(dest[0], DST_0);
2927 
2928  vis_ld64_2(dest, 8, DST_2);
2930 
2931  vis_ld64_2(ref, stride, TMP6);
2934 
2935  vis_ld64_2(ref, stride_8, TMP8);
2937 
2938  vis_ld64_2(ref, stride_16, TMP10);
2939  ref += stride;
2940 
2941  vis_ld64_2(dest, stride, REF_S0/*DST_4*/);
2944 
2945  vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/);
2948 
2951 
2954 
2957 
2959 
2962 
2965 
2968 
2971 
2974 
2977 
2980 
2983 
2986 
2988  vis_st64(DST_0, dest[0]);
2990 
2993 
2995  vis_st64_2(DST_2, dest, 8);
2996  dest += stride;
2998 
3000 
3003 
3006  vis_st64(DST_0, dest[0]);
3007 
3010 
3012  vis_st64_2(DST_2, dest, 8);
3013  dest += stride;
3014  } while (--height);
3015 }
3016 
3017 static void MC_put_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
3018  const ptrdiff_t stride, int height)
3019 {
3020  unsigned long off = (unsigned long) ref & 0x7;
3021  unsigned long off_plus_1 = off + 1;
3022  int stride_8 = stride + 8;
3023  int stride_16 = stride + 16;
3024 
3026 
3027  ref = vis_alignaddr(ref);
3028 
3029  vis_ld64(ref[ 0], TMP0);
3030  vis_fzero(ZERO);
3031 
3032  vis_ld64(ref[ 8], TMP2);
3033 
3034  vis_ld64(ref[16], TMP4);
3035 
3038 
3041 
3042  if (off != 0x7) {
3043  vis_alignaddr_g0((void *)off_plus_1);
3046  } else {
3047  vis_src1(TMP2, REF_S2);
3048  vis_src1(TMP4, REF_S6);
3049  }
3050 
3051  height >>= 1;
3052  do {
3053  vis_ld64_2(ref, stride, TMP0);
3056 
3057  vis_alignaddr_g0((void *)off);
3058 
3059  vis_ld64_2(ref, stride_8, TMP2);
3062 
3063  vis_ld64_2(ref, stride_16, TMP4);
3064  ref += stride;
3067 
3068  vis_ld64_2(ref, stride, TMP6);
3071 
3072  vis_ld64_2(ref, stride_8, TMP8);
3074 
3075  vis_ld64_2(ref, stride_16, TMP10);
3076  ref += stride;
3078 
3080 
3082 
3083  if (off != 0x7) {
3084  vis_alignaddr_g0((void *)off_plus_1);
3089  } else {
3090  vis_src1(TMP2, REF_2);
3091  vis_src1(TMP4, REF_6);
3092  vis_src1(TMP8, REF_S2);
3093  vis_src1(TMP10, REF_S6);
3094  }
3095 
3098 
3101 
3104 
3107 
3108  vis_padd16(TMP8, TMP4, TMP8);
3110 
3113 
3115 
3117 
3119 
3122 
3124  vis_st64(DST_0, dest[0]);
3126 
3129 
3132 
3135 
3138 
3140 
3142 
3145 
3147  vis_st64_2(DST_2, dest, 8);
3148  dest += stride;
3150 
3153 
3156 
3159 
3161  vis_st64(DST_0, dest[0]);
3163 
3165 
3166  vis_padd16(TMP0, TMP4, TMP0);
3167 
3168  vis_padd16(TMP2, TMP6, TMP2);
3169 
3171 
3173  vis_pack16(TMP0, DST_2);
3174 
3175  vis_pack16(TMP2, DST_3);
3176  vis_st64_2(DST_2, dest, 8);
3177  dest += stride;
3178  } while (--height);
3179 }
3180 
3181 static void MC_put_no_round_xy_8_vis (uint8_t * dest, const uint8_t * ref,
3182  const ptrdiff_t stride, int height)
3183 {
3184  unsigned long off = (unsigned long) ref & 0x7;
3185  unsigned long off_plus_1 = off + 1;
3186  int stride_8 = stride + 8;
3187 
3189 
3190  ref = vis_alignaddr(ref);
3191 
3192  vis_ld64(ref[ 0], TMP0);
3193  vis_fzero(ZERO);
3194 
3195  vis_ld64(ref[ 8], TMP2);
3196 
3198 
3201 
3202  if (off != 0x7) {
3203  vis_alignaddr_g0((void *)off_plus_1);
3205  } else {
3206  vis_src1(TMP2, REF_S2);
3207  }
3208 
3209  height >>= 1;
3210  do { /* 26 cycles */
3211  vis_ld64_2(ref, stride, TMP0);
3214 
3215  vis_alignaddr_g0((void *)off);
3216 
3217  vis_ld64_2(ref, stride_8, TMP2);
3218  ref += stride;
3221 
3222  vis_ld64_2(ref, stride, TMP4);
3223 
3224  vis_ld64_2(ref, stride_8, TMP6);
3225  ref += stride;
3227 
3229 
3231 
3233 
3234  if (off != 0x7) {
3235  vis_alignaddr_g0((void *)off_plus_1);
3238  } else {
3239  vis_src1(TMP2, REF_S6);
3240  vis_src1(TMP6, REF_S2);
3241  }
3242 
3245 
3248 
3251 
3254 
3257 
3259 
3261 
3263 
3265  vis_pack16(TMP8, DST_0);
3266 
3268  vis_st64(DST_0, dest[0]);
3269  dest += stride;
3271 
3273 
3275 
3278 
3280  vis_st64(DST_2, dest[0]);
3281  dest += stride;
3282  } while (--height);
3283 }
3284 
3285 static void MC_avg_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
3286  const ptrdiff_t stride, int height)
3287 {
3288  unsigned long off = (unsigned long) ref & 0x7;
3289  unsigned long off_plus_1 = off + 1;
3290  int stride_8 = stride + 8;
3291  int stride_16 = stride + 16;
3292 
3294 
3295  ref = vis_alignaddr(ref);
3296 
3297  vis_ld64(ref[ 0], TMP0);
3298  vis_fzero(ZERO);
3299 
3300  vis_ld64(ref[ 8], TMP2);
3301 
3302  vis_ld64(ref[16], TMP4);
3303 
3306 
3309 
3310  if (off != 0x7) {
3311  vis_alignaddr_g0((void *)off_plus_1);
3314  } else {
3315  vis_src1(TMP2, REF_S2);
3316  vis_src1(TMP4, REF_S6);
3317  }
3318 
3319  height >>= 1;
3320  do { /* 55 cycles */
3321  vis_ld64_2(ref, stride, TMP0);
3324 
3325  vis_alignaddr_g0((void *)off);
3326 
3327  vis_ld64_2(ref, stride_8, TMP2);
3330 
3331  vis_ld64_2(ref, stride_16, TMP4);
3332  ref += stride;
3335 
3336  vis_ld64_2(ref, stride, TMP6);
3339 
3340  vis_ld64_2(ref, stride_8, TMP8);
3342 
3343  vis_ld64_2(ref, stride_16, TMP10);
3344  ref += stride;
3346 
3347  vis_ld64(dest[0], DST_0);
3349 
3350  vis_ld64_2(dest, 8, DST_2);
3352 
3353  if (off != 0x7) {
3354  vis_alignaddr_g0((void *)off_plus_1);
3359  } else {
3360  vis_src1(TMP2, REF_2);
3361  vis_src1(TMP4, REF_6);
3362  vis_src1(TMP8, REF_S2);
3363  vis_src1(TMP10, REF_S6);
3364  }
3365 
3368 
3371 
3374 
3377 
3380 
3381  vis_padd16(TMP0, TMP4, TMP0);
3383 
3384  vis_padd16(TMP2, TMP6, TMP2);
3386 
3389 
3392 
3395 
3398 
3400 
3403 
3405  vis_st64(DST_0, dest[0]);
3407 
3408  vis_ld64_2(dest, stride, DST_0);
3411 
3412  vis_padd16(TMP4, TMP8, TMP4);
3414 
3416 
3418 
3420 
3422 
3424 
3427 
3430 
3432  vis_st64_2(DST_2, dest, 8);
3433  dest += stride;
3434 
3435  vis_ld64_2(dest, 8, DST_2);
3438 
3441 
3444 
3447 
3449 
3451 
3453  vis_pack16(TMP8, DST_0);
3454 
3456  vis_st64(DST_0, dest[0]);
3457 
3459 
3462 
3465 
3467 
3469 
3470  /* stall */
3471 
3474 
3476  vis_st64_2(DST_2, dest, 8);
3477  dest += stride;
3478  } while (--height);
3479 }
3480 
3481 /* End of no rounding code */
3482 
3484 {
3485  /* VIS-specific optimizations */
3486  int accel = vis_level ();
3487 
3488  if (accel & ACCEL_SPARC_VIS) {
3489  c->put_pixels_tab[0][0] = MC_put_o_16_vis;
3490  c->put_pixels_tab[0][1] = MC_put_x_16_vis;
3491  c->put_pixels_tab[0][2] = MC_put_y_16_vis;
3492  c->put_pixels_tab[0][3] = MC_put_xy_16_vis;
3493 
3494  c->put_pixels_tab[1][0] = MC_put_o_8_vis;
3495  c->put_pixels_tab[1][1] = MC_put_x_8_vis;
3496  c->put_pixels_tab[1][2] = MC_put_y_8_vis;
3497  c->put_pixels_tab[1][3] = MC_put_xy_8_vis;
3498 
3499  c->avg_pixels_tab[0][0] = MC_avg_o_16_vis;
3500  c->avg_pixels_tab[0][1] = MC_avg_x_16_vis;
3501  c->avg_pixels_tab[0][2] = MC_avg_y_16_vis;
3502  c->avg_pixels_tab[0][3] = MC_avg_xy_16_vis;
3503 
3504  c->avg_pixels_tab[1][0] = MC_avg_o_8_vis;
3505  c->avg_pixels_tab[1][1] = MC_avg_x_8_vis;
3506  c->avg_pixels_tab[1][2] = MC_avg_y_8_vis;
3507  c->avg_pixels_tab[1][3] = MC_avg_xy_8_vis;
3508 
3513 
3518 
3523  }
3524 }