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