2b016f6f958939a0b1098db69afeb0b249c5fdba
[ffmpeg.git] / libavcodec / x86 / hevc_mc.asm
1 ; /*
2 ; * Provide SSE luma and chroma mc functions for HEVC decoding
3 ; * Copyright (c) 2013 Pierre-Edouard LEPERE
4 ; *
5 ; * This file is part of FFmpeg.
6 ; *
7 ; * FFmpeg is free software; you can redistribute it and/or
8 ; * modify it under the terms of the GNU Lesser General Public
9 ; * License as published by the Free Software Foundation; either
10 ; * version 2.1 of the License, or (at your option) any later version.
11 ; *
12 ; * FFmpeg is distributed in the hope that it will be useful,
13 ; * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ; * Lesser General Public License for more details.
16 ; *
17 ; * You should have received a copy of the GNU Lesser General Public
18 ; * License along with FFmpeg; if not, write to the Free Software
19 ; * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ; */
21 %include "libavutil/x86/x86util.asm"
22
23 SECTION_RODATA 32
24 pw_8:                   times 16 dw  (1 <<  9)
25 pw_10:                  times 16 dw  (1 << 11)
26 pw_12:                  times 16 dw  (1 << 13)
27 pw_bi_8:                times 16 dw  (1 <<  8)
28 pw_bi_10:               times 16 dw  (1 << 10)
29 pw_bi_12:               times 16 dw  (1 << 12)
30 max_pixels_8:           times 16 dw ((1 <<  8)-1)
31 max_pixels_10:          times 16 dw ((1 << 10)-1)
32 max_pixels_12:          times 16 dw ((1 << 12)-1)
33 cextern pd_1
34 cextern pb_0
35
36 SECTION_TEXT 32
37 %macro EPEL_TABLE 4
38 hevc_epel_filters_%4_%1 times %2 d%3 -2, 58
39                         times %2 d%3 10, -2
40                         times %2 d%3 -4, 54
41                         times %2 d%3 16, -2
42                         times %2 d%3 -6, 46
43                         times %2 d%3 28, -4
44                         times %2 d%3 -4, 36
45                         times %2 d%3 36, -4
46                         times %2 d%3 -4, 28
47                         times %2 d%3 46, -6
48                         times %2 d%3 -2, 16
49                         times %2 d%3 54, -4
50                         times %2 d%3 -2, 10
51                         times %2 d%3 58, -2
52 %endmacro
53
54
55 EPEL_TABLE  8,16, b, avx2
56 EPEL_TABLE 10, 8, w, avx2
57
58 EPEL_TABLE  8, 8, b, sse4
59 EPEL_TABLE 10, 4, w, sse4
60 EPEL_TABLE 12, 4, w, sse4
61
62 %macro QPEL_TABLE 4
63 hevc_qpel_filters_%4_%1 times %2 d%3  -1,  4
64                         times %2 d%3 -10, 58
65                         times %2 d%3  17, -5
66                         times %2 d%3   1,  0
67                         times %2 d%3  -1,  4
68                         times %2 d%3 -11, 40
69                         times %2 d%3  40,-11
70                         times %2 d%3   4, -1
71                         times %2 d%3   0,  1
72                         times %2 d%3  -5, 17
73                         times %2 d%3  58,-10
74                         times %2 d%3   4, -1
75 %endmacro
76
77 QPEL_TABLE  8, 8, b, sse4
78 QPEL_TABLE 10, 4, w, sse4
79 QPEL_TABLE 12, 4, w, sse4
80
81 QPEL_TABLE  8,16, b, avx2
82 QPEL_TABLE 10, 8, w, avx2
83
84 %define MAX_PB_SIZE  64
85
86 %define hevc_qpel_filters_sse4_14 hevc_qpel_filters_sse4_10
87
88 %define hevc_qpel_filters_avx2_14 hevc_qpel_filters_avx2_10
89
90 %if ARCH_X86_64
91
92 %macro SIMPLE_BILOAD 4   ;width, tab, r1, r2
93 %if %1 <= 4
94     movq              %3, [%2]                                              ; load data from source2
95 %elif %1 <= 8
96     movdqa            %3, [%2]                                              ; load data from source2
97 %elif %1 <= 12
98 %if cpuflag(avx2)
99     mova              %3, [%2]
100 %else
101     movdqa            %3, [%2]                                              ; load data from source2
102     movq              %4, [%2+16]                                           ; load data from source2
103 %endif ;avx
104 %elif %1 <= 16
105 %if cpuflag(avx2)
106     mova              %3, [%2]
107 %else
108     movdqa            %3, [%2]                                              ; load data from source2
109     movdqa            %4, [%2+16]                                           ; load data from source2
110 %endif ; avx
111 %else ; %1 = 32
112     mova              %3, [%2]
113     mova              %4, [%2+32]
114 %endif
115 %endmacro
116
117 %macro SIMPLE_LOAD 4    ;width, bitd, tab, r1
118 %if %1 == 2 || (%2 == 8 && %1 <= 4)
119     movd              %4, [%3]                                               ; load data from source
120 %elif %1 == 4 || (%2 == 8 && %1 <= 8)
121     movq              %4, [%3]                                               ; load data from source
122 %elif notcpuflag(avx)
123     movu              %4, [%3]                                               ; load data from source
124 %elif %1 <= 8 || (%2 == 8 && %1 <= 16)
125     movdqu           %4, [%3]
126 %else
127     movu              %4, [%3]
128 %endif
129 %endmacro
130
131
132 %macro EPEL_FILTER 2-4                            ; bit depth, filter index
133 %if cpuflag(avx2)
134 %assign %%offset 32
135 %ifdef PIC
136     lea         rfilterq, [hevc_epel_filters_avx2_%1]
137 %else
138     %define rfilterq hevc_epel_filters_avx2_%1
139 %endif
140 %else
141 %assign %%offset 16
142 %ifdef PIC
143     lea         rfilterq, [hevc_epel_filters_sse4_%1]
144 %else
145     %define rfilterq hevc_epel_filters_sse4_%1
146 %endif
147 %endif ;cpuflag(avx2)
148     sub              %2q, 1
149 %if cpuflag(avx2)
150     shl              %2q, 6                      ; multiply by 64
151   %else
152     shl              %2q, 5                      ; multiply by 32
153 %endif
154 %if %0 == 2
155     mova           m14, [rfilterq + %2q]        ; get 2 first values of filters
156     mova           m15, [rfilterq + %2q+%%offset]     ; get 2 last values of filters
157 %else
158     mova           %3, [rfilterq + %2q]        ; get 2 first values of filters
159     mova           %4, [rfilterq + %2q+%%offset]     ; get 2 last values of filters
160 %endif
161 %endmacro
162
163 %macro EPEL_HV_FILTER 1
164 %if cpuflag(avx2)
165 %assign %%offset 32
166 %assign %%shift  6
167 %define %%table  hevc_epel_filters_avx2_%1
168 %else
169 %assign %%offset 16
170 %assign %%shift  5
171 %define %%table  hevc_epel_filters_sse4_%1
172 %endif
173
174 %ifdef PIC
175     lea         rfilterq, [%%table]
176 %else
177     %define rfilterq %%table
178 %endif
179     sub              mxq, 1
180     sub              myq, 1
181     shl              mxq, %%shift                ; multiply by 32
182     shl              myq, %%shift                ; multiply by 32
183     mova             m14, [rfilterq + mxq]        ; get 2 first values of filters
184     mova             m15, [rfilterq + mxq+%%offset]     ; get 2 last values of filters
185     lea           r3srcq, [srcstrideq*3]
186
187 %if cpuflag(avx2)
188 %define %%table  hevc_epel_filters_avx2_10
189 %else
190 %define %%table  hevc_epel_filters_sse4_10
191 %endif
192 %ifdef PIC
193     lea         rfilterq, [%%table]
194 %else
195     %define rfilterq %%table
196 %endif
197     mova             m12, [rfilterq + myq]        ; get 2 first values of filters
198     mova             m13, [rfilterq + myq+%%offset]     ; get 2 last values of filters
199 %endmacro
200
201 %macro QPEL_FILTER 2
202
203 %if cpuflag(avx2)
204 %assign %%offset 32
205 %assign %%shift  7
206 %define %%table  hevc_qpel_filters_avx2_%1
207 %else
208 %assign %%offset 16
209 %assign %%shift  6
210 %define %%table  hevc_qpel_filters_sse4_%1
211 %endif
212
213 %ifdef PIC
214     lea         rfilterq, [%%table]
215 %else
216     %define rfilterq %%table
217 %endif
218     sub              %2q, 1
219     shl              %2q, %%shift                        ; multiply by 32
220     mova             m12, [rfilterq + %2q]               ; get 4 first values of filters
221     mova             m13, [rfilterq + %2q +   %%offset]  ; get 4 first values of filters
222     mova             m14, [rfilterq + %2q + 2*%%offset]  ; get 4 first values of filters
223     mova             m15, [rfilterq + %2q + 3*%%offset]  ; get 4 first values of filters
224 %endmacro
225
226 %macro EPEL_LOAD 4
227 %ifdef PIC
228     lea rfilterq, [%2]
229 %else
230     %define rfilterq %2
231 %endif
232 %if (%1 == 8 && %4 <= 4)
233 %define %%load movd
234 %elif (%1 == 8 && %4 <= 8) || (%1 > 8 && %4 <= 4)
235 %define %%load movq
236 %else
237 %define %%load movdqu
238 %endif
239
240     %%load            m0, [rfilterq ]
241 %ifnum %3
242     %%load            m1, [rfilterq+  %3]
243     %%load            m2, [rfilterq+2*%3]
244     %%load            m3, [rfilterq+3*%3]
245 %else
246     %%load            m1, [rfilterq+  %3q]
247     %%load            m2, [rfilterq+2*%3q]
248     %%load            m3, [rfilterq+r3srcq]
249 %endif
250 %if %1 == 8
251 %if %4 > 8
252     SBUTTERFLY        bw, 0, 1, 7
253     SBUTTERFLY        bw, 2, 3, 7
254 %else
255     punpcklbw         m0, m1
256     punpcklbw         m2, m3
257 %endif
258 %else
259 %if %4 > 4
260     SBUTTERFLY        wd, 0, 1, 7
261     SBUTTERFLY        wd, 2, 3, 7
262 %else
263     punpcklwd         m0, m1
264     punpcklwd         m2, m3
265 %endif
266 %endif
267 %endmacro
268
269
270 %macro QPEL_H_LOAD 4
271 %assign %%stride (%1+7)/8
272 %if %1 == 8
273 %if %3 <= 4
274 %define %%load movd
275 %elif %3 == 8
276 %define %%load movq
277 %else
278 %define %%load movu
279 %endif
280 %else
281 %if %3 == 2
282 %define %%load movd
283 %elif %3 == 4
284 %define %%load movq
285 %else
286 %define %%load movu
287 %endif
288 %endif
289     %%load            m0, [%2-3*%%stride]        ;load data from source
290     %%load            m1, [%2-2*%%stride]
291     %%load            m2, [%2-%%stride  ]
292     %%load            m3, [%2           ]
293     %%load            m4, [%2+%%stride  ]
294     %%load            m5, [%2+2*%%stride]
295     %%load            m6, [%2+3*%%stride]
296     %%load            m7, [%2+4*%%stride]
297
298 %if %1 == 8
299 %if %3 > 8
300     SBUTTERFLY        wd, 0, 1, %4
301     SBUTTERFLY        wd, 2, 3, %4
302     SBUTTERFLY        wd, 4, 5, %4
303     SBUTTERFLY        wd, 6, 7, %4
304 %else
305     punpcklbw         m0, m1
306     punpcklbw         m2, m3
307     punpcklbw         m4, m5
308     punpcklbw         m6, m7
309 %endif
310 %else
311 %if %3 > 4
312     SBUTTERFLY        dq, 0, 1, %4
313     SBUTTERFLY        dq, 2, 3, %4
314     SBUTTERFLY        dq, 4, 5, %4
315     SBUTTERFLY        dq, 6, 7, %4
316 %else
317     punpcklwd         m0, m1
318     punpcklwd         m2, m3
319     punpcklwd         m4, m5
320     punpcklwd         m6, m7
321 %endif
322 %endif
323 %endmacro
324
325 %macro QPEL_V_LOAD 5
326     lea              %5q, [%2]
327     sub              %5q, r3srcq
328     movu              m0, [%5q            ]      ;load x- 3*srcstride
329     movu              m1, [%5q+   %3q     ]      ;load x- 2*srcstride
330     movu              m2, [%5q+ 2*%3q     ]      ;load x-srcstride
331     movu              m3, [%2       ]      ;load x
332     movu              m4, [%2+   %3q]      ;load x+stride
333     movu              m5, [%2+ 2*%3q]      ;load x+2*stride
334     movu              m6, [%2+r3srcq]      ;load x+3*stride
335     movu              m7, [%2+ 4*%3q]      ;load x+4*stride
336 %if %1 == 8
337 %if %4 > 8
338     SBUTTERFLY        bw, 0, 1, 8
339     SBUTTERFLY        bw, 2, 3, 8
340     SBUTTERFLY        bw, 4, 5, 8
341     SBUTTERFLY        bw, 6, 7, 8
342 %else
343     punpcklbw         m0, m1
344     punpcklbw         m2, m3
345     punpcklbw         m4, m5
346     punpcklbw         m6, m7
347 %endif
348 %else
349 %if %4 > 4
350     SBUTTERFLY        wd, 0, 1, 8
351     SBUTTERFLY        wd, 2, 3, 8
352     SBUTTERFLY        wd, 4, 5, 8
353     SBUTTERFLY        wd, 6, 7, 8
354 %else
355     punpcklwd         m0, m1
356     punpcklwd         m2, m3
357     punpcklwd         m4, m5
358     punpcklwd         m6, m7
359 %endif
360 %endif
361 %endmacro
362
363 %macro PEL_12STORE2 3
364     movd           [%1], %2
365 %endmacro
366 %macro PEL_12STORE4 3
367     movq           [%1], %2
368 %endmacro
369 %macro PEL_12STORE6 3
370     movq           [%1], %2
371     psrldq            %2, 8
372     movd         [%1+8], %2
373 %endmacro
374 %macro PEL_12STORE8 3
375     movdqa         [%1], %2
376 %endmacro
377 %macro PEL_12STORE12 3
378     movdqa         [%1], %2
379     movq        [%1+16], %3
380 %endmacro
381 %macro PEL_12STORE16 3
382     PEL_12STORE8      %1, %2, %3
383     movdqa       [%1+16], %3
384 %endmacro
385
386 %macro PEL_10STORE2 3
387     movd           [%1], %2
388 %endmacro
389 %macro PEL_10STORE4 3
390     movq           [%1], %2
391 %endmacro
392 %macro PEL_10STORE6 3
393     movq           [%1], %2
394     psrldq            %2, 8
395     movd         [%1+8], %2
396 %endmacro
397 %macro PEL_10STORE8 3
398     movdqa         [%1], %2
399 %endmacro
400 %macro PEL_10STORE12 3
401     movdqa         [%1], %2
402     movq        [%1+16], %3
403 %endmacro
404 %macro PEL_10STORE16 3
405 %if cpuflag(avx2)
406     movu            [%1], %2
407 %else
408     PEL_10STORE8      %1, %2, %3
409     movdqa       [%1+16], %3
410 %endif
411 %endmacro
412
413 %macro PEL_10STORE32 3
414     PEL_10STORE16     %1, %2, %3
415     movu         [%1+32], %3
416 %endmacro
417
418 %macro PEL_8STORE2 3
419     pextrw          [%1], %2, 0
420 %endmacro
421 %macro PEL_8STORE4 3
422     movd            [%1], %2
423 %endmacro
424 %macro PEL_8STORE6 3
425     movd            [%1], %2
426     pextrw        [%1+4], %2, 2
427 %endmacro
428 %macro PEL_8STORE8 3
429     movq           [%1], %2
430 %endmacro
431 %macro PEL_8STORE12 3
432     movq            [%1], %2
433     psrldq            %2, 8
434     movd          [%1+8], %2
435 %endmacro
436 %macro PEL_8STORE16 3
437 %if cpuflag(avx2)
438     movdqu        [%1], %2
439 %else
440     mova          [%1], %2
441 %endif ; avx
442 %endmacro
443 %macro PEL_8STORE32 3
444     movu          [%1], %2
445 %endmacro
446
447 %macro LOOP_END 3
448     add              %1q, 2*MAX_PB_SIZE          ; dst += dststride
449     add              %2q, %3q                    ; src += srcstride
450     dec          heightd                         ; cmp height
451     jnz               .loop                      ; height loop
452 %endmacro
453
454
455 %macro MC_PIXEL_COMPUTE 2-3 ;width, bitdepth
456 %if %2 == 8
457 %if cpuflag(avx2) && %0 ==3
458 %if %1 > 16
459     vextracti128 xm1, m0, 1
460     pmovzxbw      m1, xm1
461     psllw         m1, 14-%2
462 %endif
463     pmovzxbw      m0, xm0
464 %else ; not avx
465 %if %1 > 8
466     punpckhbw     m1, m0, m2
467     psllw         m1, 14-%2
468 %endif
469     punpcklbw     m0, m2
470 %endif
471 %endif ;avx
472     psllw         m0, 14-%2
473 %endmacro
474
475 %macro EPEL_COMPUTE 4-8 ; bitdepth, width, filter1, filter2, HV/m0, m2, m1, m3
476 %if %0 == 8
477 %define %%reg0 %5
478 %define %%reg2 %6
479 %define %%reg1 %7
480 %define %%reg3 %8
481 %else
482 %define %%reg0 m0
483 %define %%reg2 m2
484 %define %%reg1 m1
485 %define %%reg3 m3
486 %endif
487 %if %1 == 8
488 %if cpuflag(avx2) && (%0 == 5)
489 %if %2 > 16
490     vextracti128  xm10, m0, 1
491     vinserti128    m10, m1, xm10, 0
492 %endif
493     vinserti128    m0, m0, xm1, 1
494     mova           m1, m10
495 %if %2 > 16
496     vextracti128 xm10, m2, 1
497     vinserti128   m10, m3, xm10, 0
498 %endif
499     vinserti128    m2, m2, xm3, 1
500     mova           m3, m10
501 %endif
502     pmaddubsw      %%reg0, %3   ;x1*c1+x2*c2
503     pmaddubsw      %%reg2, %4   ;x3*c3+x4*c4
504     paddw          %%reg0, %%reg2
505 %if %2 > 8
506     pmaddubsw      %%reg1, %3
507     pmaddubsw      %%reg3, %4
508     paddw          %%reg1, %%reg3
509 %endif
510 %else
511     pmaddwd        %%reg0, %3
512     pmaddwd        %%reg2, %4
513     paddd          %%reg0, %%reg2
514 %if %2 > 4
515     pmaddwd        %%reg1, %3
516     pmaddwd        %%reg3, %4
517     paddd          %%reg1, %%reg3
518 %if %1 != 8
519     psrad          %%reg1, %1-8
520 %endif
521 %endif
522 %if %1 != 8
523     psrad          %%reg0, %1-8
524 %endif
525     packssdw       %%reg0, %%reg1
526 %endif
527 %endmacro
528
529 %macro QPEL_HV_COMPUTE 4     ; width, bitdepth, filter idx
530
531 %if cpuflag(avx2)
532 %assign %%offset 32
533 %define %%table  hevc_qpel_filters_avx2_%2
534 %else
535 %assign %%offset 16
536 %define %%table  hevc_qpel_filters_sse4_%2
537 %endif
538
539 %ifdef PIC
540     lea         rfilterq, [%%table]
541 %else
542     %define rfilterq %%table
543 %endif
544
545 %if %2 == 8
546     pmaddubsw         m0, [rfilterq + %3q*8   ]   ;x1*c1+x2*c2
547     pmaddubsw         m2, [rfilterq + %3q*8+%%offset]   ;x3*c3+x4*c4
548     pmaddubsw         m4, [rfilterq + %3q*8+2*%%offset]   ;x5*c5+x6*c6
549     pmaddubsw         m6, [rfilterq + %3q*8+3*%%offset]   ;x7*c7+x8*c8
550     paddw             m0, m2
551     paddw             m4, m6
552     paddw             m0, m4
553 %else
554     pmaddwd           m0, [rfilterq + %3q*8   ]
555     pmaddwd           m2, [rfilterq + %3q*8+%%offset]
556     pmaddwd           m4, [rfilterq + %3q*8+2*%%offset]
557     pmaddwd           m6, [rfilterq + %3q*8+3*%%offset]
558     paddd             m0, m2
559     paddd             m4, m6
560     paddd             m0, m4
561 %if %2 != 8
562     psrad             m0, %2-8
563 %endif
564 %if %1 > 4
565     pmaddwd           m1, [rfilterq + %3q*8   ]
566     pmaddwd           m3, [rfilterq + %3q*8+%%offset]
567     pmaddwd           m5, [rfilterq + %3q*8+2*%%offset]
568     pmaddwd           m7, [rfilterq + %3q*8+3*%%offset]
569     paddd             m1, m3
570     paddd             m5, m7
571     paddd             m1, m5
572 %if %2 != 8
573     psrad             m1, %2-8
574 %endif
575 %endif
576     p%4               m0, m1
577 %endif
578 %endmacro
579
580 %macro QPEL_COMPUTE 2-3     ; width, bitdepth
581 %if %2 == 8
582 %if cpuflag(avx2) && (%0 == 3)
583
584     vextracti128 xm10, m0, 1
585     vinserti128 m10, m1, xm10, 0
586     vinserti128 m0, m0, xm1, 1
587     mova m1, m10
588
589     vextracti128 xm10, m2, 1
590     vinserti128 m10, m3, xm10, 0
591     vinserti128 m2, m2, xm3, 1
592     mova m3, m10
593
594
595     vextracti128 xm10, m4, 1
596     vinserti128 m10, m5, xm10, 0
597     vinserti128 m4, m4, xm5, 1
598     mova m5, m10
599
600     vextracti128 xm10, m6, 1
601     vinserti128 m10, m7, xm10, 0
602     vinserti128 m6, m6, xm7, 1
603     mova m7, m10
604 %endif
605
606     pmaddubsw         m0, m12   ;x1*c1+x2*c2
607     pmaddubsw         m2, m13   ;x3*c3+x4*c4
608     pmaddubsw         m4, m14   ;x5*c5+x6*c6
609     pmaddubsw         m6, m15   ;x7*c7+x8*c8
610     paddw             m0, m2
611     paddw             m4, m6
612     paddw             m0, m4
613 %if %1 > 8
614     pmaddubsw         m1, m12
615     pmaddubsw         m3, m13
616     pmaddubsw         m5, m14
617     pmaddubsw         m7, m15
618     paddw             m1, m3
619     paddw             m5, m7
620     paddw             m1, m5
621 %endif
622 %else
623     pmaddwd           m0, m12
624     pmaddwd           m2, m13
625     pmaddwd           m4, m14
626     pmaddwd           m6, m15
627     paddd             m0, m2
628     paddd             m4, m6
629     paddd             m0, m4
630 %if %2 != 8
631     psrad             m0, %2-8
632 %endif
633 %if %1 > 4
634     pmaddwd           m1, m12
635     pmaddwd           m3, m13
636     pmaddwd           m5, m14
637     pmaddwd           m7, m15
638     paddd             m1, m3
639     paddd             m5, m7
640     paddd             m1, m5
641 %if %2 != 8
642     psrad             m1, %2-8
643 %endif
644 %endif
645 %endif
646 %endmacro
647
648 %macro BI_COMPUTE 7-8     ; width, bitd, src1l, src1h, scr2l, scr2h, pw
649     paddsw            %3, %5
650 %if %1 > 8
651     paddsw            %4, %6
652 %endif
653     UNI_COMPUTE       %1, %2, %3, %4, %7
654 %if %0 == 8 && cpuflag(avx2) && (%2 == 8)
655     vpermq            %3, %3, 216
656     vpermq            %4, %4, 216
657 %endif
658 %endmacro
659
660 %macro UNI_COMPUTE 5
661     pmulhrsw          %3, %5
662 %if %1 > 8 || (%2 > 8 && %1 > 4)
663     pmulhrsw          %4, %5
664 %endif
665 %if %2 == 8
666     packuswb          %3, %4
667 %else
668     CLIPW             %3, [pb_0], [max_pixels_%2]
669 %if (%1 > 8 && notcpuflag(avx)) || %1 > 16
670     CLIPW             %4, [pb_0], [max_pixels_%2]
671 %endif
672 %endif
673 %endmacro
674
675
676 ; ******************************
677 ; void put_hevc_mc_pixels(int16_t *dst, ptrdiff_t dststride,
678 ;                         uint8_t *_src, ptrdiff_t _srcstride,
679 ;                         int height, int mx, int my)
680 ; ******************************
681
682 %macro HEVC_PUT_HEVC_PEL_PIXELS 2
683 HEVC_PEL_PIXELS     %1, %2
684 HEVC_UNI_PEL_PIXELS %1, %2
685 HEVC_BI_PEL_PIXELS  %1, %2
686 %endmacro
687
688 %macro HEVC_PEL_PIXELS 2
689 cglobal hevc_put_hevc_pel_pixels%1_%2, 4, 4, 3, dst, src, srcstride,height
690     pxor               m2, m2
691 .loop
692     SIMPLE_LOAD       %1, %2, srcq, m0
693     MC_PIXEL_COMPUTE  %1, %2, 1
694     PEL_10STORE%1     dstq, m0, m1
695     LOOP_END         dst, src, srcstride
696     RET
697  %endmacro
698
699 %macro HEVC_UNI_PEL_PIXELS 2
700 cglobal hevc_put_hevc_uni_pel_pixels%1_%2, 5, 5, 2, dst, dststride, src, srcstride,height
701 .loop
702     SIMPLE_LOAD       %1, %2, srcq, m0
703     PEL_%2STORE%1   dstq, m0, m1
704     add             dstq, dststrideq             ; dst += dststride
705     add             srcq, srcstrideq             ; src += srcstride
706     dec          heightd                         ; cmp height
707     jnz               .loop                      ; height loop
708     RET
709 %endmacro
710
711 %macro HEVC_BI_PEL_PIXELS 2
712 cglobal hevc_put_hevc_bi_pel_pixels%1_%2, 6, 6, 6, dst, dststride, src, srcstride, src2, height
713     pxor              m2, m2
714     movdqa            m5, [pw_bi_%2]
715 .loop
716     SIMPLE_LOAD       %1, %2, srcq, m0
717     SIMPLE_BILOAD     %1, src2q, m3, m4
718     MC_PIXEL_COMPUTE  %1, %2, 1
719     BI_COMPUTE        %1, %2, m0, m1, m3, m4, m5, 1
720     PEL_%2STORE%1   dstq, m0, m1
721     add             dstq, dststrideq             ; dst += dststride
722     add             srcq, srcstrideq             ; src += srcstride
723     add            src2q, 2*MAX_PB_SIZE          ; src += srcstride
724     dec          heightd                         ; cmp height
725     jnz               .loop                      ; height loop
726     RET
727 %endmacro
728
729
730 ; ******************************
731 ; void put_hevc_epel_hX(int16_t *dst, ptrdiff_t dststride,
732 ;                       uint8_t *_src, ptrdiff_t _srcstride,
733 ;                       int width, int height, int mx, int my,
734 ;                       int16_t* mcbuffer)
735 ; ******************************
736
737
738 %macro HEVC_PUT_HEVC_EPEL 2
739 cglobal hevc_put_hevc_epel_h%1_%2, 5, 6, 11, dst, src, srcstride, height, mx, rfilter
740 %assign %%stride ((%2 + 7)/8)
741     EPEL_FILTER       %2, mx, m4, m5
742 .loop
743     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
744     EPEL_COMPUTE      %2, %1, m4, m5, 1
745     PEL_10STORE%1      dstq, m0, m1
746     LOOP_END         dst, src, srcstride
747     RET
748
749 cglobal hevc_put_hevc_uni_epel_h%1_%2, 6, 7, 11, dst, dststride, src, srcstride, height, mx, rfilter
750 %assign %%stride ((%2 + 7)/8)
751     movdqa            m6, [pw_%2]
752     EPEL_FILTER       %2, mx, m4, m5
753 .loop
754     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
755     EPEL_COMPUTE      %2, %1, m4, m5
756     UNI_COMPUTE       %1, %2, m0, m1, m6
757     PEL_%2STORE%1   dstq, m0, m1
758     add             dstq, dststrideq             ; dst += dststride
759     add             srcq, srcstrideq             ; src += srcstride
760     dec          heightd                         ; cmp height
761     jnz               .loop                      ; height loop
762     RET
763
764 cglobal hevc_put_hevc_bi_epel_h%1_%2, 7, 8, 11, dst, dststride, src, srcstride, src2, height, mx, rfilter
765     movdqa            m6, [pw_bi_%2]
766     EPEL_FILTER       %2, mx, m4, m5
767 .loop
768     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
769     EPEL_COMPUTE      %2, %1, m4, m5, 1
770     SIMPLE_BILOAD     %1, src2q, m2, m3
771     BI_COMPUTE        %1, %2, m0, m1, m2, m3, m6, 1
772     PEL_%2STORE%1   dstq, m0, m1
773     add             dstq, dststrideq             ; dst += dststride
774     add             srcq, srcstrideq             ; src += srcstride
775     add            src2q, 2*MAX_PB_SIZE          ; src += srcstride
776     dec          heightd                         ; cmp height
777     jnz               .loop                      ; height loop
778     RET
779
780 ; ******************************
781 ; void put_hevc_epel_v(int16_t *dst, ptrdiff_t dststride,
782 ;                      uint8_t *_src, ptrdiff_t _srcstride,
783 ;                      int width, int height, int mx, int my,
784 ;                      int16_t* mcbuffer)
785 ; ******************************
786
787 cglobal hevc_put_hevc_epel_v%1_%2, 6, 7, 11, dst, src, srcstride, height, r3src, my, rfilter
788     lea           r3srcq, [srcstrideq*3]
789     sub             srcq, srcstrideq
790     EPEL_FILTER       %2, my, m4, m5
791 .loop
792     EPEL_LOAD         %2, srcq, srcstride, %1
793     EPEL_COMPUTE      %2, %1, m4, m5, 1
794     PEL_10STORE%1     dstq, m0, m1
795     LOOP_END          dst, src, srcstride
796     RET
797
798 cglobal hevc_put_hevc_uni_epel_v%1_%2, 7, 8, 11, dst, dststride, src, srcstride, height, r3src, my, rfilter
799     lea           r3srcq, [srcstrideq*3]
800     movdqa            m6, [pw_%2]
801     sub             srcq, srcstrideq
802     EPEL_FILTER       %2, my, m4, m5
803 .loop
804     EPEL_LOAD         %2, srcq, srcstride, %1
805     EPEL_COMPUTE      %2, %1, m4, m5
806     UNI_COMPUTE       %1, %2, m0, m1, m6
807     PEL_%2STORE%1   dstq, m0, m1
808     add             dstq, dststrideq             ; dst += dststride
809     add             srcq, srcstrideq             ; src += srcstride
810     dec          heightd                         ; cmp height
811     jnz               .loop                      ; height loop
812     RET
813
814
815 cglobal hevc_put_hevc_bi_epel_v%1_%2, 8, 9, 11, dst, dststride, src, srcstride, src2, height, r3src, my, rfilter
816     lea           r3srcq, [srcstrideq*3]
817     movdqa            m6, [pw_bi_%2]
818     sub             srcq, srcstrideq
819     EPEL_FILTER       %2, my, m4, m5
820 .loop
821     EPEL_LOAD         %2, srcq, srcstride, %1
822     EPEL_COMPUTE      %2, %1, m4, m5, 1
823     SIMPLE_BILOAD     %1, src2q, m2, m3
824     BI_COMPUTE        %1, %2, m0, m1, m2, m3, m6, 1
825     PEL_%2STORE%1   dstq, m0, m1
826     add             dstq, dststrideq             ; dst += dststride
827     add             srcq, srcstrideq             ; src += srcstride
828     add            src2q, 2*MAX_PB_SIZE          ; src += srcstride
829     dec          heightd                         ; cmp height
830     jnz               .loop                      ; height loop
831     RET
832 %endmacro
833
834
835 ; ******************************
836 ; void put_hevc_epel_hv(int16_t *dst, ptrdiff_t dststride,
837 ;                       uint8_t *_src, ptrdiff_t _srcstride,
838 ;                       int width, int height, int mx, int my)
839 ; ******************************
840
841 %macro HEVC_PUT_HEVC_EPEL_HV 2
842 cglobal hevc_put_hevc_epel_hv%1_%2, 6, 8, 16 , dst, src, srcstride, height, mx, my, r3src, rfilter
843 %assign %%stride ((%2 + 7)/8)
844     sub             srcq, srcstrideq
845     EPEL_HV_FILTER    %2
846     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
847     EPEL_COMPUTE      %2, %1, m14, m15
848 %if (%1 > 8 && (%2 == 8))
849     SWAP              m8, m1
850 %endif
851     SWAP              m4, m0
852     add             srcq, srcstrideq
853     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
854     EPEL_COMPUTE      %2, %1, m14, m15
855 %if (%1 > 8 && (%2 == 8))
856     SWAP              m9, m1
857 %endif
858     SWAP              m5, m0
859     add             srcq, srcstrideq
860     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
861     EPEL_COMPUTE      %2, %1, m14, m15
862 %if (%1 > 8 && (%2 == 8))
863     SWAP             m10, m1
864 %endif
865     SWAP              m6, m0
866     add             srcq, srcstrideq
867 .loop
868     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
869     EPEL_COMPUTE      %2, %1, m14, m15
870 %if (%1 > 8 && (%2 == 8))
871     SWAP             m11, m1
872 %endif
873     SWAP              m7, m0
874     punpcklwd         m0, m4, m5
875     punpcklwd         m2, m6, m7
876 %if %1 > 4
877     punpckhwd         m1, m4, m5
878     punpckhwd         m3, m6, m7
879 %endif
880     EPEL_COMPUTE      14, %1, m12, m13
881 %if (%1 > 8 && (%2 == 8))
882     punpcklwd         m4, m8, m9
883     punpcklwd         m2, m10, m11
884     punpckhwd         m8, m8, m9
885     punpckhwd         m3, m10, m11
886     EPEL_COMPUTE      14, %1, m12, m13, m4, m2, m8, m3
887 %if cpuflag(avx2)
888     vinserti128       m2, m0, xm4, 1
889     vextracti128      xm3, m0, 1
890     vinserti128       m3, m4, xm3, 0
891     PEL_10STORE%1     dstq, m2, m3
892 %else
893     PEL_10STORE%1     dstq, m0, m4
894 %endif
895 %else
896     PEL_10STORE%1     dstq, m0, m1
897 %endif
898     movdqa            m4, m5
899     movdqa            m5, m6
900     movdqa            m6, m7
901 %if (%1 > 8 && (%2 == 8))
902     mova              m8, m9
903     mova              m9, m10
904     mova             m10, m11
905 %endif
906     LOOP_END         dst, src, srcstride
907     RET
908
909 cglobal hevc_put_hevc_uni_epel_hv%1_%2, 7, 9, 16 , dst, dststride, src, srcstride, height, mx, my, r3src, rfilter
910 %assign %%stride ((%2 + 7)/8)
911     sub             srcq, srcstrideq
912     EPEL_HV_FILTER    %2
913     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
914     EPEL_COMPUTE      %2, %1, m14, m15
915 %if (%1 > 8 && (%2 == 8))
916     SWAP              m8, m1
917 %endif
918     SWAP              m4, m0
919     add             srcq, srcstrideq
920     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
921     EPEL_COMPUTE      %2, %1, m14, m15
922 %if (%1 > 8 && (%2 == 8))
923     SWAP              m9, m1
924 %endif
925     SWAP              m5, m0
926     add             srcq, srcstrideq
927     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
928     EPEL_COMPUTE      %2, %1, m14, m15
929 %if (%1 > 8 && (%2 == 8))
930     SWAP             m10, m1
931 %endif
932     SWAP              m6, m0
933     add             srcq, srcstrideq
934 .loop
935     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
936     EPEL_COMPUTE      %2, %1, m14, m15
937 %if (%1 > 8 && (%2 == 8))
938     SWAP             m11, m1
939 %endif
940     mova              m7, m0
941     punpcklwd         m0, m4, m5
942     punpcklwd         m2, m6, m7
943 %if %1 > 4
944     punpckhwd         m1, m4, m5
945     punpckhwd         m3, m6, m7
946 %endif
947     EPEL_COMPUTE      14, %1, m12, m13
948 %if (%1 > 8 && (%2 == 8))
949     punpcklwd         m4, m8, m9
950     punpcklwd         m2, m10, m11
951     punpckhwd         m8, m8, m9
952     punpckhwd         m3, m10, m11
953     EPEL_COMPUTE      14, %1, m12, m13, m4, m2, m8, m3
954     UNI_COMPUTE       %1, %2, m0, m4, [pw_%2]
955 %else
956     UNI_COMPUTE       %1, %2, m0, m1, [pw_%2]
957 %endif
958     PEL_%2STORE%1   dstq, m0, m1
959     mova              m4, m5
960     mova              m5, m6
961     mova              m6, m7
962 %if (%1 > 8 && (%2 == 8))
963     mova              m8, m9
964     mova              m9, m10
965     mova             m10, m11
966 %endif
967     add             dstq, dststrideq             ; dst += dststride
968     add             srcq, srcstrideq             ; src += srcstride
969     dec          heightd                         ; cmp height
970     jnz               .loop                      ; height loop
971     RET
972
973 cglobal hevc_put_hevc_bi_epel_hv%1_%2, 8, 10, 16, dst, dststride, src, srcstride, src2, height, mx, my, r3src, rfilter
974 %assign %%stride ((%2 + 7)/8)
975     sub             srcq, srcstrideq
976     EPEL_HV_FILTER    %2
977     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
978     EPEL_COMPUTE      %2, %1, m14, m15
979 %if (%1 > 8 && (%2 == 8))
980     SWAP              m8, m1
981 %endif
982     SWAP              m4, m0
983     add             srcq, srcstrideq
984     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
985     EPEL_COMPUTE      %2, %1, m14, m15
986 %if (%1 > 8 && (%2 == 8))
987     SWAP              m9, m1
988 %endif
989     SWAP              m5, m0
990     add             srcq, srcstrideq
991     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
992     EPEL_COMPUTE      %2, %1, m14, m15
993 %if (%1 > 8 && (%2 == 8))
994     SWAP             m10, m1
995 %endif
996     SWAP              m6, m0
997     add             srcq, srcstrideq
998 .loop
999     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
1000     EPEL_COMPUTE      %2, %1, m14, m15
1001 %if (%1 > 8 && (%2 == 8))
1002     SWAP             m11, m1
1003 %endif
1004     SWAP              m7, m0
1005     punpcklwd         m0, m4, m5
1006     punpcklwd         m2, m6, m7
1007 %if %1 > 4
1008     punpckhwd         m1, m4, m5
1009     punpckhwd         m3, m6, m7
1010 %endif
1011     EPEL_COMPUTE      14, %1, m12, m13
1012 %if (%1 > 8 && (%2 == 8))
1013     punpcklwd         m4, m8, m9
1014     punpcklwd         m2, m10, m11
1015     punpckhwd         m8, m8, m9
1016     punpckhwd         m3, m10, m11
1017     EPEL_COMPUTE      14, %1, m12, m13, m4, m2, m8, m3
1018     SIMPLE_BILOAD     %1, src2q, m8, m3
1019 %if cpuflag(avx2)
1020     vinserti128       m1, m8, xm3, 1
1021     vextracti128      xm8, m8, 1
1022     vinserti128       m2, m3, xm8, 0
1023     BI_COMPUTE        %1, %2, m0, m4, m1, m2, [pw_bi_%2]
1024 %else
1025     BI_COMPUTE        %1, %2, m0, m4, m8, m3, [pw_bi_%2]
1026 %endif
1027 %else
1028     SIMPLE_BILOAD     %1, src2q, m8, m9
1029     BI_COMPUTE        %1, %2, m0, m1, m8, m9, [pw_bi_%2]
1030 %endif
1031     PEL_%2STORE%1   dstq, m0, m4
1032     mova              m4, m5
1033     mova              m5, m6
1034     mova              m6, m7
1035 %if (%1 > 8 && (%2 == 8))
1036     mova              m8, m9
1037     mova              m9, m10
1038     mova             m10, m11
1039 %endif
1040     add             dstq, dststrideq             ; dst += dststride
1041     add             srcq, srcstrideq             ; src += srcstride
1042     add            src2q, 2*MAX_PB_SIZE          ; src += srcstride
1043     dec          heightd                         ; cmp height
1044     jnz               .loop                      ; height loop
1045     RET
1046 %endmacro
1047
1048 ; ******************************
1049 ; void put_hevc_qpel_hX_X_X(int16_t *dst, ptrdiff_t dststride,
1050 ;                       uint8_t *_src, ptrdiff_t _srcstride,
1051 ;                       int width, int height, int mx, int my)
1052 ; ******************************
1053
1054 %macro HEVC_PUT_HEVC_QPEL 2
1055 cglobal hevc_put_hevc_qpel_h%1_%2, 5, 6, 16, dst, src, srcstride, height, mx, rfilter
1056     QPEL_FILTER       %2, mx
1057 .loop
1058     QPEL_H_LOAD       %2, srcq, %1, 10
1059     QPEL_COMPUTE      %1, %2, 1
1060 %if %2 > 8
1061     packssdw          m0, m1
1062 %endif
1063     PEL_10STORE%1     dstq, m0, m1
1064     LOOP_END          dst, src, srcstride
1065     RET
1066
1067 cglobal hevc_put_hevc_uni_qpel_h%1_%2, 6, 7, 16 , dst, dststride, src, srcstride, height, mx, rfilter
1068     mova              m9, [pw_%2]
1069     QPEL_FILTER       %2, mx
1070 .loop
1071     QPEL_H_LOAD       %2, srcq, %1, 10
1072     QPEL_COMPUTE      %1, %2
1073 %if %2 > 8
1074     packssdw          m0, m1
1075 %endif
1076     UNI_COMPUTE       %1, %2, m0, m1, m9
1077     PEL_%2STORE%1   dstq, m0, m1
1078     add             dstq, dststrideq             ; dst += dststride
1079     add             srcq, srcstrideq             ; src += srcstride
1080     dec          heightd                         ; cmp height
1081     jnz               .loop                      ; height loop
1082     RET
1083
1084 cglobal hevc_put_hevc_bi_qpel_h%1_%2, 7, 8, 16 , dst, dststride, src, srcstride, src2, height, mx, rfilter
1085     movdqa            m9, [pw_bi_%2]
1086     QPEL_FILTER       %2, mx
1087 .loop
1088     QPEL_H_LOAD       %2, srcq, %1, 10
1089     QPEL_COMPUTE      %1, %2, 1
1090 %if %2 > 8
1091     packssdw          m0, m1
1092 %endif
1093     SIMPLE_BILOAD     %1, src2q, m10, m11
1094     BI_COMPUTE        %1, %2, m0, m1, m10, m11, m9, 1
1095     PEL_%2STORE%1   dstq, m0, m1
1096     add             dstq, dststrideq             ; dst += dststride
1097     add             srcq, srcstrideq             ; src += srcstride
1098     add            src2q, 2*MAX_PB_SIZE          ; src += srcstride
1099     dec          heightd                         ; cmp height
1100     jnz               .loop                      ; height loop
1101     RET
1102
1103
1104 ; ******************************
1105 ; void put_hevc_qpel_vX_X_X(int16_t *dst, ptrdiff_t dststride,
1106 ;                       uint8_t *_src, ptrdiff_t _srcstride,
1107 ;                       int width, int height, int mx, int my)
1108 ; ******************************
1109
1110 cglobal hevc_put_hevc_qpel_v%1_%2, 6, 8, 16, dst, src, srcstride, height, r3src, my, rfilter
1111     lea           r3srcq, [srcstrideq*3]
1112     QPEL_FILTER       %2, my
1113 .loop
1114     QPEL_V_LOAD       %2, srcq, srcstride, %1, r7
1115     QPEL_COMPUTE      %1, %2, 1
1116 %if %2 > 8
1117     packssdw          m0, m1
1118 %endif
1119     PEL_10STORE%1     dstq, m0, m1
1120     LOOP_END         dst, src, srcstride
1121     RET
1122
1123 cglobal hevc_put_hevc_uni_qpel_v%1_%2, 7, 9, 16, dst, dststride, src, srcstride, height, r3src, my, rfilter
1124     movdqa            m9, [pw_%2]
1125     lea           r3srcq, [srcstrideq*3]
1126     QPEL_FILTER       %2, my
1127 .loop
1128     QPEL_V_LOAD       %2, srcq, srcstride, %1, r8
1129     QPEL_COMPUTE      %1, %2
1130 %if %2 > 8
1131     packssdw          m0, m1
1132 %endif
1133     UNI_COMPUTE       %1, %2, m0, m1, m9
1134     PEL_%2STORE%1   dstq, m0, m1
1135     add             dstq, dststrideq             ; dst += dststride
1136     add             srcq, srcstrideq             ; src += srcstride
1137     dec          heightd                         ; cmp height
1138     jnz               .loop                      ; height loop
1139     RET
1140
1141 cglobal hevc_put_hevc_bi_qpel_v%1_%2, 8, 10, 16, dst, dststride, src, srcstride, src2, height, r3src, my, rfilter
1142     movdqa            m9, [pw_bi_%2]
1143     lea           r3srcq, [srcstrideq*3]
1144     QPEL_FILTER       %2, my
1145 .loop
1146     QPEL_V_LOAD       %2, srcq, srcstride, %1, r9
1147     QPEL_COMPUTE      %1, %2, 1
1148 %if %2 > 8
1149     packssdw          m0, m1
1150 %endif
1151     SIMPLE_BILOAD     %1, src2q, m10, m11
1152     BI_COMPUTE        %1, %2, m0, m1, m10, m11, m9, 1
1153     PEL_%2STORE%1   dstq, m0, m1
1154     add             dstq, dststrideq             ; dst += dststride
1155     add             srcq, srcstrideq             ; src += srcstride
1156     add            src2q, 2*MAX_PB_SIZE          ; src += srcstride
1157     dec          heightd                         ; cmp height
1158     jnz               .loop                      ; height loop
1159     RET
1160 %endmacro
1161
1162
1163 ; ******************************
1164 ; void put_hevc_qpel_hvX_X(int16_t *dst, ptrdiff_t dststride,
1165 ;                       uint8_t *_src, ptrdiff_t _srcstride,
1166 ;                       int height, int mx, int my)
1167 ; ******************************
1168 %macro HEVC_PUT_HEVC_QPEL_HV 2
1169 cglobal hevc_put_hevc_qpel_hv%1_%2, 6, 8, 16, dst, src, srcstride, height, mx, my, r3src, rfilter
1170 %if cpuflag(avx2)
1171 %assign %%shift  4
1172 %else
1173 %assign %%shift  3
1174 %endif
1175     sub              mxq, 1
1176     sub              myq, 1
1177     shl              mxq, %%shift                ; multiply by 32
1178     shl              myq, %%shift                ; multiply by 32
1179     lea           r3srcq, [srcstrideq*3]
1180     sub             srcq, r3srcq
1181     QPEL_H_LOAD       %2, srcq, %1, 15
1182     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1183     SWAP              m8, m0
1184     add             srcq, srcstrideq
1185     QPEL_H_LOAD       %2, srcq, %1, 15
1186     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1187     SWAP              m9, m0
1188     add             srcq, srcstrideq
1189     QPEL_H_LOAD       %2, srcq, %1, 15
1190     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1191     SWAP             m10, m0
1192     add             srcq, srcstrideq
1193     QPEL_H_LOAD       %2, srcq, %1, 15
1194     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1195     SWAP             m11, m0
1196     add             srcq, srcstrideq
1197     QPEL_H_LOAD       %2, srcq, %1, 15
1198     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1199     SWAP             m12, m0
1200     add             srcq, srcstrideq
1201     QPEL_H_LOAD       %2, srcq, %1, 15
1202     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1203     SWAP             m13, m0
1204     add             srcq, srcstrideq
1205     QPEL_H_LOAD       %2, srcq, %1, 15
1206     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1207     SWAP             m14, m0
1208     add             srcq, srcstrideq
1209 .loop
1210     QPEL_H_LOAD       %2, srcq, %1, 15
1211     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1212     SWAP             m15, m0
1213     punpcklwd         m0, m8, m9
1214     punpcklwd         m2, m10, m11
1215     punpcklwd         m4, m12, m13
1216     punpcklwd         m6, m14, m15
1217 %if %1 > 4
1218     punpckhwd         m1, m8, m9
1219     punpckhwd         m3, m10, m11
1220     punpckhwd         m5, m12, m13
1221     punpckhwd         m7, m14, m15
1222 %endif
1223     QPEL_HV_COMPUTE   %1, 14, my, ackssdw
1224     PEL_10STORE%1     dstq, m0, m1
1225 %if %1 <= 4
1226     movq              m8, m9
1227     movq              m9, m10
1228     movq             m10, m11
1229     movq             m11, m12
1230     movq             m12, m13
1231     movq             m13, m14
1232     movq             m14, m15
1233 %else
1234     movdqa            m8, m9
1235     movdqa            m9, m10
1236     movdqa           m10, m11
1237     movdqa           m11, m12
1238     movdqa           m12, m13
1239     movdqa           m13, m14
1240     movdqa           m14, m15
1241 %endif
1242     LOOP_END         dst, src, srcstride
1243     RET
1244
1245 cglobal hevc_put_hevc_uni_qpel_hv%1_%2, 7, 9, 16 , dst, dststride, src, srcstride, height, mx, my, r3src, rfilter
1246 %if cpuflag(avx2)
1247 %assign %%shift  4
1248 %else
1249 %assign %%shift  3
1250 %endif
1251     sub              mxq, 1
1252     sub              myq, 1
1253     shl              mxq, %%shift                ; multiply by 32
1254     shl              myq, %%shift                ; multiply by 32
1255     lea           r3srcq, [srcstrideq*3]
1256     sub             srcq, r3srcq
1257     QPEL_H_LOAD       %2, srcq, %1, 15
1258     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1259     SWAP              m8, m0
1260     add             srcq, srcstrideq
1261     QPEL_H_LOAD       %2, srcq, %1, 15
1262     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1263     SWAP              m9, m0
1264     add             srcq, srcstrideq
1265     QPEL_H_LOAD       %2, srcq, %1, 15
1266     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1267     SWAP             m10, m0
1268     add             srcq, srcstrideq
1269     QPEL_H_LOAD       %2, srcq, %1, 15
1270     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1271     SWAP             m11, m0
1272     add             srcq, srcstrideq
1273     QPEL_H_LOAD       %2, srcq, %1, 15
1274     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1275     SWAP             m12, m0
1276     add             srcq, srcstrideq
1277     QPEL_H_LOAD       %2, srcq, %1, 15
1278     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1279     SWAP             m13, m0
1280     add             srcq, srcstrideq
1281     QPEL_H_LOAD       %2, srcq, %1, 15
1282     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1283     SWAP             m14, m0
1284     add             srcq, srcstrideq
1285 .loop
1286     QPEL_H_LOAD       %2, srcq, %1, 15
1287     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1288     SWAP             m15, m0
1289     punpcklwd         m0, m8, m9
1290     punpcklwd         m2, m10, m11
1291     punpcklwd         m4, m12, m13
1292     punpcklwd         m6, m14, m15
1293 %if %1 > 4
1294     punpckhwd         m1, m8, m9
1295     punpckhwd         m3, m10, m11
1296     punpckhwd         m5, m12, m13
1297     punpckhwd         m7, m14, m15
1298 %endif
1299     QPEL_HV_COMPUTE   %1, 14, my, ackusdw
1300     UNI_COMPUTE       %1, %2, m0, m1, [pw_%2]
1301     PEL_%2STORE%1   dstq, m0, m1
1302
1303 %if %1 <= 4
1304     movq              m8, m9
1305     movq              m9, m10
1306     movq             m10, m11
1307     movq             m11, m12
1308     movq             m12, m13
1309     movq             m13, m14
1310     movq             m14, m15
1311 %else
1312     mova            m8, m9
1313     mova            m9, m10
1314     mova           m10, m11
1315     mova           m11, m12
1316     mova           m12, m13
1317     mova           m13, m14
1318     mova           m14, m15
1319 %endif
1320     add             dstq, dststrideq             ; dst += dststride
1321     add             srcq, srcstrideq             ; src += srcstride
1322     dec          heightd                         ; cmp height
1323     jnz               .loop                      ; height loop
1324     RET
1325
1326 cglobal hevc_put_hevc_bi_qpel_hv%1_%2, 8, 10, 16, dst, dststride, src, srcstride, src2, height, mx, my, r3src, rfilter
1327 %if cpuflag(avx2)
1328 %assign %%shift  4
1329 %else
1330 %assign %%shift  3
1331 %endif
1332     sub              mxq, 1
1333     sub              myq, 1
1334     shl              mxq, %%shift                ; multiply by 32
1335     shl              myq, %%shift                ; multiply by 32
1336     lea           r3srcq, [srcstrideq*3]
1337     sub             srcq, r3srcq
1338     QPEL_H_LOAD       %2, srcq, %1, 15
1339     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1340     SWAP              m8, m0
1341     add             srcq, srcstrideq
1342     QPEL_H_LOAD       %2, srcq, %1, 15
1343     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1344     SWAP              m9, m0
1345     add             srcq, srcstrideq
1346     QPEL_H_LOAD       %2, srcq, %1, 15
1347     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1348     SWAP             m10, m0
1349     add             srcq, srcstrideq
1350     QPEL_H_LOAD       %2, srcq, %1, 15
1351     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1352     SWAP             m11, m0
1353     add             srcq, srcstrideq
1354     QPEL_H_LOAD       %2, srcq, %1, 15
1355     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1356     SWAP             m12, m0
1357     add             srcq, srcstrideq
1358     QPEL_H_LOAD       %2, srcq, %1, 15
1359     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1360     SWAP             m13, m0
1361     add             srcq, srcstrideq
1362     QPEL_H_LOAD       %2, srcq, %1, 15
1363     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1364     SWAP             m14, m0
1365     add             srcq, srcstrideq
1366 .loop
1367     QPEL_H_LOAD       %2, srcq, %1, 15
1368     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1369     SWAP             m15, m0
1370     punpcklwd         m0, m8, m9
1371     punpcklwd         m2, m10, m11
1372     punpcklwd         m4, m12, m13
1373     punpcklwd         m6, m14, m15
1374 %if %1 > 4
1375     punpckhwd         m1, m8, m9
1376     punpckhwd         m3, m10, m11
1377     punpckhwd         m5, m12, m13
1378     punpckhwd         m7, m14, m15
1379 %endif
1380     QPEL_HV_COMPUTE   %1, 14, my, ackssdw
1381     SIMPLE_BILOAD     %1, src2q, m8, m9 ;m9 not used in this case
1382     BI_COMPUTE        %1, %2, m0, m1, m8, m9, [pw_bi_%2]
1383     PEL_%2STORE%1   dstq, m0, m1
1384
1385 %if %1 <= 4
1386     movq              m8, m9
1387     movq              m9, m10
1388     movq             m10, m11
1389     movq             m11, m12
1390     movq             m12, m13
1391     movq             m13, m14
1392     movq             m14, m15
1393 %else
1394     movdqa            m8, m9
1395     movdqa            m9, m10
1396     movdqa           m10, m11
1397     movdqa           m11, m12
1398     movdqa           m12, m13
1399     movdqa           m13, m14
1400     movdqa           m14, m15
1401 %endif
1402     add             dstq, dststrideq             ; dst += dststride
1403     add             srcq, srcstrideq             ; src += srcstride
1404     add            src2q, 2*MAX_PB_SIZE          ; src += srcstride
1405     dec          heightd                         ; cmp height
1406     jnz               .loop                      ; height loop
1407     RET
1408 %endmacro
1409
1410 %macro WEIGHTING_FUNCS 2
1411 %if WIN64 || ARCH_X86_32
1412 cglobal hevc_put_hevc_uni_w%1_%2, 4, 5, 7, dst, dststride, src, srcstride, height, denom, wx, ox
1413     mov             r4d, denomm
1414 %define SHIFT  r4d
1415 %else
1416 cglobal hevc_put_hevc_uni_w%1_%2, 6, 6, 7, dst, dststride, src, srcstride, height, denom, wx, ox
1417 %define SHIFT  denomd
1418 %endif
1419     lea           SHIFT, [SHIFT+14-%2]          ; shift = 14 - bitd + denom
1420 %if %1 <= 4
1421     pxor             m1, m1
1422 %endif
1423     movd             m2, wxm        ; WX
1424     movd             m4, SHIFT      ; shift
1425 %if %1 <= 4
1426     punpcklwd        m2, m1
1427 %else
1428     punpcklwd        m2, m2
1429 %endif
1430     dec           SHIFT
1431     movdqu           m5, [pd_1]
1432     movd             m6, SHIFT
1433     pshufd           m2, m2, 0
1434     mov           SHIFT, oxm
1435     pslld            m5, m6
1436 %if %2 != 8
1437     shl           SHIFT, %2-8       ; ox << (bitd - 8)
1438 %endif
1439     movd             m3, SHIFT      ; OX
1440     pshufd           m3, m3, 0
1441 %if WIN64 || ARCH_X86_32
1442     mov           SHIFT, heightm
1443 %endif
1444 .loop
1445    SIMPLE_LOAD        %1, 10, srcq, m0
1446 %if %1 <= 4
1447     punpcklwd         m0, m1
1448     pmaddwd           m0, m2
1449     paddd             m0, m5
1450     psrad             m0, m4
1451     paddd             m0, m3
1452 %else
1453     pmulhw            m6, m0, m2
1454     pmullw            m0, m2
1455     punpckhwd         m1, m0, m6
1456     punpcklwd         m0, m6
1457     paddd             m0, m5
1458     paddd             m1, m5
1459     psrad             m0, m4
1460     psrad             m1, m4
1461     paddd             m0, m3
1462     paddd             m1, m3
1463 %endif
1464     packssdw          m0, m1
1465 %if %2 == 8
1466     packuswb          m0, m0
1467 %else
1468     CLIPW             m0, [pb_0], [max_pixels_%2]
1469 %endif
1470     PEL_%2STORE%1   dstq, m0, m1
1471     add             dstq, dststrideq             ; dst += dststride
1472     add             srcq, 2*MAX_PB_SIZE          ; src += srcstride
1473     dec          heightd                         ; cmp height
1474     jnz               .loop                      ; height loop
1475     RET
1476
1477 cglobal hevc_put_hevc_bi_w%1_%2, 5, 7, 10, dst, dststride, src, srcstride, src2, height, denom, wx0, wx1, ox0, ox1
1478     mov              r6d, denomm
1479 %if %1 <= 4
1480     pxor              m1, m1
1481 %endif
1482     movd              m2, wx0m         ; WX0
1483     lea              r6d, [r6d+14-%2]  ; shift = 14 - bitd + denom
1484     movd              m3, wx1m         ; WX1
1485     movd              m0, r6d          ; shift
1486 %if %1 <= 4
1487     punpcklwd         m2, m1
1488     punpcklwd         m3, m1
1489 %else
1490     punpcklwd         m2, m2
1491     punpcklwd         m3, m3
1492 %endif
1493     inc              r6d
1494     movd              m5, r6d          ; shift+1
1495     pshufd            m2, m2, 0
1496     mov              r6d, ox0m
1497     pshufd            m3, m3, 0
1498     add              r6d, ox1m
1499 %if %2 != 8
1500     shl              r6d, %2-8         ; ox << (bitd - 8)
1501 %endif
1502     inc              r6d
1503     movd              m4, r6d          ; offset
1504     pshufd            m4, m4, 0
1505     mov              r6d, heightm
1506     pslld             m4, m0
1507
1508 .loop
1509    SIMPLE_LOAD        %1, 10, srcq,  m0
1510    SIMPLE_LOAD        %1, 10, src2q, m8
1511 %if %1 <= 4
1512     punpcklwd         m0, m1
1513     punpcklwd         m8, m1
1514     pmaddwd           m0, m3
1515     pmaddwd           m8, m2
1516     paddd             m0, m4
1517     paddd             m0, m8
1518     psrad             m0, m5
1519 %else
1520     pmulhw            m6, m0, m3
1521     pmullw            m0, m3
1522     pmulhw            m7, m8, m2
1523     pmullw            m8, m2
1524     punpckhwd         m1, m0, m6
1525     punpcklwd         m0, m6
1526     punpckhwd         m9, m8, m7
1527     punpcklwd         m8, m7
1528     paddd             m0, m8
1529     paddd             m1, m9
1530     paddd             m0, m4
1531     paddd             m1, m4
1532     psrad             m0, m5
1533     psrad             m1, m5
1534 %endif
1535     packssdw          m0, m1
1536 %if %2 == 8
1537     packuswb          m0, m0
1538 %else
1539      CLIPW            m0, [pb_0], [max_pixels_%2]
1540 %endif
1541     PEL_%2STORE%1   dstq, m0, m1
1542     add             dstq, dststrideq             ; dst += dststride
1543     add             srcq, 2*MAX_PB_SIZE          ; src += srcstride
1544     add            src2q, 2*MAX_PB_SIZE          ; src2 += srcstride
1545     dec              r6d                         ; cmp height
1546     jnz               .loop                      ; height loop
1547     RET
1548 %endmacro
1549
1550 INIT_XMM sse4                                    ; adds ff_ and _sse4 to function name
1551
1552 WEIGHTING_FUNCS 2, 8
1553 WEIGHTING_FUNCS 4, 8
1554 WEIGHTING_FUNCS 6, 8
1555 WEIGHTING_FUNCS 8, 8
1556
1557 WEIGHTING_FUNCS 2, 10
1558 WEIGHTING_FUNCS 4, 10
1559 WEIGHTING_FUNCS 6, 10
1560 WEIGHTING_FUNCS 8, 10
1561
1562 WEIGHTING_FUNCS 2, 12
1563 WEIGHTING_FUNCS 4, 12
1564 WEIGHTING_FUNCS 6, 12
1565 WEIGHTING_FUNCS 8, 12
1566
1567 HEVC_PUT_HEVC_PEL_PIXELS  2, 8
1568 HEVC_PUT_HEVC_PEL_PIXELS  4, 8
1569 HEVC_PUT_HEVC_PEL_PIXELS  6, 8
1570 HEVC_PUT_HEVC_PEL_PIXELS  8, 8
1571 HEVC_PUT_HEVC_PEL_PIXELS 12, 8
1572 HEVC_PUT_HEVC_PEL_PIXELS 16, 8
1573
1574 HEVC_PUT_HEVC_PEL_PIXELS 2, 10
1575 HEVC_PUT_HEVC_PEL_PIXELS 4, 10
1576 HEVC_PUT_HEVC_PEL_PIXELS 6, 10
1577 HEVC_PUT_HEVC_PEL_PIXELS 8, 10
1578
1579 HEVC_PUT_HEVC_PEL_PIXELS 2, 12
1580 HEVC_PUT_HEVC_PEL_PIXELS 4, 12
1581 HEVC_PUT_HEVC_PEL_PIXELS 6, 12
1582 HEVC_PUT_HEVC_PEL_PIXELS 8, 12
1583
1584 HEVC_PUT_HEVC_EPEL 2,  8
1585 HEVC_PUT_HEVC_EPEL 4,  8
1586 HEVC_PUT_HEVC_EPEL 6,  8
1587 HEVC_PUT_HEVC_EPEL 8,  8
1588 HEVC_PUT_HEVC_EPEL 12, 8
1589 HEVC_PUT_HEVC_EPEL 16, 8
1590
1591
1592 HEVC_PUT_HEVC_EPEL 2, 10
1593 HEVC_PUT_HEVC_EPEL 4, 10
1594 HEVC_PUT_HEVC_EPEL 6, 10
1595 HEVC_PUT_HEVC_EPEL 8, 10
1596
1597 HEVC_PUT_HEVC_EPEL 2, 12
1598 HEVC_PUT_HEVC_EPEL 4, 12
1599 HEVC_PUT_HEVC_EPEL 6, 12
1600 HEVC_PUT_HEVC_EPEL 8, 12
1601
1602 HEVC_PUT_HEVC_EPEL_HV 2,  8
1603 HEVC_PUT_HEVC_EPEL_HV 4,  8
1604 HEVC_PUT_HEVC_EPEL_HV 6,  8
1605 HEVC_PUT_HEVC_EPEL_HV 8,  8
1606 HEVC_PUT_HEVC_EPEL_HV 16, 8
1607
1608 HEVC_PUT_HEVC_EPEL_HV 2, 10
1609 HEVC_PUT_HEVC_EPEL_HV 4, 10
1610 HEVC_PUT_HEVC_EPEL_HV 6, 10
1611 HEVC_PUT_HEVC_EPEL_HV 8, 10
1612
1613 HEVC_PUT_HEVC_EPEL_HV 2, 12
1614 HEVC_PUT_HEVC_EPEL_HV 4, 12
1615 HEVC_PUT_HEVC_EPEL_HV 6, 12
1616 HEVC_PUT_HEVC_EPEL_HV 8, 12
1617
1618 HEVC_PUT_HEVC_QPEL 4,  8
1619 HEVC_PUT_HEVC_QPEL 8,  8
1620 HEVC_PUT_HEVC_QPEL 12, 8
1621 HEVC_PUT_HEVC_QPEL 16, 8
1622
1623 HEVC_PUT_HEVC_QPEL 4, 10
1624 HEVC_PUT_HEVC_QPEL 8, 10
1625
1626 HEVC_PUT_HEVC_QPEL 4, 12
1627 HEVC_PUT_HEVC_QPEL 8, 12
1628
1629 HEVC_PUT_HEVC_QPEL_HV 2, 8
1630 HEVC_PUT_HEVC_QPEL_HV 4, 8
1631 HEVC_PUT_HEVC_QPEL_HV 6, 8
1632 HEVC_PUT_HEVC_QPEL_HV 8, 8
1633
1634 HEVC_PUT_HEVC_QPEL_HV 2, 10
1635 HEVC_PUT_HEVC_QPEL_HV 4, 10
1636 HEVC_PUT_HEVC_QPEL_HV 6, 10
1637 HEVC_PUT_HEVC_QPEL_HV 8, 10
1638
1639 HEVC_PUT_HEVC_QPEL_HV 2, 12
1640 HEVC_PUT_HEVC_QPEL_HV 4, 12
1641 HEVC_PUT_HEVC_QPEL_HV 6, 12
1642 HEVC_PUT_HEVC_QPEL_HV 8, 12
1643
1644 %if HAVE_AVX2_EXTERNAL
1645 INIT_YMM avx2  ; adds ff_ and _avx2 to function name & enables 256b registers : m0 for 256b, xm0 for 128b. cpuflag(avx2) = 1 / notcpuflag(avx) = 0
1646
1647 HEVC_PUT_HEVC_PEL_PIXELS 32, 8
1648 HEVC_PUT_HEVC_PEL_PIXELS 16, 10
1649
1650 HEVC_PUT_HEVC_EPEL 32, 8
1651 HEVC_PUT_HEVC_EPEL 16, 10
1652
1653 HEVC_PUT_HEVC_EPEL_HV 16, 10
1654 HEVC_PUT_HEVC_EPEL_HV 32, 8
1655
1656 HEVC_PUT_HEVC_QPEL 32, 8
1657
1658 HEVC_PUT_HEVC_QPEL 16, 10
1659
1660 HEVC_PUT_HEVC_QPEL_HV 16, 10
1661
1662 %endif ;AVX2
1663 %endif ; ARCH_X86_64