d314a4e14e2d04d244785d2d587b39211d158411
[ffmpeg.git] / libavcodec / x86 / fmtconvert.asm
1 ;******************************************************************************
2 ;* x86 optimized Format Conversion 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 "x86inc.asm"
23 %include "x86util.asm"
24
25 SECTION_TEXT
26
27 ;------------------------------------------------------------------------------
28 ; void ff_float_to_int16(int16_t *dst, const float *src, long len);
29 ;------------------------------------------------------------------------------
30 %macro FLOAT_TO_INT16 2
31 cglobal float_to_int16_%1, 3,3,%2, dst, src, len
32     add       lenq, lenq
33     lea       srcq, [srcq+2*lenq]
34     add       dstq, lenq
35     neg       lenq
36 .loop:
37 %ifidn %1, sse2
38     cvtps2dq    m0, [srcq+2*lenq   ]
39     cvtps2dq    m1, [srcq+2*lenq+16]
40     packssdw    m0, m1
41     mova  [dstq+lenq], m0
42 %else
43     cvtps2pi    m0, [srcq+2*lenq   ]
44     cvtps2pi    m1, [srcq+2*lenq+ 8]
45     cvtps2pi    m2, [srcq+2*lenq+16]
46     cvtps2pi    m3, [srcq+2*lenq+24]
47     packssdw    m0, m1
48     packssdw    m2, m3
49     mova  [dstq+lenq  ], m0
50     mova  [dstq+lenq+8], m2
51 %endif
52     add       lenq, 16
53     js .loop
54 %ifnidn %1, sse2
55     emms
56 %endif
57     REP_RET
58 %endmacro
59
60 INIT_XMM
61 FLOAT_TO_INT16 sse2, 2
62 INIT_MMX
63 FLOAT_TO_INT16 sse, 0
64 %define cvtps2pi pf2id
65 FLOAT_TO_INT16 3dnow, 0
66 %undef cvtps2pi
67
68
69 %macro PSWAPD_SSE 2
70     pshufw %1, %2, 0x4e
71 %endmacro
72 %macro PSWAPD_3DN1 2
73     movq  %1, %2
74     psrlq %1, 32
75     punpckldq %1, %2
76 %endmacro
77
78 %macro FLOAT_TO_INT16_INTERLEAVE6 1
79 ; void float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len)
80 cglobal float_to_int16_interleave6_%1, 2,7,0, dst, src, src1, src2, src3, src4, src5
81 %ifdef ARCH_X86_64
82     %define lend r10d
83     mov     lend, r2d
84 %else
85     %define lend dword r2m
86 %endif
87     mov src1q, [srcq+1*gprsize]
88     mov src2q, [srcq+2*gprsize]
89     mov src3q, [srcq+3*gprsize]
90     mov src4q, [srcq+4*gprsize]
91     mov src5q, [srcq+5*gprsize]
92     mov srcq,  [srcq]
93     sub src1q, srcq
94     sub src2q, srcq
95     sub src3q, srcq
96     sub src4q, srcq
97     sub src5q, srcq
98 .loop:
99     cvtps2pi   mm0, [srcq]
100     cvtps2pi   mm1, [srcq+src1q]
101     cvtps2pi   mm2, [srcq+src2q]
102     cvtps2pi   mm3, [srcq+src3q]
103     cvtps2pi   mm4, [srcq+src4q]
104     cvtps2pi   mm5, [srcq+src5q]
105     packssdw   mm0, mm3
106     packssdw   mm1, mm4
107     packssdw   mm2, mm5
108     pswapd     mm3, mm0
109     punpcklwd  mm0, mm1
110     punpckhwd  mm1, mm2
111     punpcklwd  mm2, mm3
112     pswapd     mm3, mm0
113     punpckldq  mm0, mm2
114     punpckhdq  mm2, mm1
115     punpckldq  mm1, mm3
116     movq [dstq   ], mm0
117     movq [dstq+16], mm2
118     movq [dstq+ 8], mm1
119     add srcq, 8
120     add dstq, 24
121     sub lend, 2
122     jg .loop
123     emms
124     RET
125 %endmacro ; FLOAT_TO_INT16_INTERLEAVE6
126
127 %define pswapd PSWAPD_SSE
128 FLOAT_TO_INT16_INTERLEAVE6 sse
129 %define cvtps2pi pf2id
130 %define pswapd PSWAPD_3DN1
131 FLOAT_TO_INT16_INTERLEAVE6 3dnow
132 %undef pswapd
133 FLOAT_TO_INT16_INTERLEAVE6 3dn2
134 %undef cvtps2pi
135
136 ;-----------------------------------------------------------------------------
137 ; void ff_float_interleave6(float *dst, const float **src, unsigned int len);
138 ;-----------------------------------------------------------------------------
139
140 %macro FLOAT_INTERLEAVE6 2
141 cglobal float_interleave6_%1, 2,7,%2, dst, src, src1, src2, src3, src4, src5
142 %ifdef ARCH_X86_64
143     %define lend r10d
144     mov     lend, r2d
145 %else
146     %define lend dword r2m
147 %endif
148     mov    src1q, [srcq+1*gprsize]
149     mov    src2q, [srcq+2*gprsize]
150     mov    src3q, [srcq+3*gprsize]
151     mov    src4q, [srcq+4*gprsize]
152     mov    src5q, [srcq+5*gprsize]
153     mov     srcq, [srcq]
154     sub    src1q, srcq
155     sub    src2q, srcq
156     sub    src3q, srcq
157     sub    src4q, srcq
158     sub    src5q, srcq
159 .loop:
160 %ifidn %1, sse
161     movaps    m0, [srcq]
162     movaps    m1, [srcq+src1q]
163     movaps    m2, [srcq+src2q]
164     movaps    m3, [srcq+src3q]
165     movaps    m4, [srcq+src4q]
166     movaps    m5, [srcq+src5q]
167
168     SBUTTERFLYPS 0, 1, 6
169     SBUTTERFLYPS 2, 3, 6
170     SBUTTERFLYPS 4, 5, 6
171
172     movaps    m6, m4
173     shufps    m4, m0, 0xe4
174     movlhps   m0, m2
175     movhlps   m6, m2
176     movaps [dstq   ], m0
177     movaps [dstq+16], m4
178     movaps [dstq+32], m6
179
180     movaps    m6, m5
181     shufps    m5, m1, 0xe4
182     movlhps   m1, m3
183     movhlps   m6, m3
184     movaps [dstq+48], m1
185     movaps [dstq+64], m5
186     movaps [dstq+80], m6
187 %else ; mmx
188     movq       m0, [srcq]
189     movq       m1, [srcq+src1q]
190     movq       m2, [srcq+src2q]
191     movq       m3, [srcq+src3q]
192     movq       m4, [srcq+src4q]
193     movq       m5, [srcq+src5q]
194
195     SBUTTERFLY dq, 0, 1, 6
196     SBUTTERFLY dq, 2, 3, 6
197     SBUTTERFLY dq, 4, 5, 6
198     movq [dstq   ], m0
199     movq [dstq+ 8], m2
200     movq [dstq+16], m4
201     movq [dstq+24], m1
202     movq [dstq+32], m3
203     movq [dstq+40], m5
204 %endif
205     add      srcq, mmsize
206     add      dstq, mmsize*6
207     sub      lend, mmsize/4
208     jg .loop
209 %ifidn %1, mmx
210     emms
211 %endif
212     REP_RET
213 %endmacro
214
215 INIT_MMX
216 FLOAT_INTERLEAVE6 mmx, 0
217 INIT_XMM
218 FLOAT_INTERLEAVE6 sse, 7
219
220 ;-----------------------------------------------------------------------------
221 ; void ff_float_interleave2(float *dst, const float **src, unsigned int len);
222 ;-----------------------------------------------------------------------------
223
224 %macro FLOAT_INTERLEAVE2 2
225 cglobal float_interleave2_%1, 3,4,%2, dst, src, len, src1
226     mov     src1q, [srcq+gprsize]
227     mov      srcq, [srcq        ]
228     sub     src1q, srcq
229 .loop
230     MOVPS      m0, [srcq             ]
231     MOVPS      m1, [srcq+src1q       ]
232     MOVPS      m3, [srcq      +mmsize]
233     MOVPS      m4, [srcq+src1q+mmsize]
234
235     MOVPS      m2, m0
236     PUNPCKLDQ  m0, m1
237     PUNPCKHDQ  m2, m1
238
239     MOVPS      m1, m3
240     PUNPCKLDQ  m3, m4
241     PUNPCKHDQ  m1, m4
242
243     MOVPS [dstq         ], m0
244     MOVPS [dstq+1*mmsize], m2
245     MOVPS [dstq+2*mmsize], m3
246     MOVPS [dstq+3*mmsize], m1
247
248     add      srcq, mmsize*2
249     add      dstq, mmsize*4
250     sub      lend, mmsize/2
251     jg .loop
252 %ifidn %1, mmx
253     emms
254 %endif
255     REP_RET
256 %endmacro
257
258 INIT_MMX
259 %define MOVPS     movq
260 %define PUNPCKLDQ punpckldq
261 %define PUNPCKHDQ punpckhdq
262 FLOAT_INTERLEAVE2 mmx, 0
263 INIT_XMM
264 %define MOVPS     movaps
265 %define PUNPCKLDQ unpcklps
266 %define PUNPCKHDQ unpckhps
267 FLOAT_INTERLEAVE2 sse, 5