fft: port FFT/IMDCT 3dnow functions to yasm, and disable on x86-64.
[ffmpeg.git] / libavcodec / x86 / h264_qpel_10bit.asm
1 ;*****************************************************************************
2 ;* MMX/SSE2/AVX-optimized 10-bit H.264 qpel code
3 ;*****************************************************************************
4 ;* Copyright (C) 2011 x264 project
5 ;*
6 ;* Authors: Daniel Kang <daniel.d.kang@gmail.com>
7 ;*
8 ;* This file is part of Libav.
9 ;*
10 ;* Libav is free software; you can redistribute it and/or
11 ;* modify it under the terms of the GNU Lesser General Public
12 ;* License as published by the Free Software Foundation; either
13 ;* version 2.1 of the License, or (at your option) any later version.
14 ;*
15 ;* Libav is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;* Lesser General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU Lesser General Public
21 ;* License along with Libav; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ;******************************************************************************
24
25 %include "x86inc.asm"
26 %include "x86util.asm"
27
28 SECTION_RODATA 32
29
30 cextern pw_16
31 cextern pw_1
32 cextern pb_0
33
34 pw_pixel_max: times 8 dw ((1 << 10)-1)
35
36 pad10: times 8 dw 10*1023
37 pad20: times 8 dw 20*1023
38 pad30: times 8 dw 30*1023
39 depad: times 4 dd 32*20*1023 + 512
40 depad2: times 8 dw 20*1023 + 16*1022 + 16
41 unpad: times 8 dw 16*1022/32 ; needs to be mod 16
42
43 tap1: times 4 dw  1, -5
44 tap2: times 4 dw 20, 20
45 tap3: times 4 dw -5,  1
46 pd_0f: times 4 dd 0xffff
47
48 SECTION .text
49
50
51 %macro AVG_MOV 2
52     pavgw %2, %1
53     mova  %1, %2
54 %endmacro
55
56 %macro ADDW 3
57 %if mmsize == 8
58     paddw %1, %2
59 %else
60     movu  %3, %2
61     paddw %1, %3
62 %endif
63 %endmacro
64
65 %macro FILT_H 4
66     paddw  %1, %4
67     psubw  %1, %2  ; a-b
68     psraw  %1, 2   ; (a-b)/4
69     psubw  %1, %2  ; (a-b)/4-b
70     paddw  %1, %3  ; (a-b)/4-b+c
71     psraw  %1, 2   ; ((a-b)/4-b+c)/4
72     paddw  %1, %3  ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
73 %endmacro
74
75 %macro PRELOAD_V 0
76     lea      r3, [r2*3]
77     sub      r1, r3
78     movu     m0, [r1+r2]
79     movu     m1, [r1+r2*2]
80     add      r1, r3
81     movu     m2, [r1]
82     movu     m3, [r1+r2]
83     movu     m4, [r1+r2*2]
84     add      r1, r3
85 %endmacro
86
87 %macro FILT_V 8
88     movu     %6, [r1]
89     paddw    %1, %6
90     mova     %7, %2
91     paddw    %7, %5
92     mova     %8, %3
93     paddw    %8, %4
94     FILT_H   %1, %7, %8, [pw_16]
95     psraw    %1, 1
96     CLIPW    %1, [pb_0], [pw_pixel_max]
97 %endmacro
98
99 %macro MC 1
100 %define OP_MOV mova
101 INIT_MMX
102 %1 mmxext, put, 4
103 INIT_XMM
104 %1 sse2  , put, 8
105
106 %define OP_MOV AVG_MOV
107 INIT_MMX
108 %1 mmxext, avg, 4
109 INIT_XMM
110 %1 sse2  , avg, 8
111 %endmacro
112
113 %macro MCAxA 8
114 %if ARCH_X86_64
115 %ifnidn %1,mmxext
116 MCAxA_OP %1,%2,%3,%4,%5,%6,%7,%8
117 %endif
118 %else
119 MCAxA_OP %1,%2,%3,%4,%5,%6,%7,%8
120 %endif
121 %endmacro
122
123 %macro MCAxA_OP 8
124 %if ARCH_X86_32
125 cglobal %2_h264_qpel%5_%3_10_%1, %6,%7,%8
126     call stub_%2_h264_qpel%4_%3_10_%1
127     mov  r0, r0m
128     mov  r1, r1m
129     add  r0, %4*2
130     add  r1, %4*2
131     call stub_%2_h264_qpel%4_%3_10_%1
132     mov  r0, r0m
133     mov  r1, r1m
134     lea  r0, [r0+r2*%4]
135     lea  r1, [r1+r2*%4]
136     call stub_%2_h264_qpel%4_%3_10_%1
137     mov  r0, r0m
138     mov  r1, r1m
139     lea  r0, [r0+r2*%4+%4*2]
140     lea  r1, [r1+r2*%4+%4*2]
141     call stub_%2_h264_qpel%4_%3_10_%1
142     RET
143 %else ; ARCH_X86_64
144 cglobal %2_h264_qpel%5_%3_10_%1, %6,%7 + 2,%8
145     mov r%7, r0
146 %assign p1 %7+1
147     mov r %+ p1, r1
148     call stub_%2_h264_qpel%4_%3_10_%1
149     lea  r0, [r%7+%4*2]
150     lea  r1, [r %+ p1+%4*2]
151     call stub_%2_h264_qpel%4_%3_10_%1
152     lea  r0, [r%7+r2*%4]
153     lea  r1, [r %+ p1+r2*%4]
154     call stub_%2_h264_qpel%4_%3_10_%1
155     lea  r0, [r%7+r2*%4+%4*2]
156     lea  r1, [r %+ p1+r2*%4+%4*2]
157 %if UNIX64 == 0 ; fall through to function
158     call stub_%2_h264_qpel%4_%3_10_%1
159     RET
160 %endif
161 %endif
162 %endmacro
163
164 ;cpu, put/avg, mc, 4/8, ...
165 %macro cglobal_mc 7
166 %assign i %4*2
167 MCAxA %1, %2, %3, %4, i, %5,%6,%7
168
169 cglobal %2_h264_qpel%4_%3_10_%1, %5,%6,%7
170 %if UNIX64 == 0 ; no prologue or epilogue for UNIX64
171     call stub_%2_h264_qpel%4_%3_10_%1
172     RET
173 %endif
174
175 stub_%2_h264_qpel%4_%3_10_%1:
176 %endmacro
177
178 ;-----------------------------------------------------------------------------
179 ; void h264_qpel_mc00(uint8_t *dst, uint8_t *src, int stride)
180 ;-----------------------------------------------------------------------------
181 %macro COPY4 0
182     movu          m0, [r1     ]
183     OP_MOV [r0     ], m0
184     movu          m0, [r1+r2  ]
185     OP_MOV [r0+r2  ], m0
186     movu          m0, [r1+r2*2]
187     OP_MOV [r0+r2*2], m0
188     movu          m0, [r1+r3  ]
189     OP_MOV [r0+r3  ], m0
190 %endmacro
191
192 %macro MC00 1
193 INIT_MMX
194 cglobal_mc mmxext, %1, mc00, 4, 3,4,0
195     lea           r3, [r2*3]
196     COPY4
197     ret
198
199 INIT_XMM
200 cglobal %1_h264_qpel8_mc00_10_sse2, 3,4
201     lea  r3, [r2*3]
202     COPY4
203     lea  r0, [r0+r2*4]
204     lea  r1, [r1+r2*4]
205     COPY4
206     RET
207
208 cglobal %1_h264_qpel16_mc00_10_sse2, 3,4
209     mov r3d, 8
210 .loop:
211     movu           m0, [r1      ]
212     movu           m1, [r1   +16]
213     OP_MOV [r0      ], m0
214     OP_MOV [r0   +16], m1
215     movu           m0, [r1+r2   ]
216     movu           m1, [r1+r2+16]
217     OP_MOV [r0+r2   ], m0
218     OP_MOV [r0+r2+16], m1
219     lea            r0, [r0+r2*2]
220     lea            r1, [r1+r2*2]
221     dec r3d
222     jg .loop
223     REP_RET
224 %endmacro
225
226 %define OP_MOV mova
227 MC00 put
228
229 %define OP_MOV AVG_MOV
230 MC00 avg
231
232 ;-----------------------------------------------------------------------------
233 ; void h264_qpel_mc20(uint8_t *dst, uint8_t *src, int stride)
234 ;-----------------------------------------------------------------------------
235 %macro MC_CACHE 1
236 %define OP_MOV mova
237 %define PALIGNR PALIGNR_MMX
238 INIT_MMX
239 %1 mmxext       , put, 4
240 INIT_XMM
241 %1 sse2_cache64 , put, 8
242 %define PALIGNR PALIGNR_SSSE3
243 %1 ssse3_cache64, put, 8
244 %1 sse2         , put, 8, 0
245
246 %define OP_MOV AVG_MOV
247 %define PALIGNR PALIGNR_MMX
248 INIT_MMX
249 %1 mmxext       , avg, 4
250 INIT_XMM
251 %1 sse2_cache64 , avg, 8
252 %define PALIGNR PALIGNR_SSSE3
253 %1 ssse3_cache64, avg, 8
254 %1 sse2         , avg, 8, 0
255 %endmacro
256
257 %macro MC20 3-4
258 cglobal_mc %1, %2, mc20, %3, 3,4,9
259     mov     r3d, %3
260     mova     m1, [pw_pixel_max]
261 %if num_mmregs > 8
262     mova     m8, [pw_16]
263     %define p16 m8
264 %else
265     %define p16 [pw_16]
266 %endif
267 .nextrow
268 %if %0 == 4
269     movu     m2, [r1-4]
270     movu     m3, [r1-2]
271     movu     m4, [r1+0]
272     ADDW     m2, [r1+6], m5
273     ADDW     m3, [r1+4], m5
274     ADDW     m4, [r1+2], m5
275 %else ; movu is slow on these processors
276 %if mmsize==16
277     movu     m2, [r1-4]
278     movu     m0, [r1+6]
279     mova     m6, m0
280     psrldq   m0, 6
281
282     paddw    m6, m2
283     PALIGNR  m3, m0, m2, 2, m5
284     PALIGNR  m7, m0, m2, 8, m5
285     paddw    m3, m7
286     PALIGNR  m4, m0, m2, 4, m5
287     PALIGNR  m7, m0, m2, 6, m5
288     paddw    m4, m7
289     SWAP      2, 6
290 %else
291     movu     m2, [r1-4]
292     movu     m6, [r1+4]
293     PALIGNR  m3, m6, m2, 2, m5
294     paddw    m3, m6
295     PALIGNR  m4, m6, m2, 4, m5
296     PALIGNR  m7, m6, m2, 6, m5
297     paddw    m4, m7
298     paddw    m2, [r1+6]
299 %endif
300 %endif
301
302     FILT_H   m2, m3, m4, p16
303     psraw    m2, 1
304     pxor     m0, m0
305     CLIPW    m2, m0, m1
306     OP_MOV [r0], m2
307     add      r0, r2
308     add      r1, r2
309     dec     r3d
310     jg .nextrow
311     rep ret
312 %endmacro
313
314 MC_CACHE MC20
315
316 ;-----------------------------------------------------------------------------
317 ; void h264_qpel_mc30(uint8_t *dst, uint8_t *src, int stride)
318 ;-----------------------------------------------------------------------------
319 %macro MC30 3-4
320 cglobal_mc %1, %2, mc30, %3, 3,5,9
321     lea r4, [r1+2]
322     jmp stub_%2_h264_qpel%3_mc10_10_%1.body
323 %endmacro
324
325 MC_CACHE MC30
326
327 ;-----------------------------------------------------------------------------
328 ; void h264_qpel_mc10(uint8_t *dst, uint8_t *src, int stride)
329 ;-----------------------------------------------------------------------------
330 %macro MC10 3-4
331 cglobal_mc %1, %2, mc10, %3, 3,5,9
332     mov      r4, r1
333 .body
334     mov     r3d, %3
335     mova     m1, [pw_pixel_max]
336 %if num_mmregs > 8
337     mova     m8, [pw_16]
338     %define p16 m8
339 %else
340     %define p16 [pw_16]
341 %endif
342 .nextrow
343 %if %0 == 4
344     movu     m2, [r1-4]
345     movu     m3, [r1-2]
346     movu     m4, [r1+0]
347     ADDW     m2, [r1+6], m5
348     ADDW     m3, [r1+4], m5
349     ADDW     m4, [r1+2], m5
350 %else ; movu is slow on these processors
351 %if mmsize==16
352     movu     m2, [r1-4]
353     movu     m0, [r1+6]
354     mova     m6, m0
355     psrldq   m0, 6
356
357     paddw    m6, m2
358     PALIGNR  m3, m0, m2, 2, m5
359     PALIGNR  m7, m0, m2, 8, m5
360     paddw    m3, m7
361     PALIGNR  m4, m0, m2, 4, m5
362     PALIGNR  m7, m0, m2, 6, m5
363     paddw    m4, m7
364     SWAP      2, 6
365 %else
366     movu     m2, [r1-4]
367     movu     m6, [r1+4]
368     PALIGNR  m3, m6, m2, 2, m5
369     paddw    m3, m6
370     PALIGNR  m4, m6, m2, 4, m5
371     PALIGNR  m7, m6, m2, 6, m5
372     paddw    m4, m7
373     paddw    m2, [r1+6]
374 %endif
375 %endif
376
377     FILT_H   m2, m3, m4, p16
378     psraw    m2, 1
379     pxor     m0, m0
380     CLIPW    m2, m0, m1
381     movu     m3, [r4]
382     pavgw    m2, m3
383     OP_MOV [r0], m2
384     add      r0, r2
385     add      r1, r2
386     add      r4, r2
387     dec     r3d
388     jg .nextrow
389     rep ret
390 %endmacro
391
392 MC_CACHE MC10
393
394 ;-----------------------------------------------------------------------------
395 ; void h264_qpel_mc02(uint8_t *dst, uint8_t *src, int stride)
396 ;-----------------------------------------------------------------------------
397 %macro V_FILT 11
398 v_filt%9_%10_10_%11:
399     add    r4, r2
400 .no_addr4:
401     FILT_V m0, m1, m2, m3, m4, m5, m6, m7
402     add    r1, r2
403     add    r0, r2
404     ret
405 %endmacro
406
407 INIT_MMX
408 RESET_MM_PERMUTATION
409 %assign i 0
410 %rep 4
411 V_FILT m0, m1, m2, m3, m4, m5, m6, m7, 4, i, mmxext
412 SWAP 0,1,2,3,4,5
413 %assign i i+1
414 %endrep
415
416 INIT_XMM
417 RESET_MM_PERMUTATION
418 %assign i 0
419 %rep 6
420 V_FILT m0, m1, m2, m3, m4, m5, m6, m7, 8, i, sse2
421 SWAP 0,1,2,3,4,5
422 %assign i i+1
423 %endrep
424
425 %macro MC02 3
426 cglobal_mc %1, %2, mc02, %3, 3,4,8
427     PRELOAD_V
428
429     sub      r0, r2
430 %assign j 0
431 %rep %3
432     %assign i (j % 6)
433     call v_filt%3_ %+ i %+ _10_%1.no_addr4
434     OP_MOV [r0], m0
435     SWAP 0,1,2,3,4,5
436     %assign j j+1
437 %endrep
438     ret
439 %endmacro
440
441 MC MC02
442
443 ;-----------------------------------------------------------------------------
444 ; void h264_qpel_mc01(uint8_t *dst, uint8_t *src, int stride)
445 ;-----------------------------------------------------------------------------
446 %macro MC01 3
447 cglobal_mc %1, %2, mc01, %3, 3,5,8
448     mov      r4, r1
449 .body
450     PRELOAD_V
451
452     sub      r4, r2
453     sub      r0, r2
454 %assign j 0
455 %rep %3
456     %assign i (j % 6)
457     call v_filt%3_ %+ i %+ _10_%1
458     movu     m7, [r4]
459     pavgw    m0, m7
460     OP_MOV [r0], m0
461     SWAP 0,1,2,3,4,5
462     %assign j j+1
463 %endrep
464     ret
465 %endmacro
466
467 MC MC01
468
469 ;-----------------------------------------------------------------------------
470 ; void h264_qpel_mc03(uint8_t *dst, uint8_t *src, int stride)
471 ;-----------------------------------------------------------------------------
472 %macro MC03 3
473 cglobal_mc %1, %2, mc03, %3, 3,5,8
474     lea r4, [r1+r2]
475     jmp stub_%2_h264_qpel%3_mc01_10_%1.body
476 %endmacro
477
478 MC MC03
479
480 ;-----------------------------------------------------------------------------
481 ; void h264_qpel_mc11(uint8_t *dst, uint8_t *src, int stride)
482 ;-----------------------------------------------------------------------------
483 %macro H_FILT_AVG 3-4
484 h_filt%2_%3_10_%1:
485 ;FILT_H with fewer registers and averaged with the FILT_V result
486 ;m6,m7 are tmp registers, m0 is the FILT_V result, the rest are to be used next in the next iteration
487 ;unfortunately I need three registers, so m5 will have to be re-read from memory
488     movu     m5, [r4-4]
489     ADDW     m5, [r4+6], m7
490     movu     m6, [r4-2]
491     ADDW     m6, [r4+4], m7
492     paddw    m5, [pw_16]
493     psubw    m5, m6  ; a-b
494     psraw    m5, 2   ; (a-b)/4
495     psubw    m5, m6  ; (a-b)/4-b
496     movu     m6, [r4+0]
497     ADDW     m6, [r4+2], m7
498     paddw    m5, m6  ; (a-b)/4-b+c
499     psraw    m5, 2   ; ((a-b)/4-b+c)/4
500     paddw    m5, m6  ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
501     psraw    m5, 1
502     CLIPW    m5, [pb_0], [pw_pixel_max]
503 ;avg FILT_V, FILT_H
504     pavgw    m0, m5
505 %if %0!=4
506     movu     m5, [r1+r5]
507 %endif
508     ret
509 %endmacro
510
511 INIT_MMX
512 RESET_MM_PERMUTATION
513 %assign i 0
514 %rep 3
515 H_FILT_AVG mmxext, 4, i
516 SWAP 0,1,2,3,4,5
517 %assign i i+1
518 %endrep
519 H_FILT_AVG mmxext, 4, i, 0
520
521 INIT_XMM
522 RESET_MM_PERMUTATION
523 %assign i 0
524 %rep 6
525 %if i==1
526 H_FILT_AVG sse2,   8, i, 0
527 %else
528 H_FILT_AVG sse2,   8, i
529 %endif
530 SWAP 0,1,2,3,4,5
531 %assign i i+1
532 %endrep
533
534 %macro MC11 3
535 ; this REALLY needs x86_64
536 cglobal_mc %1, %2, mc11, %3, 3,6,8
537     mov      r4, r1
538 .body
539     PRELOAD_V
540
541     sub      r0, r2
542     sub      r4, r2
543     mov      r5, r2
544     neg      r5
545 %assign j 0
546 %rep %3
547     %assign i (j % 6)
548     call v_filt%3_ %+ i %+ _10_%1
549     call h_filt%3_ %+ i %+ _10_%1
550 %if %3==8 && i==1
551     movu     m5, [r1+r5]
552 %endif
553     OP_MOV [r0], m0
554     SWAP 0,1,2,3,4,5
555     %assign j j+1
556 %endrep
557     ret
558 %endmacro
559
560 MC MC11
561
562 ;-----------------------------------------------------------------------------
563 ; void h264_qpel_mc31(uint8_t *dst, uint8_t *src, int stride)
564 ;-----------------------------------------------------------------------------
565 %macro MC31 3
566 cglobal_mc %1, %2, mc31, %3, 3,6,8
567     mov r4, r1
568     add r1, 2
569     jmp stub_%2_h264_qpel%3_mc11_10_%1.body
570 %endmacro
571
572 MC MC31
573
574 ;-----------------------------------------------------------------------------
575 ; void h264_qpel_mc13(uint8_t *dst, uint8_t *src, int stride)
576 ;-----------------------------------------------------------------------------
577 %macro MC13 3
578 cglobal_mc %1, %2, mc13, %3, 3,7,12
579     lea r4, [r1+r2]
580     jmp stub_%2_h264_qpel%3_mc11_10_%1.body
581 %endmacro
582
583 MC MC13
584
585 ;-----------------------------------------------------------------------------
586 ; void h264_qpel_mc33(uint8_t *dst, uint8_t *src, int stride)
587 ;-----------------------------------------------------------------------------
588 %macro MC33 3
589 cglobal_mc %1, %2, mc33, %3, 3,6,8
590     lea r4, [r1+r2]
591     add r1, 2
592     jmp stub_%2_h264_qpel%3_mc11_10_%1.body
593 %endmacro
594
595 MC MC33
596
597 ;-----------------------------------------------------------------------------
598 ; void h264_qpel_mc22(uint8_t *dst, uint8_t *src, int stride)
599 ;-----------------------------------------------------------------------------
600 %macro FILT_H2 3
601     psubw  %1, %2  ; a-b
602     psubw  %2, %3  ; b-c
603     psllw  %2, 2
604     psubw  %1, %2  ; a-5*b+4*c
605     psllw  %3, 4
606     paddw  %1, %3  ; a-5*b+20*c
607 %endmacro
608
609 %macro FILT_VNRD 8
610     movu     %6, [r1]
611     paddw    %1, %6
612     mova     %7, %2
613     paddw    %7, %5
614     mova     %8, %3
615     paddw    %8, %4
616     FILT_H2  %1, %7, %8
617 %endmacro
618
619 %macro HV 2
620 %ifidn %1,sse2
621 %define PAD 12
622 %define COUNT 2
623 %else
624 %define PAD 4
625 %define COUNT 3
626 %endif
627 put_hv%2_10_%1:
628     neg      r2           ; This actually saves instructions
629     lea      r1, [r1+r2*2-mmsize+PAD]
630     lea      r4, [rsp+PAD+gprsize]
631     mov     r3d, COUNT
632 .v_loop:
633     movu     m0, [r1]
634     sub      r1, r2
635     movu     m1, [r1]
636     sub      r1, r2
637     movu     m2, [r1]
638     sub      r1, r2
639     movu     m3, [r1]
640     sub      r1, r2
641     movu     m4, [r1]
642     sub      r1, r2
643 %assign i 0
644 %rep %2-1
645     FILT_VNRD m0, m1, m2, m3, m4, m5, m6, m7
646     psubw    m0, [pad20]
647     movu     [r4+i*mmsize*3], m0
648     sub      r1, r2
649     SWAP 0,1,2,3,4,5
650 %assign i i+1
651 %endrep
652     FILT_VNRD m0, m1, m2, m3, m4, m5, m6, m7
653     psubw    m0, [pad20]
654     movu     [r4+i*mmsize*3], m0
655     add      r4, mmsize
656     lea      r1, [r1+r2*8+mmsize]
657 %if %2==8
658     lea      r1, [r1+r2*4]
659 %endif
660     dec      r3d
661     jg .v_loop
662     neg      r2
663     ret
664 %endmacro
665
666 INIT_MMX
667 HV mmxext, 4
668 INIT_XMM
669 HV sse2  , 8
670
671 %macro H_LOOP 2
672 %if num_mmregs > 8
673     %define s1 m8
674     %define s2 m9
675     %define s3 m10
676     %define d1 m11
677 %else
678     %define s1 [tap1]
679     %define s2 [tap2]
680     %define s3 [tap3]
681     %define d1 [depad]
682 %endif
683 h%2_loop_op_%1:
684     movu       m1, [r1+mmsize-4]
685     movu       m2, [r1+mmsize-2]
686     mova       m3, [r1+mmsize+0]
687     movu       m4, [r1+mmsize+2]
688     movu       m5, [r1+mmsize+4]
689     movu       m6, [r1+mmsize+6]
690 %if num_mmregs > 8
691     pmaddwd    m1, s1
692     pmaddwd    m2, s1
693     pmaddwd    m3, s2
694     pmaddwd    m4, s2
695     pmaddwd    m5, s3
696     pmaddwd    m6, s3
697     paddd      m1, d1
698     paddd      m2, d1
699 %else
700     mova       m0, s1
701     pmaddwd    m1, m0
702     pmaddwd    m2, m0
703     mova       m0, s2
704     pmaddwd    m3, m0
705     pmaddwd    m4, m0
706     mova       m0, s3
707     pmaddwd    m5, m0
708     pmaddwd    m6, m0
709     mova       m0, d1
710     paddd      m1, m0
711     paddd      m2, m0
712 %endif
713     paddd      m3, m5
714     paddd      m4, m6
715     paddd      m1, m3
716     paddd      m2, m4
717     psrad      m1, 10
718     psrad      m2, 10
719     pslld      m2, 16
720     pand       m1, [pd_0f]
721     por        m1, m2
722 %if num_mmregs <= 8
723     pxor       m0, m0
724 %endif
725     CLIPW      m1, m0, m7
726     add        r1, mmsize*3
727     ret
728 %endmacro
729
730 INIT_MMX
731 H_LOOP mmxext, 4
732 INIT_XMM
733 H_LOOP sse2  , 8
734
735 %macro MC22 3
736 cglobal_mc %1, %2, mc22, %3, 3,7,12
737 %define PAD mmsize*8*4*2      ; SIZE*16*4*sizeof(pixel)
738     mov      r6, rsp          ; backup stack pointer
739     and     rsp, ~(mmsize-1)  ; align stack
740     sub     rsp, PAD
741
742     call put_hv%3_10_%1
743
744     mov       r3d, %3
745     mova       m7, [pw_pixel_max]
746 %if num_mmregs > 8
747     pxor       m0, m0
748     mova       m8, [tap1]
749     mova       m9, [tap2]
750     mova      m10, [tap3]
751     mova      m11, [depad]
752 %endif
753     mov        r1, rsp
754 .h_loop:
755     call h%3_loop_op_%1
756
757     OP_MOV   [r0], m1
758     add        r0, r2
759     dec       r3d
760     jg .h_loop
761
762     mov     rsp, r6          ; restore stack pointer
763     ret
764 %endmacro
765
766 MC MC22
767
768 ;-----------------------------------------------------------------------------
769 ; void h264_qpel_mc12(uint8_t *dst, uint8_t *src, int stride)
770 ;-----------------------------------------------------------------------------
771 %macro MC12 3
772 cglobal_mc %1, %2, mc12, %3, 3,7,12
773 %define PAD mmsize*8*4*2        ; SIZE*16*4*sizeof(pixel)
774     mov        r6, rsp          ; backup stack pointer
775     and       rsp, ~(mmsize-1)  ; align stack
776     sub       rsp, PAD
777
778     call put_hv%3_10_%1
779
780     xor       r4d, r4d
781 .body
782     mov       r3d, %3
783     pxor       m0, m0
784     mova       m7, [pw_pixel_max]
785 %if num_mmregs > 8
786     mova       m8, [tap1]
787     mova       m9, [tap2]
788     mova      m10, [tap3]
789     mova      m11, [depad]
790 %endif
791     mov        r1, rsp
792 .h_loop:
793     call h%3_loop_op_%1
794
795     movu       m3, [r1+r4-2*mmsize] ; movu needed for mc32, etc
796     paddw      m3, [depad2]
797     psrlw      m3, 5
798     psubw      m3, [unpad]
799     CLIPW      m3, m0, m7
800     pavgw      m1, m3
801
802     OP_MOV   [r0], m1
803     add        r0, r2
804     dec       r3d
805     jg .h_loop
806
807     mov     rsp, r6          ; restore stack pointer
808     ret
809 %endmacro
810
811 MC MC12
812
813 ;-----------------------------------------------------------------------------
814 ; void h264_qpel_mc32(uint8_t *dst, uint8_t *src, int stride)
815 ;-----------------------------------------------------------------------------
816 %macro MC32 3
817 cglobal_mc %1, %2, mc32, %3, 3,7,12
818 %define PAD mmsize*8*3*2  ; SIZE*16*4*sizeof(pixel)
819     mov  r6, rsp          ; backup stack pointer
820     and rsp, ~(mmsize-1)  ; align stack
821     sub rsp, PAD
822
823     call put_hv%3_10_%1
824
825     mov r4d, 2            ; sizeof(pixel)
826     jmp stub_%2_h264_qpel%3_mc12_10_%1.body
827 %endmacro
828
829 MC MC32
830
831 ;-----------------------------------------------------------------------------
832 ; void h264_qpel_mc21(uint8_t *dst, uint8_t *src, int stride)
833 ;-----------------------------------------------------------------------------
834 %macro H_NRD 2
835 put_h%2_10_%1:
836     add       rsp, gprsize
837     mov       r3d, %2
838     xor       r4d, r4d
839     mova       m6, [pad20]
840 .nextrow
841     movu       m2, [r5-4]
842     movu       m3, [r5-2]
843     movu       m4, [r5+0]
844     ADDW       m2, [r5+6], m5
845     ADDW       m3, [r5+4], m5
846     ADDW       m4, [r5+2], m5
847
848     FILT_H2    m2, m3, m4
849     psubw      m2, m6
850     mova [rsp+r4], m2
851     add       r4d, mmsize*3
852     add        r5, r2
853     dec       r3d
854     jg .nextrow
855     sub       rsp, gprsize
856     ret
857 %endmacro
858
859 INIT_MMX
860 H_NRD mmxext, 4
861 INIT_XMM
862 H_NRD sse2  , 8
863
864 %macro MC21 3
865 cglobal_mc %1, %2, mc21, %3, 3,7,12
866     mov   r5, r1
867 .body
868 %define PAD mmsize*8*3*2   ; SIZE*16*4*sizeof(pixel)
869     mov   r6, rsp          ; backup stack pointer
870     and  rsp, ~(mmsize-1)  ; align stack
871
872     sub  rsp, PAD
873     call put_h%3_10_%1
874
875     sub  rsp, PAD
876     call put_hv%3_10_%1
877
878     mov r4d, PAD-mmsize    ; H buffer
879     jmp stub_%2_h264_qpel%3_mc12_10_%1.body
880 %endmacro
881
882 MC MC21
883
884 ;-----------------------------------------------------------------------------
885 ; void h264_qpel_mc23(uint8_t *dst, uint8_t *src, int stride)
886 ;-----------------------------------------------------------------------------
887 %macro MC23 3
888 cglobal_mc %1, %2, mc23, %3, 3,7,12
889     lea   r5, [r1+r2]
890     jmp stub_%2_h264_qpel%3_mc21_10_%1.body
891 %endmacro
892
893 MC MC23