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