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