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