]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/vp9itxfm.asm
Merge commit '5fcae3b3f93fd02b3d1e009b9d9b17410fca9498'
[ffmpeg] / 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 %include "vp9itxfm_template.asm"
26
27 SECTION_RODATA 32
28
29 %macro VP9_IDCT_COEFFS 2-3 0
30 const pw_m%1_%2
31 times 8 dw -%1,  %2
32 const pw_%2_%1
33 times 8 dw  %2,  %1
34
35 %if %3 == 1
36 const pw_m%2_m%1
37 times 8 dw -%2, -%1
38 %if %1 != %2
39 const pw_m%2_%1
40 times 8 dw -%2,  %1
41 const pw_%1_%2
42 times 8 dw  %1,  %2
43 %endif
44 %endif
45
46 %if %1 < 11585
47 pw_m%1x2:   times 16 dw -%1*2
48 %elif %1 > 11585
49 pw_%1x2:    times 16 dw  %1*2
50 %else
51 const pw_%1x2
52 times 16 dw %1*2
53 %endif
54
55 %if %2 != %1
56 pw_%2x2:    times 16 dw  %2*2
57 %endif
58 %endmacro
59
60 VP9_IDCT_COEFFS 16364,   804
61 VP9_IDCT_COEFFS 16305,  1606
62 VP9_IDCT_COEFFS 16069,  3196, 1
63 VP9_IDCT_COEFFS 15893,  3981
64 VP9_IDCT_COEFFS 15137,  6270, 1
65 VP9_IDCT_COEFFS 14811,  7005
66 VP9_IDCT_COEFFS 14449,  7723
67 VP9_IDCT_COEFFS 13160,  9760
68 VP9_IDCT_COEFFS 11585, 11585, 1
69 VP9_IDCT_COEFFS 11003, 12140
70 VP9_IDCT_COEFFS 10394, 12665
71 VP9_IDCT_COEFFS  9102, 13623, 1
72 VP9_IDCT_COEFFS  8423, 14053
73 VP9_IDCT_COEFFS  5520, 15426
74 VP9_IDCT_COEFFS  4756, 15679
75 VP9_IDCT_COEFFS  2404, 16207
76
77 const pw_5283_13377
78 times 4 dw 5283, 13377
79 const pw_9929_13377
80 times 4 dw 9929, 13377
81 const pw_15212_m13377
82 times 4 dw 15212, -13377
83 const pw_15212_9929
84 times 4 dw 15212, 9929
85 const pw_m5283_m15212
86 times 4 dw -5283, -15212
87 const pw_13377x2
88 times 8 dw 13377*2
89 const pw_m13377_13377
90 times 4 dw -13377, 13377
91 const pw_13377_0
92 times 4 dw 13377, 0
93
94 cextern pw_8
95 cextern pw_16
96 cextern pw_32
97 cextern pw_512
98 cextern pw_1024
99 cextern pw_2048
100 cextern pw_m1
101 cextern pd_8192
102
103 SECTION .text
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 %if mmsize == 32
131     pmovzxbw           m%3, [%6]
132     pmovzxbw           m%4, [%6+strideq]
133 %else
134     movh               m%3, [%6]
135     movh               m%4, [%6+strideq]
136     punpcklbw          m%3, m%5
137     punpcklbw          m%4, m%5
138 %endif
139     paddw              m%3, m%1
140     paddw              m%4, m%2
141 %if mmsize == 32
142     packuswb           m%3, m%4
143     ; Intel...
144     vpermq             m%3, m%3, q3120
145     mova              [%6], xm%3
146     vextracti128 [%6+strideq], m%3, 1
147 %elif mmsize == 16
148     packuswb           m%3, m%4
149     movh              [%6], m%3
150     movhps    [%6+strideq], m%3
151 %else
152     packuswb           m%3, m%5
153     packuswb           m%4, m%5
154     movh              [%6], m%3
155     movh      [%6+strideq], m%4
156 %endif
157 %endmacro
158
159 %macro ZERO_BLOCK 4 ; mem, stride, nnzcpl, zero_reg
160 %assign %%y 0
161 %rep %3
162 %assign %%x 0
163 %rep %3*2/mmsize
164     mova      [%1+%%y+%%x], %4
165 %assign %%x (%%x+mmsize)
166 %endrep
167 %assign %%y (%%y+%2)
168 %endrep
169 %endmacro
170
171 ;-------------------------------------------------------------------------------------------
172 ; void vp9_iwht_iwht_4x4_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
173 ;-------------------------------------------------------------------------------------------
174
175 INIT_MMX mmx
176 cglobal vp9_iwht_iwht_4x4_add, 3, 3, 0, dst, stride, block, eob
177     mova                m0, [blockq+0*8]
178     mova                m1, [blockq+1*8]
179     mova                m2, [blockq+2*8]
180     mova                m3, [blockq+3*8]
181     psraw               m0, 2
182     psraw               m1, 2
183     psraw               m2, 2
184     psraw               m3, 2
185
186     VP9_IWHT4_1D
187     TRANSPOSE4x4W        0, 1, 2, 3, 4
188     VP9_IWHT4_1D
189
190     pxor                m4, m4
191     VP9_STORE_2X         0, 1, 5, 6, 4
192     lea               dstq, [dstq+strideq*2]
193     VP9_STORE_2X         2, 3, 5, 6, 4
194     ZERO_BLOCK      blockq, 8, 4, m4
195     RET
196
197 ;-------------------------------------------------------------------------------------------
198 ; void vp9_idct_idct_4x4_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
199 ;-------------------------------------------------------------------------------------------
200
201 ; 2x2 top left corner
202 %macro VP9_IDCT4_2x2_1D 0
203     pmulhrsw            m0, m5                              ; m0=t1
204     mova                m2, m0                              ; m2=t0
205     mova                m3, m1
206     pmulhrsw            m1, m6                              ; m1=t2
207     pmulhrsw            m3, m7                              ; m3=t3
208     VP9_IDCT4_1D_FINALIZE
209 %endmacro
210
211 %macro VP9_IDCT4_WRITEOUT 0
212 %if cpuflag(ssse3)
213     mova                m5, [pw_2048]
214     pmulhrsw            m0, m5              ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4
215     pmulhrsw            m1, m5
216 %else
217     mova                m5, [pw_8]
218     paddw               m0, m5
219     paddw               m1, m5
220     psraw               m0, 4
221     psraw               m1, 4
222 %endif
223     VP9_STORE_2X         0,  1,  6,  7,  4
224     lea               dstq, [dstq+2*strideq]
225 %if cpuflag(ssse3)
226     pmulhrsw            m2, m5
227     pmulhrsw            m3, m5
228 %else
229     paddw               m2, m5
230     paddw               m3, m5
231     psraw               m2, 4
232     psraw               m3, 4
233 %endif
234     VP9_STORE_2X         2,  3,  6,  7,  4
235 %endmacro
236
237 %macro IDCT_4x4_FN 1
238 INIT_MMX %1
239 cglobal vp9_idct_idct_4x4_add, 4, 4, 0, dst, stride, block, eob
240
241 %if cpuflag(ssse3)
242     cmp eobd, 4 ; 2x2 or smaller
243     jg .idctfull
244
245     cmp eobd, 1 ; faster path for when only DC is set
246     jne .idct2x2
247 %else
248     cmp eobd, 1
249     jg .idctfull
250 %endif
251
252 %if cpuflag(ssse3)
253     movd                m0, [blockq]
254     mova                m5, [pw_11585x2]
255     pmulhrsw            m0, m5
256     pmulhrsw            m0, m5
257 %else
258     DEFINE_ARGS dst, stride, block, coef
259     movsx            coefd, word [blockq]
260     imul             coefd, 11585
261     add              coefd, 8192
262     sar              coefd, 14
263     imul             coefd, 11585
264     add              coefd, (8 << 14) + 8192
265     sar              coefd, 14 + 4
266     movd                m0, coefd
267 %endif
268     pshufw              m0, m0, 0
269     pxor                m4, m4
270     movh          [blockq], m4
271 %if cpuflag(ssse3)
272     pmulhrsw            m0, [pw_2048]       ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4
273 %endif
274     VP9_STORE_2X         0,  0,  6,  7,  4
275     lea               dstq, [dstq+2*strideq]
276     VP9_STORE_2X         0,  0,  6,  7,  4
277     RET
278
279 %if cpuflag(ssse3)
280 ; faster path for when only top left 2x2 block is set
281 .idct2x2:
282     movd                m0, [blockq+0]
283     movd                m1, [blockq+8]
284     mova                m5, [pw_11585x2]
285     mova                m6, [pw_6270x2]
286     mova                m7, [pw_15137x2]
287     VP9_IDCT4_2x2_1D
288     ; partial 2x4 transpose
289     punpcklwd           m0, m1
290     punpcklwd           m2, m3
291     SBUTTERFLY          dq, 0, 2, 1
292     SWAP                1, 2
293     VP9_IDCT4_2x2_1D
294     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
295     movh       [blockq+ 0], m4
296     movh       [blockq+ 8], m4
297     VP9_IDCT4_WRITEOUT
298     RET
299 %endif
300
301 .idctfull: ; generic full 4x4 idct/idct
302     mova                m0, [blockq+ 0]
303     mova                m1, [blockq+ 8]
304     mova                m2, [blockq+16]
305     mova                m3, [blockq+24]
306 %if cpuflag(ssse3)
307     mova                m6, [pw_11585x2]
308 %endif
309     mova                m7, [pd_8192]       ; rounding
310     VP9_IDCT4_1D
311     TRANSPOSE4x4W  0, 1, 2, 3, 4
312     VP9_IDCT4_1D
313     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
314     mova       [blockq+ 0], m4
315     mova       [blockq+ 8], m4
316     mova       [blockq+16], m4
317     mova       [blockq+24], m4
318     VP9_IDCT4_WRITEOUT
319     RET
320 %endmacro
321
322 IDCT_4x4_FN mmxext
323 IDCT_4x4_FN ssse3
324
325 ;-------------------------------------------------------------------------------------------
326 ; void vp9_iadst_iadst_4x4_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
327 ;-------------------------------------------------------------------------------------------
328
329 %macro IADST4_FN 5
330 INIT_MMX %5
331 cglobal vp9_%1_%3_4x4_add, 3, 3, 0, dst, stride, block, eob
332 %if WIN64 && notcpuflag(ssse3)
333     WIN64_SPILL_XMM 8
334 %endif
335     movdqa            xmm5, [pd_8192]
336     mova                m0, [blockq+ 0]
337     mova                m1, [blockq+ 8]
338     mova                m2, [blockq+16]
339     mova                m3, [blockq+24]
340 %if cpuflag(ssse3)
341     mova                m6, [pw_11585x2]
342 %endif
343 %ifnidn %1%3, iadstiadst
344     movdq2q             m7, xmm5
345 %endif
346     VP9_%2_1D
347     TRANSPOSE4x4W  0, 1, 2, 3, 4
348     VP9_%4_1D
349     pxor                m4, m4  ; used for the block reset, and VP9_STORE_2X
350     mova       [blockq+ 0], m4
351     mova       [blockq+ 8], m4
352     mova       [blockq+16], m4
353     mova       [blockq+24], m4
354     VP9_IDCT4_WRITEOUT
355     RET
356 %endmacro
357
358 IADST4_FN idct,  IDCT4,  iadst, IADST4, sse2
359 IADST4_FN iadst, IADST4, idct,  IDCT4,  sse2
360 IADST4_FN iadst, IADST4, iadst, IADST4, sse2
361
362 IADST4_FN idct,  IDCT4,  iadst, IADST4, ssse3
363 IADST4_FN iadst, IADST4, idct,  IDCT4,  ssse3
364 IADST4_FN iadst, IADST4, iadst, IADST4, ssse3
365
366 %macro SCRATCH 3
367 %if ARCH_X86_64
368     SWAP                %1, %2
369 %else
370     mova              [%3], m%1
371 %endif
372 %endmacro
373
374 %macro UNSCRATCH 3
375 %if ARCH_X86_64
376     SWAP                %1, %2
377 %else
378     mova               m%1, [%3]
379 %endif
380 %endmacro
381
382 ;-------------------------------------------------------------------------------------------
383 ; void vp9_idct_idct_8x8_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
384 ;-------------------------------------------------------------------------------------------
385
386 %macro VP9_IDCT8_1D_FINALIZE 0
387     SUMSUB_BA            w,  3,  6, 5                       ; m3=t0+t7, m6=t0-t7
388     SUMSUB_BA            w,  1,  2, 5                       ; m1=t1+t6, m2=t1-t6
389     SUMSUB_BA            w,  7,  0, 5                       ; m7=t2+t5, m0=t2-t5
390
391     UNSCRATCH            5, 8, blockq+ 0
392     SCRATCH              2, 8, blockq+ 0
393
394     SUMSUB_BA            w,  5,  4, 2                       ; m5=t3+t4, m4=t3-t4
395     SWAP                 7,  6,  2
396     SWAP                 3,  5,  0
397
398 %if ARCH_X86_64
399     SWAP                 6, 8
400 %endif
401 %endmacro
402
403 ; x86-32
404 ; - in: m0/m4 is in mem
405 ; - out: m6 is in mem
406 ; x86-64:
407 ; - everything is in registers (m0-7)
408 %macro VP9_IDCT8_1D 0
409 %if ARCH_X86_64
410     SWAP                 0, 8
411     SWAP                 4, 9
412 %endif
413
414     VP9_UNPACK_MULSUB_2W_4X 5,  3,  9102, 13623, D_8192_REG, 0, 4  ; m5=t5a, m3=t6a
415     VP9_UNPACK_MULSUB_2W_4X 1,  7, 16069,  3196, D_8192_REG, 0, 4  ; m1=t4a, m7=t7a
416     SUMSUB_BA            w,  5,  1, 0                       ; m5=t4a+t5a (t4), m1=t4a-t5a (t5a)
417     SUMSUB_BA            w,  3,  7, 0                       ; m3=t7a+t6a (t7), m7=t7a-t6a (t6a)
418 %if cpuflag(ssse3)
419     SUMSUB_BA            w,  1,  7, 0                       ; m1=t6a+t5a (t6), m7=t6a-t5a (t5)
420     pmulhrsw            m1, W_11585x2_REG                   ; m1=t6
421     pmulhrsw            m7, W_11585x2_REG                   ; m7=t5
422 %else
423     VP9_UNPACK_MULSUB_2W_4X 7,  1, 11585, 11585, D_8192_REG, 0, 4
424 %endif
425     VP9_UNPACK_MULSUB_2W_4X 2,  6, 15137,  6270, D_8192_REG, 0, 4  ; m2=t2a, m6=t3a
426
427     UNSCRATCH            0, 8, blockq+ 0    ; IN(0)
428     UNSCRATCH            4, 9, blockq+64    ; IN(4)
429     SCRATCH              5, 8, blockq+ 0
430
431 %if cpuflag(ssse3)
432     SUMSUB_BA            w, 4, 0, 5                         ; m4=IN(0)+IN(4) m0=IN(0)-IN(4)
433     pmulhrsw            m4, W_11585x2_REG                   ; m4=t0a
434     pmulhrsw            m0, W_11585x2_REG                   ; m0=t1a
435 %else
436     SCRATCH              7, 9, blockq+64
437     VP9_UNPACK_MULSUB_2W_4X 0,  4, 11585, 11585, D_8192_REG, 5, 7
438     UNSCRATCH            7, 9, blockq+64
439 %endif
440     SUMSUB_BA            w,  6,  4, 5                       ; m6=t0a+t3a (t0), m4=t0a-t3a (t3)
441     SUMSUB_BA            w,  2,  0, 5                       ; m2=t1a+t2a (t1), m0=t1a-t2a (t2)
442
443     VP9_IDCT8_1D_FINALIZE
444 %endmacro
445
446 %macro VP9_IDCT8_4x4_1D 0
447     pmulhrsw            m0, W_11585x2_REG                   ; m0=t1a/t0a
448     pmulhrsw            m6, m2, [pw_15137x2]                ; m6=t3a
449     pmulhrsw            m2, [pw_6270x2]                     ; m2=t2a
450     pmulhrsw            m7, m1, [pw_16069x2]                ; m7=t7a
451     pmulhrsw            m1, [pw_3196x2]                     ; m1=t4a
452     pmulhrsw            m5, m3, [pw_m9102x2]                ; m5=t5a
453     pmulhrsw            m3, [pw_13623x2]                    ; m3=t6a
454     SUMSUB_BA            w,  5,  1, 4                       ; m1=t4a+t5a (t4), m5=t4a-t5a (t5a)
455     SUMSUB_BA            w,  3,  7, 4                       ; m3=t7a+t6a (t7), m7=t7a-t6a (t6a)
456     SUMSUB_BA            w,  1,  7, 4                       ; m1=t6a+t5a (t6), m7=t6a-t5a (t5)
457     pmulhrsw            m1, W_11585x2_REG                   ; m1=t6
458     pmulhrsw            m7, W_11585x2_REG                   ; m7=t5
459     psubw               m4, m0, m6                          ; m4=t0a-t3a (t3)
460     paddw               m6, m0                              ; m6=t0a+t3a (t0)
461     SCRATCH              5,  8, blockq+ 0
462     SUMSUB_BA            w,  2,  0, 5                       ; m2=t1a+t2a (t1), m0=t1a-t2a (t2)
463     VP9_IDCT8_1D_FINALIZE
464 %endmacro
465
466 %macro VP9_IDCT8_2x2_1D 1
467     pmulhrsw            m0, W_11585x2_REG                   ; m0=t0
468     pmulhrsw            m3, m1, W_16069x2_REG               ; m3=t7
469     pmulhrsw            m1, W_3196x2_REG                    ; m1=t4
470     psubw               m7, m3, m1                          ; t5 = t7a - t4a
471     paddw               m5, m3, m1                          ; t6 = t7a + t4a
472     pmulhrsw            m7, W_11585x2_REG                   ; m7=t5
473     pmulhrsw            m5, W_11585x2_REG                   ; m5=t6
474     SWAP                 5,  1
475     ; merged VP9_IDCT8_1D_FINALIZE to make register-sharing w/ avx easier
476     psubw               m6, m0, m3                          ; m6=t0-t7
477     paddw               m3, m0                              ; m3=t0+t7
478     psubw               m2, m0, m1                          ; m2=t1-t6
479     paddw               m1, m0                              ; m1=t1+t6
480 %if %1 == 1
481     punpcklwd           m3, m1
482 %define SCRATCH_REG 1
483 %elif ARCH_X86_32
484     mova       [blockq+ 0], m2
485 %define SCRATCH_REG 2
486 %else
487 %define SCRATCH_REG 8
488 %endif
489     psubw               m4, m0, m5                          ; m4=t3-t4
490     paddw               m5, m0                              ; m5=t3+t4
491     SUMSUB_BA            w,  7,  0, SCRATCH_REG             ; m7=t2+t5, m0=t2-t5
492     SWAP                 7,  6,  2
493     SWAP                 3,  5,  0
494 %undef SCRATCH_REG
495 %endmacro
496
497 %macro VP9_IDCT8_WRITEx2 6-8 5 ; line1, line2, tmp1, tmp2, zero, pw_1024/pw_16, shift
498 %if cpuflag(ssse3)
499     pmulhrsw           m%1, %6              ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5
500     pmulhrsw           m%2, %6
501 %else
502     paddw              m%1, %6
503     paddw              m%2, %6
504     psraw              m%1, %7
505     psraw              m%2, %7
506 %endif
507 %if %0 <= 7
508     VP9_STORE_2X        %1, %2, %3, %4, %5
509 %else
510     VP9_STORE_2X        %1, %2, %3, %4, %5, %8
511 %endif
512 %endmacro
513
514 ; x86-32:
515 ; - m6 is in mem
516 ; x86-64:
517 ; - m8 holds m6 (SWAP)
518 ; m6 holds zero
519 %macro VP9_IDCT8_WRITEOUT 0
520 %if ARCH_X86_64
521 %if cpuflag(ssse3)
522     mova                m9, [pw_1024]
523 %else
524     mova                m9, [pw_16]
525 %endif
526 %define ROUND_REG m9
527 %else
528 %if cpuflag(ssse3)
529 %define ROUND_REG [pw_1024]
530 %else
531 %define ROUND_REG [pw_16]
532 %endif
533 %endif
534     SCRATCH              5, 10, blockq+16
535     SCRATCH              7, 11, blockq+32
536     VP9_IDCT8_WRITEx2    0,  1, 5, 7, 6, ROUND_REG
537     lea               dstq, [dstq+2*strideq]
538     VP9_IDCT8_WRITEx2    2,  3, 5, 7, 6, ROUND_REG
539     lea               dstq, [dstq+2*strideq]
540     UNSCRATCH            5, 10, blockq+16
541     UNSCRATCH            7, 11, blockq+32
542     VP9_IDCT8_WRITEx2    4,  5, 0, 1, 6, ROUND_REG
543     lea               dstq, [dstq+2*strideq]
544     UNSCRATCH            5, 8, blockq+ 0
545     VP9_IDCT8_WRITEx2    5,  7, 0, 1, 6, ROUND_REG
546
547 %undef ROUND_REG
548 %endmacro
549
550 %macro VP9_IDCT_IDCT_8x8_ADD_XMM 2
551 INIT_XMM %1
552 cglobal vp9_idct_idct_8x8_add, 4, 4, %2, dst, stride, block, eob
553
554 %if cpuflag(ssse3)
555 %if ARCH_X86_64
556     mova               m12, [pw_11585x2]    ; often used
557 %define W_11585x2_REG m12
558 %else
559 %define W_11585x2_REG [pw_11585x2]
560 %endif
561
562     cmp eobd, 12 ; top left half or less
563     jg .idctfull
564
565     cmp eobd, 3  ; top left corner or less
566     jg .idcthalf
567
568     cmp eobd, 1 ; faster path for when only DC is set
569     jne .idcttopleftcorner
570 %else
571     cmp eobd, 1
572     jg .idctfull
573 %endif
574
575 %if cpuflag(ssse3)
576     movd                m0, [blockq]
577     pmulhrsw            m0, W_11585x2_REG
578     pmulhrsw            m0, W_11585x2_REG
579 %else
580     DEFINE_ARGS dst, stride, block, coef
581     movsx            coefd, word [blockq]
582     imul             coefd, 11585
583     add              coefd, 8192
584     sar              coefd, 14
585     imul             coefd, 11585
586     add              coefd, (16 << 14) + 8192
587     sar              coefd, 14 + 5
588     movd                m0, coefd
589 %endif
590     SPLATW              m0, m0, 0
591     pxor                m4, m4
592     movd          [blockq], m4
593 %if cpuflag(ssse3)
594     pmulhrsw            m0, [pw_1024]       ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5
595 %endif
596 %rep 3
597     VP9_STORE_2X         0,  0,  6,  7,  4
598     lea               dstq, [dstq+2*strideq]
599 %endrep
600     VP9_STORE_2X         0,  0,  6,  7,  4
601     RET
602
603 %if cpuflag(ssse3)
604 ; faster path for when only left corner is set (3 input: DC, right to DC, below
605 ; to DC). Note: also working with a 2x2 block
606 .idcttopleftcorner:
607     movd                m0, [blockq+0]
608     movd                m1, [blockq+16]
609 %if ARCH_X86_64
610     mova               m10, [pw_3196x2]
611     mova               m11, [pw_16069x2]
612 %define W_3196x2_REG m10
613 %define W_16069x2_REG m11
614 %else
615 %define W_3196x2_REG [pw_3196x2]
616 %define W_16069x2_REG [pw_16069x2]
617 %endif
618     VP9_IDCT8_2x2_1D 1
619     ; partial 2x8 transpose
620     ; punpcklwd m0, m1 already done inside idct
621     punpcklwd           m2, m3
622     punpcklwd           m4, m5
623     punpcklwd           m6, m7
624     punpckldq           m0, m2
625     punpckldq           m4, m6
626     SBUTTERFLY         qdq, 0, 4, 1
627     SWAP                 1, 4
628     VP9_IDCT8_2x2_1D 2
629 %if ARCH_X86_64
630     SWAP                 6, 8
631 %endif
632     pxor                m6, m6  ; used for the block reset, and VP9_STORE_2X
633     VP9_IDCT8_WRITEOUT
634 %if ARCH_X86_64
635     movd       [blockq+ 0], m6
636     movd       [blockq+16], m6
637 %else
638     mova       [blockq+ 0], m6
639     mova       [blockq+16], m6
640     mova       [blockq+32], m6
641 %endif
642     RET
643
644 .idcthalf:
645     movh                m0, [blockq + 0]
646     movh                m1, [blockq +16]
647     movh                m2, [blockq +32]
648     movh                m3, [blockq +48]
649     VP9_IDCT8_4x4_1D
650     ; partial 4x8 transpose
651 %if ARCH_X86_32
652     mova                m6, [blockq+ 0]
653 %endif
654     punpcklwd           m0, m1
655     punpcklwd           m2, m3
656     punpcklwd           m4, m5
657     punpcklwd           m6, m7
658     SBUTTERFLY          dq, 0, 2, 1
659     SBUTTERFLY          dq, 4, 6, 5
660     SBUTTERFLY         qdq, 0, 4, 1
661     SBUTTERFLY         qdq, 2, 6, 5
662     SWAP                 1, 4
663     SWAP                 3, 6
664     VP9_IDCT8_4x4_1D
665 %if ARCH_X86_64
666     SWAP                 6, 8
667 %endif
668     pxor                m6, m6
669     VP9_IDCT8_WRITEOUT
670 %if ARCH_X86_64
671     movh       [blockq+ 0], m6
672     movh       [blockq+16], m6
673     movh       [blockq+32], m6
674 %else
675     mova       [blockq+ 0], m6
676     mova       [blockq+16], m6
677     mova       [blockq+32], m6
678 %endif
679     movh       [blockq+48], m6
680     RET
681 %endif
682
683 .idctfull: ; generic full 8x8 idct/idct
684 %if ARCH_X86_64
685     mova                m0, [blockq+  0]    ; IN(0)
686 %endif
687     mova                m1, [blockq+ 16]    ; IN(1)
688     mova                m2, [blockq+ 32]    ; IN(2)
689     mova                m3, [blockq+ 48]    ; IN(3)
690 %if ARCH_X86_64
691     mova                m4, [blockq+ 64]    ; IN(4)
692 %endif
693     mova                m5, [blockq+ 80]    ; IN(5)
694     mova                m6, [blockq+ 96]    ; IN(6)
695     mova                m7, [blockq+112]    ; IN(7)
696 %if ARCH_X86_64
697     mova               m11, [pd_8192]       ; rounding
698 %define D_8192_REG m11
699 %else
700 %define D_8192_REG [pd_8192]
701 %endif
702     VP9_IDCT8_1D
703 %if ARCH_X86_64
704     TRANSPOSE8x8W  0, 1, 2, 3, 4, 5, 6, 7, 8
705 %else
706     TRANSPOSE8x8W  0, 1, 2, 3, 4, 5, 6, 7, [blockq+0], [blockq+64], 1
707     mova        [blockq+0], m0
708 %endif
709     VP9_IDCT8_1D
710
711 %if ARCH_X86_64
712     SWAP                 6, 8
713 %endif
714     pxor                m6, m6  ; used for the block reset, and VP9_STORE_2X
715     VP9_IDCT8_WRITEOUT
716     ZERO_BLOCK      blockq, 16, 8, m6
717     RET
718 %undef W_11585x2_REG
719 %endmacro
720
721 VP9_IDCT_IDCT_8x8_ADD_XMM sse2, 12
722 VP9_IDCT_IDCT_8x8_ADD_XMM ssse3, 13
723 VP9_IDCT_IDCT_8x8_ADD_XMM avx, 13
724
725 ;---------------------------------------------------------------------------------------------
726 ; void vp9_iadst_iadst_8x8_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
727 ;---------------------------------------------------------------------------------------------
728
729 ; x86-32:
730 ; - in: m0/3/4/7 are in mem [blockq+N*16]
731 ; - out: m6 is in mem [blockq+0]
732 ; x86-64:
733 ; - everything is in registers
734 %macro VP9_IADST8_1D 0 ; input/output=m0/1/2/3/4/5/6/7
735 %if ARCH_X86_64
736     SWAP                     0, 8
737     SWAP                     3, 9
738     SWAP                     4, 10
739     SWAP                     7, 11
740 %endif
741
742     VP9_UNPACK_MULSUB_2D_4X  5,  2,  0,  3, 14449,  7723    ; m5/2=t3[d], m2/4=t2[d]
743     VP9_UNPACK_MULSUB_2D_4X  1,  6,  4,  7,  4756, 15679    ; m1/4=t7[d], m6/7=t6[d]
744     SCRATCH                  4, 12, blockq+1*16
745     VP9_RND_SH_SUMSUB_BA     6,  2,  7,  3, 4, D_8192_REG  ; m6=t2[w], m2=t6[w]
746     UNSCRATCH                4, 12, blockq+1*16
747     VP9_RND_SH_SUMSUB_BA     1,  5,  4,  0, 3, D_8192_REG  ; m1=t3[w], m5=t7[w]
748
749     UNSCRATCH                0,  8, blockq+16*0
750     UNSCRATCH                3,  9, blockq+16*3
751     UNSCRATCH                4, 10, blockq+16*4
752     UNSCRATCH                7, 11, blockq+16*7
753     SCRATCH                  1,  8, blockq+16*1
754     SCRATCH                  2,  9, blockq+16*2
755     SCRATCH                  5, 10, blockq+16*5
756     SCRATCH                  6, 11, blockq+16*6
757
758     VP9_UNPACK_MULSUB_2D_4X  7,  0,  1,  2, 16305,  1606    ; m7/1=t1[d], m0/2=t0[d]
759     VP9_UNPACK_MULSUB_2D_4X  3,  4,  5,  6, 10394, 12665    ; m3/5=t5[d], m4/6=t4[d]
760     SCRATCH                  1, 12, blockq+ 0*16
761     VP9_RND_SH_SUMSUB_BA     4,  0,  6,  2, 1, D_8192_REG  ; m4=t0[w], m0=t4[w]
762     UNSCRATCH                1, 12, blockq+ 0*16
763     VP9_RND_SH_SUMSUB_BA     3,  7,  5,  1, 2, D_8192_REG  ; m3=t1[w], m7=t5[w]
764
765     UNSCRATCH                2,  9, blockq+16*2
766     UNSCRATCH                5, 10, blockq+16*5
767     SCRATCH                  3,  9, blockq+16*3
768     SCRATCH                  4, 10, blockq+16*4
769
770     ; m4=t0, m3=t1, m6=t2, m1=t3, m0=t4, m7=t5, m2=t6, m5=t7
771
772     VP9_UNPACK_MULSUB_2D_4X  0,  7,  1,  3, 15137,  6270    ; m0/1=t5[d], m7/3=t4[d]
773     VP9_UNPACK_MULSUB_2D_4X  5,  2,  4,  6,  6270, 15137    ; m5/4=t6[d], m2/6=t7[d]
774     SCRATCH                  1, 12, blockq+ 0*16
775     VP9_RND_SH_SUMSUB_BA     5,  7,  4,  3, 1, D_8192_REG
776     UNSCRATCH                1, 12, blockq+ 0*16
777     PSIGNW                  m5, W_M1_REG                    ; m5=out1[w], m7=t6[w]
778     VP9_RND_SH_SUMSUB_BA     2,  0,  6,  1, 3, D_8192_REG   ; m2=out6[w], m0=t7[w]
779
780     UNSCRATCH                1,  8, blockq+16*1
781     UNSCRATCH                3,  9, blockq+16*3
782     UNSCRATCH                4, 10, blockq+16*4
783     UNSCRATCH                6, 11, blockq+16*6
784     SCRATCH                  2,  8, blockq+16*0
785
786     SUMSUB_BA                w,  6,  4, 2                   ; m6=out0[w], m4=t2[w]
787     SUMSUB_BA                w,  1,  3, 2
788     PSIGNW                  m1, W_M1_REG                    ; m1=out7[w], m3=t3[w]
789
790     ; m6=out0, m5=out1, m4=t2, m3=t3, m7=t6, m0=t7, m2=out6, m1=out7
791
792     ; unfortunately, the code below overflows in some cases
793 %if 0; cpuflag(ssse3)
794     SUMSUB_BA                w,  3,  4,  2
795     SUMSUB_BA                w,  0,  7,  2
796     pmulhrsw                m3, W_11585x2_REG
797     pmulhrsw                m7, W_11585x2_REG
798     pmulhrsw                m4, W_11585x2_REG               ; out4
799     pmulhrsw                m0, W_11585x2_REG               ; out2
800 %else
801     SCRATCH                  5,  9, blockq+16*1
802     VP9_UNPACK_MULSUB_2W_4X  4, 3, 11585, 11585, D_8192_REG, 2, 5
803     VP9_UNPACK_MULSUB_2W_4X  7, 0, 11585, 11585, D_8192_REG, 2, 5
804     UNSCRATCH                5,  9, blockq+16*1
805 %endif
806     PSIGNW                  m3, W_M1_REG                    ; out3
807     PSIGNW                  m7, W_M1_REG                    ; out5
808
809     ; m6=out0, m5=out1, m0=out2, m3=out3, m4=out4, m7=out5, m2=out6, m1=out7
810
811 %if ARCH_X86_64
812     SWAP                     2, 8
813 %endif
814     SWAP                     0, 6, 2
815     SWAP                     7, 1, 5
816 %endmacro
817
818 %macro IADST8_FN 6
819 INIT_XMM %5
820 cglobal vp9_%1_%3_8x8_add, 3, 3, %6, dst, stride, block, eob
821
822 %ifidn %1, idct
823 %define first_is_idct 1
824 %else
825 %define first_is_idct 0
826 %endif
827
828 %ifidn %3, idct
829 %define second_is_idct 1
830 %else
831 %define second_is_idct 0
832 %endif
833
834 %if ARCH_X86_64
835     mova                m0, [blockq+  0]    ; IN(0)
836 %endif
837     mova                m1, [blockq+ 16]    ; IN(1)
838     mova                m2, [blockq+ 32]    ; IN(2)
839 %if ARCH_X86_64 || first_is_idct
840     mova                m3, [blockq+ 48]    ; IN(3)
841 %endif
842 %if ARCH_X86_64
843     mova                m4, [blockq+ 64]    ; IN(4)
844 %endif
845     mova                m5, [blockq+ 80]    ; IN(5)
846     mova                m6, [blockq+ 96]    ; IN(6)
847 %if ARCH_X86_64 || first_is_idct
848     mova                m7, [blockq+112]    ; IN(7)
849 %endif
850 %if ARCH_X86_64
851 %if cpuflag(ssse3)
852     mova               m15, [pw_11585x2]    ; often used
853 %endif
854     mova               m13, [pd_8192]       ; rounding
855     mova               m14, [pw_m1]
856 %define W_11585x2_REG m15
857 %define D_8192_REG m13
858 %define W_M1_REG m14
859 %else
860 %define W_11585x2_REG [pw_11585x2]
861 %define D_8192_REG [pd_8192]
862 %define W_M1_REG [pw_m1]
863 %endif
864
865     ; note different calling conventions for idct8 vs. iadst8 on x86-32
866     VP9_%2_1D
867 %if ARCH_X86_64
868     TRANSPOSE8x8W  0, 1, 2, 3, 4, 5, 6, 7, 8
869 %else
870     TRANSPOSE8x8W  0, 1, 2, 3, 4, 5, 6, 7, [blockq+0], [blockq+64], 1
871     mova      [blockq+  0], m0
872 %if second_is_idct == 0
873     mova      [blockq+ 48], m3
874     mova      [blockq+112], m7
875 %endif
876 %endif
877     VP9_%4_1D
878
879 %if ARCH_X86_64
880     SWAP                 6, 8
881 %endif
882     pxor                m6, m6  ; used for the block reset, and VP9_STORE_2X
883     VP9_IDCT8_WRITEOUT
884     ZERO_BLOCK      blockq, 16, 8, m6
885     RET
886
887 %undef W_11585x2_REG
888 %undef first_is_idct
889 %undef second_is_idct
890
891 %endmacro
892
893 IADST8_FN idct,  IDCT8,  iadst, IADST8, sse2, 15
894 IADST8_FN iadst, IADST8, idct,  IDCT8,  sse2, 15
895 IADST8_FN iadst, IADST8, iadst, IADST8, sse2, 15
896 IADST8_FN idct,  IDCT8,  iadst, IADST8, ssse3, 16
897 IADST8_FN idct,  IDCT8,  iadst, IADST8, avx, 16
898 IADST8_FN iadst, IADST8, idct,  IDCT8,  ssse3, 16
899 IADST8_FN iadst, IADST8, idct,  IDCT8,  avx, 16
900 IADST8_FN iadst, IADST8, iadst, IADST8, ssse3, 16
901 IADST8_FN iadst, IADST8, iadst, IADST8, avx, 16
902
903 ;---------------------------------------------------------------------------------------------
904 ; void vp9_idct_idct_16x16_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
905 ;---------------------------------------------------------------------------------------------
906
907 ; x86-64:
908 ; at the end of this macro, m7 is stored in [%4+15*%5]
909 ; everything else (t0-6 and t8-15) is stored in m0-6 and m8-15
910 ; the following sumsubs have not been done yet:
911 ;    SUMSUB_BA            w,  6,  9, 15      ; t6, t9
912 ;    SUMSUB_BA            w,  7,  8, 15      ; t7, t8
913 ; or (x86-32) t0-t5 are in m0-m5, t10-t15 are in x11/9/7/5/3/1,
914 ; and the following simsubs have not been done yet:
915 ;    SUMSUB_BA            w, x13, x14, 7       ; t6, t9
916 ;    SUMSUB_BA            w, x15, x12, 7       ; t7, t8
917
918 %macro VP9_IDCT16_1D_START 6 ; src, nnzc, stride, scratch, scratch_stride, is_iadst
919 %if %2 <= 4
920     mova                m3, [%1+ 1*%3]      ; IN(1)
921     mova                m0, [%1+ 3*%3]      ; IN(3)
922
923     pmulhrsw            m4, m3,  [pw_16305x2]       ; t14-15
924     pmulhrsw            m3, [pw_1606x2]             ; t8-9
925     pmulhrsw            m7, m0,  [pw_m4756x2]       ; t10-11
926     pmulhrsw            m0, [pw_15679x2]            ; t12-13
927
928     ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m14=t5, m13=t6, m15=t7
929     ; m3=t8, m5=t9, m1=t10, m7=t11, m0=t12, m6=t13, m2=t14, m4=t15
930
931     VP9_UNPACK_MULSUB_2W_4X 2, 5, 4, 3, 15137,  6270, [pd_8192], 1, 6 ; t9,  t14
932     SCRATCH              4, 10, %4+ 1*%5
933     SCRATCH              5, 11, %4+ 7*%5
934     VP9_UNPACK_MULSUB_2W_4X 6, 1, 0, 7, 6270, m15137, [pd_8192], 4, 5 ; t10, t13
935     UNSCRATCH            5, 11, %4+ 7*%5
936
937     ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7
938     ; m7=t8, m6=t9, m2=t10, m3=t11, m4=t12, m5=t13, m1=t14, m0=t15
939 %else
940     mova                m5, [%1+ 1*%3]      ; IN(1)
941     mova                m4, [%1+ 7*%3]      ; IN(7)
942 %if %2 <= 8
943     pmulhrsw            m2, m5,  [pw_16305x2]       ; t15
944     pmulhrsw            m5, [pw_1606x2]             ; t8
945     pmulhrsw            m3, m4,  [pw_m10394x2]      ; t9
946     pmulhrsw            m4, [pw_12665x2]            ; t14
947 %else
948     mova                m3, [%1+ 9*%3]      ; IN(9)
949     mova                m2, [%1+15*%3]      ; IN(15)
950
951     ; m10=in0, m5=in1, m14=in2, m6=in3, m9=in4, m7=in5, m15=in6, m4=in7
952     ; m11=in8, m3=in9, m12=in10 m0=in11, m8=in12, m1=in13, m13=in14, m2=in15
953
954     VP9_UNPACK_MULSUB_2W_4X   5,   2, 16305,  1606, [pd_8192], 0, 1 ; t8,  t15
955     VP9_UNPACK_MULSUB_2W_4X   3,   4, 10394, 12665, [pd_8192], 0, 1 ; t9,  t14
956 %endif
957
958     SUMSUB_BA            w,  3,  5, 0       ; t8,  t9
959     SUMSUB_BA            w,  4,  2, 0       ; t15, t14
960
961     VP9_UNPACK_MULSUB_2W_4X   2,   5, 15137,  6270, [pd_8192], 0, 1 ; t9,  t14
962
963     SCRATCH              4, 10, %4+ 1*%5
964     SCRATCH              5, 11, %4+ 7*%5
965
966     mova                m6, [%1+ 3*%3]      ; IN(3)
967     mova                m7, [%1+ 5*%3]      ; IN(5)
968 %if %2 <= 8
969     pmulhrsw            m0, m7,  [pw_14449x2]       ; t13
970     pmulhrsw            m7, [pw_7723x2]             ; t10
971     pmulhrsw            m1, m6,  [pw_m4756x2]       ; t11
972     pmulhrsw            m6, [pw_15679x2]            ; t12
973 %else
974     mova                m0, [%1+11*%3]      ; IN(11)
975     mova                m1, [%1+13*%3]      ; IN(13)
976
977     VP9_UNPACK_MULSUB_2W_4X   7,   0, 14449,  7723, [pd_8192], 4, 5 ; t10, t13
978     VP9_UNPACK_MULSUB_2W_4X   1,   6,  4756, 15679, [pd_8192], 4, 5 ; t11, t12
979 %endif
980
981     ; m11=t0, m10=t1, m9=t2, m8=t3, m14=t4, m12=t5, m15=t6, m13=t7
982     ; m5=t8, m3=t9, m7=t10, m1=t11, m6=t12, m0=t13, m4=t14, m2=t15
983
984     SUMSUB_BA            w,  7,  1, 4       ; t11, t10
985     SUMSUB_BA            w,  0,  6, 4       ; t12, t13
986
987     ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m14=t5, m13=t6, m15=t7
988     ; m3=t8, m5=t9, m1=t10, m7=t11, m0=t12, m6=t13, m2=t14, m4=t15
989
990     VP9_UNPACK_MULSUB_2W_4X   6,   1, 6270, m15137, [pd_8192], 4, 5 ; t10, t13
991
992     UNSCRATCH            5, 11, %4+ 7*%5
993 %endif
994
995     ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m13=t5, m14=t6, m15=t7
996     ; m3=t8, m2=t9, m6=t10, m7=t11, m0=t12, m1=t13, m5=t14, m4=t15
997
998     SUMSUB_BA            w,  7,  3, 4       ; t8,  t11
999
1000     ; backup first register
1001     mova        [%4+15*%5], m7
1002
1003     SUMSUB_BA            w,  6,  2, 7       ; t9,  t10
1004     UNSCRATCH            4, 10, %4+ 1*%5
1005     SUMSUB_BA            w,  0,  4, 7       ; t15, t12
1006     SUMSUB_BA            w,  1,  5, 7       ; t14. t13
1007
1008     ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7
1009     ; m7=t8, m6=t9, m2=t10, m3=t11, m4=t12, m5=t13, m1=t14, m0=t15
1010
1011 %if cpuflag(ssse3) && %6 == 0
1012     SUMSUB_BA            w,  2,  5, 7
1013     SUMSUB_BA            w,  3,  4, 7
1014     pmulhrsw            m5, [pw_11585x2]    ; t10
1015     pmulhrsw            m4, [pw_11585x2]    ; t11
1016     pmulhrsw            m3, [pw_11585x2]    ; t12
1017     pmulhrsw            m2, [pw_11585x2]    ; t13
1018 %else
1019     SCRATCH              6, 10, %4+ 1*%5
1020     VP9_UNPACK_MULSUB_2W_4X   5,   2, 11585, 11585, [pd_8192], 6, 7 ; t10, t13
1021     VP9_UNPACK_MULSUB_2W_4X   4,   3, 11585, 11585, [pd_8192], 6, 7 ; t11, t12
1022     UNSCRATCH            6, 10, %4+ 1*%5
1023 %endif
1024
1025     ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7
1026     ; m7=t8, m6=t9, m5=t10, m4=t11, m3=t12, m2=t13, m1=t14, m0=t15
1027
1028     SCRATCH              0,  8, %4+ 1*%5
1029     SCRATCH              1,  9, %4+ 3*%5
1030     SCRATCH              2, 10, %4+ 5*%5
1031     SCRATCH              3, 11, %4+ 7*%5
1032     SCRATCH              4, 12, %4+ 9*%5
1033     SCRATCH              5, 13, %4+11*%5
1034     SCRATCH              6, 14, %4+13*%5
1035
1036     ; even (tx8x8)
1037 %if %2 <= 4
1038     mova                m3, [%1+ 0*%3]      ; IN(0)
1039     mova                m4, [%1+ 2*%3]      ; IN(2)
1040
1041     pmulhrsw            m3, [pw_11585x2]    ; t0-t3
1042     pmulhrsw            m7, m4, [pw_16069x2]        ; t6-7
1043     pmulhrsw            m4, [pw_3196x2]             ; t4-5
1044
1045 %if 0 ; overflows :(
1046     paddw               m6, m7, m4
1047     psubw               m5, m7, m4
1048     pmulhrsw            m5, [pw_11585x2]            ; t5
1049     pmulhrsw            m6, [pw_11585x2]            ; t6
1050 %else
1051     VP9_UNPACK_MULSUB_2W_4X  5, 6, 7, 4, 11585, 11585, [pd_8192], 0, 1 ; t5,  t6
1052 %endif
1053
1054     psubw               m0, m3, m7
1055     paddw               m7, m3
1056     psubw               m1, m3, m6
1057     paddw               m6, m3
1058     psubw               m2, m3, m5
1059     paddw               m5, m3
1060
1061 %if ARCH_X86_32
1062     SWAP                 0, 7
1063 %endif
1064     SCRATCH              7, 15, %4+12*%5
1065 %else
1066     mova                m6, [%1+ 2*%3]      ; IN(2)
1067     mova                m1, [%1+ 4*%3]      ; IN(4)
1068     mova                m7, [%1+ 6*%3]      ; IN(6)
1069 %if %2 <= 8
1070     pmulhrsw            m0, m1,  [pw_15137x2]       ; t3
1071     pmulhrsw            m1, [pw_6270x2]             ; t2
1072     pmulhrsw            m5, m6, [pw_16069x2]        ; t7
1073     pmulhrsw            m6, [pw_3196x2]             ; t4
1074     pmulhrsw            m4, m7, [pw_m9102x2]        ; t5
1075     pmulhrsw            m7, [pw_13623x2]            ; t6
1076 %else
1077     mova                m4, [%1+10*%3]      ; IN(10)
1078     mova                m0, [%1+12*%3]      ; IN(12)
1079     mova                m5, [%1+14*%3]      ; IN(14)
1080
1081     VP9_UNPACK_MULSUB_2W_4X   1,   0, 15137,  6270, [pd_8192], 2, 3 ; t2,  t3
1082     VP9_UNPACK_MULSUB_2W_4X   6,   5, 16069,  3196, [pd_8192], 2, 3 ; t4,  t7
1083     VP9_UNPACK_MULSUB_2W_4X   4,   7,  9102, 13623, [pd_8192], 2, 3 ; t5,  t6
1084 %endif
1085
1086     SUMSUB_BA            w,  4,  6, 2       ; t4,  t5
1087     SUMSUB_BA            w,  7,  5, 2       ; t7,  t6
1088
1089 %if cpuflag(ssse3) && %6 == 0
1090     SUMSUB_BA            w,  6,  5, 2
1091     pmulhrsw            m5, [pw_11585x2]                              ; t5
1092     pmulhrsw            m6, [pw_11585x2]                              ; t6
1093 %else
1094     VP9_UNPACK_MULSUB_2W_4X  5,  6, 11585, 11585, [pd_8192], 2, 3 ; t5,  t6
1095 %endif
1096
1097     SCRATCH              5, 15, %4+10*%5
1098     mova                m2, [%1+ 0*%3]      ; IN(0)
1099 %if %2 <= 8
1100     pmulhrsw            m2, [pw_11585x2]    ; t0 and t1
1101     psubw               m3, m2, m0
1102     paddw               m0, m2
1103
1104     SUMSUB_BA            w,  7,  0, 5       ; t0,  t7
1105 %else
1106     mova                m3, [%1+ 8*%3]      ; IN(8)
1107
1108     ; from 3 stages back
1109 %if cpuflag(ssse3) && %6 == 0
1110     SUMSUB_BA            w,  3,  2, 5
1111     pmulhrsw            m3, [pw_11585x2]    ; t0
1112     pmulhrsw            m2, [pw_11585x2]    ; t1
1113 %else
1114     mova        [%1+ 0*%3], m0
1115     VP9_UNPACK_MULSUB_2W_4X  2,  3, 11585,  11585, [pd_8192], 5, 0 ; t0, t1
1116     mova                m0, [%1+ 0*%3]
1117 %endif
1118
1119     ; from 2 stages back
1120     SUMSUB_BA            w,  0,  3, 5      ; t0,  t3
1121
1122     SUMSUB_BA            w,  7,  0, 5      ; t0,  t7
1123 %endif
1124     UNSCRATCH            5, 15, %4+10*%5
1125 %if ARCH_X86_32
1126     SWAP                 0, 7
1127 %endif
1128     SCRATCH              7, 15, %4+12*%5
1129     SUMSUB_BA            w,  1,  2, 7       ; t1,  t2
1130
1131     ; from 1 stage back
1132     SUMSUB_BA            w,  6,  1, 7       ; t1,  t6
1133     SUMSUB_BA            w,  5,  2, 7       ; t2,  t5
1134 %endif
1135     SUMSUB_BA            w,  4,  3, 7       ; t3,  t4
1136
1137 %if ARCH_X86_64
1138     SWAP                 0, 8
1139     SWAP                 1, 9
1140     SWAP                 2, 10
1141     SWAP                 3, 11
1142     SWAP                 4, 12
1143     SWAP                 5, 13
1144     SWAP                 6, 14
1145
1146     SUMSUB_BA            w,  0, 15, 7       ; t0, t15
1147     SUMSUB_BA            w,  1, 14, 7       ; t1, t14
1148     SUMSUB_BA            w,  2, 13, 7       ; t2, t13
1149     SUMSUB_BA            w,  3, 12, 7       ; t3, t12
1150     SUMSUB_BA            w,  4, 11, 7       ; t4, t11
1151     SUMSUB_BA            w,  5, 10, 7       ; t5, t10
1152 %else
1153     SWAP                 1, 6
1154     SWAP                 2, 5
1155     SWAP                 3, 4
1156     mova        [%4+14*%5], m6
1157
1158 %macro %%SUMSUB_BA_STORE 5 ; reg, from_mem, to_mem, scratch, scratch_stride
1159     mova                m6, [%4+%2*%5]
1160     SUMSUB_BA            w,  6, %1, 7
1161     SWAP                %1, 6
1162     mova        [%4+%3*%5], m6
1163 %endmacro
1164
1165     %%SUMSUB_BA_STORE    0,  1,  1, %4, %5  ; t0, t15
1166     %%SUMSUB_BA_STORE    1,  3,  3, %4, %5  ; t1, t14
1167     %%SUMSUB_BA_STORE    2,  5,  5, %4, %5  ; t2, t13
1168     %%SUMSUB_BA_STORE    3,  7,  7, %4, %5  ; t3, t12
1169     %%SUMSUB_BA_STORE    4,  9,  9, %4, %5  ; t4, t11
1170     %%SUMSUB_BA_STORE    5, 11, 11, %4, %5  ; t5, t10
1171 %endif
1172 %endmacro
1173
1174 %macro VP9_IDCT16_1D 2-4 16, 1 ; src, pass, nnzc, is_iadst
1175 %if %2 == 1
1176     VP9_IDCT16_1D_START %1, %3, 32, tmpq, 16, %4
1177
1178 %if ARCH_X86_64
1179     ; backup a different register
1180     mova                m7, [tmpq+15*16]
1181     mova      [tmpq+ 1*16], m15
1182
1183     SUMSUB_BA            w,  6,  9, 15      ; t6, t9
1184     SUMSUB_BA            w,  7,  8, 15      ; t7, t8
1185
1186     TRANSPOSE8x8W        0, 1, 2, 3, 4, 5, 6, 7, 15
1187     mova        [tmpq+  0], m0
1188     mova        [tmpq+ 32], m1
1189     mova        [tmpq+ 64], m2
1190     mova        [tmpq+ 96], m3
1191     mova        [tmpq+128], m4
1192     mova        [tmpq+160], m5
1193     mova        [tmpq+192], m6
1194     mova        [tmpq+224], m7
1195
1196     mova               m15, [tmpq+ 1*16]
1197     TRANSPOSE8x8W        8, 9, 10, 11, 12, 13, 14, 15, 0
1198     mova        [tmpq+ 16], m8
1199     mova        [tmpq+ 48], m9
1200     mova        [tmpq+ 80], m10
1201     mova        [tmpq+112], m11
1202     mova        [tmpq+144], m12
1203     mova        [tmpq+176], m13
1204     mova        [tmpq+208], m14
1205     mova        [tmpq+240], m15
1206 %else
1207     mova                m6, [tmpq+13*16]
1208     mova                m7, [tmpq+14*16]
1209     SUMSUB_BA            w, 6, 7                ; t6, t9
1210     mova      [tmpq+14*16], m6
1211     mova      [tmpq+13*16], m7
1212     mova                m7, [tmpq+15*16]
1213     mova                m6, [tmpq+12*16]
1214     SUMSUB_BA            w, 7, 6                ; t7, t8
1215     mova      [tmpq+15*16], m6
1216
1217     TRANSPOSE8x8W       0, 1, 2, 3, 4, 5, 6, 7, [tmpq+14*16], [tmpq+ 8*16], 1
1218     mova     [tmpq+ 0*16], m0
1219     mova     [tmpq+ 2*16], m1
1220     mova     [tmpq+ 4*16], m2
1221     mova     [tmpq+ 6*16], m3
1222     mova     [tmpq+10*16], m5
1223     mova     [tmpq+12*16], m6
1224     mova     [tmpq+14*16], m7
1225
1226     mova                m0, [tmpq+15*16]
1227     mova                m1, [tmpq+13*16]
1228     mova                m2, [tmpq+11*16]
1229     mova                m3, [tmpq+ 9*16]
1230     mova                m4, [tmpq+ 7*16]
1231     mova                m5, [tmpq+ 5*16]
1232     mova                m7, [tmpq+ 1*16]
1233     TRANSPOSE8x8W       0, 1, 2, 3, 4, 5, 6, 7, [tmpq+ 3*16], [tmpq+ 9*16], 1
1234     mova     [tmpq+ 1*16], m0
1235     mova     [tmpq+ 3*16], m1
1236     mova     [tmpq+ 5*16], m2
1237     mova     [tmpq+ 7*16], m3
1238     mova     [tmpq+11*16], m5
1239     mova     [tmpq+13*16], m6
1240     mova     [tmpq+15*16], m7
1241 %endif
1242 %else ; %2 == 2
1243     VP9_IDCT16_1D_START %1, %3, 32, %1, 32, %4
1244
1245 %if cpuflag(ssse3)
1246 %define ROUND_REG [pw_512]
1247 %else
1248 %define ROUND_REG [pw_32]
1249 %endif
1250
1251     pxor                m7, m7
1252 %if ARCH_X86_64
1253     ; backup more registers
1254     mova        [%1+ 2*32], m8
1255     mova        [%1+ 3*32], m9
1256
1257     VP9_IDCT8_WRITEx2    0,  1, 8, 9, 7, ROUND_REG, 6
1258     lea               dstq, [dstq+strideq*2]
1259     VP9_IDCT8_WRITEx2    2,  3, 8, 9, 7, ROUND_REG, 6
1260     lea               dstq, [dstq+strideq*2]
1261     VP9_IDCT8_WRITEx2    4,  5, 8, 9, 7, ROUND_REG, 6
1262     lea               dstq, [dstq+strideq*2]
1263
1264     ; restore from cache
1265     SWAP                 0, 7               ; move zero from m7 to m0
1266     mova                m7, [%1+15*32]
1267     mova                m8, [%1+ 2*32]
1268     mova                m9, [%1+ 3*32]
1269
1270     SUMSUB_BA            w,  6,  9, 3       ; t6, t9
1271     SUMSUB_BA            w,  7,  8, 3       ; t7, t8
1272
1273     VP9_IDCT8_WRITEx2    6,  7, 3, 4, 0, ROUND_REG, 6
1274     lea               dstq, [dstq+strideq*2]
1275     VP9_IDCT8_WRITEx2    8,  9, 3, 4, 0, ROUND_REG, 6
1276     lea               dstq, [dstq+strideq*2]
1277     VP9_IDCT8_WRITEx2   10, 11, 1, 2, 0, ROUND_REG, 6
1278     lea               dstq, [dstq+strideq*2]
1279     VP9_IDCT8_WRITEx2   12, 13, 1, 2, 0, ROUND_REG, 6
1280     lea               dstq, [dstq+strideq*2]
1281     VP9_IDCT8_WRITEx2   14, 15, 1, 2, 0, ROUND_REG, 6
1282 %else
1283     mova      [tmpq+ 0*32], m5
1284
1285     VP9_IDCT8_WRITEx2    0,  1, 5, 6, 7, ROUND_REG, 6
1286     lea               dstq, [dstq+strideq*2]
1287     VP9_IDCT8_WRITEx2    2,  3, 5, 6, 7, ROUND_REG, 6
1288     lea               dstq, [dstq+strideq*2]
1289
1290     SWAP                 0, 7               ; move zero from m7 to m0
1291     mova                m5, [tmpq+ 0*32]
1292
1293     VP9_IDCT8_WRITEx2    4,  5, 1, 2, 0, ROUND_REG, 6
1294     lea               dstq, [dstq+strideq*2]
1295
1296     mova                m4, [tmpq+13*32]
1297     mova                m7, [tmpq+14*32]
1298     mova                m5, [tmpq+15*32]
1299     mova                m6, [tmpq+12*32]
1300     SUMSUB_BADC w, 4, 7, 5, 6, 1
1301
1302     VP9_IDCT8_WRITEx2    4,  5, 1, 2, 0, ROUND_REG, 6
1303     lea               dstq, [dstq+strideq*2]
1304     VP9_IDCT8_WRITEx2    6,  7, 1, 2, 0, ROUND_REG, 6
1305     lea               dstq, [dstq+strideq*2]
1306
1307     mova                m4, [tmpq+11*32]
1308     mova                m5, [tmpq+ 9*32]
1309     mova                m6, [tmpq+ 7*32]
1310     mova                m7, [tmpq+ 5*32]
1311
1312     VP9_IDCT8_WRITEx2    4,  5, 1, 2, 0, ROUND_REG, 6
1313     lea               dstq, [dstq+strideq*2]
1314     VP9_IDCT8_WRITEx2    6,  7, 1, 2, 0, ROUND_REG, 6
1315     lea               dstq, [dstq+strideq*2]
1316
1317     mova                m4, [tmpq+ 3*32]
1318     mova                m5, [tmpq+ 1*32]
1319
1320     VP9_IDCT8_WRITEx2    4,  5, 1, 2, 0, ROUND_REG, 6
1321     lea               dstq, [dstq+strideq*2]
1322 %endif
1323
1324 %undef ROUND_REG
1325 %endif ; %2 == 1/2
1326 %endmacro
1327
1328 %macro VP9_STORE_2XFULL 6-7 strideq; dc, tmp1, tmp2, tmp3, tmp4, zero, stride
1329     mova               m%3, [dstq]
1330     mova               m%5, [dstq+%7]
1331     punpcklbw          m%2, m%3, m%6
1332     punpckhbw          m%3, m%6
1333     punpcklbw          m%4, m%5, m%6
1334     punpckhbw          m%5, m%6
1335     paddw              m%2, m%1
1336     paddw              m%3, m%1
1337     paddw              m%4, m%1
1338     paddw              m%5, m%1
1339     packuswb           m%2, m%3
1340     packuswb           m%4, m%5
1341     mova            [dstq], m%2
1342     mova         [dstq+%7], m%4
1343 %endmacro
1344
1345 %macro VP9_IDCT_IDCT_16x16_ADD_XMM 1
1346 INIT_XMM %1
1347 cglobal vp9_idct_idct_16x16_add, 4, 6, 16, 512, dst, stride, block, eob
1348 %if cpuflag(ssse3)
1349     ; 2x2=eob=3, 4x4=eob=10
1350     cmp eobd, 38
1351     jg .idctfull
1352     cmp eobd, 1 ; faster path for when only DC is set
1353     jne .idct8x8
1354 %else
1355     cmp eobd, 1 ; faster path for when only DC is set
1356     jg .idctfull
1357 %endif
1358
1359     ; dc-only
1360 %if cpuflag(ssse3)
1361     movd                m0, [blockq]
1362     mova                m1, [pw_11585x2]
1363     pmulhrsw            m0, m1
1364     pmulhrsw            m0, m1
1365 %else
1366     DEFINE_ARGS dst, stride, block, coef
1367     movsx            coefd, word [blockq]
1368     imul             coefd, 11585
1369     add              coefd, 8192
1370     sar              coefd, 14
1371     imul             coefd, 11585
1372     add              coefd, (32 << 14) + 8192
1373     sar              coefd, 14 + 6
1374     movd                m0, coefd
1375 %endif
1376     SPLATW              m0, m0, q0000
1377 %if cpuflag(ssse3)
1378     pmulhrsw            m0, [pw_512]
1379 %endif
1380     pxor                m5, m5
1381     movd          [blockq], m5
1382 %rep 7
1383     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5
1384     lea               dstq, [dstq+2*strideq]
1385 %endrep
1386     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5
1387     RET
1388
1389     DEFINE_ARGS dst, stride, block, cnt, dst_bak, tmp
1390 %if cpuflag(ssse3)
1391 .idct8x8:
1392     mov               tmpq, rsp
1393     VP9_IDCT16_1D   blockq, 1, 8, 0
1394
1395     mov               cntd, 2
1396     mov           dst_bakq, dstq
1397 .loop2_8x8:
1398     VP9_IDCT16_1D     tmpq, 2, 8, 0
1399     lea               dstq, [dst_bakq+8]
1400     add               tmpq, 16
1401     dec               cntd
1402     jg .loop2_8x8
1403
1404     ; at the end of the loop, m0 should still be zero
1405     ; use that to zero out block coefficients
1406     ZERO_BLOCK      blockq, 32, 8, m0
1407     RET
1408 %endif
1409
1410 .idctfull:
1411     mov               cntd, 2
1412     mov               tmpq, rsp
1413 .loop1_full:
1414     VP9_IDCT16_1D   blockq, 1, 16, 0
1415     add             blockq, 16
1416     add               tmpq, 256
1417     dec               cntd
1418     jg .loop1_full
1419     sub             blockq, 32
1420
1421     mov               cntd, 2
1422     mov               tmpq, rsp
1423     mov           dst_bakq, dstq
1424 .loop2_full:
1425     VP9_IDCT16_1D     tmpq, 2, 16, 0
1426     lea               dstq, [dst_bakq+8]
1427     add               tmpq, 16
1428     dec               cntd
1429     jg .loop2_full
1430
1431     ; at the end of the loop, m0 should still be zero
1432     ; use that to zero out block coefficients
1433     ZERO_BLOCK      blockq, 32, 16, m0
1434     RET
1435 %endmacro
1436
1437 VP9_IDCT_IDCT_16x16_ADD_XMM sse2
1438 VP9_IDCT_IDCT_16x16_ADD_XMM ssse3
1439 VP9_IDCT_IDCT_16x16_ADD_XMM avx
1440
1441 %macro VP9_IDCT16_YMM_1D 0
1442     VP9_UNPACK_MULSUB_2W_4X  1,  15, 16305,  1606, [pd_8192], 0, 4 ; t8,  t15
1443     VP9_UNPACK_MULSUB_2W_4X  9,   7, 10394, 12665, [pd_8192], 0, 4 ; t9,  t14
1444
1445     SUMSUB_BA            w,  9,   1, 0      ; t8,  t9
1446     SUMSUB_BA            w,  7,  15, 0      ; t15, t14
1447
1448     VP9_UNPACK_MULSUB_2W_4X 15,   1, 15137,  6270, [pd_8192], 0, 4 ; t9,  t14
1449
1450     VP9_UNPACK_MULSUB_2W_4X  5,  11, 14449,  7723, [pd_8192], 0, 4 ; t10, t13
1451     VP9_UNPACK_MULSUB_2W_4X 13,   3,  4756, 15679, [pd_8192], 0, 4 ; t11, t12
1452
1453     SUMSUB_BA            w,  5,  13, 0      ; t11, t10
1454     SUMSUB_BA            w, 11,   3, 0      ; t12, t13
1455
1456     VP9_UNPACK_MULSUB_2W_4X  3,  13, 6270, m15137, [pd_8192], 0, 4 ; t10, t13
1457
1458     SUMSUB_BA            w,  5,   9, 0      ; t8,  t11
1459     SUMSUB_BA            w,  3,  15, 0      ; t9,  t10
1460     SUMSUB_BA            w, 11,   7, 0      ; t15, t12
1461     SUMSUB_BA            w, 13,   1, 0      ; t14, t13
1462
1463     SUMSUB_BA            w, 15,   1, 0
1464     SUMSUB_BA            w,  9,   7, 0
1465     pmulhrsw            m1, [pw_11585x2]    ; t10
1466     pmulhrsw            m7, [pw_11585x2]    ; t11
1467     pmulhrsw            m9, [pw_11585x2]    ; t12
1468     pmulhrsw           m15, [pw_11585x2]    ; t13
1469
1470     ; even (tx8x8)
1471     mova                m4, [blockq+128]
1472     mova      [blockq+128], m5
1473     VP9_UNPACK_MULSUB_2W_4X   4,  12, 15137,  6270, [pd_8192], 0, 5 ; t2,  t3
1474     VP9_UNPACK_MULSUB_2W_4X   2,  14, 16069,  3196, [pd_8192], 0, 5 ; t4,  t7
1475     VP9_UNPACK_MULSUB_2W_4X  10,   6,  9102, 13623, [pd_8192], 0, 5 ; t5,  t6
1476     mova                m0, [blockq+  0]
1477     SUMSUB_BA            w,   8,   0, 5
1478     pmulhrsw            m8, [pw_11585x2]    ; t0
1479     pmulhrsw            m0, [pw_11585x2]    ; t1
1480
1481     SUMSUB_BA            w,  10,   2, 5     ; t4,  t5
1482     SUMSUB_BA            w,   6,  14, 5     ; t7,  t6
1483     SUMSUB_BA            w,  12,   8, 5     ; t0,  t3
1484     SUMSUB_BA            w,   4,   0, 5     ; t1,  t2
1485
1486     SUMSUB_BA            w,   2,  14, 5
1487     pmulhrsw           m14, [pw_11585x2]    ; t5
1488     pmulhrsw            m2, [pw_11585x2]    ; t6
1489
1490     SUMSUB_BA            w,   6,  12, 5     ; t0,  t7
1491     SUMSUB_BA            w,   2,   4, 5     ; t1,  t6
1492     SUMSUB_BA            w,  14,   0, 5     ; t2,  t5
1493     SUMSUB_BA            w,  10,   8, 5     ; t3,  t4
1494
1495     ; final stage
1496     SUMSUB_BA            w, 11,  6,  5      ; out0, out15
1497     SUMSUB_BA            w, 13,  2,  5      ; out1, out14
1498     SUMSUB_BA            w, 15, 14,  5      ; out2, out13
1499     SUMSUB_BA            w,  9, 10,  5      ; out3, out12
1500     SUMSUB_BA            w,  7,  8,  5      ; out4, out11
1501     SUMSUB_BA            w,  1,  0,  5      ; out5, out10
1502     SUMSUB_BA            w,  3,  4,  5      ; out6, out9
1503     mova                m5, [blockq+128]
1504     mova      [blockq+192], m3
1505     SUMSUB_BA            w,  5, 12,  3      ; out7, out8
1506
1507     SWAP  0, 11,  8, 12, 10
1508     SWAP  1, 13, 14,  2, 15,  6,  3,  9,  4,  7,  5
1509 %endmacro
1510
1511 ; this is almost identical to VP9_STORE_2X, but it does two rows
1512 ; for slightly improved interleaving, and it omits vpermq since the
1513 ; input is DC so all values are identical
1514 %macro VP9_STORE_YMM_DC_4X 6 ; reg, tmp1, tmp2, tmp3, tmp4, zero
1515     mova              xm%2, [dstq]
1516     mova              xm%4, [dstq+strideq*2]
1517     vinserti128        m%2, m%2, [dstq+strideq], 1
1518     vinserti128        m%4, m%4, [dstq+stride3q], 1
1519     punpckhbw          m%3, m%2, m%6
1520     punpcklbw          m%2, m%6
1521     punpckhbw          m%5, m%4, m%6
1522     punpcklbw          m%4, m%6
1523     paddw              m%3, m%1
1524     paddw              m%2, m%1
1525     paddw              m%5, m%1
1526     paddw              m%4, m%1
1527     packuswb           m%2, m%3
1528     packuswb           m%4, m%5
1529     mova            [dstq], xm%2
1530     mova        [dstq+strideq*2], xm%4
1531     vextracti128  [dstq+strideq], m%2, 1
1532     vextracti128 [dstq+stride3q], m%4, 1
1533 %endmacro
1534
1535 %if ARCH_X86_64 && HAVE_AVX2_EXTERNAL
1536 INIT_YMM avx2
1537 cglobal vp9_idct_idct_16x16_add, 4, 4, 16, dst, stride, block, eob
1538     cmp eobd, 1 ; faster path for when only DC is set
1539     jg .idctfull
1540
1541     ; dc-only
1542     mova                m1, [pw_11585x2]
1543     vpbroadcastw        m0, [blockq]
1544     pmulhrsw            m0, m1
1545     pmulhrsw            m0, m1
1546     pxor                m5, m5
1547     pmulhrsw            m0, [pw_512]
1548     movd          [blockq], xm5
1549
1550     DEFINE_ARGS dst, stride, stride3, cnt
1551     mov               cntd, 4
1552     lea           stride3q, [strideq*3]
1553 .loop_dc:
1554     VP9_STORE_YMM_DC_4X  0, 1, 2, 3, 4, 5
1555     lea               dstq, [dstq+4*strideq]
1556     dec               cntd
1557     jg .loop_dc
1558     RET
1559
1560     DEFINE_ARGS dst, stride, block, eob
1561 .idctfull:
1562     mova                m1, [blockq+ 32]
1563     mova                m2, [blockq+ 64]
1564     mova                m3, [blockq+ 96]
1565     mova                m5, [blockq+160]
1566     mova                m6, [blockq+192]
1567     mova                m7, [blockq+224]
1568     mova                m8, [blockq+256]
1569     mova                m9, [blockq+288]
1570     mova               m10, [blockq+320]
1571     mova               m11, [blockq+352]
1572     mova               m12, [blockq+384]
1573     mova               m13, [blockq+416]
1574     mova               m14, [blockq+448]
1575     mova               m15, [blockq+480]
1576
1577     VP9_IDCT16_YMM_1D
1578     TRANSPOSE16x16W      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \
1579                          [blockq+192], [blockq+128], 1
1580     mova      [blockq+  0], m0
1581     VP9_IDCT16_YMM_1D
1582
1583     mova      [blockq+224], m7
1584     mova      [blockq+480], m15
1585     pxor               m15, m15
1586
1587     ; store
1588     VP9_IDCT8_WRITEx2    0,  1, 6, 7, 15, [pw_512], 6
1589     lea               dstq, [dstq+2*strideq]
1590     VP9_IDCT8_WRITEx2    2,  3, 6, 7, 15, [pw_512], 6
1591     lea               dstq, [dstq+2*strideq]
1592     VP9_IDCT8_WRITEx2    4,  5, 6, 7, 15, [pw_512], 6
1593     lea               dstq, [dstq+2*strideq]
1594     mova                m6, [blockq+192]
1595     mova                m7, [blockq+224]
1596     SWAP                 0, 15
1597     mova               m15, [blockq+480]
1598     VP9_IDCT8_WRITEx2    6,  7, 1, 2, 0, [pw_512], 6
1599     lea               dstq, [dstq+2*strideq]
1600     VP9_IDCT8_WRITEx2    8,  9, 1, 2, 0, [pw_512], 6
1601     lea               dstq, [dstq+2*strideq]
1602     VP9_IDCT8_WRITEx2   10, 11, 1, 2, 0, [pw_512], 6
1603     lea               dstq, [dstq+2*strideq]
1604     VP9_IDCT8_WRITEx2   12, 13, 1, 2, 0, [pw_512], 6
1605     lea               dstq, [dstq+2*strideq]
1606     VP9_IDCT8_WRITEx2   14, 15, 1, 2, 0, [pw_512], 6
1607     lea               dstq, [dstq+2*strideq]
1608
1609     ; at the end of the loop, m0 should still be zero
1610     ; use that to zero out block coefficients
1611     ZERO_BLOCK      blockq, 32, 16, m0
1612     RET
1613 %endif
1614
1615 ;---------------------------------------------------------------------------------------------
1616 ; void vp9_iadst_iadst_16x16_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
1617 ;---------------------------------------------------------------------------------------------
1618
1619 %macro VP9_IADST16_1D 2 ; src, pass
1620 %assign %%str 16*%2
1621     mova                m0, [%1+ 0*32]  ; in0
1622     mova                m1, [%1+15*32]  ; in15
1623     mova                m2, [%1+ 7*32]  ; in7
1624     mova                m3, [%1+ 8*32]  ; in8
1625
1626     VP9_UNPACK_MULSUB_2D_4X  1,  0,  4,  5, 16364,   804    ; m1/4=t1[d], m0/5=t0[d]
1627     VP9_UNPACK_MULSUB_2D_4X  2,  3,  7,  6, 11003, 12140    ; m2/7=t9[d], m3/6=t8[d]
1628     SCRATCH              4, 8, tmpq+ 0*%%str
1629     VP9_RND_SH_SUMSUB_BA     3,  0,  6,  5,  4, [pd_8192]   ; m3=t0[w], m0=t8[w]
1630     UNSCRATCH            4, 8, tmpq+ 0*%%str
1631     VP9_RND_SH_SUMSUB_BA     2,  1,  7,  4,  5, [pd_8192]   ; m2=t1[w], m1=t9[w]
1632
1633     SCRATCH              0, 10, tmpq+ 0*%%str
1634     SCRATCH              1, 11, tmpq+15*%%str
1635     mova   [tmpq+ 7*%%str], m2
1636     mova   [tmpq+ 8*%%str], m3
1637
1638     mova                m1, [%1+ 2*32]  ; in2
1639     mova                m0, [%1+13*32]  ; in13
1640     mova                m3, [%1+ 5*32]  ; in5
1641     mova                m2, [%1+10*32]  ; in10
1642
1643     VP9_UNPACK_MULSUB_2D_4X  0,  1,  6,  7, 15893,  3981    ; m0/6=t3[d], m1/7=t2[d]
1644     VP9_UNPACK_MULSUB_2D_4X  3,  2,  4,  5,  8423, 14053    ; m3/4=t11[d], m2/5=t10[d]
1645     SCRATCH              4, 12, tmpq+ 2*%%str
1646     VP9_RND_SH_SUMSUB_BA     2,  1,  5,  7,  4, [pd_8192]   ; m2=t2[w], m1=t10[w]
1647     UNSCRATCH            4, 12, tmpq+ 2*%%str
1648     VP9_RND_SH_SUMSUB_BA     3,  0,  4,  6,  5, [pd_8192]   ; m3=t3[w], m0=t11[w]
1649
1650     SCRATCH              0, 12, tmpq+ 2*%%str
1651     SCRATCH              1, 13, tmpq+13*%%str
1652     mova   [tmpq+ 5*%%str], m2
1653     mova   [tmpq+10*%%str], m3
1654
1655     mova                m2, [%1+ 4*32]  ; in4
1656     mova                m3, [%1+11*32]  ; in11
1657     mova                m0, [%1+ 3*32]  ; in3
1658     mova                m1, [%1+12*32]  ; in12
1659
1660     VP9_UNPACK_MULSUB_2D_4X  3,  2,  7,  6, 14811,  7005    ; m3/7=t5[d], m2/6=t4[d]
1661     VP9_UNPACK_MULSUB_2D_4X  0,  1,  4,  5,  5520, 15426    ; m0/4=t13[d], m1/5=t12[d]
1662     SCRATCH              4, 9, tmpq+ 4*%%str
1663     VP9_RND_SH_SUMSUB_BA     1,  2,  5,  6,  4, [pd_8192]   ; m1=t4[w], m2=t12[w]
1664     UNSCRATCH            4, 9, tmpq+ 4*%%str
1665     VP9_RND_SH_SUMSUB_BA     0,  3,  4,  7,  6, [pd_8192]   ; m0=t5[w], m3=t13[w]
1666
1667     SCRATCH              0,  8, tmpq+ 4*%%str
1668     mova   [tmpq+11*%%str], m1          ; t4:m1->r11
1669     UNSCRATCH            0, 10, tmpq+ 0*%%str
1670     UNSCRATCH            1, 11, tmpq+15*%%str
1671
1672     ; round 2 interleaved part 1
1673     VP9_UNPACK_MULSUB_2D_4X  0,  1,  6,  7, 16069,  3196    ; m1/7=t8[d], m0/6=t9[d]
1674     VP9_UNPACK_MULSUB_2D_4X  3,  2,  5,  4,  3196, 16069    ; m3/5=t12[d], m2/4=t13[d]
1675     SCRATCH              4, 9, tmpq+ 3*%%str
1676     VP9_RND_SH_SUMSUB_BA     3,  1,  5,  7,  4, [pd_8192]   ; m3=t8[w], m1=t12[w]
1677     UNSCRATCH            4, 9, tmpq+ 3*%%str
1678     VP9_RND_SH_SUMSUB_BA     2,  0,  4,  6,  5, [pd_8192]   ; m2=t9[w], m0=t13[w]
1679
1680     SCRATCH              0, 10, tmpq+ 0*%%str
1681     SCRATCH              1, 11, tmpq+15*%%str
1682     SCRATCH              2, 14, tmpq+ 3*%%str
1683     SCRATCH              3, 15, tmpq+12*%%str
1684
1685     mova                m2, [%1+ 6*32]  ; in6
1686     mova                m3, [%1+ 9*32]  ; in9
1687     mova                m0, [%1+ 1*32]  ; in1
1688     mova                m1, [%1+14*32]  ; in14
1689
1690     VP9_UNPACK_MULSUB_2D_4X  3,  2,  7,  6, 13160,  9760    ; m3/7=t7[d], m2/6=t6[d]
1691     VP9_UNPACK_MULSUB_2D_4X  0,  1,  4,  5,  2404, 16207    ; m0/4=t15[d], m1/5=t14[d]
1692     SCRATCH              4, 9, tmpq+ 6*%%str
1693     VP9_RND_SH_SUMSUB_BA     1,  2,  5,  6,  4, [pd_8192]   ; m1=t6[w], m2=t14[w]
1694     UNSCRATCH            4, 9, tmpq+ 6*%%str
1695     VP9_RND_SH_SUMSUB_BA     0,  3,  4,  7,  6, [pd_8192]   ; m0=t7[w], m3=t15[w]
1696
1697     ; r8=t0, r7=t1, r5=t2, r10=t3, r11=t4, m8|r4=t5, m1=t6, m0=t7
1698     ; m10|r0=t8, m11|r15=t9, m13|r13=t10, m12|r2=t11, m14|r3=t12, m15|r12=t13, m2=t14, m3=t15
1699
1700     UNSCRATCH            4, 12, tmpq+ 2*%%str
1701     UNSCRATCH            5, 13, tmpq+13*%%str
1702     SCRATCH              0, 12, tmpq+ 1*%%str
1703     SCRATCH              1, 13, tmpq+14*%%str
1704
1705     ; remainder of round 2 (rest of t8-15)
1706     VP9_UNPACK_MULSUB_2D_4X  5,  4,  6,  7,  9102, 13623    ; m5/6=t11[d], m4/7=t10[d]
1707     VP9_UNPACK_MULSUB_2D_4X  3,  2,  1,  0, 13623,  9102    ; m3/1=t14[d], m2/0=t15[d]
1708     SCRATCH              0, 9, tmpq+ 6*%%str
1709     VP9_RND_SH_SUMSUB_BA     3,  4,  1,  7,  0, [pd_8192]   ; m3=t10[w], m4=t14[w]
1710     UNSCRATCH            0, 9, tmpq+ 6*%%str
1711     VP9_RND_SH_SUMSUB_BA     2,  5,  0,  6,  1, [pd_8192]   ; m2=t11[w], m5=t15[w]
1712
1713     ; m15|r12=t8, m14|r3=t9, m3=t10, m2=t11, m11|r15=t12, m10|r0=t13, m4=t14, m5=t15
1714
1715     UNSCRATCH            6, 14, tmpq+ 3*%%str
1716     UNSCRATCH            7, 15, tmpq+12*%%str
1717
1718     SUMSUB_BA                w,  3,  7,  1
1719     PSIGNW                  m3, [pw_m1]                     ; m3=out1[w], m7=t10[w]
1720     SUMSUB_BA                w,  2,  6,  1                  ; m2=out14[w], m6=t11[w]
1721
1722     ; unfortunately, the code below overflows in some cases, e.g.
1723     ; http://downloads.webmproject.org/test_data/libvpx/vp90-2-14-resize-fp-tiles-16-8.webm
1724 %if 0; cpuflag(ssse3)
1725     SUMSUB_BA                w,  7,  6,  1
1726     pmulhrsw                m7, [pw_11585x2]                ; m7=out6[w]
1727     pmulhrsw                m6, [pw_11585x2]                ; m6=out9[w]
1728 %else
1729     VP9_UNPACK_MULSUB_2W_4X  6,  7, 11585, 11585, [pd_8192], 1, 0
1730 %endif
1731
1732     mova       [tmpq+ 3*%%str], m6
1733     mova       [tmpq+ 6*%%str], m7
1734     UNSCRATCH                6, 10, tmpq+ 0*%%str
1735     UNSCRATCH                7, 11, tmpq+15*%%str
1736     mova       [tmpq+13*%%str], m2
1737     SCRATCH                  3, 11, tmpq+ 9*%%str
1738
1739     VP9_UNPACK_MULSUB_2D_4X  7,  6,  2,  3, 15137,  6270    ; m6/3=t13[d], m7/2=t12[d]
1740     VP9_UNPACK_MULSUB_2D_4X  5,  4,  1,  0,  6270, 15137    ; m5/1=t14[d], m4/0=t15[d]
1741     SCRATCH              0, 9, tmpq+ 2*%%str
1742     VP9_RND_SH_SUMSUB_BA     5,  6,  1,  3,  0, [pd_8192]   ; m5=out2[w], m6=t14[w]
1743     UNSCRATCH            0, 9, tmpq+ 2*%%str
1744     VP9_RND_SH_SUMSUB_BA     4,  7,  0,  2,  1, [pd_8192]
1745     PSIGNW                  m4, [pw_m1]                     ; m4=out13[w], m7=t15[w]
1746
1747     ; unfortunately, the code below overflows in some cases
1748 %if 0; cpuflag(ssse3)
1749     SUMSUB_BA                w,  7,  6,  1
1750     pmulhrsw                m7, [pw_m11585x2]               ; m7=out5[w]
1751     pmulhrsw                m6, [pw_11585x2]                ; m6=out10[w]
1752 %else
1753     PSIGNW                  m7, [pw_m1]
1754     VP9_UNPACK_MULSUB_2W_4X  7,  6, 11585, 11585, [pd_8192], 1, 0
1755 %endif
1756
1757     ; m11|r13=out1, m5=out2, m7=out5, r15=out6, r3=out9, m6=out10, m4=out13, r2=out14
1758
1759     mova                    m2, [tmpq+ 8*%%str]
1760     mova                    m3, [tmpq+ 7*%%str]
1761     mova                    m1, [tmpq+11*%%str]
1762     mova       [tmpq+ 7*%%str], m6
1763     mova       [tmpq+11*%%str], m4
1764     mova                    m4, [tmpq+ 5*%%str]
1765     SCRATCH                  5, 14, tmpq+ 5*%%str
1766     SCRATCH                  7, 15, tmpq+ 8*%%str
1767     UNSCRATCH                6,  8, tmpq+ 4*%%str
1768     UNSCRATCH                5, 12, tmpq+ 1*%%str
1769     UNSCRATCH                7, 13, tmpq+14*%%str
1770
1771     ; m2=t0, m3=t1, m9=t2, m0=t3, m1=t4, m8=t5, m13=t6, m12=t7
1772     ; m11|r13=out1, m5=out2, m7=out5, r15=out6, r3=out9, r10=out10, r11=out13, r2=out14
1773
1774     SUMSUB_BA                w,  1,  2, 0                   ; m1=t0[w], m2=t4[w]
1775     mova                    m0, [tmpq+10*%%str]
1776     SCRATCH                  1, 12, tmpq+ 1*%%str
1777     SUMSUB_BA                w,  6,  3, 1                   ; m8=t1[w], m3=t5[w]
1778     SCRATCH                  6, 13, tmpq+ 4*%%str
1779     SUMSUB_BA                w,  7,  4, 1                   ; m13=t2[w], m9=t6[w]
1780     SCRATCH                  7,  8, tmpq+10*%%str
1781     SUMSUB_BA                w,  5,  0, 1                   ; m12=t3[w], m0=t7[w]
1782     SCRATCH                  5,  9, tmpq+14*%%str
1783
1784     VP9_UNPACK_MULSUB_2D_4X  2,  3,  7,  5, 15137,  6270    ; m2/6=t5[d], m3/10=t4[d]
1785     VP9_UNPACK_MULSUB_2D_4X  0,  4,  1,  6,  6270, 15137    ; m0/14=t6[d], m9/15=t7[d]
1786     SCRATCH                  6, 10, tmpq+ 0*%%str
1787     VP9_RND_SH_SUMSUB_BA     0,  3,  1,  5,  6, [pd_8192]
1788     UNSCRATCH                6, 10, tmpq+ 0*%%str
1789     PSIGNW                  m0, [pw_m1]                     ; m0=out3[w], m3=t6[w]
1790     VP9_RND_SH_SUMSUB_BA     4,  2,  6,  7,  5, [pd_8192]   ; m9=out12[w], m2=t7[w]
1791
1792     UNSCRATCH                1,  8, tmpq+10*%%str
1793     UNSCRATCH                5,  9, tmpq+14*%%str
1794     UNSCRATCH                6, 12, tmpq+ 1*%%str
1795     UNSCRATCH                7, 13, tmpq+ 4*%%str
1796     SCRATCH                  4,  9, tmpq+14*%%str
1797
1798     SUMSUB_BA                w,  1,  6,  4                  ; m13=out0[w], m1=t2[w]
1799     SUMSUB_BA                w,  5,  7,  4
1800     PSIGNW                  m5, [pw_m1]                     ; m12=out15[w], m8=t3[w]
1801
1802     ; unfortunately, the code below overflows in some cases, e.g.
1803     ; http://downloads.webmproject.org/test_data/libvpx/vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm
1804 %if 0 ; cpuflag(ssse3)
1805     SUMSUB_BA               w,   7,  6,  4
1806     pmulhrsw                m7, [pw_m11585x2]               ; m8=out7[w]
1807     pmulhrsw                m6, [pw_11585x2]                ; m1=out8[w]
1808     SWAP                     6,  7
1809     SUMSUB_BA                w,  3,  2,  4
1810     pmulhrsw                m3, [pw_11585x2]                ; m3=out4[w]
1811     pmulhrsw                m2, [pw_11585x2]                ; m2=out11[w]
1812 %else
1813     SCRATCH                  5,  8, tmpq+10*%%str
1814     VP9_UNPACK_MULSUB_2W_4X  6,  7, 11585, m11585, [pd_8192],  5,  4
1815     VP9_UNPACK_MULSUB_2W_4X  2,  3, 11585, 11585, [pd_8192],  5,  4
1816     UNSCRATCH                5,  8, tmpq+10*%%str
1817 %endif
1818
1819     ; m13=out0, m0=out3, m3=out4, m8=out7, m1=out8, m2=out11, m9=out12, m12=out15
1820     ; m11|r13=out1, m5=out2, m7=out5, r15=out6, r3=out9, r10=out10, r11=out13, r2=out14
1821
1822 %if %2 == 1
1823 %if ARCH_X86_64
1824     mova                   m13, [tmpq+ 6*%%str]
1825     TRANSPOSE8x8W            1, 11, 14, 0, 3, 15, 13, 6, 10
1826     mova          [tmpq+ 0*16], m1
1827     mova          [tmpq+ 2*16], m11
1828     mova          [tmpq+ 4*16], m14
1829     mova          [tmpq+ 6*16], m0
1830     mova                    m1, [tmpq+ 3*%%str]
1831     mova                   m11, [tmpq+ 7*%%str]
1832     mova                   m14, [tmpq+11*%%str]
1833     mova                    m0, [tmpq+13*%%str]
1834     mova          [tmpq+ 8*16], m3
1835     mova          [tmpq+10*16], m15
1836     mova          [tmpq+12*16], m13
1837     mova          [tmpq+14*16], m6
1838
1839     TRANSPOSE8x8W            7, 1, 11, 2, 9, 14, 0, 5, 10
1840     mova          [tmpq+ 1*16], m7
1841     mova          [tmpq+ 3*16], m1
1842     mova          [tmpq+ 5*16], m11
1843     mova          [tmpq+ 7*16], m2
1844     mova          [tmpq+ 9*16], m9
1845     mova          [tmpq+11*16], m14
1846     mova          [tmpq+13*16], m0
1847     mova          [tmpq+15*16], m5
1848 %else
1849     mova       [tmpq+12*%%str], m2
1850     mova       [tmpq+ 1*%%str], m5
1851     mova       [tmpq+15*%%str], m7
1852     mova                    m2, [tmpq+ 9*%%str]
1853     mova                    m5, [tmpq+ 5*%%str]
1854     mova                    m7, [tmpq+ 8*%%str]
1855     TRANSPOSE8x8W            1, 2, 5, 0, 3, 7, 4, 6, [tmpq+ 6*%%str], [tmpq+ 8*%%str], 1
1856     mova          [tmpq+ 0*16], m1
1857     mova          [tmpq+ 2*16], m2
1858     mova          [tmpq+ 4*16], m5
1859     mova          [tmpq+ 6*16], m0
1860     mova          [tmpq+10*16], m7
1861     mova                    m3, [tmpq+12*%%str]
1862     mova          [tmpq+12*16], m4
1863     mova                    m4, [tmpq+14*%%str]
1864     mova          [tmpq+14*16], m6
1865
1866     mova                    m0, [tmpq+15*%%str]
1867     mova                    m1, [tmpq+ 3*%%str]
1868     mova                    m2, [tmpq+ 7*%%str]
1869     mova                    m5, [tmpq+11*%%str]
1870     mova                    m7, [tmpq+ 1*%%str]
1871     TRANSPOSE8x8W            0, 1, 2, 3, 4, 5, 6, 7, [tmpq+13*%%str], [tmpq+ 9*%%str], 1
1872     mova          [tmpq+ 1*16], m0
1873     mova          [tmpq+ 3*16], m1
1874     mova          [tmpq+ 5*16], m2
1875     mova          [tmpq+ 7*16], m3
1876     mova          [tmpq+11*16], m5
1877     mova          [tmpq+13*16], m6
1878     mova          [tmpq+15*16], m7
1879 %endif
1880 %else
1881     pxor                    m4, m4
1882
1883 %if cpuflag(ssse3)
1884 %define ROUND_REG [pw_512]
1885 %else
1886 %define ROUND_REG [pw_32]
1887 %endif
1888
1889 %if ARCH_X86_64
1890     mova                   m12, [tmpq+ 6*%%str]
1891     VP9_IDCT8_WRITEx2        1, 11, 10,  8,  4, ROUND_REG, 6
1892     lea                   dstq, [dstq+strideq*2]
1893     VP9_IDCT8_WRITEx2       14,  0, 10,  8,  4, ROUND_REG, 6
1894     lea                   dstq, [dstq+strideq*2]
1895     VP9_IDCT8_WRITEx2        3, 15, 10,  8,  4, ROUND_REG, 6
1896     lea                   dstq, [dstq+strideq*2]
1897     VP9_IDCT8_WRITEx2       12,  6, 10,  8,  4, ROUND_REG, 6
1898     lea                   dstq, [dstq+strideq*2]
1899
1900     mova                    m1, [tmpq+ 3*%%str]
1901     mova                   m11, [tmpq+ 7*%%str]
1902     mova                   m14, [tmpq+11*%%str]
1903     mova                    m0, [tmpq+13*%%str]
1904
1905     VP9_IDCT8_WRITEx2        7,  1, 10,  8,  4, ROUND_REG, 6
1906     lea                   dstq, [dstq+strideq*2]
1907     VP9_IDCT8_WRITEx2       11,  2, 10,  8,  4, ROUND_REG, 6
1908     lea                   dstq, [dstq+strideq*2]
1909     VP9_IDCT8_WRITEx2        9, 14, 10,  8,  4, ROUND_REG, 6
1910     lea                   dstq, [dstq+strideq*2]
1911     VP9_IDCT8_WRITEx2        0,  5, 10,  8,  4, ROUND_REG, 6
1912 %else
1913     mova       [tmpq+ 0*%%str], m2
1914     mova       [tmpq+ 1*%%str], m5
1915     mova       [tmpq+ 2*%%str], m7
1916     mova                    m2, [tmpq+ 9*%%str]
1917     VP9_IDCT8_WRITEx2        1,  2,  5,  7,  4, ROUND_REG, 6
1918     lea                   dstq, [dstq+strideq*2]
1919     mova                    m5, [tmpq+ 5*%%str]
1920     VP9_IDCT8_WRITEx2        5,  0,  1,  2,  4, ROUND_REG, 6
1921     lea                   dstq, [dstq+strideq*2]
1922     mova                    m5, [tmpq+ 8*%%str]
1923     VP9_IDCT8_WRITEx2        3,  5,  1,  2,  4, ROUND_REG, 6
1924     lea                   dstq, [dstq+strideq*2]
1925     mova                    m5, [tmpq+ 6*%%str]
1926     VP9_IDCT8_WRITEx2        5,  6,  1,  2,  4, ROUND_REG, 6
1927     lea                   dstq, [dstq+strideq*2]
1928
1929     mova                    m0, [tmpq+ 2*%%str]
1930     mova                    m3, [tmpq+ 3*%%str]
1931     VP9_IDCT8_WRITEx2        0,  3,  1,  2,  4, ROUND_REG, 6
1932     lea                   dstq, [dstq+strideq*2]
1933     mova                    m0, [tmpq+ 7*%%str]
1934     mova                    m3, [tmpq+ 0*%%str]
1935     VP9_IDCT8_WRITEx2        0,  3,  1,  2,  4, ROUND_REG, 6
1936     lea                   dstq, [dstq+strideq*2]
1937     mova                    m0, [tmpq+14*%%str]
1938     mova                    m3, [tmpq+11*%%str]
1939     VP9_IDCT8_WRITEx2        0,  3,  1,  2,  4, ROUND_REG, 6
1940     lea                   dstq, [dstq+strideq*2]
1941     mova                    m0, [tmpq+13*%%str]
1942     mova                    m3, [tmpq+ 1*%%str]
1943     VP9_IDCT8_WRITEx2        0,  3,  1,  2,  4, ROUND_REG, 6
1944 %endif
1945
1946     SWAP                     0,  4 ; zero
1947 %undef ROUND_REG
1948 %endif
1949 %endmacro
1950
1951 %macro IADST16_FN 5
1952 INIT_XMM %5
1953 cglobal vp9_%1_%3_16x16_add, 3, 6, 16, 512, dst, stride, block, cnt, dst_bak, tmp
1954     mov               cntd, 2
1955     mov               tmpq, rsp
1956 .loop1_full:
1957     VP9_%2_1D       blockq, 1
1958     add             blockq, 16
1959     add               tmpq, 256
1960     dec               cntd
1961     jg .loop1_full
1962     sub             blockq, 32
1963
1964     mov               cntd, 2
1965     mov               tmpq, rsp
1966     mov           dst_bakq, dstq
1967 .loop2_full:
1968     VP9_%4_1D         tmpq, 2
1969     lea               dstq, [dst_bakq+8]
1970     add               tmpq, 16
1971     dec               cntd
1972     jg .loop2_full
1973
1974     ; at the end of the loop, m0 should still be zero
1975     ; use that to zero out block coefficients
1976     ZERO_BLOCK      blockq, 32, 16, m0
1977     RET
1978 %endmacro
1979
1980 IADST16_FN idct,  IDCT16,  iadst, IADST16, sse2
1981 IADST16_FN iadst, IADST16, idct,  IDCT16,  sse2
1982 IADST16_FN iadst, IADST16, iadst, IADST16, sse2
1983 IADST16_FN idct,  IDCT16,  iadst, IADST16, ssse3
1984 IADST16_FN iadst, IADST16, idct,  IDCT16,  ssse3
1985 IADST16_FN iadst, IADST16, iadst, IADST16, ssse3
1986 IADST16_FN idct,  IDCT16,  iadst, IADST16, avx
1987 IADST16_FN iadst, IADST16, idct,  IDCT16,  avx
1988 IADST16_FN iadst, IADST16, iadst, IADST16, avx
1989
1990 ;---------------------------------------------------------------------------------------------
1991 ; void vp9_idct_idct_32x32_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
1992 ;---------------------------------------------------------------------------------------------
1993
1994 %macro VP9_IDCT32_1D 2-3 32 ; src, pass, nnzc
1995 %if %2 == 1
1996 %assign %%str mmsize
1997 %else
1998 %assign %%str 64
1999 %endif
2000
2001     ; first do t0-15, this can be done identical to idct16x16
2002     VP9_IDCT16_1D_START %1, %3/2, 64*2, tmpq, 2*%%str, 1
2003
2004     ; store everything on stack to make space available for t16-31
2005     ; we store interleaved with the output of the second half (t16-31)
2006     ; so we don't need to allocate extra stack space
2007     mova    [tmpq+ 0*%%str], m0     ; t0
2008     mova    [tmpq+ 4*%%str], m1     ; t1
2009     mova    [tmpq+ 8*%%str], m2     ; t2
2010     mova    [tmpq+12*%%str], m3     ; t3
2011     mova    [tmpq+16*%%str], m4     ; t4
2012     mova    [tmpq+20*%%str], m5     ; t5
2013 %if ARCH_X86_64
2014     mova    [tmpq+22*%%str], m10    ; t10
2015     mova    [tmpq+18*%%str], m11    ; t11
2016     mova    [tmpq+14*%%str], m12    ; t12
2017     mova    [tmpq+10*%%str], m13    ; t13
2018     mova    [tmpq+ 6*%%str], m14    ; t14
2019     mova    [tmpq+ 2*%%str], m15    ; t15
2020 %endif
2021
2022     mova                m0, [tmpq+ 30*%%str]
2023     UNSCRATCH            1,  6, tmpq+26*%%str
2024     UNSCRATCH            2,  8, tmpq+24*%%str
2025     UNSCRATCH            3,  9, tmpq+28*%%str
2026     SUMSUB_BA            w,  1,  3, 4       ; t6, t9
2027     SUMSUB_BA            w,  0,  2, 4       ; t7, t8
2028
2029     mova    [tmpq+24*%%str], m1     ; t6
2030     mova    [tmpq+28*%%str], m0     ; t7
2031     mova    [tmpq+30*%%str], m2     ; t8
2032     mova    [tmpq+26*%%str], m3     ; t9
2033
2034     ; then, secondly, do t16-31
2035 %if %3 <= 8
2036     mova                 m4, [%1+ 1*64]
2037     mova                 m7, [%1+ 7*64]
2038
2039     pmulhrsw             m1,  m4, [pw_16364x2] ;t31
2040     pmulhrsw             m4, [pw_804x2] ;t16
2041
2042     VP9_UNPACK_MULSUB_2W_4X   5,  0,  1,  4, 16069,  3196, [pd_8192], 6,  2 ; t17, t30
2043
2044     pmulhrsw             m3,  m7, [pw_m5520x2] ;t19
2045     pmulhrsw             m7, [pw_15426x2] ;t28
2046
2047     SCRATCH               4, 13, tmpq+ 1*%%str
2048     SCRATCH               5, 12, tmpq+15*%%str
2049
2050     VP9_UNPACK_MULSUB_2W_4X   2,  6,  7,  3, 3196, m16069, [pd_8192], 4,  5 ; t18, t29
2051 %else
2052     mova                 m0, [%1+ 1*64]
2053     mova                 m1, [%1+15*64]
2054 %if %3 <= 16
2055     pmulhrsw             m5, m0, [pw_16364x2]
2056     pmulhrsw             m0, [pw_804x2]
2057     pmulhrsw             m4, m1, [pw_m11003x2]
2058     pmulhrsw             m1, [pw_12140x2]
2059 %else
2060     mova                 m4, [%1+17*64]
2061     mova                 m5, [%1+31*64]
2062
2063     VP9_UNPACK_MULSUB_2W_4X   0,  5, 16364,   804, [pd_8192], 2, 3 ; t16, t31
2064     VP9_UNPACK_MULSUB_2W_4X   4,  1, 11003, 12140, [pd_8192], 2, 3 ; t17, t30
2065 %endif
2066     SUMSUB_BA             w,  4,  0,  2
2067     SUMSUB_BA             w,  1,  5,  2
2068
2069     VP9_UNPACK_MULSUB_2W_4X   5,  0, 16069,  3196, [pd_8192], 2, 3 ; t17, t30
2070
2071     SCRATCH               4, 13, tmpq+ 1*%%str
2072     SCRATCH               5, 12, tmpq+15*%%str
2073
2074     mova                 m2, [%1+ 7*64]
2075     mova                 m3, [%1+ 9*64]
2076 %if %3 <= 16
2077     pmulhrsw             m7,  m3, [pw_14811x2]
2078     pmulhrsw             m3, [pw_7005x2]
2079     pmulhrsw             m6,  m2, [pw_m5520x2]
2080     pmulhrsw             m2, [pw_15426x2]
2081 %else
2082     mova                 m7, [%1+23*64]
2083     mova                 m6, [%1+25*64]
2084
2085     VP9_UNPACK_MULSUB_2W_4X   3,  7, 14811,  7005, [pd_8192], 4, 5 ; t18, t29
2086     VP9_UNPACK_MULSUB_2W_4X   6,  2,  5520, 15426, [pd_8192], 4, 5 ; t19, t28
2087 %endif
2088     SUMSUB_BA             w,  3,  6,  4
2089     SUMSUB_BA             w,  7,  2,  4
2090
2091     VP9_UNPACK_MULSUB_2W_4X   2,  6, 3196, m16069, [pd_8192], 4, 5 ; t18, t29
2092 %endif
2093
2094     UNSCRATCH             5, 12, tmpq+15*%%str
2095     SUMSUB_BA             w,  6,  0,  4
2096     mova    [tmpq+25*%%str], m6             ; t19
2097     UNSCRATCH             4, 13, tmpq+ 1*%%str
2098     SUMSUB_BA             w,  7,  1,  6
2099     SUMSUB_BA             w,  3,  4,  6
2100     mova    [tmpq+23*%%str], m3             ; t16
2101     SUMSUB_BA             w,  2,  5,  6
2102
2103     VP9_UNPACK_MULSUB_2W_4X   0,  5, 15137,  6270, [pd_8192], 6, 3 ; t18, t29
2104     VP9_UNPACK_MULSUB_2W_4X   1,  4, 15137,  6270, [pd_8192], 6, 3 ; t19, t28
2105
2106     SCRATCH               0, 10, tmpq+ 1*%%str
2107     SCRATCH               1, 11, tmpq+ 7*%%str
2108     SCRATCH               2,  9, tmpq+ 9*%%str
2109     SCRATCH               4, 14, tmpq+15*%%str
2110     SCRATCH               5, 15, tmpq+17*%%str
2111     SCRATCH               7, 13, tmpq+31*%%str
2112
2113 %if %3 <= 8
2114     mova                 m0, [%1+ 5*64]
2115     mova                 m3, [%1+ 3*64]
2116
2117     pmulhrsw             m5,  m0, [pw_15893x2] ;t27
2118     pmulhrsw             m0, [pw_3981x2] ;t20
2119
2120     VP9_UNPACK_MULSUB_2W_4X   1,  4,  5,  0,  9102, 13623, [pd_8192], 7,  2 ; t21, t26
2121
2122     pmulhrsw             m6,  m3, [pw_m2404x2] ;t23
2123     pmulhrsw             m3, [pw_16207x2] ;t24
2124
2125     SCRATCH               5,  8, tmpq+ 5*%%str
2126     SCRATCH               4, 12, tmpq+11*%%str
2127
2128     VP9_UNPACK_MULSUB_2W_4X   7,  2,  3,  6, 13623, m9102, [pd_8192], 4, 5 ; t22, t25
2129 %else
2130     mova                 m4, [%1+ 5*64]
2131     mova                 m5, [%1+11*64]
2132 %if %3 <= 16
2133     pmulhrsw             m1, m4, [pw_15893x2]
2134     pmulhrsw             m4, [pw_3981x2]
2135     pmulhrsw             m0, m5, [pw_m8423x2]
2136     pmulhrsw             m5, [pw_14053x2]
2137 %else
2138     mova                 m0, [%1+21*64]
2139     mova                 m1, [%1+27*64]
2140
2141     VP9_UNPACK_MULSUB_2W_4X   4,  1, 15893,  3981, [pd_8192], 2, 3 ; t20, t27
2142     VP9_UNPACK_MULSUB_2W_4X   0,  5,  8423, 14053, [pd_8192], 2, 3 ; t21, t26
2143 %endif
2144     SUMSUB_BA             w,  0,  4,  2
2145     SUMSUB_BA             w,  5,  1,  2
2146
2147     VP9_UNPACK_MULSUB_2W_4X   1,  4,  9102, 13623, [pd_8192], 2, 3 ; t21, t26
2148
2149     SCRATCH               5,  8, tmpq+ 5*%%str
2150     SCRATCH               4, 12, tmpq+11*%%str
2151
2152     mova                 m7, [%1+ 3*64]
2153     mova                 m6, [%1+13*64]
2154 %if %3 <= 16
2155     pmulhrsw             m3, m6, [pw_13160x2]
2156     pmulhrsw             m6, [pw_9760x2]
2157     pmulhrsw             m2, m7, [pw_m2404x2]
2158     pmulhrsw             m7, [pw_16207x2]
2159 %else
2160     mova                 m2, [%1+29*64]
2161     mova                 m3, [%1+19*64]
2162     VP9_UNPACK_MULSUB_2W_4X   6,  3, 13160,  9760, [pd_8192], 4, 5 ; t22, t25
2163     VP9_UNPACK_MULSUB_2W_4X   2,  7,  2404, 16207, [pd_8192], 4, 5 ; t23, t24
2164 %endif
2165     SUMSUB_BA             w,  6,  2,  4
2166     SUMSUB_BA             w,  3,  7,  4
2167
2168     VP9_UNPACK_MULSUB_2W_4X   7,  2, 13623, m9102, [pd_8192], 4, 5 ; t22, t25
2169 %endif
2170
2171     ; m4=t16, m5=t17, m9=t18, m8=t19, m0=t20, m1=t21, m13=t22, m12=t23,
2172     ; m3=t24, m2=t25, m14=t26, m15=t27, m7=t28, m6=t29, m10=t30, m11=t31
2173
2174     UNSCRATCH             4, 12, tmpq+11*%%str
2175     SUMSUB_BA             w,  0,  6, 5
2176     SUMSUB_BA             w,  4,  2, 5
2177     UNSCRATCH             5,  8, tmpq+ 5*%%str
2178     SCRATCH               4,  8, tmpq+11*%%str
2179     SUMSUB_BA             w,  1,  7, 4
2180     SUMSUB_BA             w,  5,  3, 4
2181     SCRATCH               5, 12, tmpq+ 5*%%str
2182
2183     VP9_UNPACK_MULSUB_2W_4X   3,  6, 6270, m15137, [pd_8192], 4, 5 ; t20, t27
2184     VP9_UNPACK_MULSUB_2W_4X   2,  7, 6270, m15137, [pd_8192], 4, 5 ; t21, t26
2185
2186     ; m8[s]=t16, m9=t17, m5=t18, m4[s]=t19, m12=t20, m13=t21, m1=t22, m0=t23,
2187     ; m15=t24, m14=t25, m2=t26, m3=t27, m11=t28, m10=t29, m6=t30, m7=t31
2188
2189     UNSCRATCH             5,  9, tmpq+ 9*%%str
2190     mova                 m4, [tmpq+23*%%str] ; t16
2191 %if ARCH_X86_64
2192     SUMSUB_BA             w,  1,  5,  9
2193     SUMSUB_BA             w,  0,  4,  9
2194 %else
2195     SUMSUB_BADC           w,  1,  5,  0,  4
2196 %endif
2197     mova    [tmpq+29*%%str], m1     ; t17
2198     mova    [tmpq+21*%%str], m0     ; t16
2199     UNSCRATCH             0, 10, tmpq+ 1*%%str
2200     UNSCRATCH             1, 11, tmpq+ 7*%%str
2201 %if ARCH_X86_64
2202     SUMSUB_BA             w,  2,  0,  9
2203     SUMSUB_BA             w,  3,  1,  9
2204 %else
2205     SUMSUB_BADC           w,  2,  0,  3,  1
2206 %endif
2207     mova    [tmpq+ 9*%%str], m2     ; t18
2208     mova    [tmpq+13*%%str], m3     ; t19
2209     SCRATCH               0, 10, tmpq+23*%%str
2210     SCRATCH               1, 11, tmpq+27*%%str
2211
2212     UNSCRATCH             2, 14, tmpq+15*%%str
2213     UNSCRATCH             3, 15, tmpq+17*%%str
2214     SUMSUB_BA             w,  6,  2, 0
2215     SUMSUB_BA             w,  7,  3, 0
2216     SCRATCH               6, 14, tmpq+ 3*%%str
2217     SCRATCH               7, 15, tmpq+ 7*%%str
2218
2219     UNSCRATCH             0,  8, tmpq+11*%%str
2220     mova                 m1, [tmpq+25*%%str] ; t19
2221     UNSCRATCH             6, 12, tmpq+ 5*%%str
2222     UNSCRATCH             7, 13, tmpq+31*%%str
2223 %if ARCH_X86_64
2224     SUMSUB_BA             w,  0,  1,  9
2225     SUMSUB_BA             w,  6,  7,  9
2226 %else
2227     SUMSUB_BADC           w,  0,  1,  6,  7
2228 %endif
2229
2230     ; m0=t16, m1=t17, m2=t18, m3=t19, m11=t20, m10=t21, m9=t22, m8=t23,
2231     ; m7=t24, m6=t25, m5=t26, m4=t27, m12=t28, m13=t29, m14=t30, m15=t31
2232
2233 %if 0; cpuflag(ssse3)
2234 %if ARCH_X86_64
2235     SUMSUB_BA             w,  4,  7,  8
2236     SUMSUB_BA             w,  5,  1,  8
2237 %else
2238     SUMSUB_BADC           w,  4,  7,  5,  1
2239 %endif
2240
2241     pmulhrsw             m7, [pw_11585x2]
2242     pmulhrsw             m4, [pw_11585x2]
2243     pmulhrsw             m1, [pw_11585x2]
2244     pmulhrsw             m5, [pw_11585x2]
2245
2246     mova    [tmpq+ 5*%%str], m7     ; t23
2247     SCRATCH               1, 13, tmpq+25*%%str
2248     UNSCRATCH             7, 10, tmpq+23*%%str
2249     UNSCRATCH             1, 11, tmpq+27*%%str
2250
2251 %if ARCH_X86_64
2252     SUMSUB_BA             w,  7,  3, 10
2253     SUMSUB_BA             w,  1,  2, 10
2254 %else
2255     SUMSUB_BADC           w,  7,  3,  1,  2
2256 %endif
2257
2258     pmulhrsw             m3, [pw_11585x2]
2259     pmulhrsw             m7, [pw_11585x2]
2260     pmulhrsw             m2, [pw_11585x2]
2261     pmulhrsw             m1, [pw_11585x2]
2262 %else
2263     SCRATCH               0,  8, tmpq+15*%%str
2264     SCRATCH               6,  9, tmpq+17*%%str
2265     VP9_UNPACK_MULSUB_2W_4X  7,  4, 11585, 11585, [pd_8192], 0, 6
2266     mova    [tmpq+ 5*%%str], m7     ; t23
2267     UNSCRATCH             7, 10, tmpq+23*%%str
2268     VP9_UNPACK_MULSUB_2W_4X  1,  5, 11585, 11585, [pd_8192], 0, 6
2269     SCRATCH               1, 13, tmpq+25*%%str
2270     UNSCRATCH             1, 11, tmpq+27*%%str
2271     VP9_UNPACK_MULSUB_2W_4X  3,  7, 11585, 11585, [pd_8192], 0, 6
2272     VP9_UNPACK_MULSUB_2W_4X  2,  1, 11585, 11585, [pd_8192], 0, 6
2273     UNSCRATCH             0,  8, tmpq+15*%%str
2274     UNSCRATCH             6,  9, tmpq+17*%%str
2275 %endif
2276
2277     ; m0=t16, m1=t17, m2=t18, m3=t19, m4=t20, m5=t21, m6=t22, m7=t23,
2278     ; m8=t24, m9=t25, m10=t26, m11=t27, m12=t28, m13=t29, m14=t30, m15=t31
2279
2280     ; then do final pass to sumsub+store the two halves
2281 %if %2 == 1
2282     mova    [tmpq+17*%%str], m2     ; t20
2283     mova    [tmpq+ 1*%%str], m3     ; t21
2284 %if ARCH_X86_64
2285     mova    [tmpq+25*%%str], m13    ; t22
2286
2287     mova                 m8, [tmpq+ 0*%%str] ; t0
2288     mova                 m9, [tmpq+ 4*%%str] ; t1
2289     mova                m12, [tmpq+ 8*%%str] ; t2
2290     mova                m11, [tmpq+12*%%str] ; t3
2291     mova                 m2, [tmpq+16*%%str] ; t4
2292     mova                 m3, [tmpq+20*%%str] ; t5
2293     mova                m13, [tmpq+24*%%str] ; t6
2294
2295     SUMSUB_BA             w,  6,  8, 10
2296     mova    [tmpq+ 3*%%str], m8              ; t15
2297     SUMSUB_BA             w,  0,  9,  8
2298     SUMSUB_BA             w, 15, 12,  8
2299     SUMSUB_BA             w, 14, 11,  8
2300     SUMSUB_BA             w,  1,  2,  8
2301     SUMSUB_BA             w,  7,  3,  8
2302     SUMSUB_BA             w,  5, 13,  8
2303     mova                m10, [tmpq+28*%%str] ; t7
2304     SUMSUB_BA             w,  4, 10,  8
2305 %if cpuflag(avx2)
2306     ; the "shitty" about this idct is that the final pass does the outermost
2307     ; interleave sumsubs (t0/31, t1/30, etc) but the tN for the 16x16 need
2308     ; to be sequential, which means I need to load/store half of the sumsub
2309     ; intermediates back to/from memory to get a 16x16 transpose going...
2310     ; This would be easier if we had more (e.g. 32) YMM regs here.
2311     mova    [tmpq+ 7*%%str], m9
2312     mova    [tmpq+11*%%str], m12
2313     mova    [tmpq+15*%%str], m11
2314     mova    [tmpq+19*%%str], m2
2315     mova    [tmpq+23*%%str], m3
2316     mova    [tmpq+27*%%str], m13
2317     mova    [tmpq+31*%%str], m10
2318     mova    [tmpq+12*%%str], m5
2319
2320     mova                m13, [tmpq+30*%%str] ; t8
2321     mova                m12, [tmpq+26*%%str] ; t9
2322     mova                m11, [tmpq+22*%%str] ; t10
2323     mova                m10, [tmpq+18*%%str] ; t11
2324     mova                 m9, [tmpq+17*%%str] ; t20
2325     mova                 m8, [tmpq+ 1*%%str] ; t21
2326     mova                 m3, [tmpq+25*%%str] ; t22
2327     mova                 m2, [tmpq+ 5*%%str] ; t23
2328
2329     SUMSUB_BA             w,  9, 10, 5
2330     SUMSUB_BA             w,  8, 11, 5
2331     SUMSUB_BA             w,  3, 12, 5
2332     SUMSUB_BA             w,  2, 13, 5
2333     mova    [tmpq+ 1*%%str], m10
2334     mova    [tmpq+ 5*%%str], m11
2335     mova    [tmpq+17*%%str], m12
2336     mova    [tmpq+25*%%str], m13
2337
2338     mova                m13, [tmpq+14*%%str] ; t12
2339     mova                m12, [tmpq+10*%%str] ; t13
2340     mova                m11, [tmpq+ 9*%%str] ; t18
2341     mova                m10, [tmpq+13*%%str] ; t19
2342
2343     SUMSUB_BA             w, 11, 12, 5
2344     SUMSUB_BA             w, 10, 13, 5
2345     mova    [tmpq+ 9*%%str], m13
2346     mova    [tmpq+13*%%str], m12
2347     mova    [tmpq+10*%%str], m10
2348     mova    [tmpq+14*%%str], m11
2349
2350     mova                m13, [tmpq+ 6*%%str] ; t14
2351     mova                m12, [tmpq+ 2*%%str] ; t15
2352     mova                m11, [tmpq+21*%%str] ; t16
2353     mova                m10, [tmpq+29*%%str] ; t17
2354     SUMSUB_BA             w, 11, 12, 5
2355     SUMSUB_BA             w, 10, 13, 5
2356     mova    [tmpq+21*%%str], m12
2357     mova    [tmpq+29*%%str], m13
2358     mova                m12, [tmpq+10*%%str]
2359     mova                m13, [tmpq+14*%%str]
2360
2361     TRANSPOSE16x16W       6,  0, 15, 14,  1,  7,  5,  4, \
2362                           2,  3,  8,  9, 12, 13, 10, 11, \
2363             [tmpq+12*%%str], [tmpq+ 8*%%str], 1
2364     mova    [tmpq+ 0*%%str], m6
2365     mova    [tmpq+ 2*%%str], m0
2366     mova    [tmpq+ 4*%%str], m15
2367     mova    [tmpq+ 6*%%str], m14
2368     mova    [tmpq+10*%%str], m7
2369     mova    [tmpq+12*%%str], m5
2370     mova    [tmpq+14*%%str], m4
2371     mova    [tmpq+16*%%str], m2
2372     mova    [tmpq+18*%%str], m3
2373     mova    [tmpq+20*%%str], m8
2374     mova    [tmpq+22*%%str], m9
2375     mova    [tmpq+24*%%str], m12
2376     mova    [tmpq+26*%%str], m13
2377     mova    [tmpq+28*%%str], m10
2378     mova    [tmpq+30*%%str], m11
2379
2380     mova                 m0, [tmpq+21*%%str]
2381     mova                 m1, [tmpq+29*%%str]
2382     mova                 m2, [tmpq+13*%%str]
2383     mova                 m3, [tmpq+ 9*%%str]
2384     mova                 m4, [tmpq+ 1*%%str]
2385     mova                 m5, [tmpq+ 5*%%str]
2386     mova                 m7, [tmpq+25*%%str]
2387     mova                 m8, [tmpq+31*%%str]
2388     mova                 m9, [tmpq+27*%%str]
2389     mova                m10, [tmpq+23*%%str]
2390     mova                m11, [tmpq+19*%%str]
2391     mova                m12, [tmpq+15*%%str]
2392     mova                m13, [tmpq+11*%%str]
2393     mova                m14, [tmpq+ 7*%%str]
2394     mova                m15, [tmpq+ 3*%%str]
2395     TRANSPOSE16x16W       0,  1,  2,  3,  4,  5,  6,  7, \
2396                           8,  9, 10, 11, 12, 13, 14, 15, \
2397             [tmpq+17*%%str], [tmpq+ 9*%%str], 1
2398     mova    [tmpq+ 1*%%str], m0
2399     mova    [tmpq+ 3*%%str], m1
2400     mova    [tmpq+ 5*%%str], m2
2401     mova    [tmpq+ 7*%%str], m3
2402     mova    [tmpq+11*%%str], m5
2403     mova    [tmpq+13*%%str], m6
2404     mova    [tmpq+15*%%str], m7
2405     mova    [tmpq+17*%%str], m8
2406     mova    [tmpq+19*%%str], m9
2407     mova    [tmpq+21*%%str], m10
2408     mova    [tmpq+23*%%str], m11
2409     mova    [tmpq+25*%%str], m12
2410     mova    [tmpq+27*%%str], m13
2411     mova    [tmpq+29*%%str], m14
2412     mova    [tmpq+31*%%str], m15
2413 %else ; !avx2
2414     TRANSPOSE8x8W         6, 0, 15, 14, 1, 7, 5, 4, 8
2415     mova    [tmpq+ 0*%%str], m6
2416     mova    [tmpq+ 4*%%str], m0
2417     mova    [tmpq+ 8*%%str], m15
2418     mova    [tmpq+12*%%str], m14
2419     mova    [tmpq+16*%%str], m1
2420     mova    [tmpq+20*%%str], m7
2421     mova    [tmpq+24*%%str], m5
2422     mova    [tmpq+28*%%str], m4
2423
2424     mova                  m8, [tmpq+ 3*%%str] ; t15
2425     TRANSPOSE8x8W         10, 13, 3, 2, 11, 12, 9, 8, 0
2426     mova    [tmpq+ 3*%%str], m10
2427     mova    [tmpq+ 7*%%str], m13
2428     mova    [tmpq+11*%%str], m3
2429     mova    [tmpq+15*%%str], m2
2430     mova    [tmpq+19*%%str], m11
2431     mova    [tmpq+23*%%str], m12
2432     mova    [tmpq+27*%%str], m9
2433     mova    [tmpq+31*%%str], m8
2434
2435     mova                m15, [tmpq+30*%%str] ; t8
2436     mova                m14, [tmpq+26*%%str] ; t9
2437     mova                m13, [tmpq+22*%%str] ; t10
2438     mova                m12, [tmpq+18*%%str] ; t11
2439     mova                m11, [tmpq+14*%%str] ; t12
2440     mova                m10, [tmpq+10*%%str] ; t13
2441     mova                 m9, [tmpq+ 6*%%str] ; t14
2442     mova                 m8, [tmpq+ 2*%%str] ; t15
2443     mova                 m7, [tmpq+21*%%str] ; t16
2444     mova                 m6, [tmpq+29*%%str] ; t17
2445     mova                 m5, [tmpq+ 9*%%str] ; t18
2446     mova                 m4, [tmpq+13*%%str] ; t19
2447     mova                 m3, [tmpq+17*%%str] ; t20
2448     mova                 m2, [tmpq+ 1*%%str] ; t21
2449     mova                 m1, [tmpq+25*%%str] ; t22
2450
2451     SUMSUB_BA             w,  7,  8, 0
2452     mova    [tmpq+ 2*%%str], m8
2453     mova                 m0, [tmpq+ 5*%%str] ; t23
2454     SUMSUB_BA             w,  6,  9, 8
2455     SUMSUB_BA             w,  5, 10, 8
2456     SUMSUB_BA             w,  4, 11, 8
2457     SUMSUB_BA             w,  3, 12, 8
2458     SUMSUB_BA             w,  2, 13, 8
2459     SUMSUB_BA             w,  1, 14, 8
2460     SUMSUB_BA             w,  0, 15, 8
2461
2462     TRANSPOSE8x8W         0, 1, 2, 3, 4, 5, 6, 7, 8
2463     mova    [tmpq+ 1*%%str], m0
2464     mova    [tmpq+ 5*%%str], m1
2465     mova    [tmpq+ 9*%%str], m2
2466     mova    [tmpq+13*%%str], m3
2467     mova    [tmpq+17*%%str], m4
2468     mova    [tmpq+21*%%str], m5
2469     mova    [tmpq+25*%%str], m6
2470     mova    [tmpq+29*%%str], m7
2471
2472     mova                 m8, [tmpq+ 2*%%str]
2473     TRANSPOSE8x8W         8, 9, 10, 11, 12, 13, 14, 15, 0
2474     mova    [tmpq+ 2*%%str], m8
2475     mova    [tmpq+ 6*%%str], m9
2476     mova    [tmpq+10*%%str], m10
2477     mova    [tmpq+14*%%str], m11
2478     mova    [tmpq+18*%%str], m12
2479     mova    [tmpq+22*%%str], m13
2480     mova    [tmpq+26*%%str], m14
2481     mova    [tmpq+30*%%str], m15
2482 %endif ; avx2
2483 %else
2484     mova                 m2, [tmpq+24*%%str] ; t6
2485     mova                 m3, [tmpq+28*%%str] ; t7
2486     SUMSUB_BADC           w,  5,  2,  4,  3
2487     mova    [tmpq+24*%%str], m5
2488     mova    [tmpq+23*%%str], m2
2489     mova    [tmpq+28*%%str], m4
2490     mova    [tmpq+19*%%str], m3
2491
2492     mova                 m2, [tmpq+16*%%str] ; t4
2493     mova                 m3, [tmpq+20*%%str] ; t5
2494     SUMSUB_BA             w,  1,  2,  5
2495     SUMSUB_BA             w,  7,  3,  5
2496     mova    [tmpq+15*%%str], m2
2497     mova    [tmpq+11*%%str], m3
2498
2499     mova                 m2, [tmpq+ 0*%%str] ; t0
2500     mova                 m3, [tmpq+ 4*%%str] ; t1
2501     SUMSUB_BA             w,  6,  2,  5
2502     SUMSUB_BA             w,  0,  3,  5
2503     mova    [tmpq+31*%%str], m2
2504     mova    [tmpq+27*%%str], m3
2505
2506     mova                 m2, [tmpq+ 8*%%str] ; t2
2507     mova                 m3, [tmpq+12*%%str] ; t3
2508     mova                 m5, [tmpq+ 7*%%str]
2509     mova                 m4, [tmpq+ 3*%%str]
2510     SUMSUB_BADC           w,  5,  2,  4,  3
2511     mova    [tmpq+ 7*%%str], m2
2512     mova    [tmpq+ 3*%%str], m3
2513
2514     mova                 m3, [tmpq+28*%%str]
2515     TRANSPOSE8x8W         6, 0, 5, 4, 1, 7, 2, 3, [tmpq+24*%%str], [tmpq+16*%%str], 1
2516     mova    [tmpq+ 0*%%str], m6
2517     mova    [tmpq+ 4*%%str], m0
2518     mova    [tmpq+ 8*%%str], m5
2519     mova    [tmpq+12*%%str], m4
2520     mova    [tmpq+20*%%str], m7
2521     mova    [tmpq+24*%%str], m2
2522     mova    [tmpq+28*%%str], m3
2523
2524     mova                 m6, [tmpq+19*%%str]
2525     mova                 m0, [tmpq+23*%%str]
2526     mova                 m5, [tmpq+11*%%str]
2527     mova                 m4, [tmpq+15*%%str]
2528     mova                 m1, [tmpq+ 3*%%str]
2529     mova                 m7, [tmpq+ 7*%%str]
2530     mova                 m3, [tmpq+31*%%str]
2531     TRANSPOSE8x8W         6, 0, 5, 4, 1, 7, 2, 3, [tmpq+27*%%str], [tmpq+19*%%str], 1
2532     mova    [tmpq+ 3*%%str], m6
2533     mova    [tmpq+ 7*%%str], m0
2534     mova    [tmpq+11*%%str], m5
2535     mova    [tmpq+15*%%str], m4
2536     mova    [tmpq+23*%%str], m7
2537     mova    [tmpq+27*%%str], m2
2538     mova    [tmpq+31*%%str], m3
2539
2540     mova                 m1, [tmpq+ 6*%%str] ; t14
2541     mova                 m0, [tmpq+ 2*%%str] ; t15
2542     mova                 m7, [tmpq+21*%%str] ; t16
2543     mova                 m6, [tmpq+29*%%str] ; t17
2544     SUMSUB_BA             w,  7,  0,  2
2545     SUMSUB_BA             w,  6,  1,  2
2546     mova    [tmpq+29*%%str], m7
2547     mova    [tmpq+ 2*%%str], m0
2548     mova    [tmpq+21*%%str], m6
2549     mova    [tmpq+ 6*%%str], m1
2550
2551     mova                 m1, [tmpq+14*%%str] ; t12
2552     mova                 m0, [tmpq+10*%%str] ; t13
2553     mova                 m5, [tmpq+ 9*%%str] ; t18
2554     mova                 m4, [tmpq+13*%%str] ; t19
2555     SUMSUB_BA             w,  5,  0,  2
2556     SUMSUB_BA             w,  4,  1,  2
2557     mova     [tmpq+10*%%str], m0
2558     mova     [tmpq+14*%%str], m1
2559
2560     mova                 m1, [tmpq+22*%%str] ; t10
2561     mova                 m0, [tmpq+18*%%str] ; t11
2562     mova                 m3, [tmpq+17*%%str] ; t20
2563     mova                 m2, [tmpq+ 1*%%str] ; t21
2564     SUMSUB_BA             w,  3,  0,  6
2565     SUMSUB_BA             w,  2,  1,  6
2566     mova     [tmpq+18*%%str], m0
2567     mova     [tmpq+22*%%str], m1
2568
2569     mova                 m7, [tmpq+30*%%str] ; t8
2570     mova                 m6, [tmpq+26*%%str] ; t9
2571     mova                 m1, [tmpq+25*%%str] ; t22
2572     mova                 m0, [tmpq+ 5*%%str] ; t23
2573     SUMSUB_BADC           w,  1,  6,  0,  7
2574     mova     [tmpq+26*%%str], m6
2575     mova     [tmpq+30*%%str], m7
2576
2577     mova                 m7, [tmpq+29*%%str]
2578     TRANSPOSE8x8W         0, 1, 2, 3, 4, 5, 6, 7, [tmpq+21*%%str], [tmpq+17*%%str], 1
2579     mova    [tmpq+ 1*%%str], m0
2580     mova    [tmpq+ 5*%%str], m1
2581     mova    [tmpq+ 9*%%str], m2
2582     mova    [tmpq+13*%%str], m3
2583     mova    [tmpq+21*%%str], m5
2584     mova    [tmpq+25*%%str], m6
2585     mova    [tmpq+29*%%str], m7
2586
2587     mova                 m0, [tmpq+ 2*%%str]
2588     mova                 m1, [tmpq+ 6*%%str]
2589     mova                 m2, [tmpq+10*%%str]
2590     mova                 m3, [tmpq+14*%%str]
2591     mova                 m4, [tmpq+18*%%str]
2592     mova                 m5, [tmpq+22*%%str]
2593     mova                 m7, [tmpq+30*%%str]
2594     TRANSPOSE8x8W         0, 1, 2, 3, 4, 5, 6, 7, [tmpq+26*%%str], [tmpq+18*%%str], 1
2595     mova    [tmpq+ 2*%%str], m0
2596     mova    [tmpq+ 6*%%str], m1
2597     mova    [tmpq+10*%%str], m2
2598     mova    [tmpq+14*%%str], m3
2599     mova    [tmpq+22*%%str], m5
2600     mova    [tmpq+26*%%str], m6
2601     mova    [tmpq+30*%%str], m7
2602 %endif
2603 %else
2604     ; t0-7 is in [tmpq+{0,4,8,12,16,20,24,28}*%%str]
2605     ; t8-15 is in [tmpq+{2,6,10,14,18,22,26,30}*%%str]
2606     ; t16-19 and t23 is in [tmpq+{1,5,9,13,29}*%%str]
2607     ; t20-22 is in m4-6
2608     ; t24-31 is in m8-15
2609
2610 %if cpuflag(ssse3)
2611 %define ROUND_REG [pw_512]
2612 %else
2613 %define ROUND_REG [pw_32]
2614 %endif
2615
2616 %macro %%STORE_2X2 7-8 1 ; src[1-4], tmp[1-2], zero, inc_dst_ptrs
2617     SUMSUB_BA            w, %4, %1, %5
2618     SUMSUB_BA            w, %3, %2, %5
2619     VP9_IDCT8_WRITEx2   %4, %3, %5, %6, %7, ROUND_REG, 6
2620 %if %8 == 1
2621     add               dstq, stride2q
2622 %endif
2623     VP9_IDCT8_WRITEx2   %2, %1, %5, %6, %7, ROUND_REG, 6, dst_endq
2624 %if %8 == 1
2625     sub           dst_endq, stride2q
2626 %endif
2627 %endmacro
2628
2629 %if ARCH_X86_64
2630     pxor               m10, m10
2631
2632     ; store t0-1 and t30-31
2633     mova                m8, [tmpq+ 0*%%str]
2634     mova                m9, [tmpq+ 4*%%str]
2635     %%STORE_2X2          8,  9,  0,  6, 12, 11, 10
2636
2637     ; store t2-3 and t28-29
2638     mova                m8, [tmpq+ 8*%%str]
2639     mova                m9, [tmpq+12*%%str]
2640     %%STORE_2X2          8,  9, 14, 15, 12, 11, 10
2641
2642     ; store t4-5 and t26-27
2643     mova                m8, [tmpq+16*%%str]
2644     mova                m9, [tmpq+20*%%str]
2645     %%STORE_2X2          8,  9,  7,  1, 12, 11, 10
2646
2647     ; store t6-7 and t24-25
2648     mova                m8, [tmpq+24*%%str]
2649     mova                m9, [tmpq+28*%%str]
2650     %%STORE_2X2          8,  9,  4,  5, 12, 11, 10
2651
2652     ; store t8-9 and t22-23
2653     mova                m8, [tmpq+30*%%str]
2654     mova                m9, [tmpq+26*%%str]
2655     mova                m0, [tmpq+ 5*%%str]
2656     %%STORE_2X2          8,  9, 13,  0, 12, 11, 10
2657
2658     ; store t10-11 and t20-21
2659     mova                m8, [tmpq+22*%%str]
2660     mova                m9, [tmpq+18*%%str]
2661     %%STORE_2X2          8,  9,  2,  3, 12, 11, 10
2662
2663     ; store t12-13 and t18-19
2664     mova                m8, [tmpq+14*%%str]
2665     mova                m9, [tmpq+10*%%str]
2666     mova                m5, [tmpq+13*%%str]
2667     mova                m4, [tmpq+ 9*%%str]
2668     %%STORE_2X2          8,  9,  4,  5, 12, 11, 10
2669
2670     ; store t14-17
2671     mova                m8, [tmpq+ 6*%%str]
2672     mova                m9, [tmpq+ 2*%%str]
2673     mova                m5, [tmpq+29*%%str]
2674     mova                m4, [tmpq+21*%%str]
2675     %%STORE_2X2          8,  9,  4,  5, 12, 11, 10, 0
2676
2677     SWAP                 1, 10 ; zero
2678 %else
2679     mova   [tmpq+ 1*%%str], m1
2680     mova   [tmpq+11*%%str], m2
2681     mova   [tmpq+15*%%str], m3
2682     mova   [tmpq+17*%%str], m4
2683     mova   [tmpq+19*%%str], m5
2684     pxor                m1, m1
2685
2686     ; store t0-1 and t30-31
2687     mova                m2, [tmpq+ 0*%%str]
2688     mova                m3, [tmpq+ 4*%%str]
2689     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2690
2691     ; store t2-3 and t28-29
2692     mova                m2, [tmpq+ 8*%%str]
2693     mova                m3, [tmpq+12*%%str]
2694     mova                m0, [tmpq+ 3*%%str]
2695     mova                m6, [tmpq+ 7*%%str]
2696     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2697
2698     ; store t4-5 and t26-27
2699     mova                m2, [tmpq+16*%%str]
2700     mova                m3, [tmpq+20*%%str]
2701     mova                m0, [tmpq+ 1*%%str]
2702     %%STORE_2X2          2,  3,  7,  0, 4, 5, 1
2703
2704     ; store t6-7 and t24-25
2705     mova                m2, [tmpq+24*%%str]
2706     mova                m3, [tmpq+28*%%str]
2707     mova                m0, [tmpq+17*%%str]
2708     mova                m6, [tmpq+19*%%str]
2709     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2710
2711     ; store t8-9 and t22-23
2712     mova                m2, [tmpq+30*%%str]
2713     mova                m3, [tmpq+26*%%str]
2714     mova                m0, [tmpq+25*%%str]
2715     mova                m6, [tmpq+ 5*%%str]
2716     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2717
2718     ; store t10-11 and t20-21
2719     mova                m2, [tmpq+22*%%str]
2720     mova                m3, [tmpq+18*%%str]
2721     mova                m0, [tmpq+11*%%str]
2722     mova                m6, [tmpq+15*%%str]
2723     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2724
2725     ; store t12-13 and t18-19
2726     mova                m2, [tmpq+14*%%str]
2727     mova                m3, [tmpq+10*%%str]
2728     mova                m6, [tmpq+13*%%str]
2729     mova                m0, [tmpq+ 9*%%str]
2730     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2731
2732     ; store t14-17
2733     mova                m2, [tmpq+ 6*%%str]
2734     mova                m3, [tmpq+ 2*%%str]
2735     mova                m6, [tmpq+29*%%str]
2736     mova                m0, [tmpq+21*%%str]
2737     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1, 0
2738 %endif
2739 %undef ROUND_REG
2740 %endif
2741 %endmacro
2742
2743 %macro VP9_IDCT_IDCT_32x32_ADD_XMM 1
2744 INIT_XMM %1
2745 cglobal vp9_idct_idct_32x32_add, 0, 6 + ARCH_X86_64 * 3, 16, 2048, dst, stride, block, eob
2746     movifnidn         eobd, dword eobm
2747 %if cpuflag(ssse3)
2748     cmp eobd, 135
2749     jg .idctfull
2750     cmp eobd, 34
2751     jg .idct16x16
2752     cmp eobd, 1
2753     jg .idct8x8
2754 %else
2755     cmp eobd, 1
2756     jg .idctfull
2757 %endif
2758
2759     ; dc-only case
2760     movifnidn       blockq, blockmp
2761     movifnidn         dstq, dstmp
2762     movifnidn      strideq, stridemp
2763 %if cpuflag(ssse3)
2764     movd                m0, [blockq]
2765     mova                m1, [pw_11585x2]
2766     pmulhrsw            m0, m1
2767     pmulhrsw            m0, m1
2768 %else
2769     DEFINE_ARGS dst, stride, block, coef
2770     movsx            coefd, word [blockq]
2771     imul             coefd, 11585
2772     add              coefd, 8192
2773     sar              coefd, 14
2774     imul             coefd, 11585
2775     add              coefd, (32 << 14) + 8192
2776     sar              coefd, 14 + 6
2777     movd                m0, coefd
2778 %endif
2779     SPLATW              m0, m0, q0000
2780 %if cpuflag(ssse3)
2781     pmulhrsw            m0, [pw_512]
2782 %endif
2783     pxor                m5, m5
2784     movd          [blockq], m5
2785 %rep 31
2786     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5, mmsize
2787     add               dstq, strideq
2788 %endrep
2789     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5, mmsize
2790     RET
2791
2792 %if ARCH_X86_64
2793     DEFINE_ARGS dst_bak, stride, block, cnt, dst, stride30, dst_end, stride2, tmp
2794 %else
2795 %define dst_bakq r0mp
2796 %endif
2797 %if cpuflag(ssse3)
2798 .idct8x8:
2799 %if ARCH_X86_32
2800     DEFINE_ARGS block, u1, u2, u3, u4, tmp
2801     mov             blockq, r2mp
2802 %endif
2803     mov               tmpq, rsp
2804     VP9_IDCT32_1D   blockq, 1, 8
2805
2806 %if ARCH_X86_32
2807     DEFINE_ARGS dst, stride, stride30, dst_end, stride2, tmp
2808     mov            strideq, r1mp
2809 %define cntd dword r3m
2810 %endif
2811     mov          stride30q, strideq         ; stride
2812     lea           stride2q, [strideq*2]     ; stride*2
2813     shl          stride30q, 5               ; stride*32
2814     mov               cntd, 4
2815     sub          stride30q, stride2q        ; stride*30
2816 .loop2_8x8:
2817     mov               dstq, dst_bakq
2818     lea           dst_endq, [dstq+stride30q]
2819     VP9_IDCT32_1D     tmpq, 2, 8
2820     add           dst_bakq, 8
2821     add               tmpq, 16
2822     dec               cntd
2823     jg .loop2_8x8
2824
2825     ; at the end of the loop, m7 should still be zero
2826     ; use that to zero out block coefficients
2827 %if ARCH_X86_32
2828     DEFINE_ARGS block
2829     mov             blockq, r2mp
2830 %endif
2831     ZERO_BLOCK      blockq, 64,  8, m1
2832     RET
2833
2834 .idct16x16:
2835 %if ARCH_X86_32
2836     DEFINE_ARGS block, tmp, cnt
2837     mov             blockq, r2mp
2838 %endif
2839     mov               cntd, 2
2840     mov               tmpq, rsp
2841 .loop1_16x16:
2842     VP9_IDCT32_1D   blockq, 1, 16
2843     add             blockq, 16
2844     add               tmpq, 512
2845     dec               cntd
2846     jg .loop1_16x16
2847
2848 %if ARCH_X86_64
2849     sub             blockq, 32
2850 %else
2851     DEFINE_ARGS dst, stride, stride30, dst_end, stride2, tmp
2852     mov            strideq, r1mp
2853 %define cntd dword r3m
2854 %endif
2855
2856     mov          stride30q, strideq         ; stride
2857     lea           stride2q, [strideq*2]     ; stride*2
2858     shl          stride30q, 5               ; stride*32
2859     mov               cntd, 4
2860     mov               tmpq, rsp
2861     sub          stride30q, stride2q        ; stride*30
2862 .loop2_16x16:
2863     mov               dstq, dst_bakq
2864     lea           dst_endq, [dstq+stride30q]
2865     VP9_IDCT32_1D     tmpq, 2, 16
2866     add           dst_bakq, 8
2867     add               tmpq, 16
2868     dec               cntd
2869     jg .loop2_16x16
2870
2871     ; at the end of the loop, m7 should still be zero
2872     ; use that to zero out block coefficients
2873 %if ARCH_X86_32
2874     DEFINE_ARGS block
2875     mov             blockq, r2mp
2876 %endif
2877     ZERO_BLOCK      blockq, 64, 16, m1
2878     RET
2879 %endif
2880
2881 .idctfull:
2882 %if ARCH_X86_32
2883     DEFINE_ARGS block, tmp, cnt
2884     mov             blockq, r2mp
2885 %endif
2886     mov               cntd, 4
2887     mov               tmpq, rsp
2888 .loop1_full:
2889     VP9_IDCT32_1D   blockq, 1
2890     add             blockq, 16
2891     add               tmpq, 512
2892     dec               cntd
2893     jg .loop1_full
2894
2895 %if ARCH_X86_64
2896     sub             blockq, 64
2897 %else
2898     DEFINE_ARGS dst, stride, stride30, dst_end, stride2, tmp
2899     mov            strideq, r1mp
2900 %define cntd dword r3m
2901 %endif
2902
2903     mov          stride30q, strideq         ; stride
2904     lea           stride2q, [strideq*2]     ; stride*2
2905     shl          stride30q, 5               ; stride*32
2906     mov               cntd, 4
2907     mov               tmpq, rsp
2908     sub          stride30q, stride2q        ; stride*30
2909 .loop2_full:
2910     mov               dstq, dst_bakq
2911     lea           dst_endq, [dstq+stride30q]
2912     VP9_IDCT32_1D     tmpq, 2
2913     add           dst_bakq, 8
2914     add               tmpq, 16
2915     dec               cntd
2916     jg .loop2_full
2917
2918     ; at the end of the loop, m7 should still be zero
2919     ; use that to zero out block coefficients
2920 %if ARCH_X86_32
2921     DEFINE_ARGS block
2922     mov             blockq, r2mp
2923 %endif
2924     ZERO_BLOCK      blockq, 64, 32, m1
2925     RET
2926 %endmacro
2927
2928 VP9_IDCT_IDCT_32x32_ADD_XMM sse2
2929 VP9_IDCT_IDCT_32x32_ADD_XMM ssse3
2930 VP9_IDCT_IDCT_32x32_ADD_XMM avx
2931
2932 ; this is almost identical to VP9_STORE_2X, but it does two rows
2933 ; for slightly improved interleaving, and it omits vpermq since the
2934 ; input is DC so all values are identical
2935 %macro VP9_STORE_YMM_DC_2X2 6 ; reg, tmp1, tmp2, tmp3, tmp4, zero
2936     mova               m%2, [dstq]
2937     mova               m%4, [dstq+strideq]
2938     punpckhbw          m%3, m%2, m%6
2939     punpcklbw          m%2, m%6
2940     punpckhbw          m%5, m%4, m%6
2941     punpcklbw          m%4, m%6
2942     paddw              m%3, m%1
2943     paddw              m%2, m%1
2944     paddw              m%5, m%1
2945     paddw              m%4, m%1
2946     packuswb           m%2, m%3
2947     packuswb           m%4, m%5
2948     mova  [dstq+strideq*0], m%2
2949     mova  [dstq+strideq*1], m%4
2950 %endmacro
2951
2952 %if ARCH_X86_64 && HAVE_AVX2_EXTERNAL
2953 INIT_YMM avx2
2954 cglobal vp9_idct_idct_32x32_add, 4, 9, 16, 2048, dst, stride, block, eob
2955     cmp eobd, 135
2956     jg .idctfull
2957     cmp eobd, 1
2958     jg .idct16x16
2959
2960     ; dc-only case
2961     mova                m1, [pw_11585x2]
2962     vpbroadcastw        m0, [blockq]
2963     pmulhrsw            m0, m1
2964     pmulhrsw            m0, m1
2965     pxor                m5, m5
2966     pmulhrsw            m0, [pw_512]
2967     movd          [blockq], xm5
2968
2969     DEFINE_ARGS dst, stride, cnt
2970     mov               cntd, 16
2971 .loop_dc:
2972     VP9_STORE_YMM_DC_2X2 0, 1, 2, 3, 4, 5
2973     lea               dstq, [dstq+2*strideq]
2974     dec               cntd
2975     jg .loop_dc
2976     RET
2977
2978     DEFINE_ARGS dst_bak, stride, block, cnt, dst, stride30, dst_end, stride2, tmp
2979 .idct16x16:
2980     mov               tmpq, rsp
2981     VP9_IDCT32_1D   blockq, 1, 16
2982
2983     mov          stride30q, strideq         ; stride
2984     lea           stride2q, [strideq*2]     ; stride*2
2985     shl          stride30q, 5               ; stride*32
2986     mov               cntd, 2
2987     sub          stride30q, stride2q        ; stride*30
2988 .loop2_16x16:
2989     mov               dstq, dst_bakq
2990     lea           dst_endq, [dstq+stride30q]
2991     VP9_IDCT32_1D     tmpq, 2, 16
2992     add           dst_bakq, 16
2993     add               tmpq, 32
2994     dec               cntd
2995     jg .loop2_16x16
2996
2997     ; at the end of the loop, m1 should still be zero
2998     ; use that to zero out block coefficients
2999     ZERO_BLOCK      blockq, 64, 16, m1
3000     RET
3001
3002 .idctfull:
3003     mov               cntd, 2
3004     mov               tmpq, rsp
3005 .loop1_full:
3006     VP9_IDCT32_1D   blockq, 1
3007     add             blockq, 32
3008     add               tmpq, 1024
3009     dec               cntd
3010     jg .loop1_full
3011
3012     sub             blockq, 64
3013
3014     mov          stride30q, strideq         ; stride
3015     lea           stride2q, [strideq*2]     ; stride*2
3016     shl          stride30q, 5               ; stride*32
3017     mov               cntd, 2
3018     mov               tmpq, rsp
3019     sub          stride30q, stride2q        ; stride*30
3020 .loop2_full:
3021     mov               dstq, dst_bakq
3022     lea           dst_endq, [dstq+stride30q]
3023     VP9_IDCT32_1D     tmpq, 2
3024     add           dst_bakq, 16
3025     add               tmpq, 32
3026     dec               cntd
3027     jg .loop2_full
3028
3029     ; at the end of the loop, m1 should still be zero
3030     ; use that to zero out block coefficients
3031     ZERO_BLOCK      blockq, 64, 32, m1
3032     RET
3033 %endif