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