]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/hevc_mc.asm
Merge commit 'b5aa48551300eed678aaea86ced7086758598a35'
[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     psrad             m0, %1-8
383     psrad             m1, %1-8
384     packssdw          m0, m1
385 %endif
386 %endmacro
387
388 %macro QPEL_HV_COMPUTE 4     ; width, bitdepth, filter idx
389 %ifdef PIC
390     lea         rfilterq, [hevc_qpel_filters_sse4_%2]
391 %else
392     %define rfilterq hevc_qpel_filters_sse4_%2
393 %endif
394
395 %if %2 == 8
396     pmaddubsw         m0, [rfilterq + %3q*8   ]   ;x1*c1+x2*c2
397     pmaddubsw         m2, [rfilterq + %3q*8+16]   ;x3*c3+x4*c4
398     pmaddubsw         m4, [rfilterq + %3q*8+32]   ;x5*c5+x6*c6
399     pmaddubsw         m6, [rfilterq + %3q*8+48]   ;x7*c7+x8*c8
400     paddw             m0, m2
401     paddw             m4, m6
402     paddw             m0, m4
403 %else
404     pmaddwd           m0, [rfilterq + %3q*8   ]
405     pmaddwd           m2, [rfilterq + %3q*8+16]
406     pmaddwd           m4, [rfilterq + %3q*8+32]
407     pmaddwd           m6, [rfilterq + %3q*8+48]
408     paddd             m0, m2
409     paddd             m4, m6
410     paddd             m0, m4
411     psrad             m0, %2-8
412 %if %1 > 4
413     pmaddwd           m1, [rfilterq + %3q*8   ]
414     pmaddwd           m3, [rfilterq + %3q*8+16]
415     pmaddwd           m5, [rfilterq + %3q*8+32]
416     pmaddwd           m7, [rfilterq + %3q*8+48]
417     paddd             m1, m3
418     paddd             m5, m7
419     paddd             m1, m5
420     psrad             m1, %2-8
421 %endif
422     p%4               m0, m1
423 %endif
424 %endmacro
425
426 %macro QPEL_COMPUTE 2     ; width, bitdepth
427 %if %2 == 8
428     pmaddubsw         m0, m12   ;x1*c1+x2*c2
429     pmaddubsw         m2, m13   ;x3*c3+x4*c4
430     pmaddubsw         m4, m14   ;x5*c5+x6*c6
431     pmaddubsw         m6, m15   ;x7*c7+x8*c8
432     paddw             m0, m2
433     paddw             m4, m6
434     paddw             m0, m4
435 %if %1 > 8
436     pmaddubsw         m1, m12
437     pmaddubsw         m3, m13
438     pmaddubsw         m5, m14
439     pmaddubsw         m7, m15
440     paddw             m1, m3
441     paddw             m5, m7
442     paddw             m1, m5
443 %endif
444 %else
445     pmaddwd           m0, m12
446     pmaddwd           m2, m13
447     pmaddwd           m4, m14
448     pmaddwd           m6, m15
449     paddd             m0, m2
450     paddd             m4, m6
451     paddd             m0, m4
452     psrad             m0, %2-8
453 %if %1 > 4
454     pmaddwd           m1, m12
455     pmaddwd           m3, m13
456     pmaddwd           m5, m14
457     pmaddwd           m7, m15
458     paddd             m1, m3
459     paddd             m5, m7
460     paddd             m1, m5
461     psrad             m1, %2-8
462 %endif
463 %endif
464 %endmacro
465
466 %macro BI_COMPUTE 7     ; width, bitd, src1l, src1h, scr2l, scr2h, pw
467     paddsw            %3, %5
468 %if %1 > 8
469     paddsw            %4, %6
470 %endif
471     UNI_COMPUTE       %1, %2, %3, %4, %7
472 %endmacro
473
474 %macro UNI_COMPUTE 5
475     pmulhrsw          %3, %5
476 %if %1 > 8 || (%2 > 8 && %1 > 4)
477     pmulhrsw          %4, %5
478 %endif
479 %if %2 == 8
480     packuswb          %3, %4
481 %else
482     pminsw            %3, [max_pixels_%2]
483     pmaxsw            %3, [zero]
484 %if %1 > 8
485     pminsw            %4, [max_pixels_%2]
486     pmaxsw            %4, [zero]
487 %endif
488 %endif
489 %endmacro
490
491 INIT_XMM sse4                                    ; adds ff_ and _sse4 to function name
492 ; ******************************
493 ; void put_hevc_mc_pixels(int16_t *dst, ptrdiff_t dststride,
494 ;                         uint8_t *_src, ptrdiff_t _srcstride,
495 ;                         int height, int mx, int my)
496 ; ******************************
497
498 %macro HEVC_PUT_HEVC_PEL_PIXELS 2
499 cglobal hevc_put_hevc_pel_pixels%1_%2, 5, 5, 3, dst, dststride, src, srcstride,height
500     pxor               m2, m2
501 .loop
502     SIMPLE_LOAD       %1, %2, srcq, m0
503     MC_PIXEL_COMPUTE  %1, %2
504     PEL_10STORE%1     dstq, m0, m1
505     LOOP_END         dst, dststride, src, srcstride
506     RET
507
508 cglobal hevc_put_hevc_uni_pel_pixels%1_%2, 5, 5, 3, dst, dststride, src, srcstride,height
509     pxor              m2, m2
510 .loop
511     SIMPLE_LOAD       %1, %2, srcq, m0
512     PEL_%2STORE%1   dstq, m0, m1
513     lea             dstq, [dstq+dststrideq]      ; dst += dststride
514     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
515     dec          heightd                         ; cmp height
516     jnz               .loop                      ; height loop
517     RET
518
519 cglobal hevc_put_hevc_bi_pel_pixels%1_%2, 7, 7, 6, dst, dststride, src, srcstride, src2, src2stride,height
520     pxor              m2, m2
521     movdqa            m5, [pw_bi_%2]
522 .loop
523     SIMPLE_LOAD       %1, %2, srcq, m0
524     SIMPLE_BILOAD     %1, src2q, m3, m4
525     MC_PIXEL_COMPUTE  %1, %2
526     BI_COMPUTE        %1, %2, m0, m1, m3, m4, m5
527     PEL_%2STORE%1   dstq, m0, m1
528     lea             dstq, [dstq+dststrideq]      ; dst += dststride
529     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
530     lea            src2q, [src2q+2*src2strideq]  ; src += srcstride
531     dec          heightd                         ; cmp height
532     jnz               .loop                      ; height loop
533     RET
534
535 %endmacro
536
537
538 ; ******************************
539 ; void put_hevc_epel_hX(int16_t *dst, ptrdiff_t dststride,
540 ;                       uint8_t *_src, ptrdiff_t _srcstride,
541 ;                       int width, int height, int mx, int my,
542 ;                       int16_t* mcbuffer)
543 ; ******************************
544
545
546 %macro HEVC_PUT_HEVC_EPEL 2
547 cglobal hevc_put_hevc_epel_h%1_%2, 6, 7, 6, dst, dststride, src, srcstride, height, mx, rfilter
548 %assign %%stride ((%2 + 7)/8)
549     EPEL_FILTER       %2, mx, m4, m5
550 .loop
551     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
552     EPEL_COMPUTE      %2, %1, m4, m5
553     PEL_10STORE%1      dstq, m0, m1
554     LOOP_END         dst, dststride, src, srcstride
555     RET
556
557 cglobal hevc_put_hevc_uni_epel_h%1_%2, 6, 7, 7, dst, dststride, src, srcstride, height, mx, rfilter
558 %assign %%stride ((%2 + 7)/8)
559     movdqa            m6, [pw_%2]
560     EPEL_FILTER       %2, mx, m4, m5
561 .loop
562     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
563     EPEL_COMPUTE      %2, %1, m4, m5
564     UNI_COMPUTE       %1, %2, m0, m1, m6
565     PEL_%2STORE%1   dstq, m0, m1
566     lea             dstq, [dstq+dststrideq]      ; dst += dststride
567     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
568     dec          heightd                         ; cmp height
569     jnz               .loop                      ; height loop
570     RET
571
572 cglobal hevc_put_hevc_bi_epel_h%1_%2, 8, 9, 7, dst, dststride, src, srcstride, src2, src2stride,height, mx, rfilter
573     movdqa            m6, [pw_bi_%2]
574     EPEL_FILTER       %2, mx, m4, m5
575 .loop
576     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
577     EPEL_COMPUTE      %2, %1, m4, m5
578     SIMPLE_BILOAD     %1, src2q, m2, m3
579     BI_COMPUTE        %1, %2, m0, m1, m2, m3, m6
580     PEL_%2STORE%1   dstq, m0, m1
581     lea             dstq, [dstq+dststrideq]      ; dst += dststride
582     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
583     lea            src2q, [src2q+2*src2strideq]  ; src += srcstride
584     dec          heightd                         ; cmp height
585     jnz               .loop                      ; height loop
586     RET
587
588 ; ******************************
589 ; void put_hevc_epel_v(int16_t *dst, ptrdiff_t dststride,
590 ;                      uint8_t *_src, ptrdiff_t _srcstride,
591 ;                      int width, int height, int mx, int my,
592 ;                      int16_t* mcbuffer)
593 ; ******************************
594
595 cglobal hevc_put_hevc_epel_v%1_%2, 7, 8, 6, dst, dststride, src, srcstride, height, r3src, my, rfilter
596     lea           r3srcq, [srcstrideq*3]
597     sub             srcq, srcstrideq
598     EPEL_FILTER       %2, my, m4, m5
599 .loop
600     EPEL_LOAD         %2, srcq, srcstride, %1
601     EPEL_COMPUTE      %2, %1, m4, m5
602     PEL_10STORE%1     dstq, m0, m1
603     LOOP_END          dst, dststride, src, srcstride
604     RET
605
606 cglobal hevc_put_hevc_uni_epel_v%1_%2, 7, 8, 7, dst, dststride, src, srcstride, height, r3src, my, rfilter
607     lea           r3srcq, [srcstrideq*3]
608     movdqa            m6, [pw_%2]
609     sub             srcq, srcstrideq
610     EPEL_FILTER       %2, my, m4, m5
611 .loop
612     EPEL_LOAD         %2, srcq, srcstride, %1
613     EPEL_COMPUTE      %2, %1, m4, m5
614     UNI_COMPUTE       %1, %2, m0, m1, m6
615     PEL_%2STORE%1   dstq, m0, m1
616     lea             dstq, [dstq+dststrideq]      ; dst += dststride
617     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
618     dec          heightd                         ; cmp height
619     jnz               .loop                      ; height loop
620     RET
621
622
623 cglobal hevc_put_hevc_bi_epel_v%1_%2, 9, 10, 7, dst, dststride, src, srcstride, src2, src2stride,height, r3src, my, rfilter
624     lea           r3srcq, [srcstrideq*3]
625     movdqa            m6, [pw_bi_%2]
626     sub             srcq, srcstrideq
627     EPEL_FILTER       %2, my, m4, m5
628 .loop
629     EPEL_LOAD         %2, srcq, srcstride, %1
630     EPEL_COMPUTE      %2, %1, m4, m5
631     SIMPLE_BILOAD     %1, src2q, m2, m3
632     BI_COMPUTE        %1, %2, m0, m1, m2, m3, m6
633     PEL_%2STORE%1   dstq, m0, m1
634     lea             dstq, [dstq+dststrideq]      ; dst += dststride
635     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
636     lea            src2q, [src2q+2*src2strideq]  ; src += srcstride
637     dec          heightd                         ; cmp height
638     jnz               .loop                      ; height loop
639     RET
640 %endmacro
641
642
643 ; ******************************
644 ; void put_hevc_epel_hv(int16_t *dst, ptrdiff_t dststride,
645 ;                       uint8_t *_src, ptrdiff_t _srcstride,
646 ;                       int width, int height, int mx, int my)
647 ; ******************************
648
649 %macro HEVC_PUT_HEVC_EPEL_HV 2
650 cglobal hevc_put_hevc_epel_hv%1_%2, 7, 9, 12 , dst, dststride, src, srcstride, height, mx, my, r3src, rfilter
651 %assign %%stride ((%2 + 7)/8)
652     sub             srcq, srcstrideq
653     EPEL_HV_FILTER    %2
654     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
655     EPEL_COMPUTE      %2, %1, m14, m15
656     SWAP              m4, m0
657     lea             srcq, [srcq + srcstrideq]
658     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
659     EPEL_COMPUTE      %2, %1, m14, m15
660     SWAP              m5, m0
661     lea             srcq, [srcq + srcstrideq]
662     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
663     EPEL_COMPUTE      %2, %1, m14, m15
664     SWAP              m6, m0
665     lea             srcq, [srcq + srcstrideq]
666 .loop
667     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
668     EPEL_COMPUTE      %2, %1, m14, m15
669     SWAP              m7, m0
670     punpcklwd         m0, m4, m5
671     punpcklwd         m2, m6, m7
672 %if %1 > 4
673     punpckhwd         m1, m4, m5
674     punpckhwd         m3, m6, m7
675 %endif
676     EPEL_COMPUTE      14, %1, m12, m13
677     PEL_10STORE%1     dstq, m0, m1
678     movdqa            m4, m5
679     movdqa            m5, m6
680     movdqa            m6, m7
681     LOOP_END         dst, dststride, src, srcstride
682     RET
683
684 cglobal hevc_put_hevc_uni_epel_hv%1_%2, 7, 9, 12 , dst, dststride, src, srcstride, height, mx, my, r3src, rfilter
685 %assign %%stride ((%2 + 7)/8)
686     sub             srcq, srcstrideq
687     EPEL_HV_FILTER    %2
688     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
689     EPEL_COMPUTE      %2, %1, m14, m15
690     SWAP              m4, m0
691     lea             srcq, [srcq + srcstrideq]
692     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
693     EPEL_COMPUTE      %2, %1, m14, m15
694     SWAP              m5, m0
695     lea             srcq, [srcq + srcstrideq]
696     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
697     EPEL_COMPUTE      %2, %1, m14, m15
698     SWAP              m6, m0
699     lea             srcq, [srcq + srcstrideq]
700 .loop
701     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
702     EPEL_COMPUTE      %2, %1, m14, m15
703     SWAP              m7, m0
704     punpcklwd         m0, m4, m5
705     punpcklwd         m2, m6, m7
706 %if %1 > 4
707     punpckhwd         m1, m4, m5
708     punpckhwd         m3, m6, m7
709 %endif
710     EPEL_COMPUTE      14, %1, m12, m13
711     UNI_COMPUTE       %1, %2, m0, m1, [pw_%2]
712     PEL_%2STORE%1   dstq, m0, m1
713     movdqa            m4, m5
714     movdqa            m5, m6
715     movdqa            m6, m7
716     lea             dstq, [dstq+dststrideq]      ; dst += dststride
717     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
718     dec          heightd                         ; cmp height
719     jnz               .loop                      ; height loop
720     RET
721
722
723 cglobal hevc_put_hevc_bi_epel_hv%1_%2, 9, 11, 16, dst, dststride, src, srcstride, src2, src2stride, height, mx, my, r3src, rfilter
724 %assign %%stride ((%2 + 7)/8)
725     sub             srcq, srcstrideq
726     EPEL_HV_FILTER    %2
727     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
728     EPEL_COMPUTE      %2, %1, m14, m15
729     SWAP              m4, m0
730     lea             srcq, [srcq + srcstrideq]
731     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
732     EPEL_COMPUTE      %2, %1, m14, m15
733     SWAP              m5, m0
734     lea             srcq, [srcq + srcstrideq]
735     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
736     EPEL_COMPUTE      %2, %1, m14, m15
737     SWAP              m6, m0
738     lea             srcq, [srcq + srcstrideq]
739 .loop
740     EPEL_LOAD         %2, srcq-%%stride, %%stride, %1
741     EPEL_COMPUTE      %2, %1, m14, m15
742     SWAP              m7, m0
743     punpcklwd         m0, m4, m5
744     punpcklwd         m2, m6, m7
745 %if %1 > 4
746     punpckhwd         m1, m4, m5
747     punpckhwd         m3, m6, m7
748 %endif
749     EPEL_COMPUTE      14, %1, m12, m13
750     SIMPLE_BILOAD     %1, src2q, m8, m9
751     BI_COMPUTE        %1, %2, m0, m1, m8, m9, [pw_bi_%2]
752     PEL_%2STORE%1   dstq, m0, m1
753     movdqa            m4, m5
754     movdqa            m5, m6
755     movdqa            m6, m7
756     lea             dstq, [dstq+dststrideq]      ; dst += dststride
757     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
758     lea            src2q, [src2q+2*src2strideq]  ; src += srcstride
759     dec          heightd                         ; cmp height
760     jnz               .loop                      ; height loop
761     RET
762 %endmacro
763
764 ; ******************************
765 ; void put_hevc_qpel_hX_X_X(int16_t *dst, ptrdiff_t dststride,
766 ;                       uint8_t *_src, ptrdiff_t _srcstride,
767 ;                       int width, int height, int mx, int my)
768 ; ******************************
769
770 %macro HEVC_PUT_HEVC_QPEL 2
771 cglobal hevc_put_hevc_qpel_h%1_%2, 6, 7, 15 , dst, dststride, src, srcstride, height, mx, rfilter
772     QPEL_FILTER       %2, mx
773 .loop
774     QPEL_H_LOAD       %2, srcq, %1, 10
775     QPEL_COMPUTE      %1, %2
776 %if %2 > 8
777     packssdw          m0, m1
778 %endif
779     PEL_10STORE%1     dstq, m0, m1
780     LOOP_END          dst, dststride, src, srcstride
781     RET
782
783 cglobal hevc_put_hevc_uni_qpel_h%1_%2, 6, 7, 15 , dst, dststride, src, srcstride, height, mx, rfilter
784     movdqa            m9, [pw_%2]
785     QPEL_FILTER       %2, mx
786 .loop
787     QPEL_H_LOAD       %2, srcq, %1, 10
788     QPEL_COMPUTE      %1, %2
789 %if %2 > 8
790     packssdw          m0, m1
791 %endif
792     UNI_COMPUTE       %1, %2, m0, m1, m9
793     PEL_%2STORE%1   dstq, m0, m1
794     lea             dstq, [dstq+dststrideq]      ; dst += dststride
795     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
796     dec          heightd                         ; cmp height
797     jnz               .loop                      ; height loop
798     RET
799
800 cglobal hevc_put_hevc_bi_qpel_h%1_%2, 8, 9, 16 , dst, dststride, src, srcstride, src2, src2stride, height, mx, rfilter
801     movdqa            m9, [pw_bi_%2]
802     QPEL_FILTER       %2, mx
803 .loop
804     QPEL_H_LOAD       %2, srcq, %1, 10
805     QPEL_COMPUTE      %1, %2
806 %if %2 > 8
807     packssdw          m0, m1
808 %endif
809     SIMPLE_BILOAD     %1, src2q, m10, m11
810     BI_COMPUTE        %1, %2, m0, m1, m10, m11, m9
811     PEL_%2STORE%1   dstq, m0, m1
812     lea             dstq, [dstq+dststrideq]      ; dst += dststride
813     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
814     lea            src2q, [src2q+2*src2strideq]  ; src += srcstride
815     dec          heightd                         ; cmp height
816     jnz               .loop                      ; height loop
817     RET
818
819
820 ; ******************************
821 ; void put_hevc_qpel_vX_X_X(int16_t *dst, ptrdiff_t dststride,
822 ;                       uint8_t *_src, ptrdiff_t _srcstride,
823 ;                       int width, int height, int mx, int my)
824 ; ******************************
825
826 cglobal hevc_put_hevc_qpel_v%1_%2, 7, 14, 15 , dst, dststride, src, srcstride, height, r3src, my, rfilter
827     lea           r3srcq, [srcstrideq*3]
828     QPEL_FILTER       %2, my
829 .loop
830     QPEL_V_LOAD       %2, srcq, srcstride, %1
831     QPEL_COMPUTE      %1, %2
832 %if %2 > 8
833     packssdw          m0, m1
834 %endif
835     PEL_10STORE%1     dstq, m0, m1
836     LOOP_END         dst, dststride, src, srcstride
837     RET
838
839 cglobal hevc_put_hevc_uni_qpel_v%1_%2, 7, 14, 15 , dst, dststride, src, srcstride, height, r3src, my, rfilter
840     movdqa            m9, [pw_%2]
841     lea           r3srcq, [srcstrideq*3]
842     QPEL_FILTER       %2, my
843 .loop
844     QPEL_V_LOAD       %2, srcq, srcstride, %1
845     QPEL_COMPUTE      %1, %2
846 %if %2 > 8
847     packusdw          m0, m1
848 %endif
849     UNI_COMPUTE       %1, %2, m0, m1, m9
850     PEL_%2STORE%1   dstq, m0, m1
851     lea             dstq, [dstq+dststrideq]      ; dst += dststride
852     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
853     dec          heightd                         ; cmp height
854     jnz               .loop                      ; height loop
855     RET
856
857 cglobal hevc_put_hevc_bi_qpel_v%1_%2, 9, 14, 16 , dst, dststride, src, srcstride, src2, src2stride, height, r3src, my, rfilter
858     movdqa            m9, [pw_bi_%2]
859     lea           r3srcq, [srcstrideq*3]
860     QPEL_FILTER       %2, my
861 .loop
862     SIMPLE_BILOAD     %1, src2q, m10, m11
863     QPEL_V_LOAD       %2, srcq, srcstride, %1
864     QPEL_COMPUTE      %1, %2
865 %if %2 > 8
866     packssdw          m0, m1
867 %endif
868     BI_COMPUTE        %1, %2, m0, m1, m10, m11, m9
869     PEL_%2STORE%1   dstq, m0, m1
870     lea             dstq, [dstq+dststrideq]      ; dst += dststride
871     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
872     lea            src2q, [src2q+2*src2strideq]  ; src += srcstride
873     dec          heightd                         ; cmp height
874     jnz               .loop                      ; height loop
875     RET
876 %endmacro
877
878
879 ; ******************************
880 ; void put_hevc_qpel_hvX_X(int16_t *dst, ptrdiff_t dststride,
881 ;                       uint8_t *_src, ptrdiff_t _srcstride,
882 ;                       int height, int mx, int my)
883 ; ******************************
884 %macro HEVC_PUT_HEVC_QPEL_HV 2
885 cglobal hevc_put_hevc_qpel_hv%1_%2, 7, 9, 12 , dst, dststride, src, srcstride, height, mx, my, r3src, rfilter
886     lea              mxq, [mxq*8-8]
887     lea              myq, [myq*8-8]
888     lea           r3srcq, [srcstrideq*3]
889     sub             srcq, r3srcq
890     QPEL_H_LOAD       %2, srcq, %1, 15
891     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
892     SWAP              m8, m0
893     lea             srcq, [srcq + srcstrideq]
894     QPEL_H_LOAD       %2, srcq, %1, 15
895     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
896     SWAP              m9, m0
897     lea             srcq, [srcq + srcstrideq]
898     QPEL_H_LOAD       %2, srcq, %1, 15
899     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
900     SWAP             m10, m0
901     lea             srcq, [srcq + srcstrideq]
902     QPEL_H_LOAD       %2, srcq, %1, 15
903     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
904     SWAP             m11, m0
905     lea             srcq, [srcq + srcstrideq]
906     QPEL_H_LOAD       %2, srcq, %1, 15
907     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
908     SWAP             m12, m0
909     lea             srcq, [srcq + srcstrideq]
910     QPEL_H_LOAD       %2, srcq, %1, 15
911     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
912     SWAP             m13, m0
913     lea             srcq, [srcq + srcstrideq]
914     QPEL_H_LOAD       %2, srcq, %1, 15
915     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
916     SWAP             m14, m0
917     lea             srcq, [srcq + srcstrideq]
918 .loop
919     QPEL_H_LOAD       %2, srcq, %1, 15
920     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
921     SWAP             m15, m0
922     punpcklwd         m0, m8, m9
923     punpcklwd         m2, m10, m11
924     punpcklwd         m4, m12, m13
925     punpcklwd         m6, m14, m15
926 %if %1 > 4
927     punpckhwd         m1, m8, m9
928     punpckhwd         m3, m10, m11
929     punpckhwd         m5, m12, m13
930     punpckhwd         m7, m14, m15
931 %endif
932     QPEL_HV_COMPUTE   %1, 14, my, ackssdw
933     PEL_10STORE%1     dstq, m0, m1
934 %if %1 <= 4
935     movq              m8, m9
936     movq              m9, m10
937     movq             m10, m11
938     movq             m11, m12
939     movq             m12, m13
940     movq             m13, m14
941     movq             m14, m15
942 %else
943     movdqa            m8, m9
944     movdqa            m9, m10
945     movdqa           m10, m11
946     movdqa           m11, m12
947     movdqa           m12, m13
948     movdqa           m13, m14
949     movdqa           m14, m15
950 %endif
951     LOOP_END         dst, dststride, src, srcstride
952     RET
953
954 cglobal hevc_put_hevc_uni_qpel_hv%1_%2, 7, 9, 12 , dst, dststride, src, srcstride, height, mx, my, r3src, rfilter
955     lea              mxq, [mxq*8-8]
956     lea              myq, [myq*8-8]
957     lea           r3srcq, [srcstrideq*3]
958     sub             srcq, r3srcq
959     QPEL_H_LOAD       %2, srcq, %1, 15
960     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
961     SWAP              m8, m0
962     lea             srcq, [srcq + srcstrideq]
963     QPEL_H_LOAD       %2, srcq, %1, 15
964     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
965     SWAP              m9, m0
966     lea             srcq, [srcq + srcstrideq]
967     QPEL_H_LOAD       %2, srcq, %1, 15
968     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
969     SWAP             m10, m0
970     lea             srcq, [srcq + srcstrideq]
971     QPEL_H_LOAD       %2, srcq, %1, 15
972     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
973     SWAP             m11, m0
974     lea             srcq, [srcq + srcstrideq]
975     QPEL_H_LOAD       %2, srcq, %1, 15
976     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
977     SWAP             m12, m0
978     lea             srcq, [srcq + srcstrideq]
979     QPEL_H_LOAD       %2, srcq, %1, 15
980     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
981     SWAP             m13, m0
982     lea             srcq, [srcq + srcstrideq]
983     QPEL_H_LOAD       %2, srcq, %1, 15
984     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
985     SWAP             m14, m0
986     lea             srcq, [srcq + srcstrideq]
987 .loop
988     QPEL_H_LOAD       %2, srcq, %1, 15
989     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
990     SWAP             m15, m0
991     punpcklwd         m0, m8, m9
992     punpcklwd         m2, m10, m11
993     punpcklwd         m4, m12, m13
994     punpcklwd         m6, m14, m15
995 %if %1 > 4
996     punpckhwd         m1, m8, m9
997     punpckhwd         m3, m10, m11
998     punpckhwd         m5, m12, m13
999     punpckhwd         m7, m14, m15
1000 %endif
1001     QPEL_HV_COMPUTE   %1, 14, my, ackusdw
1002     UNI_COMPUTE       %1, %2, m0, m1, [pw_%2]
1003     PEL_%2STORE%1   dstq, m0, m1
1004
1005 %if %1 <= 4
1006     movq              m8, m9
1007     movq              m9, m10
1008     movq             m10, m11
1009     movq             m11, m12
1010     movq             m12, m13
1011     movq             m13, m14
1012     movq             m14, m15
1013 %else
1014     movdqa            m8, m9
1015     movdqa            m9, m10
1016     movdqa           m10, m11
1017     movdqa           m11, m12
1018     movdqa           m12, m13
1019     movdqa           m13, m14
1020     movdqa           m14, m15
1021 %endif
1022     lea             dstq, [dstq+dststrideq]      ; dst += dststride
1023     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
1024     dec          heightd                         ; cmp height
1025     jnz               .loop                      ; height loop
1026     RET
1027
1028 cglobal hevc_put_hevc_bi_qpel_hv%1_%2, 9, 11, 16, dst, dststride, src, srcstride, src2, src2stride, height, mx, my, r3src, rfilter
1029     lea              mxq, [mxq*8-8]
1030     lea              myq, [myq*8-8]
1031     lea           r3srcq, [srcstrideq*3]
1032     sub             srcq, r3srcq
1033     QPEL_H_LOAD       %2, srcq, %1, 15
1034     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1035     SWAP              m8, m0
1036     lea             srcq, [srcq + srcstrideq]
1037     QPEL_H_LOAD       %2, srcq, %1, 15
1038     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1039     SWAP              m9, m0
1040     lea             srcq, [srcq + srcstrideq]
1041     QPEL_H_LOAD       %2, srcq, %1, 15
1042     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1043     SWAP             m10, m0
1044     lea             srcq, [srcq + srcstrideq]
1045     QPEL_H_LOAD       %2, srcq, %1, 15
1046     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1047     SWAP             m11, m0
1048     lea             srcq, [srcq + srcstrideq]
1049     QPEL_H_LOAD       %2, srcq, %1, 15
1050     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1051     SWAP             m12, m0
1052     lea             srcq, [srcq + srcstrideq]
1053     QPEL_H_LOAD       %2, srcq, %1, 15
1054     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1055     SWAP             m13, m0
1056     lea             srcq, [srcq + srcstrideq]
1057     QPEL_H_LOAD       %2, srcq, %1, 15
1058     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1059     SWAP             m14, m0
1060     lea             srcq, [srcq + srcstrideq]
1061 .loop
1062     QPEL_H_LOAD       %2, srcq, %1, 15
1063     QPEL_HV_COMPUTE   %1, %2, mx, ackssdw
1064     SWAP             m15, m0
1065     punpcklwd         m0, m8, m9
1066     punpcklwd         m2, m10, m11
1067     punpcklwd         m4, m12, m13
1068     punpcklwd         m6, m14, m15
1069 %if %1 > 4
1070     punpckhwd         m1, m8, m9
1071     punpckhwd         m3, m10, m11
1072     punpckhwd         m5, m12, m13
1073     punpckhwd         m7, m14, m15
1074 %endif
1075     QPEL_HV_COMPUTE   %1, 14, my, ackssdw
1076     SIMPLE_BILOAD     %1, src2q, m8, m9 ;m9 not used in this case
1077     BI_COMPUTE        %1, %2, m0, m1, m8, m9, [pw_bi_%2]
1078     PEL_%2STORE%1   dstq, m0, m1
1079
1080 %if %1 <= 4
1081     movq              m8, m9
1082     movq              m9, m10
1083     movq             m10, m11
1084     movq             m11, m12
1085     movq             m12, m13
1086     movq             m13, m14
1087     movq             m14, m15
1088 %else
1089     movdqa            m8, m9
1090     movdqa            m9, m10
1091     movdqa           m10, m11
1092     movdqa           m11, m12
1093     movdqa           m12, m13
1094     movdqa           m13, m14
1095     movdqa           m14, m15
1096 %endif
1097     lea             dstq, [dstq+dststrideq]      ; dst += dststride
1098     lea             srcq, [srcq+srcstrideq]      ; src += srcstride
1099     lea            src2q, [src2q+2*src2strideq]  ; src += srcstride
1100     dec          heightd                         ; cmp height
1101     jnz               .loop                      ; height loop
1102     RET
1103 %endmacro
1104
1105 %macro WEIGHTING_FUNCS 2
1106 cglobal hevc_put_hevc_uni_w%1_%2, 8, 10, 11, dst, dststride, src, srcstride, height, denom, wx, ox, shift
1107     lea          shiftd, [denomd+14-%2]          ; shift = 14 - bitd + denom
1108     shl             oxd, %2-8                    ; ox << (bitd - 8)
1109     movd             m2, wxd        ; WX
1110     movd             m3, oxd        ; OX
1111     movd             m4, shiftd     ; shift
1112     punpcklwd        m2, m2
1113     pshufd           m3, m3, 0
1114     pshufd           m2, m2, 0
1115     sub          shiftd, 1
1116     movd             m6, shiftd
1117     movdqu           m5, [one_per_32]
1118     pslld            m5, m6
1119 .loop
1120    SIMPLE_LOAD        %1, 10, srcq, m0
1121     pmulhw            m6, m0, m2
1122     pmullw            m0, m2
1123     punpckhwd         m1, m0, m6
1124     punpcklwd         m0, m6
1125     paddd             m0, m5
1126     paddd             m1, m5
1127     psrad             m0, m4
1128     psrad             m1, m4
1129     paddd             m0, m3
1130     paddd             m1, m3
1131     packusdw          m0, m1
1132 %if %2 == 8
1133     packuswb          m0, m0
1134 %else
1135     pminsw            m0, [max_pixels_%2]
1136 %endif
1137     PEL_%2STORE%1   dstq, m0, m1
1138     lea             dstq, [dstq+dststrideq]      ; dst += dststride
1139     lea             srcq, [srcq+2*srcstrideq]      ; src += srcstride
1140     dec          heightd                         ; cmp height
1141     jnz               .loop                      ; height loop
1142     RET
1143
1144 cglobal hevc_put_hevc_bi_w%1_%2, 12, 14, 14, dst, dststride, src, srcstride, src2, src2stride, height, denom, wx0, wx1, ox0, ox1, shift, temp
1145     shl             ox0d, %2-8                    ; ox << (bitd - 8)
1146     shl             ox1d, %2-8                    ; ox << (bitd - 8)
1147     lea           shiftd, [denomd+14-%2]          ; shift = 14 - bitd + denom
1148     movd              m2, wx0d        ; WX0
1149     movd              m3, wx1d        ; WX1
1150     punpcklwd         m2, m2
1151     punpcklwd         m3, m3
1152     pshufd            m2, m2, 0
1153     pshufd            m3, m3, 0
1154     add             ox0d, ox1d
1155     add             ox0d, 1
1156     movd              m4, ox0d         ; offset
1157     pshufd            m4, m4, 0
1158     movd              m5, shiftd       ; shift
1159     pslld             m4, m5
1160     add           shiftd, 1
1161     movd              m5, shiftd       ; shift
1162
1163 .loop
1164    SIMPLE_LOAD        %1, 10, srcq,  m0
1165    SIMPLE_LOAD        %1, 10, src2q, m10
1166     pmulhw            m6, m0, m3
1167     pmullw            m0, m3
1168     pmulhw            m7, m10, m2
1169     pmullw           m10, m2
1170     punpckhwd         m1, m0, m6
1171     punpcklwd         m0, m6
1172     punpckhwd        m11, m10, m7
1173     punpcklwd        m10, m7
1174     paddd             m0, m10
1175     paddd             m1, m11
1176     paddd             m0, m4
1177     paddd             m1, m4
1178     psrad             m0, m5
1179     psrad             m1, m5
1180     packusdw          m0, m1
1181 %if %2 == 8
1182     packuswb          m0, m0
1183 %else
1184     pminsw            m0, [max_pixels_%2]
1185 %endif
1186     PEL_%2STORE%1   dstq, m0, m1
1187     lea             dstq, [dstq+dststrideq]      ; dst += dststride
1188     lea             srcq, [srcq+2*srcstrideq]      ; src += srcstride
1189     lea            src2q, [src2q+2*src2strideq]      ; src2 += srcstride
1190     dec          heightd                         ; cmp height
1191     jnz               .loop                      ; height loop
1192     RET
1193 %endmacro
1194
1195 WEIGHTING_FUNCS 2, 8
1196 WEIGHTING_FUNCS 4, 8
1197 WEIGHTING_FUNCS 6, 8
1198 WEIGHTING_FUNCS 8, 8
1199
1200 WEIGHTING_FUNCS 2, 10
1201 WEIGHTING_FUNCS 4, 10
1202 WEIGHTING_FUNCS 6, 10
1203 WEIGHTING_FUNCS 8, 10
1204
1205 HEVC_PUT_HEVC_PEL_PIXELS  2, 8
1206 HEVC_PUT_HEVC_PEL_PIXELS  4, 8
1207 HEVC_PUT_HEVC_PEL_PIXELS  6, 8
1208 HEVC_PUT_HEVC_PEL_PIXELS  8, 8
1209 HEVC_PUT_HEVC_PEL_PIXELS 12, 8
1210 HEVC_PUT_HEVC_PEL_PIXELS 16, 8
1211
1212 HEVC_PUT_HEVC_PEL_PIXELS 2, 10
1213 HEVC_PUT_HEVC_PEL_PIXELS 4, 10
1214 HEVC_PUT_HEVC_PEL_PIXELS 6, 10
1215 HEVC_PUT_HEVC_PEL_PIXELS 8, 10
1216
1217
1218 HEVC_PUT_HEVC_EPEL 2,  8
1219 HEVC_PUT_HEVC_EPEL 4,  8
1220 HEVC_PUT_HEVC_EPEL 6,  8
1221 HEVC_PUT_HEVC_EPEL 8,  8
1222 HEVC_PUT_HEVC_EPEL 12, 8
1223 HEVC_PUT_HEVC_EPEL 16, 8
1224
1225
1226 HEVC_PUT_HEVC_EPEL 2, 10
1227 HEVC_PUT_HEVC_EPEL 4, 10
1228 HEVC_PUT_HEVC_EPEL 6, 10
1229 HEVC_PUT_HEVC_EPEL 8, 10
1230
1231
1232 HEVC_PUT_HEVC_EPEL_HV 2,  8
1233 HEVC_PUT_HEVC_EPEL_HV 4,  8
1234 HEVC_PUT_HEVC_EPEL_HV 6,  8
1235 HEVC_PUT_HEVC_EPEL_HV 8,  8
1236
1237 HEVC_PUT_HEVC_EPEL_HV 2, 10
1238 HEVC_PUT_HEVC_EPEL_HV 4, 10
1239 HEVC_PUT_HEVC_EPEL_HV 6, 10
1240 HEVC_PUT_HEVC_EPEL_HV 8, 10
1241
1242
1243 HEVC_PUT_HEVC_QPEL 4,  8
1244 HEVC_PUT_HEVC_QPEL 8,  8
1245 HEVC_PUT_HEVC_QPEL 12, 8
1246 HEVC_PUT_HEVC_QPEL 16, 8
1247
1248 HEVC_PUT_HEVC_QPEL 4, 10
1249 HEVC_PUT_HEVC_QPEL 8, 10
1250
1251 HEVC_PUT_HEVC_QPEL_HV 2, 8
1252 HEVC_PUT_HEVC_QPEL_HV 4, 8
1253 HEVC_PUT_HEVC_QPEL_HV 6, 8
1254 HEVC_PUT_HEVC_QPEL_HV 8, 8
1255
1256 HEVC_PUT_HEVC_QPEL_HV 2, 10
1257 HEVC_PUT_HEVC_QPEL_HV 4, 10
1258 HEVC_PUT_HEVC_QPEL_HV 6, 10
1259 HEVC_PUT_HEVC_QPEL_HV 8, 10
1260
1261 %endif ; ARCH_X86_64