]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/dsputil.asm
lavfi/vignette: remove extra semi-colon.
[ffmpeg] / libavcodec / x86 / dsputil.asm
1 ;******************************************************************************
2 ;* MMX optimized DSP utils
3 ;* Copyright (c) 2008 Loren Merritt
4 ;* Copyright (c) 2003-2013 Michael Niedermayer
5 ;* Copyright (c) 2013 Daniel Kang
6 ;*
7 ;* This file is part of FFmpeg.
8 ;*
9 ;* FFmpeg is free software; you can redistribute it and/or
10 ;* modify it under the terms of the GNU Lesser General Public
11 ;* License as published by the Free Software Foundation; either
12 ;* version 2.1 of the License, or (at your option) any later version.
13 ;*
14 ;* FFmpeg is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 ;* Lesser General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU Lesser General Public
20 ;* License along with FFmpeg; if not, write to the Free Software
21 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 ;******************************************************************************
23
24 %include "libavutil/x86/x86util.asm"
25
26 SECTION_RODATA
27 pb_f: times 16 db 15
28 pb_zzzzzzzz77777777: times 8 db -1
29 pb_7: times 8 db 7
30 pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11
31 pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13
32 pb_revwords: SHUFFLE_MASK_W 7, 6, 5, 4, 3, 2, 1, 0
33 pd_16384: times 4 dd 16384
34 pb_bswap32: db 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
35
36 SECTION_TEXT
37
38 %macro SCALARPRODUCT 0
39 ; int scalarproduct_int16(int16_t *v1, int16_t *v2, int order)
40 cglobal scalarproduct_int16, 3,3,3, v1, v2, order
41     shl orderq, 1
42     add v1q, orderq
43     add v2q, orderq
44     neg orderq
45     pxor    m2, m2
46 .loop:
47     movu    m0, [v1q + orderq]
48     movu    m1, [v1q + orderq + mmsize]
49     pmaddwd m0, [v2q + orderq]
50     pmaddwd m1, [v2q + orderq + mmsize]
51     paddd   m2, m0
52     paddd   m2, m1
53     add     orderq, mmsize*2
54     jl .loop
55 %if mmsize == 16
56     movhlps m0, m2
57     paddd   m2, m0
58     pshuflw m0, m2, 0x4e
59 %else
60     pshufw  m0, m2, 0x4e
61 %endif
62     paddd   m2, m0
63     movd   eax, m2
64     RET
65
66 ; int scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul)
67 cglobal scalarproduct_and_madd_int16, 4,4,8, v1, v2, v3, order, mul
68     shl orderq, 1
69     movd    m7, mulm
70 %if mmsize == 16
71     pshuflw m7, m7, 0
72     punpcklqdq m7, m7
73 %else
74     pshufw  m7, m7, 0
75 %endif
76     pxor    m6, m6
77     add v1q, orderq
78     add v2q, orderq
79     add v3q, orderq
80     neg orderq
81 .loop:
82     movu    m0, [v2q + orderq]
83     movu    m1, [v2q + orderq + mmsize]
84     mova    m4, [v1q + orderq]
85     mova    m5, [v1q + orderq + mmsize]
86     movu    m2, [v3q + orderq]
87     movu    m3, [v3q + orderq + mmsize]
88     pmaddwd m0, m4
89     pmaddwd m1, m5
90     pmullw  m2, m7
91     pmullw  m3, m7
92     paddd   m6, m0
93     paddd   m6, m1
94     paddw   m2, m4
95     paddw   m3, m5
96     mova    [v1q + orderq], m2
97     mova    [v1q + orderq + mmsize], m3
98     add     orderq, mmsize*2
99     jl .loop
100 %if mmsize == 16
101     movhlps m0, m6
102     paddd   m6, m0
103     pshuflw m0, m6, 0x4e
104 %else
105     pshufw  m0, m6, 0x4e
106 %endif
107     paddd   m6, m0
108     movd   eax, m6
109     RET
110 %endmacro
111
112 INIT_MMX mmxext
113 SCALARPRODUCT
114 INIT_XMM sse2
115 SCALARPRODUCT
116
117 %macro SCALARPRODUCT_LOOP 1
118 align 16
119 .loop%1:
120     sub     orderq, mmsize*2
121 %if %1
122     mova    m1, m4
123     mova    m4, [v2q + orderq]
124     mova    m0, [v2q + orderq + mmsize]
125     palignr m1, m0, %1
126     palignr m0, m4, %1
127     mova    m3, m5
128     mova    m5, [v3q + orderq]
129     mova    m2, [v3q + orderq + mmsize]
130     palignr m3, m2, %1
131     palignr m2, m5, %1
132 %else
133     mova    m0, [v2q + orderq]
134     mova    m1, [v2q + orderq + mmsize]
135     mova    m2, [v3q + orderq]
136     mova    m3, [v3q + orderq + mmsize]
137 %endif
138     %define t0  [v1q + orderq]
139     %define t1  [v1q + orderq + mmsize]
140 %if ARCH_X86_64
141     mova    m8, t0
142     mova    m9, t1
143     %define t0  m8
144     %define t1  m9
145 %endif
146     pmaddwd m0, t0
147     pmaddwd m1, t1
148     pmullw  m2, m7
149     pmullw  m3, m7
150     paddw   m2, t0
151     paddw   m3, t1
152     paddd   m6, m0
153     paddd   m6, m1
154     mova    [v1q + orderq], m2
155     mova    [v1q + orderq + mmsize], m3
156     jg .loop%1
157 %if %1
158     jmp .end
159 %endif
160 %endmacro
161
162 ; int scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul)
163 INIT_XMM ssse3
164 cglobal scalarproduct_and_madd_int16, 4,5,10, v1, v2, v3, order, mul
165     shl orderq, 1
166     movd    m7, mulm
167     pshuflw m7, m7, 0
168     punpcklqdq m7, m7
169     pxor    m6, m6
170     mov    r4d, v2d
171     and    r4d, 15
172     and    v2q, ~15
173     and    v3q, ~15
174     mova    m4, [v2q + orderq]
175     mova    m5, [v3q + orderq]
176     ; linear is faster than branch tree or jump table, because the branches taken are cyclic (i.e. predictable)
177     cmp    r4d, 0
178     je .loop0
179     cmp    r4d, 2
180     je .loop2
181     cmp    r4d, 4
182     je .loop4
183     cmp    r4d, 6
184     je .loop6
185     cmp    r4d, 8
186     je .loop8
187     cmp    r4d, 10
188     je .loop10
189     cmp    r4d, 12
190     je .loop12
191 SCALARPRODUCT_LOOP 14
192 SCALARPRODUCT_LOOP 12
193 SCALARPRODUCT_LOOP 10
194 SCALARPRODUCT_LOOP 8
195 SCALARPRODUCT_LOOP 6
196 SCALARPRODUCT_LOOP 4
197 SCALARPRODUCT_LOOP 2
198 SCALARPRODUCT_LOOP 0
199 .end:
200     movhlps m0, m6
201     paddd   m6, m0
202     pshuflw m0, m6, 0x4e
203     paddd   m6, m0
204     movd   eax, m6
205     RET
206
207
208 ;-----------------------------------------------------------------------------
209 ; void ff_apply_window_int16(int16_t *output, const int16_t *input,
210 ;                            const int16_t *window, unsigned int len)
211 ;-----------------------------------------------------------------------------
212
213 %macro REVERSE_WORDS 1-2
214 %if cpuflag(ssse3) && notcpuflag(atom)
215     pshufb  %1, %2
216 %elif cpuflag(sse2)
217     pshuflw  %1, %1, 0x1B
218     pshufhw  %1, %1, 0x1B
219     pshufd   %1, %1, 0x4E
220 %elif cpuflag(mmxext)
221     pshufw   %1, %1, 0x1B
222 %endif
223 %endmacro
224
225 %macro MUL16FIXED 3
226 %if cpuflag(ssse3) ; dst, src, unused
227 ; dst = ((dst * src) + (1<<14)) >> 15
228     pmulhrsw   %1, %2
229 %elif cpuflag(mmxext) ; dst, src, temp
230 ; dst = (dst * src) >> 15
231 ; pmulhw cuts off the bottom bit, so we have to lshift by 1 and add it back
232 ; in from the pmullw result.
233     mova    %3, %1
234     pmulhw  %1, %2
235     pmullw  %3, %2
236     psrlw   %3, 15
237     psllw   %1, 1
238     por     %1, %3
239 %endif
240 %endmacro
241
242 %macro APPLY_WINDOW_INT16 1 ; %1 bitexact version
243 %if %1
244 cglobal apply_window_int16, 4,5,6, output, input, window, offset, offset2
245 %else
246 cglobal apply_window_int16_round, 4,5,6, output, input, window, offset, offset2
247 %endif
248     lea     offset2q, [offsetq-mmsize]
249 %if cpuflag(ssse3) && notcpuflag(atom)
250     mova          m5, [pb_revwords]
251     ALIGN 16
252 %elif %1
253     mova          m5, [pd_16384]
254 %endif
255 .loop:
256 %if cpuflag(ssse3)
257     ; This version does the 16x16->16 multiplication in-place without expanding
258     ; to 32-bit. The ssse3 version is bit-identical.
259     mova          m0, [windowq+offset2q]
260     mova          m1, [ inputq+offset2q]
261     pmulhrsw      m1, m0
262     REVERSE_WORDS m0, m5
263     pmulhrsw      m0, [ inputq+offsetq ]
264     mova  [outputq+offset2q], m1
265     mova  [outputq+offsetq ], m0
266 %elif %1
267     ; This version expands 16-bit to 32-bit, multiplies by the window,
268     ; adds 16384 for rounding, right shifts 15, then repacks back to words to
269     ; save to the output. The window is reversed for the second half.
270     mova          m3, [windowq+offset2q]
271     mova          m4, [ inputq+offset2q]
272     pxor          m0, m0
273     punpcklwd     m0, m3
274     punpcklwd     m1, m4
275     pmaddwd       m0, m1
276     paddd         m0, m5
277     psrad         m0, 15
278     pxor          m2, m2
279     punpckhwd     m2, m3
280     punpckhwd     m1, m4
281     pmaddwd       m2, m1
282     paddd         m2, m5
283     psrad         m2, 15
284     packssdw      m0, m2
285     mova  [outputq+offset2q], m0
286     REVERSE_WORDS m3
287     mova          m4, [ inputq+offsetq]
288     pxor          m0, m0
289     punpcklwd     m0, m3
290     punpcklwd     m1, m4
291     pmaddwd       m0, m1
292     paddd         m0, m5
293     psrad         m0, 15
294     pxor          m2, m2
295     punpckhwd     m2, m3
296     punpckhwd     m1, m4
297     pmaddwd       m2, m1
298     paddd         m2, m5
299     psrad         m2, 15
300     packssdw      m0, m2
301     mova  [outputq+offsetq], m0
302 %else
303     ; This version does the 16x16->16 multiplication in-place without expanding
304     ; to 32-bit. The mmxext and sse2 versions do not use rounding, and
305     ; therefore are not bit-identical to the C version.
306     mova          m0, [windowq+offset2q]
307     mova          m1, [ inputq+offset2q]
308     mova          m2, [ inputq+offsetq ]
309     MUL16FIXED    m1, m0, m3
310     REVERSE_WORDS m0
311     MUL16FIXED    m2, m0, m3
312     mova  [outputq+offset2q], m1
313     mova  [outputq+offsetq ], m2
314 %endif
315     add      offsetd, mmsize
316     sub     offset2d, mmsize
317     jae .loop
318     REP_RET
319 %endmacro
320
321 INIT_MMX mmxext
322 APPLY_WINDOW_INT16 0
323 INIT_XMM sse2
324 APPLY_WINDOW_INT16 0
325
326 INIT_MMX mmxext
327 APPLY_WINDOW_INT16 1
328 INIT_XMM sse2
329 APPLY_WINDOW_INT16 1
330 INIT_XMM ssse3
331 APPLY_WINDOW_INT16 1
332 INIT_XMM ssse3, atom
333 APPLY_WINDOW_INT16 1
334
335
336 ; void add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top)
337 INIT_MMX mmxext
338 cglobal add_hfyu_median_prediction, 6,6,0, dst, top, diff, w, left, left_top
339     movq    mm0, [topq]
340     movq    mm2, mm0
341     movd    mm4, [left_topq]
342     psllq   mm2, 8
343     movq    mm1, mm0
344     por     mm4, mm2
345     movd    mm3, [leftq]
346     psubb   mm0, mm4 ; t-tl
347     add    dstq, wq
348     add    topq, wq
349     add   diffq, wq
350     neg      wq
351     jmp .skip
352 .loop:
353     movq    mm4, [topq+wq]
354     movq    mm0, mm4
355     psllq   mm4, 8
356     por     mm4, mm1
357     movq    mm1, mm0 ; t
358     psubb   mm0, mm4 ; t-tl
359 .skip:
360     movq    mm2, [diffq+wq]
361 %assign i 0
362 %rep 8
363     movq    mm4, mm0
364     paddb   mm4, mm3 ; t-tl+l
365     movq    mm5, mm3
366     pmaxub  mm3, mm1
367     pminub  mm5, mm1
368     pminub  mm3, mm4
369     pmaxub  mm3, mm5 ; median
370     paddb   mm3, mm2 ; +residual
371 %if i==0
372     movq    mm7, mm3
373     psllq   mm7, 56
374 %else
375     movq    mm6, mm3
376     psrlq   mm7, 8
377     psllq   mm6, 56
378     por     mm7, mm6
379 %endif
380 %if i<7
381     psrlq   mm0, 8
382     psrlq   mm1, 8
383     psrlq   mm2, 8
384 %endif
385 %assign i i+1
386 %endrep
387     movq [dstq+wq], mm7
388     add      wq, 8
389     jl .loop
390     movzx   r2d, byte [dstq-1]
391     mov [leftq], r2d
392     movzx   r2d, byte [topq-1]
393     mov [left_topq], r2d
394     RET
395
396
397 %macro ADD_HFYU_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
398     add     srcq, wq
399     add     dstq, wq
400     neg     wq
401 %%.loop:
402 %if %2
403     mova    m1, [srcq+wq]
404 %else
405     movu    m1, [srcq+wq]
406 %endif
407     mova    m2, m1
408     psllw   m1, 8
409     paddb   m1, m2
410     mova    m2, m1
411     pshufb  m1, m3
412     paddb   m1, m2
413     pshufb  m0, m5
414     mova    m2, m1
415     pshufb  m1, m4
416     paddb   m1, m2
417 %if mmsize == 16
418     mova    m2, m1
419     pshufb  m1, m6
420     paddb   m1, m2
421 %endif
422     paddb   m0, m1
423 %if %1
424     mova    [dstq+wq], m0
425 %else
426     movq    [dstq+wq], m0
427     movhps  [dstq+wq+8], m0
428 %endif
429     add     wq, mmsize
430     jl %%.loop
431     mov     eax, mmsize-1
432     sub     eax, wd
433     movd    m1, eax
434     pshufb  m0, m1
435     movd    eax, m0
436     RET
437 %endmacro
438
439 ; int add_hfyu_left_prediction(uint8_t *dst, const uint8_t *src, int w, int left)
440 INIT_MMX ssse3
441 cglobal add_hfyu_left_prediction, 3,3,7, dst, src, w, left
442 .skip_prologue:
443     mova    m5, [pb_7]
444     mova    m4, [pb_zzzz3333zzzzbbbb]
445     mova    m3, [pb_zz11zz55zz99zzdd]
446     movd    m0, leftm
447     psllq   m0, 56
448     ADD_HFYU_LEFT_LOOP 1, 1
449
450 INIT_XMM sse4
451 cglobal add_hfyu_left_prediction, 3,3,7, dst, src, w, left
452     mova    m5, [pb_f]
453     mova    m6, [pb_zzzzzzzz77777777]
454     mova    m4, [pb_zzzz3333zzzzbbbb]
455     mova    m3, [pb_zz11zz55zz99zzdd]
456     movd    m0, leftm
457     pslldq  m0, 15
458     test    srcq, 15
459     jnz .src_unaligned
460     test    dstq, 15
461     jnz .dst_unaligned
462     ADD_HFYU_LEFT_LOOP 1, 1
463 .dst_unaligned:
464     ADD_HFYU_LEFT_LOOP 0, 1
465 .src_unaligned:
466     ADD_HFYU_LEFT_LOOP 0, 0
467
468 ;-----------------------------------------------------------------------------
469 ; void ff_vector_clip_int32(int32_t *dst, const int32_t *src, int32_t min,
470 ;                           int32_t max, unsigned int len)
471 ;-----------------------------------------------------------------------------
472
473 ; %1 = number of xmm registers used
474 ; %2 = number of inline load/process/store loops per asm loop
475 ; %3 = process 4*mmsize (%3=0) or 8*mmsize (%3=1) bytes per loop
476 ; %4 = CLIPD function takes min/max as float instead of int (CLIPD_SSE2)
477 ; %5 = suffix
478 %macro VECTOR_CLIP_INT32 4-5
479 cglobal vector_clip_int32%5, 5,5,%1, dst, src, min, max, len
480 %if %4
481     cvtsi2ss  m4, minm
482     cvtsi2ss  m5, maxm
483 %else
484     movd      m4, minm
485     movd      m5, maxm
486 %endif
487     SPLATD    m4
488     SPLATD    m5
489 .loop:
490 %assign %%i 1
491 %rep %2
492     mova      m0,  [srcq+mmsize*0*%%i]
493     mova      m1,  [srcq+mmsize*1*%%i]
494     mova      m2,  [srcq+mmsize*2*%%i]
495     mova      m3,  [srcq+mmsize*3*%%i]
496 %if %3
497     mova      m7,  [srcq+mmsize*4*%%i]
498     mova      m8,  [srcq+mmsize*5*%%i]
499     mova      m9,  [srcq+mmsize*6*%%i]
500     mova      m10, [srcq+mmsize*7*%%i]
501 %endif
502     CLIPD  m0,  m4, m5, m6
503     CLIPD  m1,  m4, m5, m6
504     CLIPD  m2,  m4, m5, m6
505     CLIPD  m3,  m4, m5, m6
506 %if %3
507     CLIPD  m7,  m4, m5, m6
508     CLIPD  m8,  m4, m5, m6
509     CLIPD  m9,  m4, m5, m6
510     CLIPD  m10, m4, m5, m6
511 %endif
512     mova  [dstq+mmsize*0*%%i], m0
513     mova  [dstq+mmsize*1*%%i], m1
514     mova  [dstq+mmsize*2*%%i], m2
515     mova  [dstq+mmsize*3*%%i], m3
516 %if %3
517     mova  [dstq+mmsize*4*%%i], m7
518     mova  [dstq+mmsize*5*%%i], m8
519     mova  [dstq+mmsize*6*%%i], m9
520     mova  [dstq+mmsize*7*%%i], m10
521 %endif
522 %assign %%i %%i+1
523 %endrep
524     add     srcq, mmsize*4*(%2+%3)
525     add     dstq, mmsize*4*(%2+%3)
526     sub     lend, mmsize*(%2+%3)
527     jg .loop
528     REP_RET
529 %endmacro
530
531 INIT_MMX mmx
532 %define CLIPD CLIPD_MMX
533 VECTOR_CLIP_INT32 0, 1, 0, 0
534 INIT_XMM sse2
535 VECTOR_CLIP_INT32 6, 1, 0, 0, _int
536 %define CLIPD CLIPD_SSE2
537 VECTOR_CLIP_INT32 6, 2, 0, 1
538 INIT_XMM sse4
539 %define CLIPD CLIPD_SSE41
540 %ifdef m8
541 VECTOR_CLIP_INT32 11, 1, 1, 0
542 %else
543 VECTOR_CLIP_INT32 6, 1, 0, 0
544 %endif
545
546 ; %1 = aligned/unaligned
547 %macro BSWAP_LOOPS  1
548     mov      r3, r2
549     sar      r2, 3
550     jz       .left4_%1
551 .loop8_%1:
552     mov%1    m0, [r1 +  0]
553     mov%1    m1, [r1 + 16]
554 %if cpuflag(ssse3)
555     pshufb   m0, m2
556     pshufb   m1, m2
557     mov%1    [r0 +  0], m0
558     mov%1    [r0 + 16], m1
559 %else
560     pshuflw  m0, m0, 10110001b
561     pshuflw  m1, m1, 10110001b
562     pshufhw  m0, m0, 10110001b
563     pshufhw  m1, m1, 10110001b
564     mova     m2, m0
565     mova     m3, m1
566     psllw    m0, 8
567     psllw    m1, 8
568     psrlw    m2, 8
569     psrlw    m3, 8
570     por      m2, m0
571     por      m3, m1
572     mov%1    [r0 +  0], m2
573     mov%1    [r0 + 16], m3
574 %endif
575     add      r0, 32
576     add      r1, 32
577     dec      r2
578     jnz      .loop8_%1
579 .left4_%1:
580     mov      r2, r3
581     and      r3, 4
582     jz       .left
583     mov%1    m0, [r1]
584 %if cpuflag(ssse3)
585     pshufb   m0, m2
586     mov%1    [r0], m0
587 %else
588     pshuflw  m0, m0, 10110001b
589     pshufhw  m0, m0, 10110001b
590     mova     m2, m0
591     psllw    m0, 8
592     psrlw    m2, 8
593     por      m2, m0
594     mov%1    [r0], m2
595 %endif
596     add      r1, 16
597     add      r0, 16
598 %endmacro
599
600 ; void bswap_buf(uint32_t *dst, const uint32_t *src, int w);
601 %macro BSWAP32_BUF 0
602 %if cpuflag(ssse3)
603 cglobal bswap32_buf, 3,4,3
604     mov      r3, r1
605     mova     m2, [pb_bswap32]
606 %else
607 cglobal bswap32_buf, 3,4,5
608     mov      r3, r1
609 %endif
610     or       r3, r0
611     and      r3, 15
612     jz       .start_align
613     BSWAP_LOOPS  u
614     jmp      .left
615 .start_align:
616     BSWAP_LOOPS  a
617 .left:
618 %if cpuflag(ssse3)
619     mov      r3, r2
620     and      r2, 2
621     jz       .left1
622     movq     m0, [r1]
623     pshufb   m0, m2
624     movq     [r0], m0
625     add      r1, 8
626     add      r0, 8
627 .left1:
628     and      r3, 1
629     jz       .end
630     mov      r2d, [r1]
631     bswap    r2d
632     mov      [r0], r2d
633 %else
634     and      r2, 3
635     jz       .end
636 .loop2:
637     mov      r3d, [r1]
638     bswap    r3d
639     mov      [r0], r3d
640     add      r1, 4
641     add      r0, 4
642     dec      r2
643     jnz      .loop2
644 %endif
645 .end:
646     RET
647 %endmacro
648
649 INIT_XMM sse2
650 BSWAP32_BUF
651
652 INIT_XMM ssse3
653 BSWAP32_BUF