Merge commit 'd06dfaa5cbdd20acfd2364b16c0f4ae4ddb30a65'
[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 ; void ff_add_median_pred_mmxext(uint8_t *dst, const uint8_t *top,
40 ;                                const uint8_t *diff, int w,
41 ;                                int *left, int *left_top)
42 %macro MEDIAN_PRED 0
43 cglobal add_median_pred, 6,6,8, dst, top, diff, w, left, left_top
44     movu    m0, [topq]
45     mova    m2, m0
46     movd    m4, [left_topq]
47     LSHIFT  m2, 1
48     mova    m1, m0
49     por     m4, m2
50     movd    m3, [leftq]
51     psubb   m0, m4 ; t-tl
52     add    dstq, wq
53     add    topq, wq
54     add   diffq, wq
55     neg      wq
56     jmp .skip
57 .loop:
58     movu    m4, [topq+wq]
59     mova    m0, m4
60     LSHIFT  m4, 1
61     por     m4, m1
62     mova    m1, m0 ; t
63     psubb   m0, m4 ; t-tl
64 .skip:
65     movu    m2, [diffq+wq]
66 %assign i 0
67 %rep mmsize
68     mova    m4, m0
69     paddb   m4, m3 ; t-tl+l
70     mova    m5, m3
71     pmaxub  m3, m1
72     pminub  m5, m1
73     pminub  m3, m4
74     pmaxub  m3, m5 ; median
75     paddb   m3, m2 ; +residual
76 %if i==0
77     mova    m7, m3
78     LSHIFT  m7, mmsize-1
79 %else
80     mova    m6, m3
81     RSHIFT  m7, 1
82     LSHIFT  m6, mmsize-1
83     por     m7, m6
84 %endif
85 %if i<mmsize-1
86     RSHIFT  m0, 1
87     RSHIFT  m1, 1
88     RSHIFT  m2, 1
89 %endif
90 %assign i i+1
91 %endrep
92     movu [dstq+wq], m7
93     add      wq, mmsize
94     jl .loop
95     movzx   r2d, byte [dstq-1]
96     mov [leftq], r2d
97     movzx   r2d, byte [topq-1]
98     mov [left_topq], r2d
99     RET
100 %endmacro
101
102 %if ARCH_X86_32
103 INIT_MMX mmxext
104 MEDIAN_PRED
105 %endif
106 INIT_XMM sse2
107 MEDIAN_PRED
108
109
110 %macro ADD_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
111     add     srcq, wq
112     add     dstq, wq
113     neg     wq
114 %%.loop:
115 %if %2
116     mova    m1, [srcq+wq]
117 %else
118     movu    m1, [srcq+wq]
119 %endif
120     mova    m2, m1
121     psllw   m1, 8
122     paddb   m1, m2
123     mova    m2, m1
124     pshufb  m1, m3
125     paddb   m1, m2
126     pshufb  m0, m5
127     mova    m2, m1
128     pshufb  m1, m4
129     paddb   m1, m2
130 %if mmsize == 16
131     mova    m2, m1
132     pshufb  m1, m6
133     paddb   m1, m2
134 %endif
135     paddb   m0, m1
136 %if %1
137     mova    [dstq+wq], m0
138 %else
139     movq    [dstq+wq], m0
140     movhps  [dstq+wq+8], m0
141 %endif
142     add     wq, mmsize
143     jl %%.loop
144     mov     eax, mmsize-1
145     sub     eax, wd
146     movd    m1, eax
147     pshufb  m0, m1
148     movd    eax, m0
149     RET
150 %endmacro
151
152 ; int ff_add_left_pred(uint8_t *dst, const uint8_t *src, int w, int left)
153 INIT_MMX ssse3
154 cglobal add_left_pred, 3,3,7, dst, src, w, left
155 .skip_prologue:
156     mova    m5, [pb_7]
157     mova    m4, [pb_zzzz3333zzzzbbbb]
158     mova    m3, [pb_zz11zz55zz99zzdd]
159     movd    m0, leftm
160     psllq   m0, 56
161     ADD_LEFT_LOOP 1, 1
162
163 INIT_XMM ssse3
164 cglobal add_left_pred_unaligned, 3,3,7, dst, src, w, left
165     mova    m5, [pb_15]
166     mova    m6, [pb_zzzzzzzz77777777]
167     mova    m4, [pb_zzzz3333zzzzbbbb]
168     mova    m3, [pb_zz11zz55zz99zzdd]
169     movd    m0, leftm
170     pslldq  m0, 15
171     test    srcq, 15
172     jnz .src_unaligned
173     test    dstq, 15
174     jnz .dst_unaligned
175     ADD_LEFT_LOOP 1, 1
176 .dst_unaligned:
177     ADD_LEFT_LOOP 0, 1
178 .src_unaligned:
179     ADD_LEFT_LOOP 0, 0
180
181 %macro ADD_BYTES 0
182 cglobal add_bytes, 3,4,2, dst, src, w, size
183     mov  sizeq, wq
184     and  sizeq, -2*mmsize
185     jz  .2
186     add   dstq, sizeq
187     add   srcq, sizeq
188     neg  sizeq
189 .1:
190     mova    m0, [srcq + sizeq]
191     mova    m1, [srcq + sizeq + mmsize]
192     paddb   m0, [dstq + sizeq]
193     paddb   m1, [dstq + sizeq + mmsize]
194     mova   [dstq + sizeq], m0
195     mova   [dstq + sizeq + mmsize], m1
196     add  sizeq, 2*mmsize
197     jl .1
198 .2:
199     and     wq, 2*mmsize-1
200     jz    .end
201     add   dstq, wq
202     add   srcq, wq
203     neg     wq
204 .3:
205     mov  sizeb, [srcq + wq]
206     add [dstq + wq], sizeb
207     inc     wq
208     jl .3
209 .end:
210     REP_RET
211 %endmacro
212
213 %if ARCH_X86_32
214 INIT_MMX mmx
215 ADD_BYTES
216 %endif
217 INIT_XMM sse2
218 ADD_BYTES
219
220 %macro ADD_HFYU_LEFT_LOOP_INT16 2 ; %1 = dst alignment (a/u), %2 = src alignment (a/u)
221     add     wd, wd
222     add     srcq, wq
223     add     dstq, wq
224     neg     wq
225 %%.loop:
226     mov%2   m1, [srcq+wq]
227     mova    m2, m1
228     pslld   m1, 16
229     paddw   m1, m2
230     mova    m2, m1
231
232     pshufb  m1, m3
233     paddw   m1, m2
234     pshufb  m0, m5
235 %if mmsize == 16
236     mova    m2, m1
237     pshufb  m1, m4
238     paddw   m1, m2
239 %endif
240     paddw   m0, m1
241     pand    m0, m7
242 %ifidn %1, a
243     mova    [dstq+wq], m0
244 %else
245     movq    [dstq+wq], m0
246     movhps  [dstq+wq+8], m0
247 %endif
248     add     wq, mmsize
249     jl %%.loop
250     mov     eax, mmsize-1
251     sub     eax, wd
252     mov     wd, eax
253     shl     wd, 8
254     lea     eax, [wd+eax-1]
255     movd    m1, eax
256     pshufb  m0, m1
257     movd    eax, m0
258     RET
259 %endmacro
260
261 ; int add_left_pred_int16(uint16_t *dst, const uint16_t *src, unsigned mask, int w, int left)
262 INIT_MMX ssse3
263 cglobal add_left_pred_int16, 4,4,8, dst, src, mask, w, left
264 .skip_prologue:
265     mova    m5, [pb_67]
266     mova    m3, [pb_zzzz2323zzzzabab]
267     movd    m0, leftm
268     psllq   m0, 48
269     movd    m7, maskm
270     SPLATW  m7 ,m7
271     ADD_HFYU_LEFT_LOOP_INT16 a, a
272
273 INIT_XMM sse4
274 cglobal add_left_pred_int16, 4,4,8, dst, src, mask, w, left
275     mova    m5, [pb_ef]
276     mova    m4, [pb_zzzzzzzz67676767]
277     mova    m3, [pb_zzzz2323zzzzabab]
278     movd    m0, leftm
279     pslldq  m0, 14
280     movd    m7, maskm
281     SPLATW  m7 ,m7
282     test    srcq, 15
283     jnz .src_unaligned
284     test    dstq, 15
285     jnz .dst_unaligned
286     ADD_HFYU_LEFT_LOOP_INT16 a, a
287 .dst_unaligned:
288     ADD_HFYU_LEFT_LOOP_INT16 u, a
289 .src_unaligned:
290     ADD_HFYU_LEFT_LOOP_INT16 u, u