~ubuntu-branches/ubuntu/saucy/gst-libav1.0/saucy-proposed

« back to all changes in this revision

Viewing changes to gst-libs/ext/libav/libavcodec/x86/fft_mmx.asm

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2013-07-30 09:00:15 UTC
  • mfrom: (1.1.16) (7.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20130730090015-sc1ou2yssu7q5w4e
Tags: 1.1.3-1
* New upstream development snapshot:
  + debian/control:
    - Build depend on GStreamer and gst-plugins-base >= 1.1.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
;******************************************************************************
2
 
;* FFT transform with SSE/3DNow optimizations
3
 
;* Copyright (c) 2008 Loren Merritt
4
 
;* Copyright (c) 2011 Vitor Sessak
5
 
;*
6
 
;* This algorithm (though not any of the implementation details) is
7
 
;* based on libdjbfft by D. J. Bernstein.
8
 
;*
9
 
;* This file is part of Libav.
10
 
;*
11
 
;* Libav is free software; you can redistribute it and/or
12
 
;* modify it under the terms of the GNU Lesser General Public
13
 
;* License as published by the Free Software Foundation; either
14
 
;* version 2.1 of the License, or (at your option) any later version.
15
 
;*
16
 
;* Libav is distributed in the hope that it will be useful,
17
 
;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 
;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19
 
;* Lesser General Public License for more details.
20
 
;*
21
 
;* You should have received a copy of the GNU Lesser General Public
22
 
;* License along with Libav; if not, write to the Free Software
23
 
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
 
;******************************************************************************
25
 
 
26
 
; These functions are not individually interchangeable with the C versions.
27
 
; While C takes arrays of FFTComplex, SSE/3DNow leave intermediate results
28
 
; in blocks as conventient to the vector size.
29
 
; i.e. {4x real, 4x imaginary, 4x real, ...} (or 2x respectively)
30
 
 
31
 
%include "x86inc.asm"
32
 
 
33
 
%ifdef ARCH_X86_64
34
 
%define pointer resq
35
 
%else
36
 
%define pointer resd
37
 
%endif
38
 
 
39
 
struc FFTContext
40
 
    .nbits:    resd 1
41
 
    .reverse:  resd 1
42
 
    .revtab:   pointer 1
43
 
    .tmpbuf:   pointer 1
44
 
    .mdctsize: resd 1
45
 
    .mdctbits: resd 1
46
 
    .tcos:     pointer 1
47
 
    .tsin:     pointer 1
48
 
endstruc
49
 
 
50
 
SECTION_RODATA
51
 
 
52
 
%define M_SQRT1_2 0.70710678118654752440
53
 
%define M_COS_PI_1_8 0.923879532511287
54
 
%define M_COS_PI_3_8 0.38268343236509
55
 
 
56
 
align 32
57
 
ps_cos16_1: dd 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8, 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8
58
 
ps_cos16_2: dd 0, M_COS_PI_3_8, M_SQRT1_2, M_COS_PI_1_8, 0, -M_COS_PI_3_8, -M_SQRT1_2, -M_COS_PI_1_8
59
 
 
60
 
ps_root2: times 8 dd M_SQRT1_2
61
 
ps_root2mppm: dd -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2
62
 
ps_p1p1m1p1: dd 0, 0, 1<<31, 0, 0, 0, 1<<31, 0
63
 
 
64
 
perm1: dd 0x00, 0x02, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01
65
 
perm2: dd 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x02, 0x03
66
 
ps_p1p1m1p1root2: dd 1.0, 1.0, -1.0, 1.0, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2
67
 
ps_m1m1p1m1p1m1m1m1: dd 1<<31, 1<<31, 0, 1<<31, 0, 1<<31, 1<<31, 1<<31
68
 
ps_m1p1: dd 1<<31, 0
69
 
 
70
 
%assign i 16
71
 
%rep 13
72
 
cextern cos_ %+ i
73
 
%assign i i<<1
74
 
%endrep
75
 
 
76
 
%ifdef ARCH_X86_64
77
 
    %define pointer dq
78
 
%else
79
 
    %define pointer dd
80
 
%endif
81
 
 
82
 
%macro IF0 1+
83
 
%endmacro
84
 
%macro IF1 1+
85
 
    %1
86
 
%endmacro
87
 
 
88
 
SECTION_TEXT
89
 
 
90
 
%macro T2_3DN 4 ; z0, z1, mem0, mem1
91
 
    mova     %1, %3
92
 
    mova     %2, %1
93
 
    pfadd    %1, %4
94
 
    pfsub    %2, %4
95
 
%endmacro
96
 
 
97
 
%macro T4_3DN 6 ; z0, z1, z2, z3, tmp0, tmp1
98
 
    mova     %5, %3
99
 
    pfsub    %3, %4
100
 
    pfadd    %5, %4 ; {t6,t5}
101
 
    pxor     %3, [ps_m1p1] ; {t8,t7}
102
 
    mova     %6, %1
103
 
    pswapd   %3, %3
104
 
    pfadd    %1, %5 ; {r0,i0}
105
 
    pfsub    %6, %5 ; {r2,i2}
106
 
    mova     %4, %2
107
 
    pfadd    %2, %3 ; {r1,i1}
108
 
    pfsub    %4, %3 ; {r3,i3}
109
 
    SWAP     %3, %6
110
 
%endmacro
111
 
 
112
 
;  in: %1 = {r0,i0,r2,i2,r4,i4,r6,i6}
113
 
;      %2 = {r1,i1,r3,i3,r5,i5,r7,i7}
114
 
;      %3, %4, %5 tmp
115
 
; out: %1 = {r0,r1,r2,r3,i0,i1,i2,i3}
116
 
;      %2 = {r4,r5,r6,r7,i4,i5,i6,i7}
117
 
%macro T8_AVX 5
118
 
    vsubps     %5, %1, %2       ; v  = %1 - %2
119
 
    vaddps     %3, %1, %2       ; w  = %1 + %2
120
 
    vmulps     %2, %5, [ps_p1p1m1p1root2]  ; v *= vals1
121
 
    vpermilps  %2, %2, [perm1]
122
 
    vblendps   %1, %2, %3, 0x33 ; q = {w1,w2,v4,v2,w5,w6,v7,v6}
123
 
    vshufps    %5, %3, %2, 0x4e ; r = {w3,w4,v1,v3,w7,w8,v8,v5}
124
 
    vsubps     %4, %5, %1       ; s = r - q
125
 
    vaddps     %1, %5, %1       ; u = r + q
126
 
    vpermilps  %1, %1, [perm2]  ; k  = {u1,u2,u3,u4,u6,u5,u7,u8}
127
 
    vshufps    %5, %4, %1, 0xbb
128
 
    vshufps    %3, %4, %1, 0xee
129
 
    vperm2f128 %3, %3, %5, 0x13
130
 
    vxorps     %4, %4, [ps_m1m1p1m1p1m1m1m1]  ; s *= {1,1,-1,-1,1,-1,-1,-1}
131
 
    vshufps    %2, %1, %4, 0xdd
132
 
    vshufps    %1, %1, %4, 0x88
133
 
    vperm2f128 %4, %2, %1, 0x02 ; v  = {k1,k3,s1,s3,k2,k4,s2,s4}
134
 
    vperm2f128 %1, %1, %2, 0x13 ; w  = {k6,k8,s6,s8,k5,k7,s5,s7}
135
 
    vsubps     %5, %1, %3
136
 
    vblendps   %1, %5, %1, 0x55 ; w -= {0,s7,0,k7,0,s8,0,k8}
137
 
    vsubps     %2, %4, %1       ; %2 = v - w
138
 
    vaddps     %1, %4, %1       ; %1 = v + w
139
 
%endmacro
140
 
 
141
 
; In SSE mode do one fft4 transforms
142
 
; in:  %1={r0,i0,r2,i2} %2={r1,i1,r3,i3}
143
 
; out: %1={r0,r1,r2,r3} %2={i0,i1,i2,i3}
144
 
;
145
 
; In AVX mode do two fft4 transforms
146
 
; in:  %1={r0,i0,r2,i2,r4,i4,r6,i6} %2={r1,i1,r3,i3,r5,i5,r7,i7}
147
 
; out: %1={r0,r1,r2,r3,r4,r5,r6,r7} %2={i0,i1,i2,i3,i4,i5,i6,i7}
148
 
%macro T4_SSE 3
149
 
    subps    %3, %1, %2       ; {t3,t4,-t8,t7}
150
 
    addps    %1, %1, %2       ; {t1,t2,t6,t5}
151
 
    xorps    %3, %3, [ps_p1p1m1p1]
152
 
    shufps   %2, %1, %3, 0xbe ; {t6,t5,t7,t8}
153
 
    shufps   %1, %1, %3, 0x44 ; {t1,t2,t3,t4}
154
 
    subps    %3, %1, %2       ; {r2,i2,r3,i3}
155
 
    addps    %1, %1, %2       ; {r0,i0,r1,i1}
156
 
    shufps   %2, %1, %3, 0xdd ; {i0,i1,i2,i3}
157
 
    shufps   %1, %1, %3, 0x88 ; {r0,r1,r2,r3}
158
 
%endmacro
159
 
 
160
 
; In SSE mode do one FFT8
161
 
; in:  %1={r0,r1,r2,r3} %2={i0,i1,i2,i3} %3={r4,i4,r6,i6} %4={r5,i5,r7,i7}
162
 
; out: %1={r0,r1,r2,r3} %2={i0,i1,i2,i3} %1={r4,r5,r6,r7} %2={i4,i5,i6,i7}
163
 
;
164
 
; In AVX mode do two FFT8
165
 
; in:  %1={r0,i0,r2,i2,r8, i8, r10,i10} %2={r1,i1,r3,i3,r9, i9, r11,i11}
166
 
;      %3={r4,i4,r6,i6,r12,i12,r14,i14} %4={r5,i5,r7,i7,r13,i13,r15,i15}
167
 
; out: %1={r0,r1,r2,r3,r8, r9, r10,r11} %2={i0,i1,i2,i3,i8, i9, i10,i11}
168
 
;      %3={r4,r5,r6,r7,r12,r13,r14,r15} %4={i4,i5,i6,i7,i12,i13,i14,i15}
169
 
%macro T8_SSE 6
170
 
    addps    %6, %3, %4       ; {t1,t2,t3,t4}
171
 
    subps    %3, %3, %4       ; {r5,i5,r7,i7}
172
 
    shufps   %4, %3, %3, 0xb1 ; {i5,r5,i7,r7}
173
 
    mulps    %3, %3, [ps_root2mppm] ; {-r5,i5,r7,-i7}
174
 
    mulps    %4, %4, [ps_root2]
175
 
    addps    %3, %3, %4       ; {t8,t7,ta,t9}
176
 
    shufps   %4, %6, %3, 0x9c ; {t1,t4,t7,ta}
177
 
    shufps   %6, %6, %3, 0x36 ; {t3,t2,t9,t8}
178
 
    subps    %3, %6, %4       ; {t6,t5,tc,tb}
179
 
    addps    %6, %6, %4       ; {t1,t2,t9,ta}
180
 
    shufps   %5, %6, %3, 0x8d ; {t2,ta,t6,tc}
181
 
    shufps   %6, %6, %3, 0xd8 ; {t1,t9,t5,tb}
182
 
    subps    %3, %1, %6       ; {r4,r5,r6,r7}
183
 
    addps    %1, %1, %6       ; {r0,r1,r2,r3}
184
 
    subps    %4, %2, %5       ; {i4,i5,i6,i7}
185
 
    addps    %2, %2, %5       ; {i0,i1,i2,i3}
186
 
%endmacro
187
 
 
188
 
; scheduled for cpu-bound sizes
189
 
%macro PASS_SMALL 3 ; (to load m4-m7), wre, wim
190
 
IF%1 mova    m4, Z(4)
191
 
IF%1 mova    m5, Z(5)
192
 
    mova     m0, %2 ; wre
193
 
    mova     m1, %3 ; wim
194
 
    mulps    m2, m4, m0 ; r2*wre
195
 
IF%1 mova    m6, Z2(6)
196
 
    mulps    m3, m5, m1 ; i2*wim
197
 
IF%1 mova    m7, Z2(7)
198
 
    mulps    m4, m4, m1 ; r2*wim
199
 
    mulps    m5, m5, m0 ; i2*wre
200
 
    addps    m2, m2, m3 ; r2*wre + i2*wim
201
 
    mulps    m3, m1, m7 ; i3*wim
202
 
    subps    m5, m5, m4 ; i2*wre - r2*wim
203
 
    mulps    m1, m1, m6 ; r3*wim
204
 
    mulps    m4, m0, m6 ; r3*wre
205
 
    mulps    m0, m0, m7 ; i3*wre
206
 
    subps    m4, m4, m3 ; r3*wre - i3*wim
207
 
    mova     m3, Z(0)
208
 
    addps    m0, m0, m1 ; i3*wre + r3*wim
209
 
    subps    m1, m4, m2 ; t3
210
 
    addps    m4, m4, m2 ; t5
211
 
    subps    m3, m3, m4 ; r2
212
 
    addps    m4, m4, Z(0) ; r0
213
 
    mova     m6, Z(2)
214
 
    mova   Z(4), m3
215
 
    mova   Z(0), m4
216
 
    subps    m3, m5, m0 ; t4
217
 
    subps    m4, m6, m3 ; r3
218
 
    addps    m3, m3, m6 ; r1
219
 
    mova  Z2(6), m4
220
 
    mova   Z(2), m3
221
 
    mova     m2, Z(3)
222
 
    addps    m3, m5, m0 ; t6
223
 
    subps    m2, m2, m1 ; i3
224
 
    mova     m7, Z(1)
225
 
    addps    m1, m1, Z(3) ; i1
226
 
    mova  Z2(7), m2
227
 
    mova   Z(3), m1
228
 
    subps    m4, m7, m3 ; i2
229
 
    addps    m3, m3, m7 ; i0
230
 
    mova   Z(5), m4
231
 
    mova   Z(1), m3
232
 
%endmacro
233
 
 
234
 
; scheduled to avoid store->load aliasing
235
 
%macro PASS_BIG 1 ; (!interleave)
236
 
    mova     m4, Z(4) ; r2
237
 
    mova     m5, Z(5) ; i2
238
 
    mova     m0, [wq] ; wre
239
 
    mova     m1, [wq+o1q] ; wim
240
 
    mulps    m2, m4, m0 ; r2*wre
241
 
    mova     m6, Z2(6) ; r3
242
 
    mulps    m3, m5, m1 ; i2*wim
243
 
    mova     m7, Z2(7) ; i3
244
 
    mulps    m4, m4, m1 ; r2*wim
245
 
    mulps    m5, m5, m0 ; i2*wre
246
 
    addps    m2, m2, m3 ; r2*wre + i2*wim
247
 
    mulps    m3, m1, m7 ; i3*wim
248
 
    mulps    m1, m1, m6 ; r3*wim
249
 
    subps    m5, m5, m4 ; i2*wre - r2*wim
250
 
    mulps    m4, m0, m6 ; r3*wre
251
 
    mulps    m0, m0, m7 ; i3*wre
252
 
    subps    m4, m4, m3 ; r3*wre - i3*wim
253
 
    mova     m3, Z(0)
254
 
    addps    m0, m0, m1 ; i3*wre + r3*wim
255
 
    subps    m1, m4, m2 ; t3
256
 
    addps    m4, m4, m2 ; t5
257
 
    subps    m3, m3, m4 ; r2
258
 
    addps    m4, m4, Z(0) ; r0
259
 
    mova     m6, Z(2)
260
 
    mova   Z(4), m3
261
 
    mova   Z(0), m4
262
 
    subps    m3, m5, m0 ; t4
263
 
    subps    m4, m6, m3 ; r3
264
 
    addps    m3, m3, m6 ; r1
265
 
IF%1 mova Z2(6), m4
266
 
IF%1 mova  Z(2), m3
267
 
    mova     m2, Z(3)
268
 
    addps    m5, m5, m0 ; t6
269
 
    subps    m2, m2, m1 ; i3
270
 
    mova     m7, Z(1)
271
 
    addps    m1, m1, Z(3) ; i1
272
 
IF%1 mova Z2(7), m2
273
 
IF%1 mova  Z(3), m1
274
 
    subps    m6, m7, m5 ; i2
275
 
    addps    m5, m5, m7 ; i0
276
 
IF%1 mova  Z(5), m6
277
 
IF%1 mova  Z(1), m5
278
 
%if %1==0
279
 
    INTERL m1, m3, m7, Z, 2
280
 
    INTERL m2, m4, m0, Z2, 6
281
 
 
282
 
    mova     m1, Z(0)
283
 
    mova     m2, Z(4)
284
 
 
285
 
    INTERL m5, m1, m3, Z, 0
286
 
    INTERL m6, m2, m7, Z, 4
287
 
%endif
288
 
%endmacro
289
 
 
290
 
%macro PUNPCK 3
291
 
    mova      %3, %1
292
 
    punpckldq %1, %2
293
 
    punpckhdq %3, %2
294
 
%endmacro
295
 
 
296
 
%define Z(x) [r0+mmsize*x]
297
 
%define Z2(x) [r0+mmsize*x]
298
 
%define ZH(x) [r0+mmsize*x+mmsize/2]
299
 
 
300
 
INIT_YMM
301
 
 
302
 
%ifdef HAVE_AVX
303
 
align 16
304
 
fft8_avx:
305
 
    mova      m0, Z(0)
306
 
    mova      m1, Z(1)
307
 
    T8_AVX    m0, m1, m2, m3, m4
308
 
    mova      Z(0), m0
309
 
    mova      Z(1), m1
310
 
    ret
311
 
 
312
 
 
313
 
align 16
314
 
fft16_avx:
315
 
    mova       m2, Z(2)
316
 
    mova       m3, Z(3)
317
 
    T4_SSE     m2, m3, m7
318
 
 
319
 
    mova       m0, Z(0)
320
 
    mova       m1, Z(1)
321
 
    T8_AVX     m0, m1, m4, m5, m7
322
 
 
323
 
    mova       m4, [ps_cos16_1]
324
 
    mova       m5, [ps_cos16_2]
325
 
    vmulps     m6, m2, m4
326
 
    vmulps     m7, m3, m5
327
 
    vaddps     m7, m7, m6
328
 
    vmulps     m2, m2, m5
329
 
    vmulps     m3, m3, m4
330
 
    vsubps     m3, m3, m2
331
 
    vblendps   m2, m7, m3, 0xf0
332
 
    vperm2f128 m3, m7, m3, 0x21
333
 
    vaddps     m4, m2, m3
334
 
    vsubps     m2, m3, m2
335
 
    vperm2f128 m2, m2, m2, 0x01
336
 
    vsubps     m3, m1, m2
337
 
    vaddps     m1, m1, m2
338
 
    vsubps     m5, m0, m4
339
 
    vaddps     m0, m0, m4
340
 
    vextractf128   Z(0), m0, 0
341
 
    vextractf128  ZH(0), m1, 0
342
 
    vextractf128   Z(1), m0, 1
343
 
    vextractf128  ZH(1), m1, 1
344
 
    vextractf128   Z(2), m5, 0
345
 
    vextractf128  ZH(2), m3, 0
346
 
    vextractf128   Z(3), m5, 1
347
 
    vextractf128  ZH(3), m3, 1
348
 
    ret
349
 
 
350
 
align 16
351
 
fft32_avx:
352
 
    call fft16_avx
353
 
 
354
 
    mova m0, Z(4)
355
 
    mova m1, Z(5)
356
 
 
357
 
    T4_SSE      m0, m1, m4
358
 
 
359
 
    mova m2, Z(6)
360
 
    mova m3, Z(7)
361
 
 
362
 
    T8_SSE      m0, m1, m2, m3, m4, m6
363
 
    ; m0={r0,r1,r2,r3,r8, r9, r10,r11} m1={i0,i1,i2,i3,i8, i9, i10,i11}
364
 
    ; m2={r4,r5,r6,r7,r12,r13,r14,r15} m3={i4,i5,i6,i7,i12,i13,i14,i15}
365
 
 
366
 
    vperm2f128  m4, m0, m2, 0x20
367
 
    vperm2f128  m5, m1, m3, 0x20
368
 
    vperm2f128  m6, m0, m2, 0x31
369
 
    vperm2f128  m7, m1, m3, 0x31
370
 
 
371
 
    PASS_SMALL 0, [cos_32], [cos_32+32]
372
 
 
373
 
    ret
374
 
 
375
 
fft32_interleave_avx:
376
 
    call fft32_avx
377
 
    mov r2d, 32
378
 
.deint_loop:
379
 
    mova     m2, Z(0)
380
 
    mova     m3, Z(1)
381
 
    vunpcklps      m0, m2, m3
382
 
    vunpckhps      m1, m2, m3
383
 
    vextractf128   Z(0), m0, 0
384
 
    vextractf128  ZH(0), m1, 0
385
 
    vextractf128   Z(1), m0, 1
386
 
    vextractf128  ZH(1), m1, 1
387
 
    add r0, mmsize*2
388
 
    sub r2d, mmsize/4
389
 
    jg .deint_loop
390
 
    ret
391
 
%endif
392
 
 
393
 
INIT_XMM
394
 
%define movdqa  movaps
395
 
 
396
 
align 16
397
 
fft4_avx:
398
 
fft4_sse:
399
 
    mova     m0, Z(0)
400
 
    mova     m1, Z(1)
401
 
    T4_SSE   m0, m1, m2
402
 
    mova   Z(0), m0
403
 
    mova   Z(1), m1
404
 
    ret
405
 
 
406
 
align 16
407
 
fft8_sse:
408
 
    mova     m0, Z(0)
409
 
    mova     m1, Z(1)
410
 
    T4_SSE   m0, m1, m2
411
 
    mova     m2, Z(2)
412
 
    mova     m3, Z(3)
413
 
    T8_SSE   m0, m1, m2, m3, m4, m5
414
 
    mova   Z(0), m0
415
 
    mova   Z(1), m1
416
 
    mova   Z(2), m2
417
 
    mova   Z(3), m3
418
 
    ret
419
 
 
420
 
align 16
421
 
fft16_sse:
422
 
    mova     m0, Z(0)
423
 
    mova     m1, Z(1)
424
 
    T4_SSE   m0, m1, m2
425
 
    mova     m2, Z(2)
426
 
    mova     m3, Z(3)
427
 
    T8_SSE   m0, m1, m2, m3, m4, m5
428
 
    mova     m4, Z(4)
429
 
    mova     m5, Z(5)
430
 
    mova   Z(0), m0
431
 
    mova   Z(1), m1
432
 
    mova   Z(2), m2
433
 
    mova   Z(3), m3
434
 
    T4_SSE   m4, m5, m6
435
 
    mova     m6, Z2(6)
436
 
    mova     m7, Z2(7)
437
 
    T4_SSE   m6, m7, m0
438
 
    PASS_SMALL 0, [cos_16], [cos_16+16]
439
 
    ret
440
 
 
441
 
 
442
 
INIT_MMX
443
 
 
444
 
%macro FFT48_3DN 1
445
 
align 16
446
 
fft4%1:
447
 
    T2_3DN   m0, m1, Z(0), Z(1)
448
 
    mova     m2, Z(2)
449
 
    mova     m3, Z(3)
450
 
    T4_3DN   m0, m1, m2, m3, m4, m5
451
 
    PUNPCK   m0, m1, m4
452
 
    PUNPCK   m2, m3, m5
453
 
    mova   Z(0), m0
454
 
    mova   Z(1), m4
455
 
    mova   Z(2), m2
456
 
    mova   Z(3), m5
457
 
    ret
458
 
 
459
 
align 16
460
 
fft8%1:
461
 
    T2_3DN   m0, m1, Z(0), Z(1)
462
 
    mova     m2, Z(2)
463
 
    mova     m3, Z(3)
464
 
    T4_3DN   m0, m1, m2, m3, m4, m5
465
 
    mova   Z(0), m0
466
 
    mova   Z(2), m2
467
 
    T2_3DN   m4, m5,  Z(4),  Z(5)
468
 
    T2_3DN   m6, m7, Z2(6), Z2(7)
469
 
    pswapd   m0, m5
470
 
    pswapd   m2, m7
471
 
    pxor     m0, [ps_m1p1]
472
 
    pxor     m2, [ps_m1p1]
473
 
    pfsub    m5, m0
474
 
    pfadd    m7, m2
475
 
    pfmul    m5, [ps_root2]
476
 
    pfmul    m7, [ps_root2]
477
 
    T4_3DN   m1, m3, m5, m7, m0, m2
478
 
    mova   Z(5), m5
479
 
    mova  Z2(7), m7
480
 
    mova     m0, Z(0)
481
 
    mova     m2, Z(2)
482
 
    T4_3DN   m0, m2, m4, m6, m5, m7
483
 
    PUNPCK   m0, m1, m5
484
 
    PUNPCK   m2, m3, m7
485
 
    mova   Z(0), m0
486
 
    mova   Z(1), m5
487
 
    mova   Z(2), m2
488
 
    mova   Z(3), m7
489
 
    PUNPCK   m4,  Z(5), m5
490
 
    PUNPCK   m6, Z2(7), m7
491
 
    mova   Z(4), m4
492
 
    mova   Z(5), m5
493
 
    mova  Z2(6), m6
494
 
    mova  Z2(7), m7
495
 
    ret
496
 
%endmacro
497
 
 
498
 
FFT48_3DN _3dn2
499
 
 
500
 
%macro pswapd 2
501
 
%ifidn %1, %2
502
 
    movd [r0+12], %1
503
 
    punpckhdq %1, [r0+8]
504
 
%else
505
 
    movq  %1, %2
506
 
    psrlq %1, 32
507
 
    punpckldq %1, %2
508
 
%endif
509
 
%endmacro
510
 
 
511
 
FFT48_3DN _3dn
512
 
 
513
 
 
514
 
%define Z(x) [zq + o1q*(x&6) + mmsize*(x&1)]
515
 
%define Z2(x) [zq + o3q + mmsize*(x&1)]
516
 
%define ZH(x) [zq + o1q*(x&6) + mmsize*(x&1) + mmsize/2]
517
 
%define Z2H(x) [zq + o3q + mmsize*(x&1) + mmsize/2]
518
 
 
519
 
%macro DECL_PASS 2+ ; name, payload
520
 
align 16
521
 
%1:
522
 
DEFINE_ARGS z, w, n, o1, o3
523
 
    lea o3q, [nq*3]
524
 
    lea o1q, [nq*8]
525
 
    shl o3q, 4
526
 
.loop:
527
 
    %2
528
 
    add zq, mmsize*2
529
 
    add wq, mmsize
530
 
    sub nd, mmsize/8
531
 
    jg .loop
532
 
    rep ret
533
 
%endmacro
534
 
 
535
 
INIT_YMM
536
 
 
537
 
%ifdef HAVE_AVX
538
 
%macro INTERL_AVX 5
539
 
    vunpckhps      %3, %2, %1
540
 
    vunpcklps      %2, %2, %1
541
 
    vextractf128   %4(%5), %2, 0
542
 
    vextractf128  %4 %+ H(%5), %3, 0
543
 
    vextractf128   %4(%5 + 1), %2, 1
544
 
    vextractf128  %4 %+ H(%5 + 1), %3, 1
545
 
%endmacro
546
 
 
547
 
%define INTERL INTERL_AVX
548
 
 
549
 
DECL_PASS pass_avx, PASS_BIG 1
550
 
DECL_PASS pass_interleave_avx, PASS_BIG 0
551
 
%endif
552
 
 
553
 
INIT_XMM
554
 
 
555
 
%macro INTERL_SSE 5
556
 
    mova     %3, %2
557
 
    unpcklps %2, %1
558
 
    unpckhps %3, %1
559
 
    mova  %4(%5), %2
560
 
    mova  %4(%5+1), %3
561
 
%endmacro
562
 
 
563
 
%define INTERL INTERL_SSE
564
 
 
565
 
DECL_PASS pass_sse, PASS_BIG 1
566
 
DECL_PASS pass_interleave_sse, PASS_BIG 0
567
 
 
568
 
INIT_MMX
569
 
%define mulps pfmul
570
 
%define addps pfadd
571
 
%define subps pfsub
572
 
%define unpcklps punpckldq
573
 
%define unpckhps punpckhdq
574
 
DECL_PASS pass_3dn, PASS_SMALL 1, [wq], [wq+o1q]
575
 
DECL_PASS pass_interleave_3dn, PASS_BIG 0
576
 
%define pass_3dn2 pass_3dn
577
 
%define pass_interleave_3dn2 pass_interleave_3dn
578
 
 
579
 
%ifdef PIC
580
 
%define SECTION_REL - $$
581
 
%else
582
 
%define SECTION_REL
583
 
%endif
584
 
 
585
 
%macro FFT_DISPATCH 2; clobbers 5 GPRs, 8 XMMs
586
 
    lea r2, [dispatch_tab%1]
587
 
    mov r2, [r2 + (%2q-2)*gprsize]
588
 
%ifdef PIC
589
 
    lea r3, [$$]
590
 
    add r2, r3
591
 
%endif
592
 
    call r2
593
 
%endmacro ; FFT_DISPATCH
594
 
 
595
 
%macro DECL_FFT 2-3 ; nbits, cpu, suffix
596
 
%xdefine list_of_fft fft4%2 SECTION_REL, fft8%2 SECTION_REL
597
 
%if %1>=5
598
 
%xdefine list_of_fft list_of_fft, fft16%2 SECTION_REL
599
 
%endif
600
 
%if %1>=6
601
 
%xdefine list_of_fft list_of_fft, fft32%3%2 SECTION_REL
602
 
%endif
603
 
 
604
 
%assign n 1<<%1
605
 
%rep 17-%1
606
 
%assign n2 n/2
607
 
%assign n4 n/4
608
 
%xdefine list_of_fft list_of_fft, fft %+ n %+ %3%2 SECTION_REL
609
 
 
610
 
align 16
611
 
fft %+ n %+ %3%2:
612
 
    call fft %+ n2 %+ %2
613
 
    add r0, n*4 - (n&(-2<<%1))
614
 
    call fft %+ n4 %+ %2
615
 
    add r0, n*2 - (n2&(-2<<%1))
616
 
    call fft %+ n4 %+ %2
617
 
    sub r0, n*6 + (n2&(-2<<%1))
618
 
    lea r1, [cos_ %+ n]
619
 
    mov r2d, n4/2
620
 
    jmp pass%3%2
621
 
 
622
 
%assign n n*2
623
 
%endrep
624
 
%undef n
625
 
 
626
 
align 8
627
 
dispatch_tab%3%2: pointer list_of_fft
628
 
 
629
 
section .text
630
 
 
631
 
; On x86_32, this function does the register saving and restoring for all of fft.
632
 
; The others pass args in registers and don't spill anything.
633
 
cglobal fft_dispatch%3%2, 2,5,8, z, nbits
634
 
    FFT_DISPATCH %3%2, nbits
635
 
%ifidn %2, _avx
636
 
    vzeroupper
637
 
%endif
638
 
    RET
639
 
%endmacro ; DECL_FFT
640
 
 
641
 
%ifdef HAVE_AVX
642
 
INIT_YMM
643
 
DECL_FFT 6, _avx
644
 
DECL_FFT 6, _avx, _interleave
645
 
%endif
646
 
INIT_XMM
647
 
DECL_FFT 5, _sse
648
 
DECL_FFT 5, _sse, _interleave
649
 
INIT_MMX
650
 
DECL_FFT 4, _3dn
651
 
DECL_FFT 4, _3dn, _interleave
652
 
DECL_FFT 4, _3dn2
653
 
DECL_FFT 4, _3dn2, _interleave
654
 
 
655
 
INIT_XMM
656
 
%undef mulps
657
 
%undef addps
658
 
%undef subps
659
 
%undef unpcklps
660
 
%undef unpckhps
661
 
 
662
 
%macro PREROTATER 5 ;-2*k, 2*k, input+n4, tcos+n8, tsin+n8
663
 
    movaps   xmm0, [%3+%2*4]
664
 
    movaps   xmm1, [%3+%1*4-0x10]
665
 
    movaps   xmm2, xmm0
666
 
    shufps   xmm0, xmm1, 0x88
667
 
    shufps   xmm1, xmm2, 0x77
668
 
    movlps   xmm4, [%4+%2*2]
669
 
    movlps   xmm5, [%5+%2*2+0x0]
670
 
    movhps   xmm4, [%4+%1*2-0x8]
671
 
    movhps   xmm5, [%5+%1*2-0x8]
672
 
    movaps   xmm2, xmm0
673
 
    movaps   xmm3, xmm1
674
 
    mulps    xmm0, xmm5
675
 
    mulps    xmm1, xmm4
676
 
    mulps    xmm2, xmm4
677
 
    mulps    xmm3, xmm5
678
 
    subps    xmm1, xmm0
679
 
    addps    xmm2, xmm3
680
 
    movaps   xmm0, xmm1
681
 
    unpcklps xmm1, xmm2
682
 
    unpckhps xmm0, xmm2
683
 
%endmacro
684
 
 
685
 
%macro CMUL 6 ;j, xmm0, xmm1, 3, 4, 5
686
 
    mulps      m6, %3, [%5+%1]
687
 
    mulps      m7, %2, [%5+%1]
688
 
    mulps      %2, %2, [%6+%1]
689
 
    mulps      %3, %3, [%6+%1]
690
 
    subps      %2, %2, m6
691
 
    addps      %3, %3, m7
692
 
%endmacro
693
 
 
694
 
%macro POSROTATESHUF_AVX 5 ;j, k, z+n8, tcos+n8, tsin+n8
695
 
.post:
696
 
    vmovaps      ymm1,   [%3+%1*2]
697
 
    vmovaps      ymm0,   [%3+%1*2+0x20]
698
 
    vmovaps      ymm3,   [%3+%2*2]
699
 
    vmovaps      ymm2,   [%3+%2*2+0x20]
700
 
 
701
 
    CMUL         %1, ymm0, ymm1, %3, %4, %5
702
 
    CMUL         %2, ymm2, ymm3, %3, %4, %5
703
 
    vshufps      ymm1, ymm1, ymm1, 0x1b
704
 
    vshufps      ymm3, ymm3, ymm3, 0x1b
705
 
    vperm2f128   ymm1, ymm1, ymm1, 0x01
706
 
    vperm2f128   ymm3, ymm3, ymm3, 0x01
707
 
    vunpcklps    ymm6, ymm2, ymm1
708
 
    vunpckhps    ymm4, ymm2, ymm1
709
 
    vunpcklps    ymm7, ymm0, ymm3
710
 
    vunpckhps    ymm5, ymm0, ymm3
711
 
 
712
 
    vextractf128 [%3+%1*2],      ymm7, 0
713
 
    vextractf128 [%3+%1*2+0x10], ymm5, 0
714
 
    vextractf128 [%3+%1*2+0x20], ymm7, 1
715
 
    vextractf128 [%3+%1*2+0x30], ymm5, 1
716
 
 
717
 
    vextractf128 [%3+%2*2],      ymm6, 0
718
 
    vextractf128 [%3+%2*2+0x10], ymm4, 0
719
 
    vextractf128 [%3+%2*2+0x20], ymm6, 1
720
 
    vextractf128 [%3+%2*2+0x30], ymm4, 1
721
 
    sub      %2,   0x20
722
 
    add      %1,   0x20
723
 
    jl       .post
724
 
%endmacro
725
 
 
726
 
%macro POSROTATESHUF 5 ;j, k, z+n8, tcos+n8, tsin+n8
727
 
.post:
728
 
    movaps   xmm1, [%3+%1*2]
729
 
    movaps   xmm0, [%3+%1*2+0x10]
730
 
    CMUL     %1,   xmm0, xmm1, %3, %4, %5
731
 
    movaps   xmm5, [%3+%2*2]
732
 
    movaps   xmm4, [%3+%2*2+0x10]
733
 
    CMUL     %2,   xmm4, xmm5, %3, %4, %5
734
 
    shufps   xmm1, xmm1, 0x1b
735
 
    shufps   xmm5, xmm5, 0x1b
736
 
    movaps   xmm6, xmm4
737
 
    unpckhps xmm4, xmm1
738
 
    unpcklps xmm6, xmm1
739
 
    movaps   xmm2, xmm0
740
 
    unpcklps xmm0, xmm5
741
 
    unpckhps xmm2, xmm5
742
 
    movaps   [%3+%2*2],      xmm6
743
 
    movaps   [%3+%2*2+0x10], xmm4
744
 
    movaps   [%3+%1*2],      xmm0
745
 
    movaps   [%3+%1*2+0x10], xmm2
746
 
    sub      %2,   0x10
747
 
    add      %1,   0x10
748
 
    jl       .post
749
 
%endmacro
750
 
 
751
 
%macro DECL_IMDCT 2
752
 
cglobal imdct_half%1, 3,7,8; FFTContext *s, FFTSample *output, const FFTSample *input
753
 
%ifdef ARCH_X86_64
754
 
%define rrevtab r10
755
 
%define rtcos   r11
756
 
%define rtsin   r12
757
 
    push  r12
758
 
    push  r13
759
 
    push  r14
760
 
%else
761
 
%define rrevtab r6
762
 
%define rtsin   r6
763
 
%define rtcos   r5
764
 
%endif
765
 
    mov   r3d, [r0+FFTContext.mdctsize]
766
 
    add   r2, r3
767
 
    shr   r3, 1
768
 
    mov   rtcos, [r0+FFTContext.tcos]
769
 
    mov   rtsin, [r0+FFTContext.tsin]
770
 
    add   rtcos, r3
771
 
    add   rtsin, r3
772
 
%ifndef ARCH_X86_64
773
 
    push  rtcos
774
 
    push  rtsin
775
 
%endif
776
 
    shr   r3, 1
777
 
    mov   rrevtab, [r0+FFTContext.revtab]
778
 
    add   rrevtab, r3
779
 
%ifndef ARCH_X86_64
780
 
    push  rrevtab
781
 
%endif
782
 
 
783
 
    sub   r3, 4
784
 
%ifdef ARCH_X86_64
785
 
    xor   r4, r4
786
 
    sub   r4, r3
787
 
%endif
788
 
.pre:
789
 
%ifndef ARCH_X86_64
790
 
;unspill
791
 
    xor   r4, r4
792
 
    sub   r4, r3
793
 
    mov   rtsin, [esp+4]
794
 
    mov   rtcos, [esp+8]
795
 
%endif
796
 
 
797
 
    PREROTATER r4, r3, r2, rtcos, rtsin
798
 
%ifdef ARCH_X86_64
799
 
    movzx  r5,  word [rrevtab+r4-4]
800
 
    movzx  r6,  word [rrevtab+r4-2]
801
 
    movzx  r13, word [rrevtab+r3]
802
 
    movzx  r14, word [rrevtab+r3+2]
803
 
    movlps [r1+r5 *8], xmm0
804
 
    movhps [r1+r6 *8], xmm0
805
 
    movlps [r1+r13*8], xmm1
806
 
    movhps [r1+r14*8], xmm1
807
 
    add    r4, 4
808
 
%else
809
 
    mov    r6, [esp]
810
 
    movzx  r5, word [r6+r4-4]
811
 
    movzx  r4, word [r6+r4-2]
812
 
    movlps [r1+r5*8], xmm0
813
 
    movhps [r1+r4*8], xmm0
814
 
    movzx  r5, word [r6+r3]
815
 
    movzx  r4, word [r6+r3+2]
816
 
    movlps [r1+r5*8], xmm1
817
 
    movhps [r1+r4*8], xmm1
818
 
%endif
819
 
    sub    r3, 4
820
 
    jns    .pre
821
 
 
822
 
    mov  r5, r0
823
 
    mov  r6, r1
824
 
    mov  r0, r1
825
 
    mov  r1d, [r5+FFTContext.nbits]
826
 
 
827
 
    FFT_DISPATCH %1, r1
828
 
 
829
 
    mov  r0d, [r5+FFTContext.mdctsize]
830
 
    add  r6, r0
831
 
    shr  r0, 1
832
 
%ifndef ARCH_X86_64
833
 
%define rtcos r2
834
 
%define rtsin r3
835
 
    mov  rtcos, [esp+8]
836
 
    mov  rtsin, [esp+4]
837
 
%endif
838
 
    neg  r0
839
 
    mov  r1, -mmsize
840
 
    sub  r1, r0
841
 
    %2 r0, r1, r6, rtcos, rtsin
842
 
%ifdef ARCH_X86_64
843
 
    pop  r14
844
 
    pop  r13
845
 
    pop  r12
846
 
%else
847
 
    add esp, 12
848
 
%endif
849
 
%ifidn avx_enabled, 1
850
 
    vzeroupper
851
 
%endif
852
 
    RET
853
 
%endmacro
854
 
 
855
 
DECL_IMDCT _sse, POSROTATESHUF
856
 
 
857
 
INIT_YMM
858
 
 
859
 
%ifdef HAVE_AVX
860
 
DECL_IMDCT _avx, POSROTATESHUF_AVX
861
 
%endif