probetest: fix possible use of uninitialized data
[ffmpeg.git] / libavcodec / x86 / vc1dsp.asm
1 ;******************************************************************************
2 ;* VC1 deblocking optimizations
3 ;* Copyright (c) 2009 David Conrad
4 ;*
5 ;* This file is part of FFmpeg.
6 ;*
7 ;* FFmpeg is free software; you can redistribute it and/or
8 ;* modify it under the terms of the GNU Lesser General Public
9 ;* License as published by the Free Software Foundation; either
10 ;* version 2.1 of the License, or (at your option) any later version.
11 ;*
12 ;* FFmpeg is distributed in the hope that it will be useful,
13 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;* Lesser General Public License for more details.
16 ;*
17 ;* You should have received a copy of the GNU Lesser General Public
18 ;* License along with FFmpeg; if not, write to the Free Software
19 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ;******************************************************************************
21
22 %include "libavutil/x86/x86inc.asm"
23 %include "libavutil/x86/x86util.asm"
24
25 cextern pw_4
26 cextern pw_5
27
28 section .text
29
30 ; dst_low, dst_high (src), zero
31 ; zero-extends one vector from 8 to 16 bits
32 %macro UNPACK_8TO16 4
33     mova      m%2, m%3
34     punpckh%1 m%3, m%4
35     punpckl%1 m%2, m%4
36 %endmacro
37
38 %macro STORE_4_WORDS_MMX 6
39     movd  %6d, %5
40 %if mmsize==16
41     psrldq %5, 4
42 %else
43     psrlq  %5, 32
44 %endif
45     mov    %1, %6w
46     shr    %6, 16
47     mov    %2, %6w
48     movd  %6d, %5
49     mov    %3, %6w
50     shr    %6, 16
51     mov    %4, %6w
52 %endmacro
53
54 %macro STORE_4_WORDS_SSE4 6
55     pextrw %1, %5, %6+0
56     pextrw %2, %5, %6+1
57     pextrw %3, %5, %6+2
58     pextrw %4, %5, %6+3
59 %endmacro
60
61 ; in:  p1 p0 q0 q1, clobbers p0
62 ; out: p1 = (2*(p1 - q1) - 5*(p0 - q0) + 4) >> 3
63 %macro VC1_LOOP_FILTER_A0 4
64     psubw  %1, %4
65     psubw  %2, %3
66     paddw  %1, %1
67     pmullw %2, [pw_5]
68     psubw  %1, %2
69     paddw  %1, [pw_4]
70     psraw  %1, 3
71 %endmacro
72
73 ; in: p0 q0 a0 a1 a2
74 ;     m0 m1 m7 m6 m5
75 ; %1: size
76 ; out: m0=p0' m1=q0'
77 %macro VC1_FILTER 1
78     PABSW   m4, m7
79     PABSW   m3, m6
80     PABSW   m2, m5
81     mova    m6, m4
82     pminsw  m3, m2
83     pcmpgtw m6, m3  ; if (a2 < a0 || a1 < a0)
84     psubw   m3, m4
85     pmullw  m3, [pw_5]   ; 5*(a3 - a0)
86     PABSW   m2, m3
87     psraw   m2, 3   ; abs(d/8)
88     pxor    m7, m3  ; d_sign ^= a0_sign
89
90     pxor    m5, m5
91     movd    m3, r2d
92 %if %1 > 4
93     punpcklbw m3, m3
94 %endif
95     punpcklbw m3, m5
96     pcmpgtw m3, m4  ; if (a0 < pq)
97     pand    m6, m3
98
99     mova    m3, m0
100     psubw   m3, m1
101     PABSW   m4, m3
102     psraw   m4, 1
103     pxor    m3, m7  ; d_sign ^ clip_sign
104     psraw   m3, 15
105     pminsw  m2, m4  ; min(d, clip)
106     pcmpgtw m4, m5
107     pand    m6, m4  ; filt3 (C return value)
108
109 ; each set of 4 pixels is not filtered if the 3rd is not
110 %if mmsize==16
111     pshuflw m4, m6, 0xaa
112 %if %1 > 4
113     pshufhw m4, m4, 0xaa
114 %endif
115 %else
116     pshufw  m4, m6, 0xaa
117 %endif
118     pandn   m3, m4
119     pand    m2, m6
120     pand    m3, m2  ; d final
121
122     psraw   m7, 15
123     pxor    m3, m7
124     psubw   m3, m7
125     psubw   m0, m3
126     paddw   m1, m3
127     packuswb m0, m0
128     packuswb m1, m1
129 %endmacro
130
131 ; 1st param: size of filter
132 ; 2nd param: mov suffix equivalent to the filter size
133 %macro VC1_V_LOOP_FILTER 2
134     pxor      m5, m5
135     mov%2     m6, [r4]
136     mov%2     m4, [r4+r1]
137     mov%2     m7, [r4+2*r1]
138     mov%2     m0, [r4+r3]
139     punpcklbw m6, m5
140     punpcklbw m4, m5
141     punpcklbw m7, m5
142     punpcklbw m0, m5
143
144     VC1_LOOP_FILTER_A0 m6, m4, m7, m0
145     mov%2     m1, [r0]
146     mov%2     m2, [r0+r1]
147     punpcklbw m1, m5
148     punpcklbw m2, m5
149     mova      m4, m0
150     VC1_LOOP_FILTER_A0 m7, m4, m1, m2
151     mov%2     m3, [r0+2*r1]
152     mov%2     m4, [r0+r3]
153     punpcklbw m3, m5
154     punpcklbw m4, m5
155     mova      m5, m1
156     VC1_LOOP_FILTER_A0 m5, m2, m3, m4
157
158     VC1_FILTER %1
159     mov%2 [r4+r3], m0
160     mov%2 [r0],    m1
161 %endmacro
162
163 ; 1st param: size of filter
164 ;     NOTE: UNPACK_8TO16 this number of 8 bit numbers are in half a register
165 ; 2nd (optional) param: temp register to use for storing words
166 %macro VC1_H_LOOP_FILTER 1-2
167 %if %1 == 4
168     movq      m0, [r0     -4]
169     movq      m1, [r0+  r1-4]
170     movq      m2, [r0+2*r1-4]
171     movq      m3, [r0+  r3-4]
172     TRANSPOSE4x4B 0, 1, 2, 3, 4
173 %else
174     movq      m0, [r0     -4]
175     movq      m4, [r0+  r1-4]
176     movq      m1, [r0+2*r1-4]
177     movq      m5, [r0+  r3-4]
178     movq      m2, [r4     -4]
179     movq      m6, [r4+  r1-4]
180     movq      m3, [r4+2*r1-4]
181     movq      m7, [r4+  r3-4]
182     punpcklbw m0, m4
183     punpcklbw m1, m5
184     punpcklbw m2, m6
185     punpcklbw m3, m7
186     TRANSPOSE4x4W 0, 1, 2, 3, 4
187 %endif
188     pxor      m5, m5
189
190     UNPACK_8TO16 bw, 6, 0, 5
191     UNPACK_8TO16 bw, 7, 1, 5
192     VC1_LOOP_FILTER_A0 m6, m0, m7, m1
193     UNPACK_8TO16 bw, 4, 2, 5
194     mova    m0, m1                      ; m0 = p0
195     VC1_LOOP_FILTER_A0 m7, m1, m4, m2
196     UNPACK_8TO16 bw, 1, 3, 5
197     mova    m5, m4
198     VC1_LOOP_FILTER_A0 m5, m2, m1, m3
199     SWAP 1, 4                           ; m1 = q0
200
201     VC1_FILTER %1
202     punpcklbw m0, m1
203 %if %0 > 1
204     STORE_4_WORDS_MMX [r0-1], [r0+r1-1], [r0+2*r1-1], [r0+r3-1], m0, %2
205 %if %1 > 4
206     psrldq m0, 4
207     STORE_4_WORDS_MMX [r4-1], [r4+r1-1], [r4+2*r1-1], [r4+r3-1], m0, %2
208 %endif
209 %else
210     STORE_4_WORDS_SSE4 [r0-1], [r0+r1-1], [r0+2*r1-1], [r0+r3-1], m0, 0
211     STORE_4_WORDS_SSE4 [r4-1], [r4+r1-1], [r4+2*r1-1], [r4+r3-1], m0, 4
212 %endif
213 %endmacro
214
215
216 %macro START_V_FILTER 0
217     mov  r4, r0
218     lea  r3, [4*r1]
219     sub  r4, r3
220     lea  r3, [r1+2*r1]
221     imul r2, 0x01010101
222 %endmacro
223
224 %macro START_H_FILTER 1
225     lea  r3, [r1+2*r1]
226 %if %1 > 4
227     lea  r4, [r0+4*r1]
228 %endif
229     imul r2, 0x01010101
230 %endmacro
231
232 %macro VC1_LF_MMX 1
233 INIT_MMX
234 cglobal vc1_v_loop_filter_internal_%1
235     VC1_V_LOOP_FILTER 4, d
236     ret
237
238 cglobal vc1_h_loop_filter_internal_%1
239     VC1_H_LOOP_FILTER 4, r4
240     ret
241
242 ; void ff_vc1_v_loop_filter4_mmx2(uint8_t *src, int stride, int pq)
243 cglobal vc1_v_loop_filter4_%1, 3,5,0
244     START_V_FILTER
245     call vc1_v_loop_filter_internal_%1
246     RET
247
248 ; void ff_vc1_h_loop_filter4_mmx2(uint8_t *src, int stride, int pq)
249 cglobal vc1_h_loop_filter4_%1, 3,5,0
250     START_H_FILTER 4
251     call vc1_h_loop_filter_internal_%1
252     RET
253
254 ; void ff_vc1_v_loop_filter8_mmx2(uint8_t *src, int stride, int pq)
255 cglobal vc1_v_loop_filter8_%1, 3,5,0
256     START_V_FILTER
257     call vc1_v_loop_filter_internal_%1
258     add  r4, 4
259     add  r0, 4
260     call vc1_v_loop_filter_internal_%1
261     RET
262
263 ; void ff_vc1_h_loop_filter8_mmx2(uint8_t *src, int stride, int pq)
264 cglobal vc1_h_loop_filter8_%1, 3,5,0
265     START_H_FILTER 4
266     call vc1_h_loop_filter_internal_%1
267     lea  r0, [r0+4*r1]
268     call vc1_h_loop_filter_internal_%1
269     RET
270 %endmacro
271
272 %define PABSW PABSW_MMX2
273 VC1_LF_MMX mmx2
274
275 INIT_XMM
276 ; void ff_vc1_v_loop_filter8_sse2(uint8_t *src, int stride, int pq)
277 cglobal vc1_v_loop_filter8_sse2, 3,5,8
278     START_V_FILTER
279     VC1_V_LOOP_FILTER 8, q
280     RET
281
282 ; void ff_vc1_h_loop_filter8_sse2(uint8_t *src, int stride, int pq)
283 cglobal vc1_h_loop_filter8_sse2, 3,6,8
284     START_H_FILTER 8
285     VC1_H_LOOP_FILTER 8, r5
286     RET
287
288 %define PABSW PABSW_SSSE3
289
290 INIT_MMX
291 ; void ff_vc1_v_loop_filter4_ssse3(uint8_t *src, int stride, int pq)
292 cglobal vc1_v_loop_filter4_ssse3, 3,5,0
293     START_V_FILTER
294     VC1_V_LOOP_FILTER 4, d
295     RET
296
297 ; void ff_vc1_h_loop_filter4_ssse3(uint8_t *src, int stride, int pq)
298 cglobal vc1_h_loop_filter4_ssse3, 3,5,0
299     START_H_FILTER 4
300     VC1_H_LOOP_FILTER 4, r4
301     RET
302
303 INIT_XMM
304 ; void ff_vc1_v_loop_filter8_ssse3(uint8_t *src, int stride, int pq)
305 cglobal vc1_v_loop_filter8_ssse3, 3,5,8
306     START_V_FILTER
307     VC1_V_LOOP_FILTER 8, q
308     RET
309
310 ; void ff_vc1_h_loop_filter8_ssse3(uint8_t *src, int stride, int pq)
311 cglobal vc1_h_loop_filter8_ssse3, 3,6,8
312     START_H_FILTER 8
313     VC1_H_LOOP_FILTER 8, r5
314     RET
315
316 ; void ff_vc1_h_loop_filter8_sse4(uint8_t *src, int stride, int pq)
317 cglobal vc1_h_loop_filter8_sse4, 3,5,8
318     START_H_FILTER 8
319     VC1_H_LOOP_FILTER 8
320     RET