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