Merge commit '57b5b84e208ad61ffdd74ad849bed212deb92bc5'
[ffmpeg.git] / 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_bswap32: db 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
33
34 SECTION_TEXT
35
36 %macro SCALARPRODUCT 0
37 ; int ff_scalarproduct_int16(int16_t *v1, int16_t *v2, int order)
38 cglobal scalarproduct_int16, 3,3,3, v1, v2, order
39     shl orderq, 1
40     add v1q, orderq
41     add v2q, orderq
42     neg orderq
43     pxor    m2, m2
44 .loop:
45     movu    m0, [v1q + orderq]
46     movu    m1, [v1q + orderq + mmsize]
47     pmaddwd m0, [v2q + orderq]
48     pmaddwd m1, [v2q + orderq + mmsize]
49     paddd   m2, m0
50     paddd   m2, m1
51     add     orderq, mmsize*2
52     jl .loop
53 %if mmsize == 16
54     movhlps m0, m2
55     paddd   m2, m0
56     pshuflw m0, m2, 0x4e
57 %else
58     pshufw  m0, m2, 0x4e
59 %endif
60     paddd   m2, m0
61     movd   eax, m2
62 %if mmsize == 8
63     emms
64 %endif
65     RET
66
67 ; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3,
68 ;                                     int order, int mul)
69 cglobal scalarproduct_and_madd_int16, 4,4,8, v1, v2, v3, order, mul
70     shl orderq, 1
71     movd    m7, mulm
72 %if mmsize == 16
73     pshuflw m7, m7, 0
74     punpcklqdq m7, m7
75 %else
76     pshufw  m7, m7, 0
77 %endif
78     pxor    m6, m6
79     add v1q, orderq
80     add v2q, orderq
81     add v3q, orderq
82     neg orderq
83 .loop:
84     movu    m0, [v2q + orderq]
85     movu    m1, [v2q + orderq + mmsize]
86     mova    m4, [v1q + orderq]
87     mova    m5, [v1q + orderq + mmsize]
88     movu    m2, [v3q + orderq]
89     movu    m3, [v3q + orderq + mmsize]
90     pmaddwd m0, m4
91     pmaddwd m1, m5
92     pmullw  m2, m7
93     pmullw  m3, m7
94     paddd   m6, m0
95     paddd   m6, m1
96     paddw   m2, m4
97     paddw   m3, m5
98     mova    [v1q + orderq], m2
99     mova    [v1q + orderq + mmsize], m3
100     add     orderq, mmsize*2
101     jl .loop
102 %if mmsize == 16
103     movhlps m0, m6
104     paddd   m6, m0
105     pshuflw m0, m6, 0x4e
106 %else
107     pshufw  m0, m6, 0x4e
108 %endif
109     paddd   m6, m0
110     movd   eax, m6
111     RET
112 %endmacro
113
114 INIT_MMX mmxext
115 SCALARPRODUCT
116 INIT_XMM sse2
117 SCALARPRODUCT
118
119 %macro SCALARPRODUCT_LOOP 1
120 align 16
121 .loop%1:
122     sub     orderq, mmsize*2
123 %if %1
124     mova    m1, m4
125     mova    m4, [v2q + orderq]
126     mova    m0, [v2q + orderq + mmsize]
127     palignr m1, m0, %1
128     palignr m0, m4, %1
129     mova    m3, m5
130     mova    m5, [v3q + orderq]
131     mova    m2, [v3q + orderq + mmsize]
132     palignr m3, m2, %1
133     palignr m2, m5, %1
134 %else
135     mova    m0, [v2q + orderq]
136     mova    m1, [v2q + orderq + mmsize]
137     mova    m2, [v3q + orderq]
138     mova    m3, [v3q + orderq + mmsize]
139 %endif
140     %define t0  [v1q + orderq]
141     %define t1  [v1q + orderq + mmsize]
142 %if ARCH_X86_64
143     mova    m8, t0
144     mova    m9, t1
145     %define t0  m8
146     %define t1  m9
147 %endif
148     pmaddwd m0, t0
149     pmaddwd m1, t1
150     pmullw  m2, m7
151     pmullw  m3, m7
152     paddw   m2, t0
153     paddw   m3, t1
154     paddd   m6, m0
155     paddd   m6, m1
156     mova    [v1q + orderq], m2
157     mova    [v1q + orderq + mmsize], m3
158     jg .loop%1
159 %if %1
160     jmp .end
161 %endif
162 %endmacro
163
164 ; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3,
165 ;                                     int order, int mul)
166 INIT_XMM ssse3
167 cglobal scalarproduct_and_madd_int16, 4,5,10, v1, v2, v3, order, mul
168     shl orderq, 1
169     movd    m7, mulm
170     pshuflw m7, m7, 0
171     punpcklqdq m7, m7
172     pxor    m6, m6
173     mov    r4d, v2d
174     and    r4d, 15
175     and    v2q, ~15
176     and    v3q, ~15
177     mova    m4, [v2q + orderq]
178     mova    m5, [v3q + orderq]
179     ; linear is faster than branch tree or jump table, because the branches taken are cyclic (i.e. predictable)
180     cmp    r4d, 0
181     je .loop0
182     cmp    r4d, 2
183     je .loop2
184     cmp    r4d, 4
185     je .loop4
186     cmp    r4d, 6
187     je .loop6
188     cmp    r4d, 8
189     je .loop8
190     cmp    r4d, 10
191     je .loop10
192     cmp    r4d, 12
193     je .loop12
194 SCALARPRODUCT_LOOP 14
195 SCALARPRODUCT_LOOP 12
196 SCALARPRODUCT_LOOP 10
197 SCALARPRODUCT_LOOP 8
198 SCALARPRODUCT_LOOP 6
199 SCALARPRODUCT_LOOP 4
200 SCALARPRODUCT_LOOP 2
201 SCALARPRODUCT_LOOP 0
202 .end:
203     movhlps m0, m6
204     paddd   m6, m0
205     pshuflw m0, m6, 0x4e
206     paddd   m6, m0
207     movd   eax, m6
208     RET
209
210
211 ; void ff_add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top,
212 ;                                           const uint8_t *diff, int w,
213 ;                                           int *left, int *left_top)
214 INIT_MMX mmxext
215 cglobal add_hfyu_median_prediction, 6,6,0, dst, top, diff, w, left, left_top
216     movq    mm0, [topq]
217     movq    mm2, mm0
218     movd    mm4, [left_topq]
219     psllq   mm2, 8
220     movq    mm1, mm0
221     por     mm4, mm2
222     movd    mm3, [leftq]
223     psubb   mm0, mm4 ; t-tl
224     add    dstq, wq
225     add    topq, wq
226     add   diffq, wq
227     neg      wq
228     jmp .skip
229 .loop:
230     movq    mm4, [topq+wq]
231     movq    mm0, mm4
232     psllq   mm4, 8
233     por     mm4, mm1
234     movq    mm1, mm0 ; t
235     psubb   mm0, mm4 ; t-tl
236 .skip:
237     movq    mm2, [diffq+wq]
238 %assign i 0
239 %rep 8
240     movq    mm4, mm0
241     paddb   mm4, mm3 ; t-tl+l
242     movq    mm5, mm3
243     pmaxub  mm3, mm1
244     pminub  mm5, mm1
245     pminub  mm3, mm4
246     pmaxub  mm3, mm5 ; median
247     paddb   mm3, mm2 ; +residual
248 %if i==0
249     movq    mm7, mm3
250     psllq   mm7, 56
251 %else
252     movq    mm6, mm3
253     psrlq   mm7, 8
254     psllq   mm6, 56
255     por     mm7, mm6
256 %endif
257 %if i<7
258     psrlq   mm0, 8
259     psrlq   mm1, 8
260     psrlq   mm2, 8
261 %endif
262 %assign i i+1
263 %endrep
264     movq [dstq+wq], mm7
265     add      wq, 8
266     jl .loop
267     movzx   r2d, byte [dstq-1]
268     mov [leftq], r2d
269     movzx   r2d, byte [topq-1]
270     mov [left_topq], r2d
271     RET
272
273
274 %macro ADD_HFYU_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
275     add     srcq, wq
276     add     dstq, wq
277     neg     wq
278 %%.loop:
279 %if %2
280     mova    m1, [srcq+wq]
281 %else
282     movu    m1, [srcq+wq]
283 %endif
284     mova    m2, m1
285     psllw   m1, 8
286     paddb   m1, m2
287     mova    m2, m1
288     pshufb  m1, m3
289     paddb   m1, m2
290     pshufb  m0, m5
291     mova    m2, m1
292     pshufb  m1, m4
293     paddb   m1, m2
294 %if mmsize == 16
295     mova    m2, m1
296     pshufb  m1, m6
297     paddb   m1, m2
298 %endif
299     paddb   m0, m1
300 %if %1
301     mova    [dstq+wq], m0
302 %else
303     movq    [dstq+wq], m0
304     movhps  [dstq+wq+8], m0
305 %endif
306     add     wq, mmsize
307     jl %%.loop
308     mov     eax, mmsize-1
309     sub     eax, wd
310     movd    m1, eax
311     pshufb  m0, m1
312     movd    eax, m0
313     RET
314 %endmacro
315
316 ; int ff_add_hfyu_left_prediction(uint8_t *dst, const uint8_t *src,
317 ;                                 int w, int left)
318 INIT_MMX ssse3
319 cglobal add_hfyu_left_prediction, 3,3,7, dst, src, w, left
320 .skip_prologue:
321     mova    m5, [pb_7]
322     mova    m4, [pb_zzzz3333zzzzbbbb]
323     mova    m3, [pb_zz11zz55zz99zzdd]
324     movd    m0, leftm
325     psllq   m0, 56
326     ADD_HFYU_LEFT_LOOP 1, 1
327
328 INIT_XMM sse4
329 cglobal add_hfyu_left_prediction, 3,3,7, dst, src, w, left
330     mova    m5, [pb_f]
331     mova    m6, [pb_zzzzzzzz77777777]
332     mova    m4, [pb_zzzz3333zzzzbbbb]
333     mova    m3, [pb_zz11zz55zz99zzdd]
334     movd    m0, leftm
335     pslldq  m0, 15
336     test    srcq, 15
337     jnz .src_unaligned
338     test    dstq, 15
339     jnz .dst_unaligned
340     ADD_HFYU_LEFT_LOOP 1, 1
341 .dst_unaligned:
342     ADD_HFYU_LEFT_LOOP 0, 1
343 .src_unaligned:
344     ADD_HFYU_LEFT_LOOP 0, 0
345
346
347 ;-----------------------------------------------------------------------------
348 ; void ff_vector_clip_int32(int32_t *dst, const int32_t *src, int32_t min,
349 ;                           int32_t max, unsigned int len)
350 ;-----------------------------------------------------------------------------
351
352 ; %1 = number of xmm registers used
353 ; %2 = number of inline load/process/store loops per asm loop
354 ; %3 = process 4*mmsize (%3=0) or 8*mmsize (%3=1) bytes per loop
355 ; %4 = CLIPD function takes min/max as float instead of int (CLIPD_SSE2)
356 ; %5 = suffix
357 %macro VECTOR_CLIP_INT32 4-5
358 cglobal vector_clip_int32%5, 5,5,%1, dst, src, min, max, len
359 %if %4
360     cvtsi2ss  m4, minm
361     cvtsi2ss  m5, maxm
362 %else
363     movd      m4, minm
364     movd      m5, maxm
365 %endif
366     SPLATD    m4
367     SPLATD    m5
368 .loop:
369 %assign %%i 1
370 %rep %2
371     mova      m0,  [srcq+mmsize*0*%%i]
372     mova      m1,  [srcq+mmsize*1*%%i]
373     mova      m2,  [srcq+mmsize*2*%%i]
374     mova      m3,  [srcq+mmsize*3*%%i]
375 %if %3
376     mova      m7,  [srcq+mmsize*4*%%i]
377     mova      m8,  [srcq+mmsize*5*%%i]
378     mova      m9,  [srcq+mmsize*6*%%i]
379     mova      m10, [srcq+mmsize*7*%%i]
380 %endif
381     CLIPD  m0,  m4, m5, m6
382     CLIPD  m1,  m4, m5, m6
383     CLIPD  m2,  m4, m5, m6
384     CLIPD  m3,  m4, m5, m6
385 %if %3
386     CLIPD  m7,  m4, m5, m6
387     CLIPD  m8,  m4, m5, m6
388     CLIPD  m9,  m4, m5, m6
389     CLIPD  m10, m4, m5, m6
390 %endif
391     mova  [dstq+mmsize*0*%%i], m0
392     mova  [dstq+mmsize*1*%%i], m1
393     mova  [dstq+mmsize*2*%%i], m2
394     mova  [dstq+mmsize*3*%%i], m3
395 %if %3
396     mova  [dstq+mmsize*4*%%i], m7
397     mova  [dstq+mmsize*5*%%i], m8
398     mova  [dstq+mmsize*6*%%i], m9
399     mova  [dstq+mmsize*7*%%i], m10
400 %endif
401 %assign %%i %%i+1
402 %endrep
403     add     srcq, mmsize*4*(%2+%3)
404     add     dstq, mmsize*4*(%2+%3)
405     sub     lend, mmsize*(%2+%3)
406     jg .loop
407     REP_RET
408 %endmacro
409
410 INIT_MMX mmx
411 %define CLIPD CLIPD_MMX
412 VECTOR_CLIP_INT32 0, 1, 0, 0
413 INIT_XMM sse2
414 VECTOR_CLIP_INT32 6, 1, 0, 0, _int
415 %define CLIPD CLIPD_SSE2
416 VECTOR_CLIP_INT32 6, 2, 0, 1
417 INIT_XMM sse4
418 %define CLIPD CLIPD_SSE41
419 %ifdef m8
420 VECTOR_CLIP_INT32 11, 1, 1, 0
421 %else
422 VECTOR_CLIP_INT32 6, 1, 0, 0
423 %endif
424
425 ; %1 = aligned/unaligned
426 %macro BSWAP_LOOPS  1
427     mov      r3, r2
428     sar      r2, 3
429     jz       .left4_%1
430 .loop8_%1:
431     mov%1    m0, [r1 +  0]
432     mov%1    m1, [r1 + 16]
433 %if cpuflag(ssse3)
434     pshufb   m0, m2
435     pshufb   m1, m2
436     mov%1    [r0 +  0], m0
437     mov%1    [r0 + 16], m1
438 %else
439     pshuflw  m0, m0, 10110001b
440     pshuflw  m1, m1, 10110001b
441     pshufhw  m0, m0, 10110001b
442     pshufhw  m1, m1, 10110001b
443     mova     m2, m0
444     mova     m3, m1
445     psllw    m0, 8
446     psllw    m1, 8
447     psrlw    m2, 8
448     psrlw    m3, 8
449     por      m2, m0
450     por      m3, m1
451     mov%1    [r0 +  0], m2
452     mov%1    [r0 + 16], m3
453 %endif
454     add      r0, 32
455     add      r1, 32
456     dec      r2
457     jnz      .loop8_%1
458 .left4_%1:
459     mov      r2, r3
460     and      r3, 4
461     jz       .left
462     mov%1    m0, [r1]
463 %if cpuflag(ssse3)
464     pshufb   m0, m2
465     mov%1    [r0], m0
466 %else
467     pshuflw  m0, m0, 10110001b
468     pshufhw  m0, m0, 10110001b
469     mova     m2, m0
470     psllw    m0, 8
471     psrlw    m2, 8
472     por      m2, m0
473     mov%1    [r0], m2
474 %endif
475     add      r1, 16
476     add      r0, 16
477 %endmacro
478
479 ; void ff_bswap_buf(uint32_t *dst, const uint32_t *src, int w);
480 %macro BSWAP32_BUF 0
481 %if cpuflag(ssse3)
482 cglobal bswap32_buf, 3,4,3
483     mov      r3, r1
484     mova     m2, [pb_bswap32]
485 %else
486 cglobal bswap32_buf, 3,4,5
487     mov      r3, r1
488 %endif
489     or       r3, r0
490     and      r3, 15
491     jz       .start_align
492     BSWAP_LOOPS  u
493     jmp      .left
494 .start_align:
495     BSWAP_LOOPS  a
496 .left:
497 %if cpuflag(ssse3)
498     mov      r3, r2
499     and      r2, 2
500     jz       .left1
501     movq     m0, [r1]
502     pshufb   m0, m2
503     movq     [r0], m0
504     add      r1, 8
505     add      r0, 8
506 .left1:
507     and      r3, 1
508     jz       .end
509     mov      r2d, [r1]
510     bswap    r2d
511     mov      [r0], r2d
512 %else
513     and      r2, 3
514     jz       .end
515 .loop2:
516     mov      r3d, [r1]
517     bswap    r3d
518     mov      [r0], r3d
519     add      r1, 4
520     add      r0, 4
521     dec      r2
522     jnz      .loop2
523 %endif
524 .end:
525     RET
526 %endmacro
527
528 INIT_XMM sse2
529 BSWAP32_BUF
530
531 INIT_XMM ssse3
532 BSWAP32_BUF