x86: sbrdsp: implement SSE2 qmf_pre_shuffle
[ffmpeg.git] / libavcodec / x86 / sbrdsp.asm
1 ;******************************************************************************
2 ;* AAC Spectral Band Replication decoding functions
3 ;* Copyright (C) 2012 Christophe Gisquet <christophe.gisquet@gmail.com>
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 ; mask equivalent for multiply by -1.0 1.0
26 ps_mask         times 2 dd 1<<31, 0
27 ps_mask2        times 2 dd 0, 1<<31
28 ps_neg          times 4 dd 1<<31
29
30 SECTION_TEXT
31
32 INIT_XMM sse
33 cglobal sbr_sum_square, 2, 3, 6
34     mov         r2, r1
35     xorps       m0, m0
36     xorps       m1, m1
37     sar         r2, 3
38     jz          .prepare
39 .loop:
40     movu        m2, [r0 +  0]
41     movu        m3, [r0 + 16]
42     movu        m4, [r0 + 32]
43     movu        m5, [r0 + 48]
44     mulps       m2, m2
45     mulps       m3, m3
46     mulps       m4, m4
47     mulps       m5, m5
48     addps       m0, m2
49     addps       m1, m3
50     addps       m0, m4
51     addps       m1, m5
52     add         r0, 64
53     dec         r2
54     jnz         .loop
55 .prepare:
56     and         r1, 7
57     sar         r1, 1
58     jz          .end
59 ; len is a multiple of 2, thus there are at least 4 elements to process
60 .endloop:
61     movu        m2, [r0]
62     add         r0, 16
63     mulps       m2, m2
64     dec         r1
65     addps       m0, m2
66     jnz         .endloop
67 .end:
68     addps       m0, m1
69     movhlps     m2, m0
70     addps       m0, m2
71     movss       m1, m0
72     shufps      m0, m0, 1
73     addss       m0, m1
74 %if ARCH_X86_64 == 0
75     movss       r0m,  m0
76     fld         dword r0m
77 %endif
78     RET
79
80 %define STEP  40*4*2
81 cglobal sbr_hf_g_filt, 5, 6, 5
82     lea         r1, [r1 + 8*r4] ; offset by ixh elements into X_high
83     mov         r5, r3
84     and         r3, 0xFC
85     lea         r2, [r2 + r3*4]
86     lea         r0, [r0 + r3*8]
87     neg         r3
88     jz          .loop1
89 .loop4:
90     movlps      m0, [r2 + 4*r3 + 0]
91     movlps      m1, [r2 + 4*r3 + 8]
92     movlps      m2, [r1 + 0*STEP]
93     movlps      m3, [r1 + 2*STEP]
94     movhps      m2, [r1 + 1*STEP]
95     movhps      m3, [r1 + 3*STEP]
96     unpcklps    m0, m0
97     unpcklps    m1, m1
98     mulps       m0, m2
99     mulps       m1, m3
100     movu        [r0 + 8*r3 +  0], m0
101     movu        [r0 + 8*r3 + 16], m1
102     add         r1, 4*STEP
103     add         r3, 4
104     jnz         .loop4
105     and         r5, 3 ; number of single element loops
106     jz          .end
107 .loop1: ; element 0 and 1 can be computed at the same time
108     movss       m0, [r2]
109     movlps      m2, [r1]
110     unpcklps    m0, m0
111     mulps       m2, m0
112     movlps    [r0], m2
113     add         r0, 8
114     add         r2, 4
115     add         r1, STEP
116     dec         r5
117     jnz         .loop1
118 .end:
119     RET
120
121 ; static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2],
122 ;                          const float alpha0[2], const float alpha1[2],
123 ;                          float bw, int start, int end)
124 ;
125 cglobal sbr_hf_gen, 4,4,8, X_high, X_low, alpha0, alpha1, BW, S, E
126     ; load alpha factors
127 %define bw m0
128 %if ARCH_X86_64 == 0 || WIN64
129     movss      bw, BWm
130 %endif
131     movlps     m2, [alpha1q]
132     movlps     m1, [alpha0q]
133     shufps     bw, bw, 0
134     mulps      m2, bw             ; (a1[0] a1[1])*bw
135     mulps      m1, bw             ; (a0[0] a0[1])*bw    = (a2 a3)
136     mulps      m2, bw             ; (a1[0] a1[1])*bw*bw = (a0 a1)
137     mova       m3, m1
138     mova       m4, m2
139
140     ; Set pointers
141 %if ARCH_X86_64 == 0 || WIN64
142     ; start and end 6th and 7th args on stack
143     mov        r2d, Sm
144     mov        r3d, Em
145 %define  start r2q
146 %define  end   r3q
147 %else
148 ; BW does not actually occupy a register, so shift by 1
149 %define  start BWq
150 %define  end   Sq
151 %endif
152     sub      start, end          ; neg num of loops
153     lea    X_highq, [X_highq + end*2*4]
154     lea     X_lowq, [X_lowq  + end*2*4 - 2*2*4]
155     shl      start, 3            ; offset from num loops
156
157     mova        m0, [X_lowq + start]
158     shufps      m3, m3, q1111
159     shufps      m4, m4, q1111
160     xorps       m3, [ps_mask]
161     shufps      m1, m1, q0000
162     shufps      m2, m2, q0000
163     xorps       m4, [ps_mask]
164 .loop2:
165     movu        m7, [X_lowq + start + 8]        ; BbCc
166     mova        m6, m0
167     mova        m5, m7
168     shufps      m0, m0, q2301                   ; aAbB
169     shufps      m7, m7, q2301                   ; bBcC
170     mulps       m0, m4
171     mulps       m7, m3
172     mulps       m6, m2
173     mulps       m5, m1
174     addps       m7, m0
175     mova        m0, [X_lowq + start +16]        ; CcDd
176     addps       m7, m0
177     addps       m6, m5
178     addps       m7, m6
179     mova  [X_highq + start], m7
180     add     start, 16
181     jnz         .loop2
182     RET
183
184 cglobal sbr_sum64x5, 1,2,4,z
185     lea    r1q, [zq+ 256]
186 .loop:
187     mova    m0, [zq+   0]
188     mova    m2, [zq+  16]
189     mova    m1, [zq+ 256]
190     mova    m3, [zq+ 272]
191     addps   m0, [zq+ 512]
192     addps   m2, [zq+ 528]
193     addps   m1, [zq+ 768]
194     addps   m3, [zq+ 784]
195     addps   m0, [zq+1024]
196     addps   m2, [zq+1040]
197     addps   m0, m1
198     addps   m2, m3
199     mova  [zq], m0
200     mova  [zq+16], m2
201     add     zq, 32
202     cmp     zq, r1q
203     jne  .loop
204     REP_RET
205
206 INIT_XMM sse
207 cglobal sbr_qmf_post_shuffle, 2,3,4,W,z
208     lea              r2q, [zq + (64-4)*4]
209     mova              m3, [ps_neg]
210 .loop:
211     mova              m1, [zq]
212     xorps             m0, m3, [r2q]
213     shufps            m0, m0, m0, q0123
214     unpcklps          m2, m0, m1
215     unpckhps          m0, m0, m1
216     mova       [Wq +  0], m2
217     mova       [Wq + 16], m0
218     add               Wq, 32
219     sub              r2q, 16
220     add               zq, 16
221     cmp               zq, r2q
222     jl             .loop
223     REP_RET
224
225 INIT_XMM sse
226 cglobal sbr_neg_odd_64, 1,2,4,z
227     lea        r1q, [zq+256]
228 .loop:
229     mova        m0, [zq+ 0]
230     mova        m1, [zq+16]
231     mova        m2, [zq+32]
232     mova        m3, [zq+48]
233     xorps       m0, [ps_mask2]
234     xorps       m1, [ps_mask2]
235     xorps       m2, [ps_mask2]
236     xorps       m3, [ps_mask2]
237     mova   [zq+ 0], m0
238     mova   [zq+16], m1
239     mova   [zq+32], m2
240     mova   [zq+48], m3
241     add         zq, 64
242     cmp         zq, r1q
243     jne      .loop
244     REP_RET
245
246 ; sbr_qmf_deint_bfly(float *v, const float *src0, const float *src1)
247 %macro SBR_QMF_DEINT_BFLY  0
248 cglobal sbr_qmf_deint_bfly, 3,5,8, v,src0,src1,vrev,c
249     mov        cq, 64*4-2*mmsize
250     lea     vrevq, [vq + 64*4]
251 .loop:
252     mova       m0, [src0q+cq]
253     mova       m1, [src1q]
254     mova       m4, [src0q+cq+mmsize]
255     mova       m5, [src1q+mmsize]
256 %if cpuflag(sse2)
257     pshufd     m2, m0, q0123
258     pshufd     m3, m1, q0123
259     pshufd     m6, m4, q0123
260     pshufd     m7, m5, q0123
261 %else
262     shufps     m2, m0, m0, q0123
263     shufps     m3, m1, m1, q0123
264     shufps     m6, m4, m4, q0123
265     shufps     m7, m5, m5, q0123
266 %endif
267     addps      m5, m2
268     subps      m0, m7
269     addps      m1, m6
270     subps      m4, m3
271     mova  [vrevq], m1
272     mova  [vrevq+mmsize], m5
273     mova  [vq+cq], m0
274     mova  [vq+cq+mmsize], m4
275     add     src1q, 2*mmsize
276     add     vrevq, 2*mmsize
277     sub        cq, 2*mmsize
278     jge     .loop
279     REP_RET
280 %endmacro
281
282 INIT_XMM sse
283 SBR_QMF_DEINT_BFLY
284
285 INIT_XMM sse2
286 SBR_QMF_DEINT_BFLY
287
288 INIT_XMM sse2
289 cglobal sbr_qmf_pre_shuffle, 1,4,7,z
290 %define OFFSET  (32*4-2*mmsize)
291     mov       r3q, OFFSET
292     lea       r1q, [zq + (32+1)*4]
293     lea       r2q, [zq + 64*4]
294     mova       m6, [ps_neg]
295 .loop:
296     movu       m0, [r1q]
297     movu       m2, [r1q + mmsize]
298     movu       m1, [zq + r3q + 4 + mmsize]
299     movu       m3, [zq + r3q + 4]
300
301     pxor       m2, m6
302     pxor       m0, m6
303     pshufd     m2, m2, q0123
304     pshufd     m0, m0, q0123
305     SBUTTERFLY dq, 2, 3, 5
306     SBUTTERFLY dq, 0, 1, 4
307     mova  [r2q + 2*r3q + 0*mmsize], m2
308     mova  [r2q + 2*r3q + 1*mmsize], m3
309     mova  [r2q + 2*r3q + 2*mmsize], m0
310     mova  [r2q + 2*r3q + 3*mmsize], m1
311     add       r1q, 2*mmsize
312     sub       r3q, 2*mmsize
313     jge      .loop
314     mova       m2, [zq]
315     movq    [r2q], m2
316     REP_RET