vp9: split pre-load of 11585x2 out of 1d idct macro.
[ffmpeg.git] / libavcodec / x86 / vp9itxfm.asm
1 ;******************************************************************************
2 ;* VP9 IDCT SIMD optimizations
3 ;*
4 ;* Copyright (C) 2013 Clément Bœsch <u pkh me>
5 ;*
6 ;* This file is part of FFmpeg.
7 ;*
8 ;* FFmpeg is free software; you can redistribute it and/or
9 ;* modify it under the terms of the GNU Lesser General Public
10 ;* License as published by the Free Software Foundation; either
11 ;* version 2.1 of the License, or (at your option) any later version.
12 ;*
13 ;* FFmpeg is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ;* Lesser General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU Lesser General Public
19 ;* License along with FFmpeg; if not, write to the Free Software
20 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;******************************************************************************
22
23 %include "libavutil/x86/x86util.asm"
24
25 SECTION_RODATA
26
27 pw_11585x2: times 8 dw 23170
28
29 %macro VP9_IDCT_COEFFS 2
30 pw_m%1_%2: dw -%1, %2, -%1, %2, -%1, %2, -%1, %2
31 pw_%2_%1:  dw  %2, %1,  %2, %1,  %2, %1,  %2, %1
32 %endmacro
33
34 %macro VP9_IDCT_COEFFS_ALL 2
35 pw_%1x2: times 8 dw %1*2
36 pw_%2x2: times 8 dw %2*2
37 VP9_IDCT_COEFFS %1, %2
38 %endmacro
39
40 VP9_IDCT_COEFFS_ALL 15137,  6270
41 VP9_IDCT_COEFFS_ALL 16069,  3196
42 VP9_IDCT_COEFFS      9102, 13623
43
44 pd_8192: times 4 dd 8192
45 pw_2048: times 8 dw 2048
46 pw_1024: times 8 dw 1024
47
48 SECTION .text
49
50 ; (a*x + b*y + round) >> shift
51 %macro VP9_MULSUB_2W_2X 6 ; dst1, dst2, src (unchanged), round, coefs1, coefs2
52     pmaddwd            m%1, m%3, %5
53     pmaddwd            m%2, m%3, %6
54     paddd              m%1,  %4
55     paddd              m%2,  %4
56     psrad              m%1,  14
57     psrad              m%2,  14
58 %endmacro
59
60 %macro VP9_UNPACK_MULSUB_2W_4X 7 ; dst1, dst2, coef1, coef2, rnd, tmp1, tmp2
61     punpckhwd          m%6, m%2, m%1
62     VP9_MULSUB_2W_2X    %7,  %6,  %6, %5, [pw_m%3_%4], [pw_%4_%3]
63     punpcklwd          m%2, m%1
64     VP9_MULSUB_2W_2X    %1,  %2,  %2, %5, [pw_m%3_%4], [pw_%4_%3]
65     packssdw           m%1, m%7
66     packssdw           m%2, m%6
67 %endmacro
68
69 %macro VP9_STORE_2X 5 ; reg1, reg2, tmp1, tmp2, zero
70     movh               m%3, [dstq]
71     movh               m%4, [dstq+strideq]
72     punpcklbw          m%3, m%5
73     punpcklbw          m%4, m%5
74     paddw              m%3, m%1
75     paddw              m%4, m%2
76     packuswb           m%3, m%5
77     packuswb           m%4, m%5
78     movh            [dstq], m%3
79     movh    [dstq+strideq], m%4
80 %endmacro
81
82 ;-------------------------------------------------------------------------------------------
83 ; void vp9_idct_idct_4x4_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
84 ;-------------------------------------------------------------------------------------------
85
86 %macro VP9_IDCT4_1D_FINALIZE 0
87     SUMSUB_BA            w, 3, 2, 4                         ; m3=t3+t0, m2=-t3+t0
88     SUMSUB_BA            w, 1, 0, 4                         ; m1=t2+t1, m0=-t2+t1
89     SWAP                 0, 3, 2                            ; 3102 -> 0123
90 %endmacro
91
92 %macro VP9_IDCT4_1D 0
93     SUMSUB_BA            w, 2, 0, 4                         ; m2=IN(0)+IN(2) m0=IN(0)-IN(2)
94     pmulhrsw            m2, m6                              ; m2=t0
95     pmulhrsw            m0, m6                              ; m0=t1
96     VP9_UNPACK_MULSUB_2W_4X 1, 3, 15137, 6270, m7, 4, 5     ; m1=t2, m3=t3
97     VP9_IDCT4_1D_FINALIZE
98 %endmacro
99
100 ; 2x2 top left corner
101 %macro VP9_IDCT4_2x2_1D 0
102     pmulhrsw            m0, m5                              ; m0=t1
103     mova                m2, m0                              ; m2=t0
104     mova                m3, m1
105     pmulhrsw            m1, m6                              ; m1=t2
106     pmulhrsw            m3, m7                              ; m3=t3
107     VP9_IDCT4_1D_FINALIZE
108 %endmacro
109
110 %macro VP9_IDCT4_WRITEOUT 0
111     mova                m5, [pw_2048]
112     pmulhrsw            m0, m5              ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4
113     pmulhrsw            m1, m5
114     VP9_STORE_2X         0,  1,  6,  7,  4
115     lea               dstq, [dstq+2*strideq]
116     pmulhrsw            m2, m5
117     pmulhrsw            m3, m5
118     VP9_STORE_2X         2,  3,  6,  7,  4
119 %endmacro
120
121 INIT_MMX ssse3
122 cglobal vp9_idct_idct_4x4_add, 4,4,0, dst, stride, block, eob
123
124     cmp eobd, 4 ; 2x2 or smaller
125     jg .idctfull
126
127     cmp eobd, 1 ; faster path for when only DC is set
128     jne .idct2x2
129
130     movd                m0, [blockq]
131     mova                m5, [pw_11585x2]
132     pmulhrsw            m0, m5
133     pmulhrsw            m0, m5
134     pshufw              m0, m0, 0
135     pxor                m4, m4
136     movh          [blockq], m4
137     pmulhrsw            m0, [pw_2048]       ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4
138     VP9_STORE_2X         0,  0,  6,  7,  4
139     lea               dstq, [dstq+2*strideq]
140     VP9_STORE_2X         0,  0,  6,  7,  4
141     RET
142
143 ; faster path for when only top left 2x2 block is set
144 .idct2x2:
145     movd                m0, [blockq+0]
146     movd                m1, [blockq+8]
147     mova                m5, [pw_11585x2]
148     mova                m6, [pw_6270x2]
149     mova                m7, [pw_15137x2]
150     VP9_IDCT4_2x2_1D
151     TRANSPOSE4x4W  0, 1, 2, 3, 4
152     VP9_IDCT4_2x2_1D
153     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
154     movh       [blockq+ 0], m4
155     movh       [blockq+ 8], m4
156     VP9_IDCT4_WRITEOUT
157     RET
158
159 .idctfull: ; generic full 4x4 idct/idct
160     mova                m0, [blockq+ 0]
161     mova                m1, [blockq+ 8]
162     mova                m2, [blockq+16]
163     mova                m3, [blockq+24]
164     mova                m6, [pw_11585x2]
165     mova                m7, [pd_8192]       ; rounding
166     VP9_IDCT4_1D
167     TRANSPOSE4x4W  0, 1, 2, 3, 4
168     VP9_IDCT4_1D
169     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
170     mova       [blockq+ 0], m4
171     mova       [blockq+ 8], m4
172     mova       [blockq+16], m4
173     mova       [blockq+24], m4
174     VP9_IDCT4_WRITEOUT
175     RET
176
177 ;-------------------------------------------------------------------------------------------
178 ; void vp9_idct_idct_8x8_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
179 ;-------------------------------------------------------------------------------------------
180
181 %if ARCH_X86_64 ; TODO: 32-bit? (32-bit limited to 8 xmm reg, we use 13 here)
182 %macro VP9_IDCT8_1D_FINALIZE 0
183     SUMSUB_BA            w,  3, 10, 4                       ;  m3=t0+t7, m10=t0-t7
184     SUMSUB_BA            w,  1,  2, 4                       ;  m1=t1+t6,  m2=t1-t6
185     SUMSUB_BA            w, 11,  0, 4                       ; m11=t2+t5,  m0=t2-t5
186     SUMSUB_BA            w,  9,  8, 4                       ;  m9=t3+t4,  m8=t3-t4
187     SWAP                11, 10, 2
188     SWAP                 3,  9, 0
189 %endmacro
190
191 %macro VP9_IDCT8_1D 0
192     SUMSUB_BA            w, 8, 0, 4                         ; m8=IN(0)+IN(4) m0=IN(0)-IN(4)
193     pmulhrsw            m8, m12                             ; m8=t0a
194     pmulhrsw            m0, m12                             ; m0=t1a
195     VP9_UNPACK_MULSUB_2W_4X 2, 10, 15137,  6270, m7, 4, 5   ; m2=t2a, m10=t3a
196     VP9_UNPACK_MULSUB_2W_4X 1, 11, 16069,  3196, m7, 4, 5   ; m1=t4a, m11=t7a
197     VP9_UNPACK_MULSUB_2W_4X 9,  3,  9102, 13623, m7, 4, 5   ; m9=t5a,  m3=t6a
198     SUMSUB_BA            w, 10,  8, 4                       ; m10=t0a+t3a (t0),  m8=t0a-t3a (t3)
199     SUMSUB_BA            w,  2,  0, 4                       ;  m2=t1a+t2a (t1),  m0=t1a-t2a (t2)
200     SUMSUB_BA            w,  9,  1, 4                       ;  m9=t4a+t5a (t4),  m1=t4a-t5a (t5a)
201     SUMSUB_BA            w,  3, 11, 4                       ;  m3=t7a+t6a (t7), m11=t7a-t6a (t6a)
202     SUMSUB_BA            w,  1, 11, 4                       ;  m1=t6a+t5a (t6), m11=t6a-t5a (t5)
203     pmulhrsw            m1, m12                             ; m1=t6
204     pmulhrsw           m11, m12                             ; m11=t5
205     VP9_IDCT8_1D_FINALIZE
206 %endmacro
207
208 ; TODO: a lot of t* copies can probably be removed and merged with
209 ; following SUMSUBs from VP9_IDCT8_1D_FINALIZE with AVX
210 %macro VP9_IDCT8_2x2_1D 0
211     pmulhrsw            m0, m12                             ;  m0=t0
212     mova                m3, m1
213     pmulhrsw            m1, m6                              ;  m1=t4
214     pmulhrsw            m3, m7                              ;  m3=t7
215     mova                m2, m0                              ;  m2=t1
216     mova               m10, m0                              ; m10=t2
217     mova                m8, m0                              ;  m8=t3
218     mova               m11, m3                              ; t5 = t7a ...
219     mova                m9, m3                              ; t6 = t7a ...
220     psubw              m11, m1                              ; t5 = t7a - t4a
221     paddw               m9, m1                              ; t6 = t7a + t4a
222     pmulhrsw           m11, m12                             ; m11=t5
223     pmulhrsw            m9, m12                             ;  m9=t6
224     SWAP                 0, 10
225     SWAP                 9,  1
226     VP9_IDCT8_1D_FINALIZE
227 %endmacro
228
229 %macro VP9_IDCT8_WRITEOUT 0
230     mova                m5, [pw_1024]
231     pmulhrsw            m0, m5              ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5
232     pmulhrsw            m1, m5
233     VP9_STORE_2X         0,  1,  6,  7,  4
234     lea               dstq, [dstq+2*strideq]
235     pmulhrsw            m2, m5
236     pmulhrsw            m3, m5
237     VP9_STORE_2X         2,  3,  6,  7,  4
238     lea               dstq, [dstq+2*strideq]
239     pmulhrsw            m8, m5
240     pmulhrsw            m9, m5
241     VP9_STORE_2X         8,  9,  6,  7,  4
242     lea               dstq, [dstq+2*strideq]
243     pmulhrsw           m10, m5
244     pmulhrsw           m11, m5
245     VP9_STORE_2X        10, 11,  6,  7,  4
246 %endmacro
247
248 INIT_XMM ssse3
249 cglobal vp9_idct_idct_8x8_add, 4,4,13, dst, stride, block, eob
250
251     mova               m12, [pw_11585x2]    ; often used
252
253     cmp eobd, 3 ; top left corner or less
254     jg .idctfull
255
256     cmp eobd, 1 ; faster path for when only DC is set
257     jne .idcttopleftcorner
258
259     movd                m0, [blockq]
260     pmulhrsw            m0, m12
261     pmulhrsw            m0, m12
262     SPLATW              m0, m0, 0
263     pxor                m4, m4
264     movd          [blockq], m4
265     mova                m5, [pw_1024]
266     pmulhrsw            m0, m5              ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5
267     VP9_STORE_2X         0,  0,  6,  7,  4
268     lea               dstq, [dstq+2*strideq]
269     VP9_STORE_2X         0,  0,  6,  7,  4
270     lea               dstq, [dstq+2*strideq]
271     VP9_STORE_2X         0,  0,  6,  7,  4
272     lea               dstq, [dstq+2*strideq]
273     VP9_STORE_2X         0,  0,  6,  7,  4
274     RET
275
276 ; faster path for when only left corner is set (3 input: DC, right to DC, below
277 ; to DC). Note: also working with a 2x2 block
278 .idcttopleftcorner:
279     movd                m0, [blockq+0]
280     movd                m1, [blockq+16]
281     mova                m6, [pw_3196x2]
282     mova                m7, [pw_16069x2]
283     VP9_IDCT8_2x2_1D
284     TRANSPOSE8x8W  0, 1, 2, 3, 8, 9, 10, 11, 4
285     VP9_IDCT8_2x2_1D
286     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
287     movd       [blockq+ 0], m4
288     movd       [blockq+16], m4
289     VP9_IDCT8_WRITEOUT
290     RET
291
292 .idctfull: ; generic full 8x8 idct/idct
293     mova                m0, [blockq+  0]    ; IN(0)
294     mova                m1, [blockq+ 16]    ; IN(1)
295     mova                m2, [blockq+ 32]    ; IN(2)
296     mova                m3, [blockq+ 48]    ; IN(3)
297     mova                m8, [blockq+ 64]    ; IN(4)
298     mova                m9, [blockq+ 80]    ; IN(5)
299     mova               m10, [blockq+ 96]    ; IN(6)
300     mova               m11, [blockq+112]    ; IN(7)
301     mova                m7, [pd_8192]       ; rounding
302     VP9_IDCT8_1D
303     TRANSPOSE8x8W  0, 1, 2, 3, 8, 9, 10, 11, 4
304     VP9_IDCT8_1D
305     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
306     mova      [blockq+  0], m4
307     mova      [blockq+ 16], m4
308     mova      [blockq+ 32], m4
309     mova      [blockq+ 48], m4
310     mova      [blockq+ 64], m4
311     mova      [blockq+ 80], m4
312     mova      [blockq+ 96], m4
313     mova      [blockq+112], m4
314     VP9_IDCT8_WRITEOUT
315     RET
316 %endif