dsputil: Split off HuffYUV decoding bits into their own context
[ffmpeg.git] / libavcodec / x86 / dsputil.asm
1 ;******************************************************************************
2 ;* MMX optimized DSP utils
3 ;* Copyright (c) 2008 Loren Merritt
4 ;*
5 ;* This file is part of Libav.
6 ;*
7 ;* Libav 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 ;* Libav 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 Libav; 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/x86util.asm"
23
24 SECTION_RODATA
25 pb_bswap32: db 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
26
27 SECTION_TEXT
28
29 %macro SCALARPRODUCT 0
30 ; int ff_scalarproduct_int16(int16_t *v1, int16_t *v2, int order)
31 cglobal scalarproduct_int16, 3,3,3, v1, v2, order
32     shl orderq, 1
33     add v1q, orderq
34     add v2q, orderq
35     neg orderq
36     pxor    m2, m2
37 .loop:
38     movu    m0, [v1q + orderq]
39     movu    m1, [v1q + orderq + mmsize]
40     pmaddwd m0, [v2q + orderq]
41     pmaddwd m1, [v2q + orderq + mmsize]
42     paddd   m2, m0
43     paddd   m2, m1
44     add     orderq, mmsize*2
45     jl .loop
46 %if mmsize == 16
47     movhlps m0, m2
48     paddd   m2, m0
49     pshuflw m0, m2, 0x4e
50 %else
51     pshufw  m0, m2, 0x4e
52 %endif
53     paddd   m2, m0
54     movd   eax, m2
55     RET
56
57 ; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3,
58 ;                                     int order, int mul)
59 cglobal scalarproduct_and_madd_int16, 4,4,8, v1, v2, v3, order, mul
60     shl orderq, 1
61     movd    m7, mulm
62 %if mmsize == 16
63     pshuflw m7, m7, 0
64     punpcklqdq m7, m7
65 %else
66     pshufw  m7, m7, 0
67 %endif
68     pxor    m6, m6
69     add v1q, orderq
70     add v2q, orderq
71     add v3q, orderq
72     neg orderq
73 .loop:
74     movu    m0, [v2q + orderq]
75     movu    m1, [v2q + orderq + mmsize]
76     mova    m4, [v1q + orderq]
77     mova    m5, [v1q + orderq + mmsize]
78     movu    m2, [v3q + orderq]
79     movu    m3, [v3q + orderq + mmsize]
80     pmaddwd m0, m4
81     pmaddwd m1, m5
82     pmullw  m2, m7
83     pmullw  m3, m7
84     paddd   m6, m0
85     paddd   m6, m1
86     paddw   m2, m4
87     paddw   m3, m5
88     mova    [v1q + orderq], m2
89     mova    [v1q + orderq + mmsize], m3
90     add     orderq, mmsize*2
91     jl .loop
92 %if mmsize == 16
93     movhlps m0, m6
94     paddd   m6, m0
95     pshuflw m0, m6, 0x4e
96 %else
97     pshufw  m0, m6, 0x4e
98 %endif
99     paddd   m6, m0
100     movd   eax, m6
101     RET
102 %endmacro
103
104 INIT_MMX mmxext
105 SCALARPRODUCT
106 INIT_XMM sse2
107 SCALARPRODUCT
108
109 %macro SCALARPRODUCT_LOOP 1
110 align 16
111 .loop%1:
112     sub     orderq, mmsize*2
113 %if %1
114     mova    m1, m4
115     mova    m4, [v2q + orderq]
116     mova    m0, [v2q + orderq + mmsize]
117     palignr m1, m0, %1
118     palignr m0, m4, %1
119     mova    m3, m5
120     mova    m5, [v3q + orderq]
121     mova    m2, [v3q + orderq + mmsize]
122     palignr m3, m2, %1
123     palignr m2, m5, %1
124 %else
125     mova    m0, [v2q + orderq]
126     mova    m1, [v2q + orderq + mmsize]
127     mova    m2, [v3q + orderq]
128     mova    m3, [v3q + orderq + mmsize]
129 %endif
130     %define t0  [v1q + orderq]
131     %define t1  [v1q + orderq + mmsize]
132 %if ARCH_X86_64
133     mova    m8, t0
134     mova    m9, t1
135     %define t0  m8
136     %define t1  m9
137 %endif
138     pmaddwd m0, t0
139     pmaddwd m1, t1
140     pmullw  m2, m7
141     pmullw  m3, m7
142     paddw   m2, t0
143     paddw   m3, t1
144     paddd   m6, m0
145     paddd   m6, m1
146     mova    [v1q + orderq], m2
147     mova    [v1q + orderq + mmsize], m3
148     jg .loop%1
149 %if %1
150     jmp .end
151 %endif
152 %endmacro
153
154 ; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3,
155 ;                                     int order, int mul)
156 INIT_XMM ssse3
157 cglobal scalarproduct_and_madd_int16, 4,5,10, v1, v2, v3, order, mul
158     shl orderq, 1
159     movd    m7, mulm
160     pshuflw m7, m7, 0
161     punpcklqdq m7, m7
162     pxor    m6, m6
163     mov    r4d, v2d
164     and    r4d, 15
165     and    v2q, ~15
166     and    v3q, ~15
167     mova    m4, [v2q + orderq]
168     mova    m5, [v3q + orderq]
169     ; linear is faster than branch tree or jump table, because the branches taken are cyclic (i.e. predictable)
170     cmp    r4d, 0
171     je .loop0
172     cmp    r4d, 2
173     je .loop2
174     cmp    r4d, 4
175     je .loop4
176     cmp    r4d, 6
177     je .loop6
178     cmp    r4d, 8
179     je .loop8
180     cmp    r4d, 10
181     je .loop10
182     cmp    r4d, 12
183     je .loop12
184 SCALARPRODUCT_LOOP 14
185 SCALARPRODUCT_LOOP 12
186 SCALARPRODUCT_LOOP 10
187 SCALARPRODUCT_LOOP 8
188 SCALARPRODUCT_LOOP 6
189 SCALARPRODUCT_LOOP 4
190 SCALARPRODUCT_LOOP 2
191 SCALARPRODUCT_LOOP 0
192 .end:
193     movhlps m0, m6
194     paddd   m6, m0
195     pshuflw m0, m6, 0x4e
196     paddd   m6, m0
197     movd   eax, m6
198     RET
199
200
201 ;-----------------------------------------------------------------------------
202 ; void ff_vector_clip_int32(int32_t *dst, const int32_t *src, int32_t min,
203 ;                           int32_t max, unsigned int len)
204 ;-----------------------------------------------------------------------------
205
206 ; %1 = number of xmm registers used
207 ; %2 = number of inline load/process/store loops per asm loop
208 ; %3 = process 4*mmsize (%3=0) or 8*mmsize (%3=1) bytes per loop
209 ; %4 = CLIPD function takes min/max as float instead of int (CLIPD_SSE2)
210 ; %5 = suffix
211 %macro VECTOR_CLIP_INT32 4-5
212 cglobal vector_clip_int32%5, 5,5,%1, dst, src, min, max, len
213 %if %4
214     cvtsi2ss  m4, minm
215     cvtsi2ss  m5, maxm
216 %else
217     movd      m4, minm
218     movd      m5, maxm
219 %endif
220     SPLATD    m4
221     SPLATD    m5
222 .loop:
223 %assign %%i 1
224 %rep %2
225     mova      m0,  [srcq+mmsize*0*%%i]
226     mova      m1,  [srcq+mmsize*1*%%i]
227     mova      m2,  [srcq+mmsize*2*%%i]
228     mova      m3,  [srcq+mmsize*3*%%i]
229 %if %3
230     mova      m7,  [srcq+mmsize*4*%%i]
231     mova      m8,  [srcq+mmsize*5*%%i]
232     mova      m9,  [srcq+mmsize*6*%%i]
233     mova      m10, [srcq+mmsize*7*%%i]
234 %endif
235     CLIPD  m0,  m4, m5, m6
236     CLIPD  m1,  m4, m5, m6
237     CLIPD  m2,  m4, m5, m6
238     CLIPD  m3,  m4, m5, m6
239 %if %3
240     CLIPD  m7,  m4, m5, m6
241     CLIPD  m8,  m4, m5, m6
242     CLIPD  m9,  m4, m5, m6
243     CLIPD  m10, m4, m5, m6
244 %endif
245     mova  [dstq+mmsize*0*%%i], m0
246     mova  [dstq+mmsize*1*%%i], m1
247     mova  [dstq+mmsize*2*%%i], m2
248     mova  [dstq+mmsize*3*%%i], m3
249 %if %3
250     mova  [dstq+mmsize*4*%%i], m7
251     mova  [dstq+mmsize*5*%%i], m8
252     mova  [dstq+mmsize*6*%%i], m9
253     mova  [dstq+mmsize*7*%%i], m10
254 %endif
255 %assign %%i %%i+1
256 %endrep
257     add     srcq, mmsize*4*(%2+%3)
258     add     dstq, mmsize*4*(%2+%3)
259     sub     lend, mmsize*(%2+%3)
260     jg .loop
261     REP_RET
262 %endmacro
263
264 INIT_MMX mmx
265 %define CLIPD CLIPD_MMX
266 VECTOR_CLIP_INT32 0, 1, 0, 0
267 INIT_XMM sse2
268 VECTOR_CLIP_INT32 6, 1, 0, 0, _int
269 %define CLIPD CLIPD_SSE2
270 VECTOR_CLIP_INT32 6, 2, 0, 1
271 INIT_XMM sse4
272 %define CLIPD CLIPD_SSE41
273 %ifdef m8
274 VECTOR_CLIP_INT32 11, 1, 1, 0
275 %else
276 VECTOR_CLIP_INT32 6, 1, 0, 0
277 %endif
278
279 ; %1 = aligned/unaligned
280 %macro BSWAP_LOOPS  1
281     mov      r3, r2
282     sar      r2, 3
283     jz       .left4_%1
284 .loop8_%1:
285     mov%1    m0, [r1 +  0]
286     mov%1    m1, [r1 + 16]
287 %if cpuflag(ssse3)
288     pshufb   m0, m2
289     pshufb   m1, m2
290     mov%1    [r0 +  0], m0
291     mov%1    [r0 + 16], m1
292 %else
293     pshuflw  m0, m0, 10110001b
294     pshuflw  m1, m1, 10110001b
295     pshufhw  m0, m0, 10110001b
296     pshufhw  m1, m1, 10110001b
297     mova     m2, m0
298     mova     m3, m1
299     psllw    m0, 8
300     psllw    m1, 8
301     psrlw    m2, 8
302     psrlw    m3, 8
303     por      m2, m0
304     por      m3, m1
305     mov%1    [r0 +  0], m2
306     mov%1    [r0 + 16], m3
307 %endif
308     add      r0, 32
309     add      r1, 32
310     dec      r2
311     jnz      .loop8_%1
312 .left4_%1:
313     mov      r2, r3
314     and      r3, 4
315     jz       .left
316     mov%1    m0, [r1]
317 %if cpuflag(ssse3)
318     pshufb   m0, m2
319     mov%1    [r0], m0
320 %else
321     pshuflw  m0, m0, 10110001b
322     pshufhw  m0, m0, 10110001b
323     mova     m2, m0
324     psllw    m0, 8
325     psrlw    m2, 8
326     por      m2, m0
327     mov%1    [r0], m2
328 %endif
329     add      r1, 16
330     add      r0, 16
331 %endmacro
332
333 ; void ff_bswap_buf(uint32_t *dst, const uint32_t *src, int w);
334 %macro BSWAP32_BUF 0
335 %if cpuflag(ssse3)
336 cglobal bswap32_buf, 3,4,3
337     mov      r3, r1
338     mova     m2, [pb_bswap32]
339 %else
340 cglobal bswap32_buf, 3,4,5
341     mov      r3, r1
342 %endif
343     and      r3, 15
344     jz       .start_align
345     BSWAP_LOOPS  u
346     jmp      .left
347 .start_align:
348     BSWAP_LOOPS  a
349 .left:
350 %if cpuflag(ssse3)
351     mov      r3, r2
352     and      r2, 2
353     jz       .left1
354     movq     m0, [r1]
355     pshufb   m0, m2
356     movq     [r0], m0
357     add      r1, 8
358     add      r0, 8
359 .left1:
360     and      r3, 1
361     jz       .end
362     mov      r2d, [r1]
363     bswap    r2d
364     mov      [r0], r2d
365 %else
366     and      r2, 3
367     jz       .end
368 .loop2:
369     mov      r3d, [r1]
370     bswap    r3d
371     mov      [r0], r3d
372     add      r1, 4
373     add      r0, 4
374     dec      r2
375     jnz      .loop2
376 %endif
377 .end:
378     RET
379 %endmacro
380
381 INIT_XMM sse2
382 BSWAP32_BUF
383
384 INIT_XMM ssse3
385 BSWAP32_BUF