x86: sbrdsp: Implement SSE qmf_post_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_neg          times 4 dd 1<<31
28
29 SECTION_TEXT
30
31 INIT_XMM sse
32 cglobal sbr_sum_square, 2, 3, 6
33     mov         r2, r1
34     xorps       m0, m0
35     xorps       m1, m1
36     sar         r2, 3
37     jz          .prepare
38 .loop:
39     movu        m2, [r0 +  0]
40     movu        m3, [r0 + 16]
41     movu        m4, [r0 + 32]
42     movu        m5, [r0 + 48]
43     mulps       m2, m2
44     mulps       m3, m3
45     mulps       m4, m4
46     mulps       m5, m5
47     addps       m0, m2
48     addps       m1, m3
49     addps       m0, m4
50     addps       m1, m5
51     add         r0, 64
52     dec         r2
53     jnz         .loop
54 .prepare:
55     and         r1, 7
56     sar         r1, 1
57     jz          .end
58 ; len is a multiple of 2, thus there are at least 4 elements to process
59 .endloop:
60     movu        m2, [r0]
61     add         r0, 16
62     mulps       m2, m2
63     dec         r1
64     addps       m0, m2
65     jnz         .endloop
66 .end:
67     addps       m0, m1
68     movhlps     m2, m0
69     addps       m0, m2
70     movss       m1, m0
71     shufps      m0, m0, 1
72     addss       m0, m1
73 %if ARCH_X86_64 == 0
74     movss       r0m,  m0
75     fld         dword r0m
76 %endif
77     RET
78
79 %define STEP  40*4*2
80 cglobal sbr_hf_g_filt, 5, 6, 5
81     lea         r1, [r1 + 8*r4] ; offset by ixh elements into X_high
82     mov         r5, r3
83     and         r3, 0xFC
84     lea         r2, [r2 + r3*4]
85     lea         r0, [r0 + r3*8]
86     neg         r3
87     jz          .loop1
88 .loop4:
89     movlps      m0, [r2 + 4*r3 + 0]
90     movlps      m1, [r2 + 4*r3 + 8]
91     movlps      m2, [r1 + 0*STEP]
92     movlps      m3, [r1 + 2*STEP]
93     movhps      m2, [r1 + 1*STEP]
94     movhps      m3, [r1 + 3*STEP]
95     unpcklps    m0, m0
96     unpcklps    m1, m1
97     mulps       m0, m2
98     mulps       m1, m3
99     movu        [r0 + 8*r3 +  0], m0
100     movu        [r0 + 8*r3 + 16], m1
101     add         r1, 4*STEP
102     add         r3, 4
103     jnz         .loop4
104     and         r5, 3 ; number of single element loops
105     jz          .end
106 .loop1: ; element 0 and 1 can be computed at the same time
107     movss       m0, [r2]
108     movlps      m2, [r1]
109     unpcklps    m0, m0
110     mulps       m2, m0
111     movlps    [r0], m2
112     add         r0, 8
113     add         r2, 4
114     add         r1, STEP
115     dec         r5
116     jnz         .loop1
117 .end:
118     RET
119
120 ; static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2],
121 ;                          const float alpha0[2], const float alpha1[2],
122 ;                          float bw, int start, int end)
123 ;
124 cglobal sbr_hf_gen, 4,4,8, X_high, X_low, alpha0, alpha1, BW, S, E
125     ; load alpha factors
126 %define bw m0
127 %if ARCH_X86_64 == 0 || WIN64
128     movss      bw, BWm
129 %endif
130     movlps     m2, [alpha1q]
131     movlps     m1, [alpha0q]
132     shufps     bw, bw, 0
133     mulps      m2, bw             ; (a1[0] a1[1])*bw
134     mulps      m1, bw             ; (a0[0] a0[1])*bw    = (a2 a3)
135     mulps      m2, bw             ; (a1[0] a1[1])*bw*bw = (a0 a1)
136     mova       m3, m1
137     mova       m4, m2
138     mova       m7, [ps_mask]
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     movlhps     m1, m1           ; (a2 a3 a2 a3)
159     movlhps     m2, m2           ; (a0 a1 a0 a1)
160     shufps      m3, m3, q0101    ; (a3 a2 a3 a2)
161     shufps      m4, m4, q0101    ; (a1 a0 a1 a0)
162     xorps       m3, m7           ; (-a3 a2 -a3 a2)
163     xorps       m4, m7           ; (-a1 a0 -a1 a0)
164 .loop2:
165     mova        m5, m0
166     mova        m6, m0
167     shufps      m0, m0, q2200    ; {Xl[-2][0],",Xl[-1][0],"}
168     shufps      m5, m5, q3311    ; {Xl[-2][1],",Xl[-1][1],"}
169     mulps       m0, m2
170     mulps       m5, m4
171     mova        m7, m6
172     addps       m5, m0
173     mova        m0, [X_lowq + start + 2*2*4]
174     shufps      m6, m0, q0022    ; {Xl[-1][0],",Xl[0][0],"}
175     shufps      m7, m0, q1133    ; {Xl[-1][1],",Xl[1][1],"}
176     mulps       m6, m1
177     mulps       m7, m3
178     addps       m5, m6
179     addps       m7, m0
180     addps       m5, m7
181     mova  [X_highq + start], m5
182     add     start, 16
183     jnz         .loop2
184     RET
185
186 cglobal sbr_sum64x5, 1,2,4,z
187     lea    r1q, [zq+ 256]
188 .loop:
189     mova    m0, [zq+   0]
190     mova    m2, [zq+  16]
191     mova    m1, [zq+ 256]
192     mova    m3, [zq+ 272]
193     addps   m0, [zq+ 512]
194     addps   m2, [zq+ 528]
195     addps   m1, [zq+ 768]
196     addps   m3, [zq+ 784]
197     addps   m0, [zq+1024]
198     addps   m2, [zq+1040]
199     addps   m0, m1
200     addps   m2, m3
201     mova  [zq], m0
202     mova  [zq+16], m2
203     add     zq, 32
204     cmp     zq, r1q
205     jne  .loop
206     REP_RET
207
208 INIT_XMM sse
209 cglobal sbr_qmf_post_shuffle, 2,3,4,W,z
210     lea              r2q, [zq + (64-4)*4]
211     mova              m3, [ps_neg]
212 .loop:
213     mova              m1, [zq]
214     xorps             m0, m3, [r2q]
215     shufps            m0, m0, m0, q0123
216     unpcklps          m2, m0, m1
217     unpckhps          m0, m0, m1
218     mova       [Wq +  0], m2
219     mova       [Wq + 16], m0
220     add               Wq, 32
221     sub              r2q, 16
222     add               zq, 16
223     cmp               zq, r2q
224     jl             .loop
225     REP_RET