avcodec/x86/lossless_videodsp : add avx2 version for add_left_pred
[ffmpeg.git] / libavcodec / x86 / lossless_videodsp.asm
1 ;******************************************************************************
2 ;* SIMD lossless video DSP utils
3 ;* Copyright (c) 2008 Loren Merritt
4 ;* Copyright (c) 2014 Michael Niedermayer
5 ;*
6 ;* This file is part of FFmpeg.
7 ;*
8 ;* FFmpeg is free software; you can redistribute it and/or
9 ;* modify it under the terms of the GNU Lesser General Public
10 ;* License as published by the Free Software Foundation; either
11 ;* version 2.1 of the License, or (at your option) any later version.
12 ;*
13 ;* FFmpeg is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ;* Lesser General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU Lesser General Public
19 ;* License along with FFmpeg; if not, write to the Free Software
20 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;******************************************************************************
22
23 %include "libavutil/x86/x86util.asm"
24
25 SECTION_RODATA
26
27 cextern pb_15
28 pb_zzzzzzzz77777777: times 8 db -1
29 pb_7: times 8 db 7
30 pb_ef: times 8 db 14,15
31 pb_67: times 8 db  6, 7
32 pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11
33 pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13
34 pb_zzzz2323zzzzabab: db -1,-1,-1,-1, 2, 3, 2, 3,-1,-1,-1,-1,10,11,10,11
35 pb_zzzzzzzz67676767: db -1,-1,-1,-1,-1,-1,-1,-1, 6, 7, 6, 7, 6, 7, 6, 7
36
37 SECTION .text
38
39 ;------------------------------------------------------------------------------
40 ; void ff_add_median_pred_mmxext(uint8_t *dst, const uint8_t *top,
41 ;                                const uint8_t *diff, int w,
42 ;                                int *left, int *left_top)
43 ;------------------------------------------------------------------------------
44 %macro MEDIAN_PRED 0
45 cglobal add_median_pred, 6,6,8, dst, top, diff, w, left, left_top
46     movu    m0, [topq]
47     mova    m2, m0
48     movd    m4, [left_topq]
49     LSHIFT  m2, 1
50     mova    m1, m0
51     por     m4, m2
52     movd    m3, [leftq]
53     psubb   m0, m4 ; t-tl
54     add    dstq, wq
55     add    topq, wq
56     add   diffq, wq
57     neg      wq
58     jmp .skip
59 .loop:
60     movu    m4, [topq+wq]
61     mova    m0, m4
62     LSHIFT  m4, 1
63     por     m4, m1
64     mova    m1, m0 ; t
65     psubb   m0, m4 ; t-tl
66 .skip:
67     movu    m2, [diffq+wq]
68 %assign i 0
69 %rep mmsize
70     mova    m4, m0
71     paddb   m4, m3 ; t-tl+l
72     mova    m5, m3
73     pmaxub  m3, m1
74     pminub  m5, m1
75     pminub  m3, m4
76     pmaxub  m3, m5 ; median
77     paddb   m3, m2 ; +residual
78 %if i==0
79     mova    m7, m3
80     LSHIFT  m7, mmsize-1
81 %else
82     mova    m6, m3
83     RSHIFT  m7, 1
84     LSHIFT  m6, mmsize-1
85     por     m7, m6
86 %endif
87 %if i<mmsize-1
88     RSHIFT  m0, 1
89     RSHIFT  m1, 1
90     RSHIFT  m2, 1
91 %endif
92 %assign i i+1
93 %endrep
94     movu [dstq+wq], m7
95     add      wq, mmsize
96     jl .loop
97     movzx   r2d, byte [dstq-1]
98     mov [leftq], r2d
99     movzx   r2d, byte [topq-1]
100     mov [left_topq], r2d
101     RET
102 %endmacro
103
104 %if ARCH_X86_32
105 INIT_MMX mmxext
106 MEDIAN_PRED
107 %endif
108 INIT_XMM sse2
109 MEDIAN_PRED
110
111
112 %macro ADD_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
113     add     srcq, wq
114     add     dstq, wq
115     neg     wq
116 %%.loop:
117     pshufb  xm0, xm5
118 %if %2
119     mova    m1, [srcq+wq]
120 %else
121     movu    m1, [srcq+wq]
122 %endif
123     psllw   m2, m1, 8
124     paddb   m1, m2
125     pshufb  m2, m1, m3
126     paddb   m1, m2
127     pshufb  m2, m1, m4
128     paddb   m1, m2
129 %if mmsize >= 16
130     pshufb  m2, m1, m6
131     paddb   m1, m2
132 %endif
133     paddb   xm0, xm1
134 %if %1
135     mova    [dstq+wq], xm0
136 %else
137     movq    [dstq+wq], xm0
138     movhps  [dstq+wq+8], xm0
139 %endif
140
141 %if mmsize == 32
142     vextracti128    xm2, m1, 1 ; get second lane of the ymm
143     pshufb          xm0, xm5   ; set alls val to last val of the first lane
144     paddb           xm0, xm2
145 ;store val
146 %if %1
147     mova    [dstq+wq+16], xm0
148 %else;
149     movq    [dstq+wq+16], xm0
150     movhps  [dstq+wq+16+8], xm0
151 %endif
152 %endif
153     add     wq, mmsize
154     jl %%.loop
155 %if mmsize == 32
156     mov    eax, [dstq -1]
157     and    eax, 0xff
158 %else;
159     mov     eax, mmsize-1
160     sub     eax, wd
161     movd    m1, eax
162     pshufb  m0, m1
163     movd    eax, m0
164 %endif
165     RET
166 %endmacro
167
168 ;------------------------------------------------------------------------------
169 ; int ff_add_left_pred(uint8_t *dst, const uint8_t *src, int w, int left)
170 ;------------------------------------------------------------------------------
171 INIT_MMX ssse3
172 cglobal add_left_pred, 3,3,7, dst, src, w, left
173 .skip_prologue:
174     mova    m5, [pb_7]
175     mova    m4, [pb_zzzz3333zzzzbbbb]
176     mova    m3, [pb_zz11zz55zz99zzdd]
177     movd    m0, leftm
178     psllq   m0, 56
179     ADD_LEFT_LOOP 1, 1
180
181 %macro ADD_LEFT_PRED_UNALIGNED 0
182 cglobal add_left_pred_unaligned, 3,3,7, dst, src, w, left
183     mova    xm5, [pb_15]
184     VBROADCASTI128    m6, [pb_zzzzzzzz77777777]
185     VBROADCASTI128    m4, [pb_zzzz3333zzzzbbbb]
186     VBROADCASTI128    m3, [pb_zz11zz55zz99zzdd]
187     movd    xm0, leftm
188     pslldq  xm0, 15
189     test    srcq, mmsize - 1
190     jnz .src_unaligned
191     test    dstq, mmsize - 1
192     jnz .dst_unaligned
193     ADD_LEFT_LOOP 1, 1
194 .dst_unaligned:
195     ADD_LEFT_LOOP 0, 1
196 .src_unaligned:
197     ADD_LEFT_LOOP 0, 0
198 %endmacro
199
200 INIT_XMM ssse3
201 ADD_LEFT_PRED_UNALIGNED
202
203 %if HAVE_AVX2_EXTERNAL
204 INIT_YMM avx2
205 ADD_LEFT_PRED_UNALIGNED
206 %endif
207
208 ;------------------------------------------------------------------------------
209 ; void ff_add_bytes(uint8_t *dst, uint8_t *src, ptrdiff_t w);
210 ;------------------------------------------------------------------------------
211 %macro ADD_BYTES 0
212 cglobal add_bytes, 3,4,2, dst, src, w, size
213     mov  sizeq, wq
214     and  sizeq, -2*mmsize
215     jz  .2
216     add   dstq, sizeq
217     add   srcq, sizeq
218     neg  sizeq
219 .1:
220     mova    m0, [srcq + sizeq]
221     mova    m1, [srcq + sizeq + mmsize]
222     paddb   m0, [dstq + sizeq]
223     paddb   m1, [dstq + sizeq + mmsize]
224     mova   [dstq + sizeq], m0
225     mova   [dstq + sizeq + mmsize], m1
226     add  sizeq, 2*mmsize
227     jl .1
228 .2:
229     and     wq, 2*mmsize-1
230     jz    .end
231     add   dstq, wq
232     add   srcq, wq
233     neg     wq
234 .3:
235     mov  sizeb, [srcq + wq]
236     add [dstq + wq], sizeb
237     inc     wq
238     jl .3
239 .end:
240     REP_RET
241 %endmacro
242
243 %if ARCH_X86_32
244 INIT_MMX mmx
245 ADD_BYTES
246 %endif
247 INIT_XMM sse2
248 ADD_BYTES
249
250 %if HAVE_AVX2_EXTERNAL
251 INIT_YMM avx2
252 ADD_BYTES
253 %endif
254
255 %macro ADD_HFYU_LEFT_LOOP_INT16 2 ; %1 = dst alignment (a/u), %2 = src alignment (a/u)
256     add     wd, wd
257     add     srcq, wq
258     add     dstq, wq
259     neg     wq
260 %%.loop:
261     mov%2   m1, [srcq+wq]
262     mova    m2, m1
263     pslld   m1, 16
264     paddw   m1, m2
265     mova    m2, m1
266
267     pshufb  m1, m3
268     paddw   m1, m2
269     pshufb  m0, m5
270 %if mmsize == 16
271     mova    m2, m1
272     pshufb  m1, m4
273     paddw   m1, m2
274 %endif
275     paddw   m0, m1
276     pand    m0, m7
277 %ifidn %1, a
278     mova    [dstq+wq], m0
279 %else
280     movq    [dstq+wq], m0
281     movhps  [dstq+wq+8], m0
282 %endif
283     add     wq, mmsize
284     jl %%.loop
285     mov     eax, mmsize-1
286     sub     eax, wd
287     mov     wd, eax
288     shl     wd, 8
289     lea     eax, [wd+eax-1]
290     movd    m1, eax
291     pshufb  m0, m1
292     movd    eax, m0
293     RET
294 %endmacro
295
296 ;---------------------------------------------------------------------------------------------
297 ; int add_left_pred_int16(uint16_t *dst, const uint16_t *src, unsigned mask, int w, int left)
298 ;---------------------------------------------------------------------------------------------
299 INIT_MMX ssse3
300 cglobal add_left_pred_int16, 4,4,8, dst, src, mask, w, left
301 .skip_prologue:
302     mova    m5, [pb_67]
303     mova    m3, [pb_zzzz2323zzzzabab]
304     movd    m0, leftm
305     psllq   m0, 48
306     movd    m7, maskm
307     SPLATW  m7 ,m7
308     ADD_HFYU_LEFT_LOOP_INT16 a, a
309
310 INIT_XMM sse4
311 cglobal add_left_pred_int16, 4,4,8, dst, src, mask, w, left
312     mova    m5, [pb_ef]
313     mova    m4, [pb_zzzzzzzz67676767]
314     mova    m3, [pb_zzzz2323zzzzabab]
315     movd    m0, leftm
316     pslldq  m0, 14
317     movd    m7, maskm
318     SPLATW  m7 ,m7
319     test    srcq, 15
320     jnz .src_unaligned
321     test    dstq, 15
322     jnz .dst_unaligned
323     ADD_HFYU_LEFT_LOOP_INT16 a, a
324 .dst_unaligned:
325     ADD_HFYU_LEFT_LOOP_INT16 u, a
326 .src_unaligned:
327     ADD_HFYU_LEFT_LOOP_INT16 u, u