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