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