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