Merge commit '6860b4081d046558c44b1b42f22022ea341a2a73'
[ffmpeg.git] / libswresample / x86 / rematrix.asm
1 ;******************************************************************************
2 ;* Copyright (c) 2012 Michael Niedermayer
3 ;*
4 ;* This file is part of FFmpeg.
5 ;*
6 ;* FFmpeg is free software; you can redistribute it and/or
7 ;* modify it under the terms of the GNU Lesser General Public
8 ;* License as published by the Free Software Foundation; either
9 ;* version 2.1 of the License, or (at your option) any later version.
10 ;*
11 ;* FFmpeg is distributed in the hope that it will be useful,
12 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ;* Lesser General Public License for more details.
15 ;*
16 ;* You should have received a copy of the GNU Lesser General Public
17 ;* License along with FFmpeg; if not, write to the Free Software
18 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 ;******************************************************************************
20
21 %include "libavutil/x86/x86util.asm"
22
23
24 SECTION_RODATA
25 align 32
26 dw1: times 8  dd 1
27 w1 : times 16 dw 1
28
29 SECTION .text
30
31 %macro MIX2_FLT 1
32 cglobal mix_2_1_%1_float, 7, 7, 6, out, in1, in2, coeffp, index1, index2, len
33 %ifidn %1, a
34     test in1q, mmsize-1
35         jne mix_2_1_float_u_int %+ SUFFIX
36     test in2q, mmsize-1
37         jne mix_2_1_float_u_int %+ SUFFIX
38     test outq, mmsize-1
39         jne mix_2_1_float_u_int %+ SUFFIX
40 %else
41 mix_2_1_float_u_int %+ SUFFIX
42 %endif
43     VBROADCASTSS m4, [coeffpq + 4*index1q]
44     VBROADCASTSS m5, [coeffpq + 4*index2q]
45     shl lend    , 2
46     add in1q    , lenq
47     add in2q    , lenq
48     add outq    , lenq
49     neg lenq
50 .next:
51 %ifidn %1, a
52     mulps        m0, m4, [in1q + lenq         ]
53     mulps        m1, m5, [in2q + lenq         ]
54     mulps        m2, m4, [in1q + lenq + mmsize]
55     mulps        m3, m5, [in2q + lenq + mmsize]
56 %else
57     movu         m0, [in1q + lenq         ]
58     movu         m1, [in2q + lenq         ]
59     movu         m2, [in1q + lenq + mmsize]
60     movu         m3, [in2q + lenq + mmsize]
61     mulps        m0, m0, m4
62     mulps        m1, m1, m5
63     mulps        m2, m2, m4
64     mulps        m3, m3, m5
65 %endif
66     addps        m0, m0, m1
67     addps        m2, m2, m3
68     mov%1  [outq + lenq         ], m0
69     mov%1  [outq + lenq + mmsize], m2
70     add        lenq, mmsize*2
71         jl .next
72     REP_RET
73 %endmacro
74
75 %macro MIX1_FLT 1
76 cglobal mix_1_1_%1_float, 5, 5, 3, out, in, coeffp, index, len
77 %ifidn %1, a
78     test inq, mmsize-1
79         jne mix_1_1_float_u_int %+ SUFFIX
80     test outq, mmsize-1
81         jne mix_1_1_float_u_int %+ SUFFIX
82 %else
83 mix_1_1_float_u_int %+ SUFFIX
84 %endif
85     VBROADCASTSS m2, [coeffpq + 4*indexq]
86     shl lenq    , 2
87     add inq     , lenq
88     add outq    , lenq
89     neg lenq
90 .next:
91 %ifidn %1, a
92     mulps        m0, m2, [inq + lenq         ]
93     mulps        m1, m2, [inq + lenq + mmsize]
94 %else
95     movu         m0, [inq + lenq         ]
96     movu         m1, [inq + lenq + mmsize]
97     mulps        m0, m0, m2
98     mulps        m1, m1, m2
99 %endif
100     mov%1  [outq + lenq         ], m0
101     mov%1  [outq + lenq + mmsize], m1
102     add        lenq, mmsize*2
103         jl .next
104     REP_RET
105 %endmacro
106
107 %macro MIX1_INT16 1
108 cglobal mix_1_1_%1_int16, 5, 5, 6, out, in, coeffp, index, len
109 %ifidn %1, a
110     test inq, mmsize-1
111         jne mix_1_1_int16_u_int %+ SUFFIX
112     test outq, mmsize-1
113         jne mix_1_1_int16_u_int %+ SUFFIX
114 %else
115 mix_1_1_int16_u_int %+ SUFFIX
116 %endif
117     movd   m4, [coeffpq + 4*indexq]
118     SPLATW m5, m4
119     psllq  m4, 32
120     psrlq  m4, 48
121     mova   m0, [w1]
122     psllw  m0, m4
123     psrlw  m0, 1
124     punpcklwd m5, m0
125     add lenq    , lenq
126     add inq     , lenq
127     add outq    , lenq
128     neg lenq
129 .next:
130     mov%1        m0, [inq + lenq         ]
131     mov%1        m2, [inq + lenq + mmsize]
132     mova         m1, m0
133     mova         m3, m2
134     punpcklwd    m0, [w1]
135     punpckhwd    m1, [w1]
136     punpcklwd    m2, [w1]
137     punpckhwd    m3, [w1]
138     pmaddwd      m0, m5
139     pmaddwd      m1, m5
140     pmaddwd      m2, m5
141     pmaddwd      m3, m5
142     psrad        m0, m4
143     psrad        m1, m4
144     psrad        m2, m4
145     psrad        m3, m4
146     packssdw     m0, m1
147     packssdw     m2, m3
148     mov%1  [outq + lenq         ], m0
149     mov%1  [outq + lenq + mmsize], m2
150     add        lenq, mmsize*2
151         jl .next
152 %if mmsize == 8
153     emms
154     RET
155 %else
156     REP_RET
157 %endif
158 %endmacro
159
160 %macro MIX2_INT16 1
161 cglobal mix_2_1_%1_int16, 7, 7, 8, out, in1, in2, coeffp, index1, index2, len
162 %ifidn %1, a
163     test in1q, mmsize-1
164         jne mix_2_1_int16_u_int %+ SUFFIX
165     test in2q, mmsize-1
166         jne mix_2_1_int16_u_int %+ SUFFIX
167     test outq, mmsize-1
168         jne mix_2_1_int16_u_int %+ SUFFIX
169 %else
170 mix_2_1_int16_u_int %+ SUFFIX
171 %endif
172     movd   m4, [coeffpq + 4*index1q]
173     movd   m6, [coeffpq + 4*index2q]
174     SPLATW m5, m4
175     SPLATW m6, m6
176     psllq  m4, 32
177     psrlq  m4, 48
178     mova   m7, [dw1]
179     pslld  m7, m4
180     psrld  m7, 1
181     punpcklwd m5, m6
182     add lend    , lend
183     add in1q    , lenq
184     add in2q    , lenq
185     add outq    , lenq
186     neg lenq
187 .next:
188     mov%1        m0, [in1q + lenq         ]
189     mov%1        m2, [in2q + lenq         ]
190     mova         m1, m0
191     punpcklwd    m0, m2
192     punpckhwd    m1, m2
193
194     mov%1        m2, [in1q + lenq + mmsize]
195     mov%1        m6, [in2q + lenq + mmsize]
196     mova         m3, m2
197     punpcklwd    m2, m6
198     punpckhwd    m3, m6
199
200     pmaddwd      m0, m5
201     pmaddwd      m1, m5
202     pmaddwd      m2, m5
203     pmaddwd      m3, m5
204     paddd        m0, m7
205     paddd        m1, m7
206     paddd        m2, m7
207     paddd        m3, m7
208     psrad        m0, m4
209     psrad        m1, m4
210     psrad        m2, m4
211     psrad        m3, m4
212     packssdw     m0, m1
213     packssdw     m2, m3
214     mov%1  [outq + lenq         ], m0
215     mov%1  [outq + lenq + mmsize], m2
216     add        lenq, mmsize*2
217         jl .next
218 %if mmsize == 8
219     emms
220     RET
221 %else
222     REP_RET
223 %endif
224 %endmacro
225
226
227 INIT_MMX mmx
228 MIX1_INT16 u
229 MIX1_INT16 a
230 MIX2_INT16 u
231 MIX2_INT16 a
232
233 INIT_XMM sse
234 MIX2_FLT u
235 MIX2_FLT a
236 MIX1_FLT u
237 MIX1_FLT a
238
239 INIT_XMM sse2
240 MIX1_INT16 u
241 MIX1_INT16 a
242 MIX2_INT16 u
243 MIX2_INT16 a
244
245 %if HAVE_AVX_EXTERNAL
246 INIT_YMM avx
247 MIX2_FLT u
248 MIX2_FLT a
249 MIX1_FLT u
250 MIX1_FLT a
251 %endif