b142b8f778ceadbbb58f31fe3387f42daa6bdd09
[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 ;* Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
6 ;*
7 ;* This file is part of FFmpeg.
8 ;*
9 ;* FFmpeg is free software; you can redistribute it and/or
10 ;* modify it under the terms of the GNU Lesser General Public
11 ;* License as published by the Free Software Foundation; either
12 ;* version 2.1 of the License, or (at your option) any later version.
13 ;*
14 ;* FFmpeg is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 ;* Lesser General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU Lesser General Public
20 ;* License along with FFmpeg; if not, write to the Free Software
21 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 ;******************************************************************************
23
24 %include "libavutil/x86/x86util.asm"
25
26 SECTION_RODATA
27
28 pw_11585x2:  times 8 dw 23170
29 pw_m11585x2: times 8 dw -23170
30
31 %macro VP9_IDCT_COEFFS 2-3 0
32 pw_%1x2:    times 8 dw  %1*2
33 pw_m%1x2:   times 8 dw -%1*2
34 pw_%2x2:    times 8 dw  %2*2
35 pw_m%2x2:   times 8 dw -%2*2
36 pw_m%1_%2:  times 4 dw -%1,  %2
37 pw_%2_%1:   times 4 dw  %2,  %1
38 pw_m%2_m%1: times 4 dw -%2, -%1
39 %if %3 == 1
40 pw_m%2_%1:  times 4 dw -%2,  %1
41 pw_%1_%2:   times 4 dw  %1,  %2
42 %endif
43 %endmacro
44
45 VP9_IDCT_COEFFS 15137,  6270, 1
46 VP9_IDCT_COEFFS 16069,  3196, 1
47 VP9_IDCT_COEFFS  9102, 13623, 1
48 VP9_IDCT_COEFFS 16305,  1606
49 VP9_IDCT_COEFFS 10394, 12665
50 VP9_IDCT_COEFFS 14449,  7723
51 VP9_IDCT_COEFFS  4756, 15679
52 VP9_IDCT_COEFFS 16364,   804
53 VP9_IDCT_COEFFS 11003, 12140
54 VP9_IDCT_COEFFS 14811,  7005
55 VP9_IDCT_COEFFS  5520, 15426
56 VP9_IDCT_COEFFS 15893,  3981
57 VP9_IDCT_COEFFS  8423, 14053
58 VP9_IDCT_COEFFS 13160,  9760
59 VP9_IDCT_COEFFS  2404, 16207
60
61 pw_5283_13377: times 4 dw 5283, 13377
62 pw_9929_13377: times 4 dw 9929, 13377
63 pw_15212_m13377: times 4 dw 15212, -13377
64 pw_15212_9929: times 4 dw 15212, 9929
65 pw_m5283_m15212: times 4 dw -5283, -15212
66 pw_13377x2: times 8 dw 13377*2
67
68 pd_8192: times 4 dd 8192
69 pw_2048: times 8 dw 2048
70 pw_1024: times 8 dw 1024
71 pw_512:  times 8 dw 512
72 pw_m1:   times 8 dw -1
73
74 SECTION .text
75
76 ; (a*x + b*y + round) >> shift
77 %macro VP9_MULSUB_2W_2X 5 ; dst1, dst2/src, round, coefs1, coefs2
78     pmaddwd            m%1, m%2, %4
79     pmaddwd            m%2,  %5
80     paddd              m%1,  %3
81     paddd              m%2,  %3
82     psrad              m%1,  14
83     psrad              m%2,  14
84 %endmacro
85
86 %macro VP9_MULSUB_2W_4X 7 ; dst1, dst2, coef1, coef2, rnd, tmp1/src, tmp2
87     VP9_MULSUB_2W_2X    %7,  %6,  %5, [pw_m%3_%4], [pw_%4_%3]
88     VP9_MULSUB_2W_2X    %1,  %2,  %5, [pw_m%3_%4], [pw_%4_%3]
89     packssdw           m%1, m%7
90     packssdw           m%2, m%6
91 %endmacro
92
93 %macro VP9_UNPACK_MULSUB_2W_4X 7-9 ; dst1, dst2, (src1, src2,) coef1, coef2, rnd, tmp1, tmp2
94 %if %0 == 7
95     punpckhwd          m%6, m%2, m%1
96     punpcklwd          m%2, m%1
97     VP9_MULSUB_2W_4X   %1, %2, %3, %4, %5, %6, %7
98 %else
99     punpckhwd          m%8, m%4, m%3
100     punpcklwd          m%2, m%4, m%3
101     VP9_MULSUB_2W_4X   %1, %2, %5, %6, %7, %8, %9
102 %endif
103 %endmacro
104
105 %macro VP9_UNPACK_MULSUB_2D_4X 6 ; dst1 [src1], dst2 [src2], dst3, dst4, mul1, mul2
106     punpckhwd          m%4, m%2, m%1
107     punpcklwd          m%2, m%1
108     pmaddwd            m%3, m%4, [pw_m%5_%6]
109     pmaddwd            m%4, [pw_%6_%5]
110     pmaddwd            m%1, m%2, [pw_m%5_%6]
111     pmaddwd            m%2, [pw_%6_%5]
112 %endmacro
113
114 %macro VP9_RND_SH_SUMSUB_BA 6 ; dst1 [src1], dst2 [src2], src3, src4, tmp, round
115     SUMSUB_BA            d, %1, %2, %5
116     SUMSUB_BA            d, %3, %4, %5
117     paddd              m%1, %6
118     paddd              m%2, %6
119     paddd              m%3, %6
120     paddd              m%4, %6
121     psrad              m%1, 14
122     psrad              m%2, 14
123     psrad              m%3, 14
124     psrad              m%4, 14
125     packssdw           m%1, m%3
126     packssdw           m%2, m%4
127 %endmacro
128
129 %macro VP9_STORE_2X 5-6 dstq ; reg1, reg2, tmp1, tmp2, zero, dst
130     movh               m%3, [%6]
131     movh               m%4, [%6+strideq]
132     punpcklbw          m%3, m%5
133     punpcklbw          m%4, m%5
134     paddw              m%3, m%1
135     paddw              m%4, m%2
136     packuswb           m%3, m%5
137     packuswb           m%4, m%5
138     movh              [%6], m%3
139     movh      [%6+strideq], m%4
140 %endmacro
141
142 %macro ZERO_BLOCK 4 ; mem, stride, nnzcpl, zero_reg
143 %assign %%y 0
144 %rep %3
145 %assign %%x 0
146 %rep %3*2/mmsize
147     mova      [%1+%%y+%%x], %4
148 %assign %%x (%%x+mmsize)
149 %endrep
150 %assign %%y (%%y+%2)
151 %endrep
152 %endmacro
153
154 ;-------------------------------------------------------------------------------------------
155 ; void vp9_iwht_iwht_4x4_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
156 ;-------------------------------------------------------------------------------------------
157
158 %macro VP9_IWHT4_1D 0
159     SWAP                 1, 2, 3
160     paddw               m0, m2
161     psubw               m3, m1
162     psubw               m4, m0, m3
163     psraw               m4, 1
164     psubw               m5, m4, m1
165     SWAP                 5, 1
166     psubw               m4, m2
167     SWAP                 4, 2
168     psubw               m0, m1
169     paddw               m3, m2
170     SWAP                 3, 2, 1
171 %endmacro
172
173 INIT_MMX mmx
174 cglobal vp9_iwht_iwht_4x4_add, 3, 3, 0, dst, stride, block, eob
175     mova                m0, [blockq+0*8]
176     mova                m1, [blockq+1*8]
177     mova                m2, [blockq+2*8]
178     mova                m3, [blockq+3*8]
179     psraw               m0, 2
180     psraw               m1, 2
181     psraw               m2, 2
182     psraw               m3, 2
183
184     VP9_IWHT4_1D
185     TRANSPOSE4x4W        0, 1, 2, 3, 4
186     VP9_IWHT4_1D
187
188     pxor                m4, m4
189     VP9_STORE_2X         0, 1, 5, 6, 4
190     lea               dstq, [dstq+strideq*2]
191     VP9_STORE_2X         2, 3, 5, 6, 4
192     ZERO_BLOCK      blockq, 8, 4, m4
193     RET
194
195 ;-------------------------------------------------------------------------------------------
196 ; void vp9_idct_idct_4x4_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
197 ;-------------------------------------------------------------------------------------------
198
199 %macro VP9_IDCT4_1D_FINALIZE 0
200     SUMSUB_BA            w, 3, 2, 4                         ; m3=t3+t0, m2=-t3+t0
201     SUMSUB_BA            w, 1, 0, 4                         ; m1=t2+t1, m0=-t2+t1
202     SWAP                 0, 3, 2                            ; 3102 -> 0123
203 %endmacro
204
205 %macro VP9_IDCT4_1D 0
206     SUMSUB_BA            w, 2, 0, 4                         ; m2=IN(0)+IN(2) m0=IN(0)-IN(2)
207     pmulhrsw            m2, m6                              ; m2=t0
208     pmulhrsw            m0, m6                              ; m0=t1
209     VP9_UNPACK_MULSUB_2W_4X 1, 3, 15137, 6270, m7, 4, 5     ; m1=t2, m3=t3
210     VP9_IDCT4_1D_FINALIZE
211 %endmacro
212
213 ; 2x2 top left corner
214 %macro VP9_IDCT4_2x2_1D 0
215     pmulhrsw            m0, m5                              ; m0=t1
216     mova                m2, m0                              ; m2=t0
217     mova                m3, m1
218     pmulhrsw            m1, m6                              ; m1=t2
219     pmulhrsw            m3, m7                              ; m3=t3
220     VP9_IDCT4_1D_FINALIZE
221 %endmacro
222
223 %macro VP9_IDCT4_WRITEOUT 0
224     mova                m5, [pw_2048]
225     pmulhrsw            m0, m5              ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4
226     pmulhrsw            m1, m5
227     VP9_STORE_2X         0,  1,  6,  7,  4
228     lea               dstq, [dstq+2*strideq]
229     pmulhrsw            m2, m5
230     pmulhrsw            m3, m5
231     VP9_STORE_2X         2,  3,  6,  7,  4
232 %endmacro
233
234 INIT_MMX ssse3
235 cglobal vp9_idct_idct_4x4_add, 4,4,0, dst, stride, block, eob
236
237     cmp eobd, 4 ; 2x2 or smaller
238     jg .idctfull
239
240     cmp eobd, 1 ; faster path for when only DC is set
241     jne .idct2x2
242
243     movd                m0, [blockq]
244     mova                m5, [pw_11585x2]
245     pmulhrsw            m0, m5
246     pmulhrsw            m0, m5
247     pshufw              m0, m0, 0
248     pxor                m4, m4
249     movh          [blockq], m4
250     pmulhrsw            m0, [pw_2048]       ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4
251     VP9_STORE_2X         0,  0,  6,  7,  4
252     lea               dstq, [dstq+2*strideq]
253     VP9_STORE_2X         0,  0,  6,  7,  4
254     RET
255
256 ; faster path for when only top left 2x2 block is set
257 .idct2x2:
258     movd                m0, [blockq+0]
259     movd                m1, [blockq+8]
260     mova                m5, [pw_11585x2]
261     mova                m6, [pw_6270x2]
262     mova                m7, [pw_15137x2]
263     VP9_IDCT4_2x2_1D
264     TRANSPOSE4x4W  0, 1, 2, 3, 4
265     VP9_IDCT4_2x2_1D
266     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
267     movh       [blockq+ 0], m4
268     movh       [blockq+ 8], m4
269     VP9_IDCT4_WRITEOUT
270     RET
271
272 .idctfull: ; generic full 4x4 idct/idct
273     mova                m0, [blockq+ 0]
274     mova                m1, [blockq+ 8]
275     mova                m2, [blockq+16]
276     mova                m3, [blockq+24]
277     mova                m6, [pw_11585x2]
278     mova                m7, [pd_8192]       ; rounding
279     VP9_IDCT4_1D
280     TRANSPOSE4x4W  0, 1, 2, 3, 4
281     VP9_IDCT4_1D
282     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
283     mova       [blockq+ 0], m4
284     mova       [blockq+ 8], m4
285     mova       [blockq+16], m4
286     mova       [blockq+24], m4
287     VP9_IDCT4_WRITEOUT
288     RET
289
290 ;-------------------------------------------------------------------------------------------
291 ; void vp9_iadst_iadst_4x4_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
292 ;-------------------------------------------------------------------------------------------
293
294 %macro VP9_IADST4_1D 0
295     movq2dq           xmm0, m0
296     movq2dq           xmm1, m1
297     movq2dq           xmm2, m2
298     movq2dq           xmm3, m3
299     paddw               m3, m0
300     punpcklwd         xmm0, xmm1
301     punpcklwd         xmm2, xmm3
302     pmaddwd           xmm1, xmm0, [pw_5283_13377]
303     pmaddwd           xmm4, xmm0, [pw_9929_13377]
304     pmaddwd           xmm0, [pw_15212_m13377]
305     pmaddwd           xmm3, xmm2, [pw_15212_9929]
306     pmaddwd           xmm2, [pw_m5283_m15212]
307     psubw               m3, m2
308     paddd             xmm0, xmm2
309     paddd             xmm3, [pd_8192]
310     paddd             xmm2, [pd_8192]
311     paddd             xmm1, xmm3
312     paddd             xmm0, xmm3
313     paddd             xmm4, xmm2
314     psrad             xmm1, 14
315     psrad             xmm0, 14
316     psrad             xmm4, 14
317     pmulhrsw            m3, [pw_13377x2]        ; out2
318     packssdw          xmm0, xmm0
319     packssdw          xmm1, xmm1
320     packssdw          xmm4, xmm4
321     movdq2q             m0, xmm0                ; out3
322     movdq2q             m1, xmm1                ; out0
323     movdq2q             m2, xmm4                ; out1
324     SWAP                 0, 1, 2, 3
325 %endmacro
326
327 %macro IADST4_FN 5
328 INIT_MMX %5
329 cglobal vp9_%1_%3_4x4_add, 3, 3, 8, dst, stride, block, eob
330     mova                m0, [blockq+ 0]
331     mova                m1, [blockq+ 8]
332     mova                m2, [blockq+16]
333     mova                m3, [blockq+24]
334     mova                m6, [pw_11585x2]
335     mova                m7, [pd_8192]       ; rounding
336     VP9_%2_1D
337     TRANSPOSE4x4W  0, 1, 2, 3, 4
338     VP9_%4_1D
339     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
340     mova       [blockq+ 0], m4
341     mova       [blockq+ 8], m4
342     mova       [blockq+16], m4
343     mova       [blockq+24], m4
344     VP9_IDCT4_WRITEOUT
345     RET
346 %endmacro
347
348 IADST4_FN idct,  IDCT4,  iadst, IADST4, ssse3
349 IADST4_FN iadst, IADST4, idct,  IDCT4,  ssse3
350 IADST4_FN iadst, IADST4, iadst, IADST4, ssse3
351
352 %if ARCH_X86_64 ; TODO: 32-bit? (32-bit limited to 8 xmm reg, we use more)
353
354 ;-------------------------------------------------------------------------------------------
355 ; void vp9_idct_idct_8x8_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
356 ;-------------------------------------------------------------------------------------------
357
358 %macro VP9_IDCT8_1D_FINALIZE 0
359     SUMSUB_BA            w,  3, 10, 4                       ;  m3=t0+t7, m10=t0-t7
360     SUMSUB_BA            w,  1,  2, 4                       ;  m1=t1+t6,  m2=t1-t6
361     SUMSUB_BA            w, 11,  0, 4                       ; m11=t2+t5,  m0=t2-t5
362     SUMSUB_BA            w,  9,  8, 4                       ;  m9=t3+t4,  m8=t3-t4
363     SWAP                11, 10, 2
364     SWAP                 3,  9, 0
365 %endmacro
366
367 %macro VP9_IDCT8_1D 0
368     SUMSUB_BA            w, 8, 0, 4                         ; m8=IN(0)+IN(4) m0=IN(0)-IN(4)
369     pmulhrsw            m8, m12                             ; m8=t0a
370     pmulhrsw            m0, m12                             ; m0=t1a
371     VP9_UNPACK_MULSUB_2W_4X 2, 10, 15137,  6270, m7, 4, 5   ; m2=t2a, m10=t3a
372     VP9_UNPACK_MULSUB_2W_4X 1, 11, 16069,  3196, m7, 4, 5   ; m1=t4a, m11=t7a
373     VP9_UNPACK_MULSUB_2W_4X 9,  3,  9102, 13623, m7, 4, 5   ; m9=t5a,  m3=t6a
374     SUMSUB_BA            w, 10,  8, 4                       ; m10=t0a+t3a (t0),  m8=t0a-t3a (t3)
375     SUMSUB_BA            w,  2,  0, 4                       ;  m2=t1a+t2a (t1),  m0=t1a-t2a (t2)
376     SUMSUB_BA            w,  9,  1, 4                       ;  m9=t4a+t5a (t4),  m1=t4a-t5a (t5a)
377     SUMSUB_BA            w,  3, 11, 4                       ;  m3=t7a+t6a (t7), m11=t7a-t6a (t6a)
378     SUMSUB_BA            w,  1, 11, 4                       ;  m1=t6a+t5a (t6), m11=t6a-t5a (t5)
379     pmulhrsw            m1, m12                             ; m1=t6
380     pmulhrsw           m11, m12                             ; m11=t5
381     VP9_IDCT8_1D_FINALIZE
382 %endmacro
383
384 %macro VP9_IDCT8_4x4_1D 0
385     pmulhrsw            m0, m12                             ; m0=t1a/t0a
386     pmulhrsw           m10, m2, [pw_15137x2]                ; m10=t3a
387     pmulhrsw            m2, [pw_6270x2]                     ; m2=t2a
388     pmulhrsw           m11, m1, [pw_16069x2]                ; m11=t7a
389     pmulhrsw            m1, [pw_3196x2]                     ; m1=t4a
390     pmulhrsw            m9, m3, [pw_9102x2]                 ; m9=-t5a
391     pmulhrsw            m3, [pw_13623x2]                    ; m3=t6a
392     psubw               m8, m0, m10                         ; m8=t0a-t3a (t3)
393     paddw              m10, m0                              ; m10=t0a+t3a (t0)
394     SUMSUB_BA            w,  2,  0, 4                       ;  m2=t1a+t2a (t1),  m0=t1a-t2a (t2)
395     SUMSUB_BA            w,  9,  1, 4                       ;  m1=t4a+t5a (t4),  m9=t4a-t5a (t5a)
396     SWAP                 1,  9
397     SUMSUB_BA            w,  3, 11, 4                       ;  m3=t7a+t6a (t7), m11=t7a-t6a (t6a)
398     SUMSUB_BA            w,  1, 11, 4                       ;  m1=t6a+t5a (t6), m11=t6a-t5a (t5)
399     pmulhrsw            m1, m12                             ; m1=t6
400     pmulhrsw           m11, m12                             ; m11=t5
401     VP9_IDCT8_1D_FINALIZE
402 %endmacro
403
404 ; TODO: a lot of t* copies can probably be removed and merged with
405 ; following SUMSUBs from VP9_IDCT8_1D_FINALIZE with AVX
406 %macro VP9_IDCT8_2x2_1D 0
407     pmulhrsw            m0, m12                             ;  m0=t0
408     mova                m3, m1
409     pmulhrsw            m1, m6                              ;  m1=t4
410     pmulhrsw            m3, m7                              ;  m3=t7
411     mova                m2, m0                              ;  m2=t1
412     mova               m10, m0                              ; m10=t2
413     mova                m8, m0                              ;  m8=t3
414     mova               m11, m3                              ; t5 = t7a ...
415     mova                m9, m3                              ; t6 = t7a ...
416     psubw              m11, m1                              ; t5 = t7a - t4a
417     paddw               m9, m1                              ; t6 = t7a + t4a
418     pmulhrsw           m11, m12                             ; m11=t5
419     pmulhrsw            m9, m12                             ;  m9=t6
420     SWAP                 0, 10
421     SWAP                 9,  1
422     VP9_IDCT8_1D_FINALIZE
423 %endmacro
424
425 %macro VP9_IDCT8_WRITEOUT 0
426     mova                m5, [pw_1024]
427     pmulhrsw            m0, m5              ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5
428     pmulhrsw            m1, m5
429     VP9_STORE_2X         0,  1,  6,  7,  4
430     lea               dstq, [dstq+2*strideq]
431     pmulhrsw            m2, m5
432     pmulhrsw            m3, m5
433     VP9_STORE_2X         2,  3,  6,  7,  4
434     lea               dstq, [dstq+2*strideq]
435     pmulhrsw            m8, m5
436     pmulhrsw            m9, m5
437     VP9_STORE_2X         8,  9,  6,  7,  4
438     lea               dstq, [dstq+2*strideq]
439     pmulhrsw           m10, m5
440     pmulhrsw           m11, m5
441     VP9_STORE_2X        10, 11,  6,  7,  4
442 %endmacro
443
444 %macro VP9_IDCT_IDCT_8x8_ADD_XMM 1
445 INIT_XMM %1
446 cglobal vp9_idct_idct_8x8_add, 4,4,13, dst, stride, block, eob
447
448     mova               m12, [pw_11585x2]    ; often used
449
450     cmp eobd, 12 ; top left half or less
451     jg .idctfull
452
453     cmp eobd, 3  ; top left corner or less
454     jg .idcthalf
455
456     cmp eobd, 1 ; faster path for when only DC is set
457     jne .idcttopleftcorner
458
459     movd                m0, [blockq]
460     pmulhrsw            m0, m12
461     pmulhrsw            m0, m12
462     SPLATW              m0, m0, 0
463     pxor                m4, m4
464     movd          [blockq], m4
465     mova                m5, [pw_1024]
466     pmulhrsw            m0, m5              ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5
467     VP9_STORE_2X         0,  0,  6,  7,  4
468     lea               dstq, [dstq+2*strideq]
469     VP9_STORE_2X         0,  0,  6,  7,  4
470     lea               dstq, [dstq+2*strideq]
471     VP9_STORE_2X         0,  0,  6,  7,  4
472     lea               dstq, [dstq+2*strideq]
473     VP9_STORE_2X         0,  0,  6,  7,  4
474     RET
475
476 ; faster path for when only left corner is set (3 input: DC, right to DC, below
477 ; to DC). Note: also working with a 2x2 block
478 .idcttopleftcorner:
479     movd                m0, [blockq+0]
480     movd                m1, [blockq+16]
481     mova                m6, [pw_3196x2]
482     mova                m7, [pw_16069x2]
483     VP9_IDCT8_2x2_1D
484     TRANSPOSE8x8W  0, 1, 2, 3, 8, 9, 10, 11, 4
485     VP9_IDCT8_2x2_1D
486     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
487     movd       [blockq+ 0], m4
488     movd       [blockq+16], m4
489     VP9_IDCT8_WRITEOUT
490     RET
491
492 .idcthalf:
493     movh                m0, [blockq + 0]
494     movh                m1, [blockq +16]
495     movh                m2, [blockq +32]
496     movh                m3, [blockq +48]
497     VP9_IDCT8_4x4_1D
498     TRANSPOSE8x8W  0, 1, 2, 3, 8, 9, 10, 11, 4
499     VP9_IDCT8_4x4_1D
500     pxor                m4, m4
501     movh       [blockq+ 0], m4
502     movh       [blockq+16], m4
503     movh       [blockq+32], m4
504     movh       [blockq+48], m4
505     VP9_IDCT8_WRITEOUT
506     RET
507
508 .idctfull: ; generic full 8x8 idct/idct
509     mova                m0, [blockq+  0]    ; IN(0)
510     mova                m1, [blockq+ 16]    ; IN(1)
511     mova                m2, [blockq+ 32]    ; IN(2)
512     mova                m3, [blockq+ 48]    ; IN(3)
513     mova                m8, [blockq+ 64]    ; IN(4)
514     mova                m9, [blockq+ 80]    ; IN(5)
515     mova               m10, [blockq+ 96]    ; IN(6)
516     mova               m11, [blockq+112]    ; IN(7)
517     mova                m7, [pd_8192]       ; rounding
518     VP9_IDCT8_1D
519     TRANSPOSE8x8W  0, 1, 2, 3, 8, 9, 10, 11, 4
520     VP9_IDCT8_1D
521
522     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
523     ZERO_BLOCK      blockq, 16, 8, m4
524     VP9_IDCT8_WRITEOUT
525     RET
526 %endmacro
527
528 VP9_IDCT_IDCT_8x8_ADD_XMM ssse3
529 VP9_IDCT_IDCT_8x8_ADD_XMM avx
530
531 ;---------------------------------------------------------------------------------------------
532 ; void vp9_iadst_iadst_8x8_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
533 ;---------------------------------------------------------------------------------------------
534
535 %macro VP9_IADST8_1D 0 ; input/output=m0/1/2/3/8/9/10/11
536     VP9_UNPACK_MULSUB_2D_4X 11,  0,  4,  5, 16305,  1606    ; m11/4=t1[d], m0/5=t0[d]
537     VP9_UNPACK_MULSUB_2D_4X  3,  8,  6, 13, 10394, 12665    ; m3/6=t5[d], m8/13=t4[d]
538     VP9_RND_SH_SUMSUB_BA     8,  0, 13,  5, 14, m7          ; m8=t0[w], m0=t4[w]
539     VP9_RND_SH_SUMSUB_BA     3, 11,  6,  4, 14, m7          ; m3=t1[w], m11=t5[w]
540
541     VP9_UNPACK_MULSUB_2D_4X  9,  2,  4,  5, 14449,  7723    ; m9/4=t3[d], m2/5=t2[d]
542     VP9_UNPACK_MULSUB_2D_4X  1, 10,  6, 13,  4756, 15679    ; m1/6=t7[d], m10/13=t6[d]
543     VP9_RND_SH_SUMSUB_BA    10,  2, 13,  5, 14, m7          ; m10=t2[w], m2=t6[w]
544     VP9_RND_SH_SUMSUB_BA     1,  9,  6,  4, 14, m7          ; m1=t3[w], m9=t7[w]
545
546     ; m8=t0, m3=t1, m10=t2, m1=t3, m0=t4, m11=t5, m2=t6, m9=t7
547
548     VP9_UNPACK_MULSUB_2D_4X  0, 11,  4,  5, 15137,  6270    ; m0/4=t5[d], m11/5=t4[d]
549     VP9_UNPACK_MULSUB_2D_4X  9,  2,  6, 13,  6270, 15137    ; m9/6=t6[d], m2/13=t7[d]
550     VP9_RND_SH_SUMSUB_BA     9, 11,  6,  5, 14, m7
551     psignw                  m9, [pw_m1]                     ; m9=out1[w], m11=t6[w]
552     VP9_RND_SH_SUMSUB_BA     2,  0, 13,  4, 14, m7          ; m2=out6[w], m0=t7[w]
553
554     SUMSUB_BA                w, 10,  8, 14                  ; m10=out0[w], m8=t2[w]
555     SUMSUB_BA                w,  1,  3, 14
556     psignw                  m1, [pw_m1]                     ; m1=out7[w], m3=t3[w]
557
558     ; m10=out0, m9=out1, m8=t2, m3=t3, m11=t6, m0=t7, m2=out6, m1=out7
559
560     SUMSUB_BA                w,  3,  8,  4
561     SUMSUB_BA                w,  0, 11,  5
562     pmulhrsw                m3, m12
563     pmulhrsw               m11, m12
564     pmulhrsw                m8, m12                         ; out4
565     pmulhrsw                m0, m12                         ; out2
566     psignw                  m3, [pw_m1]                     ; out3
567     psignw                 m11, [pw_m1]                     ; out5
568
569     ; m10=out0, m9=out1, m0=out2, m3=out3, m8=out4, m11=out5, m2=out6, m1=out7
570
571     SWAP                     0, 10, 2
572     SWAP                    11,  1, 9
573 %endmacro
574
575 %macro IADST8_FN 5
576 INIT_XMM %5
577 cglobal vp9_%1_%3_8x8_add, 3, 3, 15, dst, stride, block, eob
578     mova                m0, [blockq+  0]    ; IN(0)
579     mova                m1, [blockq+ 16]    ; IN(1)
580     mova                m2, [blockq+ 32]    ; IN(2)
581     mova                m3, [blockq+ 48]    ; IN(3)
582     mova                m8, [blockq+ 64]    ; IN(4)
583     mova                m9, [blockq+ 80]    ; IN(5)
584     mova               m10, [blockq+ 96]    ; IN(6)
585     mova               m11, [blockq+112]    ; IN(7)
586
587     mova               m12, [pw_11585x2]    ; often used
588     mova                m7, [pd_8192]       ; rounding
589     VP9_%2_1D
590     TRANSPOSE8x8W  0, 1, 2, 3, 8, 9, 10, 11, 4
591     VP9_%4_1D
592
593     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
594     ZERO_BLOCK      blockq, 16, 8, m4
595     VP9_IDCT8_WRITEOUT
596     RET
597 %endmacro
598
599 IADST8_FN idct,  IDCT8,  iadst, IADST8, ssse3
600 IADST8_FN idct,  IDCT8,  iadst, IADST8, avx
601 IADST8_FN iadst, IADST8, idct,  IDCT8,  ssse3
602 IADST8_FN iadst, IADST8, idct,  IDCT8,  avx
603 IADST8_FN iadst, IADST8, iadst, IADST8, ssse3
604 IADST8_FN iadst, IADST8, iadst, IADST8, avx
605
606 ;---------------------------------------------------------------------------------------------
607 ; void vp9_idct_idct_16x16_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
608 ;---------------------------------------------------------------------------------------------
609
610 ; at the end of this macro, m7 is stored in stack_scratch
611 ; everything else (t0-6 and t8-15) is stored in m0-6 and m8-15
612 ; the following sumsubs have not been done yet:
613 ;    SUMSUB_BA            w,  6,  9, 15      ; t6, t9
614 ;    SUMSUB_BA            w,  7,  8, 15      ; t7, t8
615 %macro VP9_IDCT16_1D_START 4 ; src, nnzc, stride, stack_scratch
616 %if %2 <= 4
617     mova                m3, [%1+ 1*%3]      ; IN(1)
618     mova               m12, [%1+ 2*%3]      ; IN(2)
619     mova                m0, [%1+ 3*%3]      ; IN(3)
620
621     pmulhrsw           m15, m12, [pw_16069x2]       ; t6-7
622     pmulhrsw           m12, [pw_3196x2]             ; t4-5
623     pmulhrsw            m4, m3,  [pw_16305x2]       ; t14-15
624     pmulhrsw            m3, [pw_1606x2]             ; t8-9
625     pmulhrsw            m7, m0,  [pw_m4756x2]       ; t10-11
626     pmulhrsw            m0, [pw_15679x2]            ; t12-13
627
628     ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m14=t5, m13=t6, m15=t7
629     ; m3=t8, m5=t9, m1=t10, m7=t11, m0=t12, m6=t13, m2=t14, m4=t15
630
631     paddw              m14, m15, m12
632     psubw              m13, m15, m12
633     pmulhrsw           m13, [pw_11585x2]            ; t5
634     pmulhrsw           m14, [pw_11585x2]            ; t6
635
636     VP9_UNPACK_MULSUB_2W_4X 2, 5, 4, 3, 15137,  6270, [pd_8192], 10, 11 ; t9,  t14
637     VP9_UNPACK_MULSUB_2W_4X 6, 1, 0, 7, 6270, m15137, [pd_8192], 10, 11 ; t10, t13
638
639     ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7
640     ; m7=t8, m6=t9, m2=t10, m3=t11, m4=t12, m5=t13, m1=t14, m0=t15
641 %else
642     mova                m5, [%1+ 1*%3]     ; IN(1)
643     mova               m14, [%1+ 2*%3]     ; IN(2)
644     mova                m6, [%1+ 3*%3]     ; IN(3)
645     mova                m9, [%1+ 4*%3]     ; IN(4)
646     mova                m7, [%1+ 5*%3]     ; IN(5)
647     mova               m15, [%1+ 6*%3]     ; IN(6)
648     mova                m4, [%1+ 7*%3]     ; IN(7)
649 %if %2 <= 8
650     pmulhrsw            m8, m9,  [pw_15137x2]       ; t3
651     pmulhrsw            m9, [pw_6270x2]             ; t2
652     pmulhrsw           m13, m14, [pw_16069x2]       ; t7
653     pmulhrsw           m14, [pw_3196x2]             ; t4
654     pmulhrsw           m12, m15, [pw_m9102x2]       ; t5
655     pmulhrsw           m15, [pw_13623x2]            ; t6
656     pmulhrsw            m2, m5,  [pw_16305x2]       ; t15
657     pmulhrsw            m5, [pw_1606x2]             ; t8
658     pmulhrsw            m3, m4,  [pw_m10394x2]      ; t9
659     pmulhrsw            m4, [pw_12665x2]            ; t14
660     pmulhrsw            m0, m7,  [pw_14449x2]       ; t13
661     pmulhrsw            m7, [pw_7723x2]             ; t10
662     pmulhrsw            m1, m6,  [pw_m4756x2]       ; t11
663     pmulhrsw            m6, [pw_15679x2]            ; t12
664 %else
665     mova                m3, [%1+ 9*%3]     ; IN(9)
666     mova               m12, [%1+10*%3]     ; IN(10)
667     mova                m0, [%1+11*%3]     ; IN(11)
668     mova                m8, [%1+12*%3]     ; IN(12)
669     mova                m1, [%1+13*%3]     ; IN(13)
670     mova               m13, [%1+14*%3]     ; IN(14)
671     mova                m2, [%1+15*%3]     ; IN(15)
672
673     ; m10=in0, m5=in1, m14=in2, m6=in3, m9=in4, m7=in5, m15=in6, m4=in7
674     ; m11=in8, m3=in9, m12=in10 m0=in11, m8=in12, m1=in13, m13=in14, m2=in15
675
676     VP9_UNPACK_MULSUB_2W_4X   9,   8, 15137,  6270, [pd_8192], 10, 11 ; t2,  t3
677     VP9_UNPACK_MULSUB_2W_4X  14,  13, 16069,  3196, [pd_8192], 10, 11 ; t4,  t7
678     VP9_UNPACK_MULSUB_2W_4X  12,  15,  9102, 13623, [pd_8192], 10, 11 ; t5,  t6
679     VP9_UNPACK_MULSUB_2W_4X   5,   2, 16305,  1606, [pd_8192], 10, 11 ; t8,  t15
680     VP9_UNPACK_MULSUB_2W_4X   3,   4, 10394, 12665, [pd_8192], 10, 11 ; t9,  t14
681     VP9_UNPACK_MULSUB_2W_4X   7,   0, 14449,  7723, [pd_8192], 10, 11 ; t10, t13
682     VP9_UNPACK_MULSUB_2W_4X   1,   6,  4756, 15679, [pd_8192], 10, 11 ; t11, t12
683 %endif
684
685     ; m11=t0, m10=t1, m9=t2, m8=t3, m14=t4, m12=t5, m15=t6, m13=t7
686     ; m5=t8, m3=t9, m7=t10, m1=t11, m6=t12, m0=t13, m4=t14, m2=t15
687
688     SUMSUB_BA            w, 12, 14, 10      ; t4,  t5
689     SUMSUB_BA            w, 15, 13, 10      ; t7,  t6
690     SUMSUB_BA            w,  3,  5, 10      ; t8,  t9
691     SUMSUB_BA            w,  7,  1, 10      ; t11, t10
692     SUMSUB_BA            w,  0,  6, 10      ; t12, t13
693     SUMSUB_BA            w,  4,  2, 10      ; t15, t14
694
695     ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m14=t5, m13=t6, m15=t7
696     ; m3=t8, m5=t9, m1=t10, m7=t11, m0=t12, m6=t13, m2=t14, m4=t15
697
698     SUMSUB_BA            w, 14, 13, 10
699     pmulhrsw           m13, [pw_11585x2]                              ; t5
700     pmulhrsw           m14, [pw_11585x2]                              ; t6
701     VP9_UNPACK_MULSUB_2W_4X   2,   5, 15137,  6270, [pd_8192], 10, 11 ; t9,  t14
702     VP9_UNPACK_MULSUB_2W_4X   6,   1, 6270, m15137, [pd_8192], 10, 11 ; t10, t13
703 %endif
704
705     ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m13=t5, m14=t6, m15=t7
706     ; m3=t8, m2=t9, m6=t10, m7=t11, m0=t12, m1=t13, m5=t14, m4=t15
707
708     SUMSUB_BA            w,  7,  3, 10      ; t8,  t11
709     SUMSUB_BA            w,  6,  2, 10      ; t9,  t10
710     SUMSUB_BA            w,  0,  4, 10      ; t15, t12
711     SUMSUB_BA            w,  1,  5, 10      ; t14. t13
712
713     ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7
714     ; m7=t8, m6=t9, m2=t10, m3=t11, m4=t12, m5=t13, m1=t14, m0=t15
715
716     SUMSUB_BA            w,  2,  5, 10
717     SUMSUB_BA            w,  3,  4, 10
718     pmulhrsw            m5, [pw_11585x2]    ; t10
719     pmulhrsw            m4, [pw_11585x2]    ; t11
720     pmulhrsw            m3, [pw_11585x2]    ; t12
721     pmulhrsw            m2, [pw_11585x2]    ; t13
722
723     ; backup first register
724     mova              [%4], m7
725
726     ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7
727     ; m7=t8, m6=t9, m5=t10, m4=t11, m3=t12, m2=t13, m1=t14, m0=t15
728
729     ; from load/start
730 %if %2 <= 4
731     mova               m11, [%1+ 0*%3]      ; IN(0)
732     pmulhrsw           m11, [pw_11585x2]    ; t0-t3
733
734     psubw               m8, m11, m15
735     paddw              m15, m11
736     psubw               m9, m11, m14
737     paddw              m14, m11
738     psubw              m10, m11, m13
739     paddw              m13, m11
740 %else
741     mova               m10, [%1+ 0*%3]      ; IN(0)
742 %if %2 <= 8
743     pmulhrsw           m10, [pw_11585x2]    ; t0 and t1
744     psubw              m11, m10, m8
745     paddw               m8, m10
746 %else
747     mova               m11, [%1+ 8*%3]      ; IN(8)
748
749     ; from 3 stages back
750     SUMSUB_BA            w, 11, 10, 7
751     pmulhrsw           m11, [pw_11585x2]    ; t0
752     pmulhrsw           m10, [pw_11585x2]    ; t1
753
754     ; from 2 stages back
755     SUMSUB_BA            w,  8, 11, 7       ; t0,  t3
756 %endif
757     SUMSUB_BA            w,  9, 10, 7       ; t1,  t2
758
759     ; from 1 stage back
760     SUMSUB_BA            w, 15,  8, 7       ; t0,  t7
761     SUMSUB_BA            w, 14,  9, 7       ; t1,  t6
762     SUMSUB_BA            w, 13, 10, 7       ; t2,  t5
763 %endif
764     SUMSUB_BA            w, 12, 11, 7       ; t3,  t4
765
766     SUMSUB_BA            w,  0, 15, 7       ; t0, t15
767     SUMSUB_BA            w,  1, 14, 7       ; t1, t14
768     SUMSUB_BA            w,  2, 13, 7       ; t2, t13
769     SUMSUB_BA            w,  3, 12, 7       ; t3, t12
770     SUMSUB_BA            w,  4, 11, 7       ; t4, t11
771     SUMSUB_BA            w,  5, 10, 7       ; t5, t10
772 %endmacro
773
774 %macro VP9_IDCT16_1D 2-3 16 ; src, pass, nnzc
775     VP9_IDCT16_1D_START %1, %3, 32, rsp+32
776
777 %if %2 == 1
778     ; backup a different register
779     mova          [rsp+16], m15
780     mova                m7, [rsp+32]
781
782     SUMSUB_BA            w,  6,  9, 15      ; t6, t9
783     SUMSUB_BA            w,  7,  8, 15      ; t7, t8
784
785     TRANSPOSE8x8W        0, 1, 2, 3, 4, 5, 6, 7, 15
786     mova         [rsp+  0], m0
787     mova         [rsp+ 32], m1
788     mova         [rsp+ 64], m2
789     mova         [rsp+ 96], m3
790     mova         [rsp+128], m4
791     mova         [rsp+160], m5
792     mova         [rsp+192], m6
793     mova         [rsp+224], m7
794
795     mova               m15, [rsp+16]
796     TRANSPOSE8x8W        8, 9, 10, 11, 12, 13, 14, 15, 0
797     mova         [rsp+ 16], m8
798     mova         [rsp+ 48], m9
799     mova         [rsp+ 80], m10
800     mova         [rsp+112], m11
801     mova         [rsp+144], m12
802     mova         [rsp+176], m13
803     mova         [rsp+208], m14
804     mova         [rsp+240], m15
805 %else ; %2 == 2
806     ; backup more registers
807     mova          [rsp+64], m8
808     mova          [rsp+96], m9
809
810     pxor                m7, m7
811     pmulhrsw            m0, [pw_512]
812     pmulhrsw            m1, [pw_512]
813     VP9_STORE_2X         0,  1,  8,  9,  7
814     lea               dstq, [dstq+strideq*2]
815     pmulhrsw            m2, [pw_512]
816     pmulhrsw            m3, [pw_512]
817     VP9_STORE_2X         2,  3,  8,  9,  7
818     lea               dstq, [dstq+strideq*2]
819     pmulhrsw            m4, [pw_512]
820     pmulhrsw            m5, [pw_512]
821     VP9_STORE_2X         4,  5,  8,  9,  7
822     lea               dstq, [dstq+strideq*2]
823
824     ; restore from cache
825     SWAP                 0, 7               ; move zero from m7 to m0
826     mova                m7, [rsp+32]
827     mova                m8, [rsp+64]
828     mova                m9, [rsp+96]
829
830     SUMSUB_BA            w,  6,  9, 1       ; t6, t9
831     SUMSUB_BA            w,  7,  8, 1       ; t7, t8
832
833     pmulhrsw            m6, [pw_512]
834     pmulhrsw            m7, [pw_512]
835     VP9_STORE_2X         6,  7,  1,  2,  0
836     lea               dstq, [dstq+strideq*2]
837     pmulhrsw            m8, [pw_512]
838     pmulhrsw            m9, [pw_512]
839     VP9_STORE_2X         8,  9,  1,  2,  0
840     lea               dstq, [dstq+strideq*2]
841     pmulhrsw           m10, [pw_512]
842     pmulhrsw           m11, [pw_512]
843     VP9_STORE_2X        10, 11,  1,  2,  0
844     lea               dstq, [dstq+strideq*2]
845     pmulhrsw           m12, [pw_512]
846     pmulhrsw           m13, [pw_512]
847     VP9_STORE_2X        12, 13,  1,  2,  0
848     lea               dstq, [dstq+strideq*2]
849     pmulhrsw           m14, [pw_512]
850     pmulhrsw           m15, [pw_512]
851     VP9_STORE_2X        14, 15,  1,  2,  0
852 %endif ; %2 == 1/2
853 %endmacro
854
855 %macro VP9_STORE_2XFULL 6-7 strideq; dc, tmp1, tmp2, tmp3, tmp4, zero, stride
856     mova               m%3, [dstq]
857     mova               m%5, [dstq+%7]
858     punpcklbw          m%2, m%3, m%6
859     punpckhbw          m%3, m%6
860     punpcklbw          m%4, m%5, m%6
861     punpckhbw          m%5, m%6
862     paddw              m%2, m%1
863     paddw              m%3, m%1
864     paddw              m%4, m%1
865     paddw              m%5, m%1
866     packuswb           m%2, m%3
867     packuswb           m%4, m%5
868     mova            [dstq], m%2
869     mova         [dstq+%7], m%4
870 %endmacro
871
872 %macro VP9_IDCT_IDCT_16x16_ADD_XMM 1
873 INIT_XMM %1
874 cglobal vp9_idct_idct_16x16_add, 4, 5, 16, 512, dst, stride, block, eob
875     ; 2x2=eob=3, 4x4=eob=10
876     cmp eobd, 38
877     jg .idctfull
878     cmp eobd, 1 ; faster path for when only DC is set
879     jne .idct8x8
880
881     ; dc-only
882     movd                m0, [blockq]
883     mova                m1, [pw_11585x2]
884     pmulhrsw            m0, m1
885     pmulhrsw            m0, m1
886     SPLATW              m0, m0, q0000
887     pmulhrsw            m0, [pw_512]
888     pxor                m5, m5
889     movd          [blockq], m5
890 %rep 7
891     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5
892     lea               dstq, [dstq+2*strideq]
893 %endrep
894     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5
895     RET
896
897 .idct8x8:
898     DEFINE_ARGS dst, stride, block, cnt, dst_bak
899     VP9_IDCT16_1D   blockq, 1, 8
900
901     mov               cntd, 2
902     mov           dst_bakq, dstq
903 .loop2_8x8:
904     VP9_IDCT16_1D      rsp, 2, 8
905     lea               dstq, [dst_bakq+8]
906     add                rsp, 16
907     dec               cntd
908     jg .loop2_8x8
909     sub                rsp, 32
910
911     ; at the end of the loop, m0 should still be zero
912     ; use that to zero out block coefficients
913     ZERO_BLOCK      blockq, 32, 8, m0
914     RET
915
916 .idctfull:
917     DEFINE_ARGS dst, stride, block, cnt, dst_bak
918     mov               cntd, 2
919 .loop1_full:
920     VP9_IDCT16_1D   blockq, 1
921     add             blockq, 16
922     add                rsp, 256
923     dec               cntd
924     jg .loop1_full
925     sub             blockq, 32
926     sub                rsp, 512
927
928     mov               cntd, 2
929     mov           dst_bakq, dstq
930 .loop2_full:
931     VP9_IDCT16_1D      rsp, 2
932     lea               dstq, [dst_bakq+8]
933     add                rsp, 16
934     dec               cntd
935     jg .loop2_full
936     sub                rsp, 32
937
938     ; at the end of the loop, m0 should still be zero
939     ; use that to zero out block coefficients
940     ZERO_BLOCK      blockq, 32, 16, m0
941     RET
942 %endmacro
943
944 VP9_IDCT_IDCT_16x16_ADD_XMM ssse3
945 VP9_IDCT_IDCT_16x16_ADD_XMM avx
946
947 ;---------------------------------------------------------------------------------------------
948 ; void vp9_iadst_iadst_16x16_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
949 ;---------------------------------------------------------------------------------------------
950
951 %macro VP9_IADST16_1D 2 ; src, pass
952 %assign %%str 16*%2
953     mova                m0, [%1+ 0*32]  ; in0
954     mova                m1, [%1+15*32]  ; in15
955     mova                m8, [%1+ 7*32]  ; in7
956     mova                m9, [%1+ 8*32]  ; in8
957
958     VP9_UNPACK_MULSUB_2D_4X  1,  0,  2,  3, 16364,   804    ; m1/2=t1[d], m0/3=t0[d]
959     VP9_UNPACK_MULSUB_2D_4X  8,  9, 11, 10, 11003, 12140    ; m8/11=t9[d], m9/10=t8[d]
960     VP9_RND_SH_SUMSUB_BA     9,  0, 10,  3,  4, [pd_8192]   ; m9=t0[w], m0=t8[w]
961     VP9_RND_SH_SUMSUB_BA     8,  1, 11,  2,  4, [pd_8192]   ; m8=t1[w], m1=t9[w]
962
963     mova               m11, [%1+ 2*32]  ; in2
964     mova               m10, [%1+13*32]  ; in13
965     mova                m3, [%1+ 5*32]  ; in5
966     mova                m2, [%1+10*32]  ; in10
967
968     VP9_UNPACK_MULSUB_2D_4X 10, 11,  6,  7, 15893,  3981    ; m10/6=t3[d], m11/7=t2[d]
969     VP9_UNPACK_MULSUB_2D_4X  3,  2,  4,  5,  8423, 14053    ; m3/4=t11[d], m2/5=t10[d]
970     VP9_RND_SH_SUMSUB_BA     2, 11,  5,  7, 12, [pd_8192]   ; m2=t2[w], m11=t10[w]
971     VP9_RND_SH_SUMSUB_BA     3, 10,  4,  6, 12, [pd_8192]   ; m3=t3[w], m10=t11[w]
972
973     mova    [rsp+ 0*%%str], m9          ; make some scratch space (t0:m9->r0)
974     mova                m4, [%1+ 4*32]  ; in4
975     mova                m5, [%1+11*32]  ; in11
976     mova               m12, [%1+ 3*32]  ; in3
977     mova               m13, [%1+12*32]  ; in12
978
979     VP9_UNPACK_MULSUB_2D_4X  5,  4,  7,  6, 14811,  7005    ; m5/7=t5[d], m4/6=t4[d]
980     VP9_UNPACK_MULSUB_2D_4X 12, 13, 14, 15,  5520, 15426    ; m12/14=t13[d], m13/15=t12[d]
981     VP9_RND_SH_SUMSUB_BA    13,  4, 15,  6,  9, [pd_8192]   ; m13=t4[w], m4=t12[w]
982     VP9_RND_SH_SUMSUB_BA    12,  5, 14,  7,  9, [pd_8192]   ; m12=t5[w], m5=t13[w]
983
984     mova    [rsp+ 2*%%str], m8          ; t1:m9->r2
985     mova    [rsp+ 3*%%str], m2          ; t2:m2->r3
986     mova    [rsp+ 4*%%str], m3          ; t3:m3->r4
987     mova    [rsp+ 5*%%str], m13         ; t4:m13->r5
988     mova                m2, [%1+ 6*32]  ; in6
989     mova                m3, [%1+ 9*32]  ; in9
990     mova                m8, [%1+ 1*32]  ; in1
991     mova                m9, [%1+14*32]  ; in14
992
993     VP9_UNPACK_MULSUB_2D_4X  3,  2,  7,  6, 13160,  9760    ; m3/7=t7[d], m2/6=t6[d]
994     VP9_UNPACK_MULSUB_2D_4X  8,  9, 13, 14,  2404, 16207    ; m8/13=t15[d], m9/14=t14[d]
995     VP9_RND_SH_SUMSUB_BA     9,  2, 14,  6, 15, [pd_8192]   ; m9=t6[w], m2=t14[w]
996     VP9_RND_SH_SUMSUB_BA     8,  3, 13,  7, 15, [pd_8192]   ; m8=t7[w], m3=t15[w]
997
998     ; r0=t0, r2=t1, r3=t2, r4=t3, r5=t4, m12=t5, m9=t6, m8=t7
999     ; m0=t8, m1=t9, m11=t10, m10=t11, m4=t12, m5=t13, m2=t14, m3=t15
1000
1001     ; handle t8-15 first
1002     VP9_UNPACK_MULSUB_2D_4X  0,  1,  6,  7, 16069,  3196    ; m1/7=t8[d], m0/6=t9[d]
1003     VP9_UNPACK_MULSUB_2D_4X  5,  4, 13, 14,  3196, 16069    ; m5/13=t12[d], m4/14=t13[d]
1004     VP9_RND_SH_SUMSUB_BA     5,  1, 13,  7, 15, [pd_8192]   ; m5=t8[w], m1=t12[w]
1005     VP9_RND_SH_SUMSUB_BA     4,  0, 14,  6, 15, [pd_8192]   ; m4=t9[w], m0=t13[w]
1006
1007     VP9_UNPACK_MULSUB_2D_4X 11, 10,  6,  7,  9102, 13623    ; m11/6=t11[d], m10/7=t10[d]
1008     VP9_UNPACK_MULSUB_2D_4X  3,  2, 13, 14, 13623,  9102    ; m3/13=t14[d], m2/14=t15[d]
1009     VP9_RND_SH_SUMSUB_BA     3, 10, 13,  7, 15, [pd_8192]   ; m3=t10[w], m10=t14[w]
1010     VP9_RND_SH_SUMSUB_BA     2, 11, 14,  6, 15, [pd_8192]   ; m2=t11[w], m11=t15[w]
1011
1012     ; m5=t8, m4=t9, m3=t10, m2=t11, m1=t12, m0=t13, m10=t14, m11=t15
1013
1014     VP9_UNPACK_MULSUB_2D_4X  1,  0,  6,  7, 15137,  6270    ; m1/6=t13[d], m0/7=t12[d]
1015     VP9_UNPACK_MULSUB_2D_4X 11, 10, 13, 14,  6270, 15137    ; m11/13=t14[d], m10/14=t15[d]
1016     VP9_RND_SH_SUMSUB_BA    11,  0, 13,  7, 15, [pd_8192]   ; m11=out2[w], m0=t14[w]
1017     VP9_RND_SH_SUMSUB_BA    10,  1, 14,  6, 15, [pd_8192]
1018     psignw                 m10, [pw_m1]                     ; m10=out13[w], m1=t15[w]
1019
1020     SUMSUB_BA                w,  3,  5, 15
1021     psignw                  m3, [pw_m1]                     ; m3=out1[w], m5=t10[w]
1022     SUMSUB_BA                w,  2,  4, 15                  ; m2=out14[w], m4=t11[w]
1023
1024     SUMSUB_BA                w,  5,  4, 15
1025     pmulhrsw                m5, [pw_11585x2]                ; m5=out6[w]
1026     pmulhrsw                m4, [pw_11585x2]                ; m4=out9[w]
1027     SUMSUB_BA                w,  1,  0, 15
1028     pmulhrsw                m1, [pw_m11585x2]               ; m1=out5[w]
1029     pmulhrsw                m0, [pw_11585x2]                ; m0=out10[w]
1030
1031     ; m3=out1, m11=out2, m1=out5, m5=out6, m4=out9, m0=out10, m10=out13, m2=out14
1032
1033     mova                    m6, [rsp+ 0*%%str]
1034     mova                    m7, [rsp+ 2*%%str]
1035     mova                   m13, [rsp+ 3*%%str]
1036     mova                   m14, [rsp+ 4*%%str]
1037     mova                   m15, [rsp+ 5*%%str]
1038     mova        [rsp+ 8*%%str], m5
1039     mova        [rsp+ 9*%%str], m4
1040     mova        [rsp+10*%%str], m0
1041     mova        [rsp+11*%%str], m10
1042     mova        [rsp+12*%%str], m2
1043
1044     ; m6=t0, m7=t1, m13=t2, m14=t3, m15=t4, m12=t5, m9=t6, m8=t7
1045     ; m3=out1, m11=out2, m1=out5, r8=out6, r9=out9, r10=out10, r11=out13, r12=out14
1046
1047     SUMSUB_BA                w, 15,  6,  0                  ; m15=t0[w], m6=t4[w]
1048     SUMSUB_BA                w, 12,  7,  0                  ; m12=t1[w], m7=t5[w]
1049     SUMSUB_BA                w,  9, 13,  0                  ; m9=t2[w], m13=t6[w]
1050     SUMSUB_BA                w,  8, 14,  0                  ; m8=t3[w], m14=t7[w]
1051
1052     VP9_UNPACK_MULSUB_2D_4X  6,  7,  0,  2, 15137,  6270    ; m6/0=t5[d], m7/2=t4[d]
1053     VP9_UNPACK_MULSUB_2D_4X 14, 13,  4,  5,  6270, 15137    ; m14/4=t6[d], m13/5=t7[d]
1054     VP9_RND_SH_SUMSUB_BA    14,  7,  4,  2, 10, [pd_8192]
1055     psignw                 m14, [pw_m1]                     ; m14=out3[w], m7=t6[w]
1056     VP9_RND_SH_SUMSUB_BA    13,  6,  5,  0, 10, [pd_8192]   ; m13=out12[w], m6=t7[w]
1057     SUMSUB_BA                w,  9, 15, 10                  ; m9=out0[w], m15=t2[w]
1058     SUMSUB_BA                w,  8, 12, 10
1059     psignw                  m8, [pw_m1]                     ; m8=out15[w], m12=t3[w]
1060
1061     SUMSUB_BA                w, 12, 15, 10
1062     pmulhrsw               m12, [pw_m11585x2]               ; m12=out7[w]
1063     pmulhrsw               m15, [pw_11585x2]                ; m15=out8[w]
1064     SUMSUB_BA                w,  7,  6, 10
1065     pmulhrsw                m7, [pw_11585x2]                ; m7=out4[w]
1066     pmulhrsw                m6, [pw_11585x2]                ; m6=out11[w]
1067
1068     ; m9=out0, m14=out3, m7=out4, m12=out7, m15=out8, m6=out11, m13=out12, m8=out15
1069     ; m3=out1, m11=out2, m1=out5, r8=out6, r9=out9, r10=out10, r11=out13, r12=out14
1070
1071 %if %2 == 1
1072     mova                    m0, [rsp+ 8*%%str]
1073     TRANSPOSE8x8W            9, 3, 11, 14, 7, 1, 0, 12, 2
1074     mova           [rsp+ 0*16], m9
1075     mova           [rsp+ 2*16], m3
1076     mova           [rsp+ 4*16], m11
1077     mova           [rsp+ 6*16], m14
1078     mova                    m9, [rsp+ 9*%%str]
1079     mova                    m3, [rsp+10*%%str]
1080     mova                   m11, [rsp+11*%%str]
1081     mova                   m14, [rsp+12*%%str]
1082     mova           [rsp+ 8*16], m7
1083     mova           [rsp+10*16], m1
1084     mova           [rsp+12*16], m0
1085     mova           [rsp+14*16], m12
1086
1087     TRANSPOSE8x8W           15, 9, 3, 6, 13, 11, 14, 8, 2
1088     mova           [rsp+ 1*16], m15
1089     mova           [rsp+ 3*16], m9
1090     mova           [rsp+ 5*16], m3
1091     mova           [rsp+ 7*16], m6
1092     mova           [rsp+ 9*16], m13
1093     mova           [rsp+11*16], m11
1094     mova           [rsp+13*16], m14
1095     mova           [rsp+15*16], m8
1096 %else
1097     mova                    m5, [rsp+ 8*%%str]
1098     pxor                    m0, m0
1099
1100     pmulhrsw                m9, [pw_512]
1101     pmulhrsw                m3, [pw_512]
1102     VP9_STORE_2X             9,  3, 2, 4, 0
1103     lea                   dstq, [dstq+strideq*2]
1104     pmulhrsw               m11, [pw_512]
1105     pmulhrsw               m14, [pw_512]
1106     VP9_STORE_2X            11, 14, 2, 4, 0
1107     lea                   dstq, [dstq+strideq*2]
1108     pmulhrsw                m7, [pw_512]
1109     pmulhrsw                m1, [pw_512]
1110     VP9_STORE_2X             7,  1, 2, 4, 0
1111     lea                   dstq, [dstq+strideq*2]
1112     pmulhrsw                m5, [pw_512]
1113     pmulhrsw               m12, [pw_512]
1114     VP9_STORE_2X             5, 12, 2, 4, 0
1115     lea                   dstq, [dstq+strideq*2]
1116
1117     mova                    m9, [rsp+ 9*%%str]
1118     mova                    m3, [rsp+10*%%str]
1119     mova                   m11, [rsp+11*%%str]
1120     mova                   m14, [rsp+12*%%str]
1121
1122     pmulhrsw               m15, [pw_512]
1123     pmulhrsw                m9, [pw_512]
1124     VP9_STORE_2X            15,  9, 2, 4, 0
1125     lea                   dstq, [dstq+strideq*2]
1126     pmulhrsw                m3, [pw_512]
1127     pmulhrsw                m6, [pw_512]
1128     VP9_STORE_2X             3,  6, 2, 4, 0
1129     lea                   dstq, [dstq+strideq*2]
1130     pmulhrsw               m13, [pw_512]
1131     pmulhrsw               m11, [pw_512]
1132     VP9_STORE_2X            13, 11, 2, 4, 0
1133     lea                   dstq, [dstq+strideq*2]
1134     pmulhrsw               m14, [pw_512]
1135     pmulhrsw                m8, [pw_512]
1136     VP9_STORE_2X            14,  8, 2, 4, 0
1137 %endif
1138 %endmacro
1139
1140 %macro IADST16_FN 5
1141 INIT_XMM %5
1142 cglobal vp9_%1_%3_16x16_add, 3, 5, 16, 512, dst, stride, block, eob
1143     ; potential eob checks go here
1144
1145     DEFINE_ARGS dst, stride, block, cnt, dst_bak
1146     mov               cntd, 2
1147 .loop1_full:
1148     VP9_%2_1D       blockq, 1
1149     add             blockq, 16
1150     add                rsp, 256
1151     dec               cntd
1152     jg .loop1_full
1153     sub             blockq, 32
1154     sub                rsp, 512
1155
1156     mov               cntd, 2
1157     mov           dst_bakq, dstq
1158 .loop2_full:
1159     VP9_%4_1D          rsp, 2
1160     lea               dstq, [dst_bakq+8]
1161     add                rsp, 16
1162     dec               cntd
1163     jg .loop2_full
1164     sub                rsp, 32
1165
1166     ; at the end of the loop, m0 should still be zero
1167     ; use that to zero out block coefficients
1168     ZERO_BLOCK      blockq, 32, 16, m0
1169     RET
1170 %endmacro
1171
1172 IADST16_FN idct,  IDCT16,  iadst, IADST16, ssse3
1173 IADST16_FN idct,  IDCT16,  iadst, IADST16, avx
1174 IADST16_FN iadst, IADST16, idct,  IDCT16,  ssse3
1175 IADST16_FN iadst, IADST16, idct,  IDCT16,  avx
1176 IADST16_FN iadst, IADST16, iadst, IADST16, ssse3
1177 IADST16_FN iadst, IADST16, iadst, IADST16, avx
1178
1179 ;---------------------------------------------------------------------------------------------
1180 ; void vp9_idct_idct_32x32_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
1181 ;---------------------------------------------------------------------------------------------
1182
1183 %macro VP9_IDCT32_1D 2-3 32 ; src, pass, nnzc
1184 %assign %%str 16*%2*%2
1185     ; first do t0-15, this can be done identical to idct16x16
1186     VP9_IDCT16_1D_START %1, %3/2, 64*2, rsp+ 4*%%str
1187
1188     ; backup a different register
1189     mova     [rsp+30*%%str], m15    ; t15
1190     mova                m7, [rsp+ 4*%%str]
1191
1192     SUMSUB_BA            w,  6,  9, 15      ; t6, t9
1193     SUMSUB_BA            w,  7,  8, 15      ; t7, t8
1194
1195     ; store everything on stack to make space available for t16-31
1196     ; we store interleaved with the output of the second half (t16-31)
1197     ; so we don't need to allocate extra stack space
1198     mova     [rsp+ 0*%%str], m0     ; t0
1199     mova     [rsp+ 4*%%str], m1     ; t1
1200     mova     [rsp+ 8*%%str], m2     ; t2
1201     mova     [rsp+12*%%str], m3     ; t3
1202     mova     [rsp+16*%%str], m4     ; t4
1203     mova     [rsp+20*%%str], m5     ; t5
1204     mova     [rsp+24*%%str], m6     ; t6
1205     mova     [rsp+28*%%str], m7     ; t7
1206     mova     [rsp+ 2*%%str], m8     ; t8
1207     mova     [rsp+ 6*%%str], m9     ; t9
1208     mova     [rsp+10*%%str], m10    ; t10
1209     mova     [rsp+14*%%str], m11    ; t11
1210     mova     [rsp+18*%%str], m12    ; t12
1211     mova     [rsp+22*%%str], m13    ; t13
1212     mova     [rsp+26*%%str], m14    ; t14
1213
1214     ; then, secondly, do t16-31
1215 %if %3 <= 8
1216     mova                 m4, [%1+ 1*64]
1217     mova                 m3, [%1+ 3*64]
1218     mova                 m0, [%1+ 5*64]
1219     mova                 m7, [%1+ 7*64]
1220
1221     pmulhrsw            m11,  m4, [pw_16364x2] ;t31
1222     pmulhrsw             m4, [pw_804x2] ;t16
1223     pmulhrsw             m8,  m7, [pw_m5520x2] ;t19
1224     pmulhrsw             m7, [pw_15426x2] ;t28
1225     pmulhrsw            m15,  m0, [pw_15893x2] ;t27
1226     pmulhrsw             m0, [pw_3981x2] ;t20
1227     pmulhrsw            m12,  m3, [pw_m2404x2] ;t23
1228     pmulhrsw             m3, [pw_16207x2] ;t24
1229
1230     ; m4=t16/17, m8=t18/19, m0=t20/21, m12=t22/23,
1231     ; m3=t24/25, m15=t26/27, m7=t28/29, m11=t30/31
1232
1233     VP9_UNPACK_MULSUB_2W_4X   5, 10, 11,  4, 16069,  3196, [pd_8192], 6,  9 ; t17, t30
1234     VP9_UNPACK_MULSUB_2W_4X   9,  6,  7,  8, 3196, m16069, [pd_8192], 1, 14 ; t18, t29
1235     ; from 1 stage forward
1236     SUMSUB_BA                 w,  8,  4,  1
1237     ; temporary storage
1238     mova     [rsp+17*%%str], m8             ; t16
1239     mova     [rsp+21*%%str], m4             ; t19
1240     VP9_UNPACK_MULSUB_2W_4X   1, 14, 15,  0,  9102, 13623, [pd_8192], 4,  8 ; t21, t26
1241     VP9_UNPACK_MULSUB_2W_4X  13,  2,  3, 12, 13623, m9102, [pd_8192], 4,  8 ; t22, t25
1242
1243     ; m4=t16, m5=t17, m9=t18, m8=t19, m0=t20, m1=t21, m13=t22, m12=t23,
1244     ; m3=t24, m2=t25, m14=t26, m15=t27, m7=t28, m6=t29, m10=t30, m11=t31
1245 %else
1246     mova                m10, [%1+ 1*64]
1247     mova                m13, [%1+ 3*64]
1248     mova                m14, [%1+ 5*64]
1249     mova                 m9, [%1+ 7*64]
1250     mova                 m8, [%1+ 9*64]
1251     mova                m15, [%1+11*64]
1252     mova                m12, [%1+13*64]
1253     mova                m11, [%1+15*64]
1254 %if %3 <= 16
1255     pmulhrsw             m5, m10, [pw_16364x2]
1256     pmulhrsw            m10, [pw_804x2]
1257     pmulhrsw             m4, m11, [pw_m11003x2]
1258     pmulhrsw            m11, [pw_12140x2]
1259     pmulhrsw             m7,  m8, [pw_14811x2]
1260     pmulhrsw             m8, [pw_7005x2]
1261     pmulhrsw             m6,  m9, [pw_m5520x2]
1262     pmulhrsw             m9, [pw_15426x2]
1263     pmulhrsw             m1, m14, [pw_15893x2]
1264     pmulhrsw            m14, [pw_3981x2]
1265     pmulhrsw             m0, m15, [pw_m8423x2]
1266     pmulhrsw            m15, [pw_14053x2]
1267 %else
1268     mova                 m4, [%1+17*64]
1269     mova                 m0, [%1+21*64]
1270     mova                 m7, [%1+23*64]
1271     mova                 m6, [%1+25*64]
1272     mova                 m1, [%1+27*64]
1273     mova                 m5, [%1+31*64]
1274
1275     ; m10=in1, m4=in17, m8=in9, m6=in25, m14=in5, m0=in21, m12=in13, m2=in29,
1276     ; m13=in3, m3=in19, m15=in11, m1=in27, m9=in7, m7=in23, m11=in15, m5=in31
1277
1278     VP9_UNPACK_MULSUB_2W_4X  10,  5, 16364,   804, [pd_8192], 2, 3 ; t16, t31
1279     VP9_UNPACK_MULSUB_2W_4X   4, 11, 11003, 12140, [pd_8192], 2, 3 ; t17, t30
1280     VP9_UNPACK_MULSUB_2W_4X   8,  7, 14811,  7005, [pd_8192], 2, 3 ; t18, t29
1281     VP9_UNPACK_MULSUB_2W_4X   6,  9,  5520, 15426, [pd_8192], 2, 3 ; t19, t28
1282     VP9_UNPACK_MULSUB_2W_4X  14,  1, 15893,  3981, [pd_8192], 2, 3 ; t20, t27
1283     VP9_UNPACK_MULSUB_2W_4X   0, 15,  8423, 14053, [pd_8192], 2, 3 ; t21, t26
1284 %endif
1285
1286     ; from 1 stage forward
1287     SUMSUB_BA             w,  4, 10,  2
1288     SUMSUB_BA             w,  8,  6,  2
1289     ; from 2 stages forward
1290     SUMSUB_BA             w,  8,  4,  2
1291     ; temporary storage
1292     mova     [rsp+17*%%str], m8             ; t16
1293     mova     [rsp+21*%%str], m4             ; t19
1294 %if %3 <= 16
1295     pmulhrsw             m3, m12, [pw_13160x2]
1296     pmulhrsw            m12, [pw_9760x2]
1297     pmulhrsw             m2, m13, [pw_m2404x2]
1298     pmulhrsw            m13, [pw_16207x2]
1299 %else
1300     mova                 m2, [%1+29*64]
1301     mova                 m3, [%1+19*64]
1302     VP9_UNPACK_MULSUB_2W_4X  12,  3, 13160,  9760, [pd_8192], 4, 8 ; t22, t25
1303     VP9_UNPACK_MULSUB_2W_4X   2, 13,  2404, 16207, [pd_8192], 4, 8 ; t23, t24
1304 %endif
1305
1306     ; m10=t16, m4=t17, m8=t18, m6=t19, m14=t20, m0=t21, m12=t22, m2=t23,
1307     ; m13=t24, m3=t25, m15=t26, m1=t27, m9=t28, m7=t29, m11=t30, m5=t31
1308
1309     SUMSUB_BA             w,  0, 14,  4
1310     SUMSUB_BA             w, 12,  2,  4
1311     SUMSUB_BA             w,  3, 13,  4
1312     SUMSUB_BA             w, 15,  1,  4
1313     SUMSUB_BA             w,  7,  9,  4
1314     SUMSUB_BA             w, 11,  5,  4
1315
1316     ; m4=t16, m10=t17, m6=t18, m8=t19, m0=t20, m14=t21, m2=t22, m12=t23,
1317     ; m3=t24, m13=t25, m1=t26, m15=t27, m7=t28, m9=t29, m5=t30, m11=t31
1318
1319     VP9_UNPACK_MULSUB_2W_4X   5, 10, 16069,  3196, [pd_8192], 4, 8 ; t17, t30
1320     VP9_UNPACK_MULSUB_2W_4X   9,  6, 3196, m16069, [pd_8192], 4, 8 ; t18, t29
1321     VP9_UNPACK_MULSUB_2W_4X   1, 14,  9102, 13623, [pd_8192], 4, 8 ; t21, t26
1322     VP9_UNPACK_MULSUB_2W_4X  13,  2, 13623, m9102, [pd_8192], 4, 8 ; t22, t25
1323 %endif
1324
1325     ; m4=t16, m5=t17, m9=t18, m8=t19, m0=t20, m1=t21, m13=t22, m12=t23,
1326     ; m3=t24, m2=t25, m14=t26, m15=t27, m7=t28, m6=t29, m10=t30, m11=t31
1327
1328     SUMSUB_BA             w,  9,  5,  4
1329     SUMSUB_BA             w,  1, 13,  4
1330     SUMSUB_BA             w,  0, 12,  4
1331     SUMSUB_BA             w, 15,  3,  4
1332     SUMSUB_BA             w, 14,  2,  4
1333     SUMSUB_BA             w,  6, 10,  4
1334     SUMSUB_BA             w,  7, 11,  4
1335
1336     ; m8[s]=t16, m9=t17, m5=t18, m4[s]=t19, m12=t20, m13=t21, m1=t22, m0=t23,
1337     ; m15=t24, m14=t25, m2=t26, m3=t27, m11=t28, m10=t29, m6=t30, m7=t31
1338
1339     mova                 m8, [rsp+17*%%str] ; t16
1340     ; from 2 stages forward
1341     SUMSUB_BA             w,  0,  8,  4
1342     SUMSUB_BA             w, 15,  7,  4
1343     ; from 3 stages forward
1344     SUMSUB_BA             w,  8,  7,  4
1345     pmulhrsw             m7, [pw_11585x2]
1346     pmulhrsw             m8, [pw_11585x2]
1347     ; store t16/t23
1348     mova     [rsp+ 1*%%str], m0     ; t16
1349     mova     [rsp+29*%%str], m7     ; t23
1350
1351     mova                 m4, [rsp+21*%%str] ; t19
1352     VP9_UNPACK_MULSUB_2W_4X  10,  5, 15137,  6270, [pd_8192], 0, 7 ; t18, t29
1353     VP9_UNPACK_MULSUB_2W_4X  11,  4, 15137,  6270, [pd_8192], 0, 7 ; t19, t28
1354     VP9_UNPACK_MULSUB_2W_4X   3, 12, 6270, m15137, [pd_8192], 0, 7 ; t20, t27
1355     VP9_UNPACK_MULSUB_2W_4X   2, 13, 6270, m15137, [pd_8192], 0, 7 ; t21, t26
1356
1357     ; m8=t16, m9=t17, m10=t18, m11=t19, m3=t20, m2=t21, m1=t22, m0=t23,
1358     ; m15=t24, m14=t25, m13=t26, m12=t27, m4=t28, m5=t29, m6=t30, m7=t31
1359
1360     SUMSUB_BA             w,  1,  9,  0
1361     SUMSUB_BA             w,  2, 10,  0
1362     SUMSUB_BA             w,  3, 11,  0
1363     SUMSUB_BA             w, 12,  4,  0
1364     SUMSUB_BA             w, 13,  5,  0
1365     SUMSUB_BA             w, 14,  6,  0
1366
1367     ; m0=t16, m1=t17, m2=t18, m3=t19, m11=t20, m10=t21, m9=t22, m8=t23,
1368     ; m7=t24, m6=t25, m5=t26, m4=t27, m12=t28, m13=t29, m14=t30, m15=t31
1369
1370     SUMSUB_BA             w,  9,  6,  0
1371     SUMSUB_BA             w, 10,  5,  0
1372     SUMSUB_BA             w, 11,  4,  0
1373
1374     pmulhrsw             m6, [pw_11585x2]
1375     pmulhrsw             m9, [pw_11585x2]
1376     pmulhrsw             m5, [pw_11585x2]
1377     pmulhrsw            m10, [pw_11585x2]
1378     pmulhrsw             m4, [pw_11585x2]
1379     pmulhrsw            m11, [pw_11585x2]
1380
1381     ; m0=t16, m1=t17, m2=t18, m3=t19, m4=t20, m5=t21, m6=t22, m7=t23,
1382     ; m8=t24, m9=t25, m10=t26, m11=t27, m12=t28, m13=t29, m14=t30, m15=t31
1383
1384     ; store t17-19 (and t20-22 for pass 1) - keep t24-31 in registers for
1385     ; final sumsub in pass 1, or keep t20-22 and t24-31 in registers for
1386     ; final sumsub of pass 2
1387     mova     [rsp+ 5*%%str], m1     ; t17
1388     mova     [rsp+ 9*%%str], m2     ; t18
1389     mova     [rsp+13*%%str], m3     ; t19
1390
1391     ; then do final pass to sumsub+store the two halves
1392 %if %2 == 1
1393     mova     [rsp+17*%%str], m4     ; t20
1394     mova     [rsp+21*%%str], m5     ; t21
1395     mova     [rsp+25*%%str], m6     ; t22
1396
1397     mova                 m0, [rsp+ 0*%%str] ; t0
1398     mova                 m1, [rsp+ 4*%%str] ; t1
1399     mova                 m2, [rsp+ 8*%%str] ; t2
1400     mova                 m3, [rsp+12*%%str] ; t3
1401     mova                 m4, [rsp+16*%%str] ; t4
1402     mova                 m5, [rsp+20*%%str] ; t5
1403     mova                 m6, [rsp+24*%%str] ; t6
1404
1405     SUMSUB_BA             w, 15,  0, 7
1406     mova     [rsp+ 3*%%str], m0             ; t15
1407     mova                 m7, [rsp+28*%%str] ; t7
1408     SUMSUB_BA             w, 14,  1, 0
1409     SUMSUB_BA             w, 13,  2, 0
1410     SUMSUB_BA             w, 12,  3, 0
1411     SUMSUB_BA             w, 11,  4, 0
1412     SUMSUB_BA             w, 10,  5, 0
1413     SUMSUB_BA             w,  9,  6, 0
1414     SUMSUB_BA             w,  8,  7, 0
1415
1416     TRANSPOSE8x8W        15, 14, 13, 12, 11, 10, 9, 8, 0
1417     mova     [rsp+ 0*%%str], m15
1418     mova     [rsp+ 4*%%str], m14
1419     mova     [rsp+ 8*%%str], m13
1420     mova     [rsp+12*%%str], m12
1421     mova     [rsp+16*%%str], m11
1422     mova     [rsp+20*%%str], m10
1423     mova     [rsp+24*%%str], m9
1424     mova     [rsp+28*%%str], m8
1425
1426     mova                  m0, [rsp+ 3*%%str] ; t15
1427     TRANSPOSE8x8W          7, 6, 5, 4, 3, 2, 1, 0, 8
1428     mova     [rsp+ 3*%%str], m7
1429     mova     [rsp+ 7*%%str], m6
1430     mova     [rsp+11*%%str], m5
1431     mova     [rsp+15*%%str], m4
1432     mova     [rsp+19*%%str], m3
1433     mova     [rsp+23*%%str], m2
1434     mova     [rsp+27*%%str], m1
1435     mova     [rsp+31*%%str], m0
1436
1437     mova                m15, [rsp+ 2*%%str] ; t8
1438     mova                m14, [rsp+ 6*%%str] ; t9
1439     mova                m13, [rsp+10*%%str] ; t10
1440     mova                m12, [rsp+14*%%str] ; t11
1441     mova                m11, [rsp+18*%%str] ; t12
1442     mova                m10, [rsp+22*%%str] ; t13
1443     mova                 m9, [rsp+26*%%str] ; t14
1444     mova                 m8, [rsp+30*%%str] ; t15
1445     mova                 m7, [rsp+ 1*%%str] ; t16
1446     mova                 m6, [rsp+ 5*%%str] ; t17
1447     mova                 m5, [rsp+ 9*%%str] ; t18
1448     mova                 m4, [rsp+13*%%str] ; t19
1449     mova                 m3, [rsp+17*%%str] ; t20
1450     mova                 m2, [rsp+21*%%str] ; t21
1451     mova                 m1, [rsp+25*%%str] ; t22
1452
1453     SUMSUB_BA             w,  7,  8, 0
1454     mova     [rsp+ 2*%%str], m8
1455     mova                 m0, [rsp+29*%%str] ; t23
1456     SUMSUB_BA             w,  6,  9, 8
1457     SUMSUB_BA             w,  5, 10, 8
1458     SUMSUB_BA             w,  4, 11, 8
1459     SUMSUB_BA             w,  3, 12, 8
1460     SUMSUB_BA             w,  2, 13, 8
1461     SUMSUB_BA             w,  1, 14, 8
1462     SUMSUB_BA             w,  0, 15, 8
1463
1464     TRANSPOSE8x8W         0, 1, 2, 3, 4, 5, 6, 7, 8
1465     mova     [rsp+ 1*%%str], m0
1466     mova     [rsp+ 5*%%str], m1
1467     mova     [rsp+ 9*%%str], m2
1468     mova     [rsp+13*%%str], m3
1469     mova     [rsp+17*%%str], m4
1470     mova     [rsp+21*%%str], m5
1471     mova     [rsp+25*%%str], m6
1472     mova     [rsp+29*%%str], m7
1473
1474     mova                 m8, [rsp+ 2*%%str]
1475     TRANSPOSE8x8W         8, 9, 10, 11, 12, 13, 14, 15, 0
1476     mova     [rsp+ 2*%%str], m8
1477     mova     [rsp+ 6*%%str], m9
1478     mova     [rsp+10*%%str], m10
1479     mova     [rsp+14*%%str], m11
1480     mova     [rsp+18*%%str], m12
1481     mova     [rsp+22*%%str], m13
1482     mova     [rsp+26*%%str], m14
1483     mova     [rsp+30*%%str], m15
1484 %else
1485     ; t0-7 is in [rsp+{0,4,8,12,16,20,24,28}*%%str]
1486     ; t8-15 is in [rsp+{2,6,10,14,18,22,26,30}*%%str]
1487     ; t16-19 and t23 is in [rsp+{1,5,9,13,29}*%%str]
1488     ; t20-22 is in m4-6
1489     ; t24-31 is in m8-15
1490     pxor                m7, m7
1491
1492 %macro %%STORE_2X2 7-8 1 ; src[1-4], tmp[1-2], zero, inc_dst_ptrs
1493     SUMSUB_BA            w, %4, %1, %5
1494     SUMSUB_BA            w, %3, %2, %5
1495     pmulhrsw           m%4, [pw_512]
1496     pmulhrsw           m%3, [pw_512]
1497     VP9_STORE_2X        %4, %3, %5, %6, %7
1498 %if %8 == 1
1499     add               dstq, stride2q
1500 %endif
1501     pmulhrsw           m%2, [pw_512]
1502     pmulhrsw           m%1, [pw_512]
1503     VP9_STORE_2X        %2, %1, %5, %6, %7, dst_endq
1504 %if %8 == 1
1505     sub           dst_endq, stride2q
1506 %endif
1507 %endmacro
1508
1509     ; store t0-1 and t30-31
1510     mova                m0, [rsp+ 0*%%str]
1511     mova                m1, [rsp+ 4*%%str]
1512     %%STORE_2X2          0,  1, 14, 15, 2, 3, 7
1513
1514     ; store t2-3 and t28-29
1515     mova                m0, [rsp+ 8*%%str]
1516     mova                m1, [rsp+12*%%str]
1517     %%STORE_2X2          0,  1, 12, 13, 2, 3, 7
1518
1519     ; store t4-5 and t26-27
1520     mova                m0, [rsp+16*%%str]
1521     mova                m1, [rsp+20*%%str]
1522     %%STORE_2X2          0,  1, 10, 11, 2, 3, 7
1523
1524     ; store t6-7 and t24-25
1525     mova                m0, [rsp+24*%%str]
1526     mova                m1, [rsp+28*%%str]
1527     %%STORE_2X2          0,  1,  8,  9, 2, 3, 7
1528
1529     ; store t8-9 and t22-23
1530     mova                m0, [rsp+ 2*%%str]
1531     mova                m1, [rsp+ 6*%%str]
1532     mova                m8, [rsp+29*%%str]
1533     %%STORE_2X2          0,  1,  6,  8, 2, 3, 7
1534
1535     ; store t10-11 and t20-21
1536     mova                m0, [rsp+10*%%str]
1537     mova                m1, [rsp+14*%%str]
1538     %%STORE_2X2          0,  1,  4,  5, 2, 3, 7
1539
1540     ; store t12-13 and t18-19
1541     mova                m0, [rsp+18*%%str]
1542     mova                m1, [rsp+22*%%str]
1543     mova                m5, [rsp+13*%%str]
1544     mova                m4, [rsp+ 9*%%str]
1545     %%STORE_2X2          0,  1,  4,  5, 2, 3, 7
1546
1547     ; store t14-17
1548     mova                m0, [rsp+26*%%str]
1549     mova                m1, [rsp+30*%%str]
1550     mova                m5, [rsp+ 5*%%str]
1551     mova                m4, [rsp+ 1*%%str]
1552     %%STORE_2X2          0,  1,  4,  5, 2, 3, 7, 0
1553 %endif
1554 %endmacro
1555
1556 %macro VP9_IDCT_IDCT_32x32_ADD_XMM 1
1557 INIT_XMM %1
1558 cglobal vp9_idct_idct_32x32_add, 4, 8, 16, 2048, dst, stride, block, eob
1559     cmp eobd, 135
1560     jg .idctfull
1561     cmp eobd, 34
1562     jg .idct16x16
1563     cmp eobd, 1
1564     jg .idct8x8
1565
1566     ; dc-only case
1567     movd                m0, [blockq]
1568     mova                m1, [pw_11585x2]
1569     pmulhrsw            m0, m1
1570     pmulhrsw            m0, m1
1571     SPLATW              m0, m0, q0000
1572     pmulhrsw            m0, [pw_512]
1573     pxor                m5, m5
1574     movd          [blockq], m5
1575     DEFINE_ARGS        dst, stride, block, cnt
1576 %rep 31
1577     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5, mmsize
1578     add               dstq, strideq
1579 %endrep
1580     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5, mmsize
1581     RET
1582
1583     DEFINE_ARGS dst_bak, stride, block, cnt, dst, stride30, dst_end, stride2
1584 .idct8x8:
1585     VP9_IDCT32_1D   blockq, 1, 8
1586
1587     mov          stride30q, strideq         ; stride
1588     lea           stride2q, [strideq*2]     ; stride*2
1589     shl          stride30q, 5               ; stride*32
1590     mov               cntd, 4
1591     sub          stride30q, stride2q        ; stride*30
1592 .loop2_8x8:
1593     mov               dstq, dst_bakq
1594     lea           dst_endq, [dst_bakq+stride30q]
1595     VP9_IDCT32_1D      rsp, 2, 8
1596     add           dst_bakq, 8
1597     add                rsp, 16
1598     dec               cntd
1599     jg .loop2_8x8
1600     sub                rsp, 64
1601
1602     ; at the end of the loop, m7 should still be zero
1603     ; use that to zero out block coefficients
1604     ZERO_BLOCK      blockq, 64,  8, m7
1605     RET
1606
1607 .idct16x16:
1608     mov               cntd, 2
1609 .loop1_16x16:
1610     VP9_IDCT32_1D   blockq, 1, 16
1611     add             blockq, 16
1612     add                rsp, 512
1613     dec               cntd
1614     jg .loop1_16x16
1615     sub             blockq, 32
1616     sub                rsp, 1024
1617
1618     mov          stride30q, strideq         ; stride
1619     lea           stride2q, [strideq*2]     ; stride*2
1620     shl          stride30q, 5               ; stride*32
1621     mov               cntd, 4
1622     sub          stride30q, stride2q        ; stride*30
1623 .loop2_16x16:
1624     mov               dstq, dst_bakq
1625     lea           dst_endq, [dst_bakq+stride30q]
1626     VP9_IDCT32_1D      rsp, 2, 16
1627     add           dst_bakq, 8
1628     add                rsp, 16
1629     dec               cntd
1630     jg .loop2_16x16
1631     sub                rsp, 64
1632
1633     ; at the end of the loop, m7 should still be zero
1634     ; use that to zero out block coefficients
1635     ZERO_BLOCK      blockq, 64, 16, m7
1636     RET
1637
1638 .idctfull:
1639     mov               cntd, 4
1640 .loop1_full:
1641     VP9_IDCT32_1D   blockq, 1
1642     add             blockq, 16
1643     add                rsp, 512
1644     dec               cntd
1645     jg .loop1_full
1646     sub             blockq, 64
1647     sub                rsp, 2048
1648
1649     mov          stride30q, strideq         ; stride
1650     lea           stride2q, [strideq*2]     ; stride*2
1651     shl          stride30q, 5               ; stride*32
1652     mov               cntd, 4
1653     sub          stride30q, stride2q        ; stride*30
1654 .loop2_full:
1655     mov               dstq, dst_bakq
1656     lea           dst_endq, [dst_bakq+stride30q]
1657     VP9_IDCT32_1D      rsp, 2
1658     add           dst_bakq, 8
1659     add                rsp, 16
1660     dec               cntd
1661     jg .loop2_full
1662     sub                rsp, 64
1663
1664     ; at the end of the loop, m7 should still be zero
1665     ; use that to zero out block coefficients
1666     ZERO_BLOCK      blockq, 64, 32, m7
1667     RET
1668 %endmacro
1669
1670 VP9_IDCT_IDCT_32x32_ADD_XMM ssse3
1671 VP9_IDCT_IDCT_32x32_ADD_XMM avx
1672
1673 %endif ; x86-64