]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/vp9itxfm.asm
Merge commit '27852f2f1dec3749ea79883b70484c841169f747'
[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 %if cpuflag(ssse3)
872     SUMSUB_BA                w,  3,  4,  2
873     SUMSUB_BA                w,  0,  7,  2
874     pmulhrsw                m3, W_11585x2_REG
875     pmulhrsw                m7, W_11585x2_REG
876     pmulhrsw                m4, W_11585x2_REG               ; out4
877     pmulhrsw                m0, W_11585x2_REG               ; out2
878 %else
879     SCRATCH                  5,  9, blockq+16*1
880     VP9_UNPACK_MULSUB_2W_4X  4, 3, 11585, 11585, D_8192_REG, 2, 5
881     VP9_UNPACK_MULSUB_2W_4X  7, 0, 11585, 11585, D_8192_REG, 2, 5
882     UNSCRATCH                5,  9, blockq+16*1
883 %endif
884     PSIGNW                  m3, W_M1_REG                    ; out3
885     PSIGNW                  m7, W_M1_REG                    ; out5
886
887     ; m6=out0, m5=out1, m0=out2, m3=out3, m4=out4, m7=out5, m2=out6, m1=out7
888
889 %if ARCH_X86_64
890     SWAP                     2, 8
891 %endif
892     SWAP                     0, 6, 2
893     SWAP                     7, 1, 5
894 %endmacro
895
896 %macro IADST8_FN 6
897 INIT_XMM %5
898 cglobal vp9_%1_%3_8x8_add, 3, 3, %6, dst, stride, block, eob
899
900 %ifidn %1, idct
901 %define first_is_idct 1
902 %else
903 %define first_is_idct 0
904 %endif
905
906 %ifidn %3, idct
907 %define second_is_idct 1
908 %else
909 %define second_is_idct 0
910 %endif
911
912 %if ARCH_X86_64
913     mova                m0, [blockq+  0]    ; IN(0)
914 %endif
915     mova                m1, [blockq+ 16]    ; IN(1)
916     mova                m2, [blockq+ 32]    ; IN(2)
917 %if ARCH_X86_64 || first_is_idct
918     mova                m3, [blockq+ 48]    ; IN(3)
919 %endif
920 %if ARCH_X86_64
921     mova                m4, [blockq+ 64]    ; IN(4)
922 %endif
923     mova                m5, [blockq+ 80]    ; IN(5)
924     mova                m6, [blockq+ 96]    ; IN(6)
925 %if ARCH_X86_64 || first_is_idct
926     mova                m7, [blockq+112]    ; IN(7)
927 %endif
928 %if ARCH_X86_64
929 %if cpuflag(ssse3)
930     mova               m15, [pw_11585x2]    ; often used
931 %endif
932     mova               m13, [pd_8192]       ; rounding
933     mova               m14, [pw_m1]
934 %define W_11585x2_REG m15
935 %define D_8192_REG m13
936 %define W_M1_REG m14
937 %else
938 %define W_11585x2_REG [pw_11585x2]
939 %define D_8192_REG [pd_8192]
940 %define W_M1_REG [pw_m1]
941 %endif
942
943     ; note different calling conventions for idct8 vs. iadst8 on x86-32
944     VP9_%2_1D
945 %if ARCH_X86_64
946     TRANSPOSE8x8W  0, 1, 2, 3, 4, 5, 6, 7, 8
947 %else
948     TRANSPOSE8x8W  0, 1, 2, 3, 4, 5, 6, 7, [blockq+0], [blockq+64], 1
949     mova      [blockq+  0], m0
950 %if second_is_idct == 0
951     mova      [blockq+ 48], m3
952     mova      [blockq+112], m7
953 %endif
954 %endif
955     VP9_%4_1D
956
957 %if ARCH_X86_64
958     SWAP                 6, 8
959 %endif
960     pxor                m6, m6  ; used for the block reset, and VP9_STORE_2X
961     VP9_IDCT8_WRITEOUT
962     ZERO_BLOCK      blockq, 16, 8, m6
963     RET
964
965 %undef W_11585x2_REG
966 %undef first_is_idct
967 %undef second_is_idct
968
969 %endmacro
970
971 %define PSIGNW PSIGNW_MMX
972 IADST8_FN idct,  IDCT8,  iadst, IADST8, sse2, 15
973 IADST8_FN iadst, IADST8, idct,  IDCT8,  sse2, 15
974 IADST8_FN iadst, IADST8, iadst, IADST8, sse2, 15
975 %define PSIGNW PSIGNW_SSSE3
976 IADST8_FN idct,  IDCT8,  iadst, IADST8, ssse3, 16
977 IADST8_FN idct,  IDCT8,  iadst, IADST8, avx, 16
978 IADST8_FN iadst, IADST8, idct,  IDCT8,  ssse3, 16
979 IADST8_FN iadst, IADST8, idct,  IDCT8,  avx, 16
980 IADST8_FN iadst, IADST8, iadst, IADST8, ssse3, 16
981 IADST8_FN iadst, IADST8, iadst, IADST8, avx, 16
982 %undef PSIGNW
983
984 ;---------------------------------------------------------------------------------------------
985 ; void vp9_idct_idct_16x16_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
986 ;---------------------------------------------------------------------------------------------
987
988 ; x86-64:
989 ; at the end of this macro, m7 is stored in [%4+15*%5]
990 ; everything else (t0-6 and t8-15) is stored in m0-6 and m8-15
991 ; the following sumsubs have not been done yet:
992 ;    SUMSUB_BA            w,  6,  9, 15      ; t6, t9
993 ;    SUMSUB_BA            w,  7,  8, 15      ; t7, t8
994 ; or (x86-32) t0-t5 are in m0-m5, t10-t15 are in x11/9/7/5/3/1,
995 ; and the following simsubs have not been done yet:
996 ;    SUMSUB_BA            w, x13, x14, 7       ; t6, t9
997 ;    SUMSUB_BA            w, x15, x12, 7       ; t7, t8
998
999 %macro VP9_IDCT16_1D_START 5 ; src, nnzc, stride, scratch, scratch_stride
1000 %if %2 <= 4
1001     mova                m3, [%1+ 1*%3]      ; IN(1)
1002     mova                m0, [%1+ 3*%3]      ; IN(3)
1003
1004     pmulhrsw            m4, m3,  [pw_16305x2]       ; t14-15
1005     pmulhrsw            m3, [pw_1606x2]             ; t8-9
1006     pmulhrsw            m7, m0,  [pw_m4756x2]       ; t10-11
1007     pmulhrsw            m0, [pw_15679x2]            ; t12-13
1008
1009     ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m14=t5, m13=t6, m15=t7
1010     ; m3=t8, m5=t9, m1=t10, m7=t11, m0=t12, m6=t13, m2=t14, m4=t15
1011
1012     VP9_UNPACK_MULSUB_2W_4X 2, 5, 4, 3, 15137,  6270, [pd_8192], 1, 6 ; t9,  t14
1013     SCRATCH              4, 10, %4+ 1*%5
1014     SCRATCH              5, 11, %4+ 7*%5
1015     VP9_UNPACK_MULSUB_2W_4X 6, 1, 0, 7, 6270, m15137, [pd_8192], 4, 5 ; t10, t13
1016     UNSCRATCH            5, 11, %4+ 7*%5
1017
1018     ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7
1019     ; m7=t8, m6=t9, m2=t10, m3=t11, m4=t12, m5=t13, m1=t14, m0=t15
1020 %else
1021     mova                m5, [%1+ 1*%3]      ; IN(1)
1022     mova                m4, [%1+ 7*%3]      ; IN(7)
1023 %if %2 <= 8
1024     pmulhrsw            m2, m5,  [pw_16305x2]       ; t15
1025     pmulhrsw            m5, [pw_1606x2]             ; t8
1026     pmulhrsw            m3, m4,  [pw_m10394x2]      ; t9
1027     pmulhrsw            m4, [pw_12665x2]            ; t14
1028 %else
1029     mova                m3, [%1+ 9*%3]      ; IN(9)
1030     mova                m2, [%1+15*%3]      ; IN(15)
1031
1032     ; m10=in0, m5=in1, m14=in2, m6=in3, m9=in4, m7=in5, m15=in6, m4=in7
1033     ; m11=in8, m3=in9, m12=in10 m0=in11, m8=in12, m1=in13, m13=in14, m2=in15
1034
1035     VP9_UNPACK_MULSUB_2W_4X   5,   2, 16305,  1606, [pd_8192], 0, 1 ; t8,  t15
1036     VP9_UNPACK_MULSUB_2W_4X   3,   4, 10394, 12665, [pd_8192], 0, 1 ; t9,  t14
1037 %endif
1038
1039     SUMSUB_BA            w,  3,  5, 0       ; t8,  t9
1040     SUMSUB_BA            w,  4,  2, 0       ; t15, t14
1041
1042     VP9_UNPACK_MULSUB_2W_4X   2,   5, 15137,  6270, [pd_8192], 0, 1 ; t9,  t14
1043
1044     SCRATCH              4, 10, %4+ 1*%5
1045     SCRATCH              5, 11, %4+ 7*%5
1046
1047     mova                m6, [%1+ 3*%3]      ; IN(3)
1048     mova                m7, [%1+ 5*%3]      ; IN(5)
1049 %if %2 <= 8
1050     pmulhrsw            m0, m7,  [pw_14449x2]       ; t13
1051     pmulhrsw            m7, [pw_7723x2]             ; t10
1052     pmulhrsw            m1, m6,  [pw_m4756x2]       ; t11
1053     pmulhrsw            m6, [pw_15679x2]            ; t12
1054 %else
1055     mova                m0, [%1+11*%3]      ; IN(11)
1056     mova                m1, [%1+13*%3]      ; IN(13)
1057
1058     VP9_UNPACK_MULSUB_2W_4X   7,   0, 14449,  7723, [pd_8192], 4, 5 ; t10, t13
1059     VP9_UNPACK_MULSUB_2W_4X   1,   6,  4756, 15679, [pd_8192], 4, 5 ; t11, t12
1060 %endif
1061
1062     ; m11=t0, m10=t1, m9=t2, m8=t3, m14=t4, m12=t5, m15=t6, m13=t7
1063     ; m5=t8, m3=t9, m7=t10, m1=t11, m6=t12, m0=t13, m4=t14, m2=t15
1064
1065     SUMSUB_BA            w,  7,  1, 4       ; t11, t10
1066     SUMSUB_BA            w,  0,  6, 4       ; t12, t13
1067
1068     ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m14=t5, m13=t6, m15=t7
1069     ; m3=t8, m5=t9, m1=t10, m7=t11, m0=t12, m6=t13, m2=t14, m4=t15
1070
1071     VP9_UNPACK_MULSUB_2W_4X   6,   1, 6270, m15137, [pd_8192], 4, 5 ; t10, t13
1072
1073     UNSCRATCH            5, 11, %4+ 7*%5
1074 %endif
1075
1076     ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m13=t5, m14=t6, m15=t7
1077     ; m3=t8, m2=t9, m6=t10, m7=t11, m0=t12, m1=t13, m5=t14, m4=t15
1078
1079     SUMSUB_BA            w,  7,  3, 4       ; t8,  t11
1080
1081     ; backup first register
1082     mova        [%4+15*%5], m7
1083
1084     SUMSUB_BA            w,  6,  2, 7       ; t9,  t10
1085     UNSCRATCH            4, 10, %4+ 1*%5
1086     SUMSUB_BA            w,  0,  4, 7       ; t15, t12
1087     SUMSUB_BA            w,  1,  5, 7       ; t14. t13
1088
1089     ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7
1090     ; m7=t8, m6=t9, m2=t10, m3=t11, m4=t12, m5=t13, m1=t14, m0=t15
1091
1092 %if cpuflag(ssse3)
1093     SUMSUB_BA            w,  2,  5, 7
1094     SUMSUB_BA            w,  3,  4, 7
1095     pmulhrsw            m5, [pw_11585x2]    ; t10
1096     pmulhrsw            m4, [pw_11585x2]    ; t11
1097     pmulhrsw            m3, [pw_11585x2]    ; t12
1098     pmulhrsw            m2, [pw_11585x2]    ; t13
1099 %else
1100     SCRATCH              6, 10, %4+ 1*%5
1101     VP9_UNPACK_MULSUB_2W_4X   5,   2, 11585, 11585, [pd_8192], 6, 7 ; t10, t13
1102     VP9_UNPACK_MULSUB_2W_4X   4,   3, 11585, 11585, [pd_8192], 6, 7 ; t11, t12
1103     UNSCRATCH            6, 10, %4+ 1*%5
1104 %endif
1105
1106     ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7
1107     ; m7=t8, m6=t9, m5=t10, m4=t11, m3=t12, m2=t13, m1=t14, m0=t15
1108
1109     SCRATCH              0,  8, %4+ 1*%5
1110     SCRATCH              1,  9, %4+ 3*%5
1111     SCRATCH              2, 10, %4+ 5*%5
1112     SCRATCH              3, 11, %4+ 7*%5
1113     SCRATCH              4, 12, %4+ 9*%5
1114     SCRATCH              5, 13, %4+11*%5
1115     SCRATCH              6, 14, %4+13*%5
1116
1117     ; even (tx8x8)
1118 %if %2 <= 4
1119     mova                m3, [%1+ 0*%3]      ; IN(0)
1120     mova                m4, [%1+ 2*%3]      ; IN(2)
1121
1122     pmulhrsw            m3, [pw_11585x2]    ; t0-t3
1123     pmulhrsw            m7, m4, [pw_16069x2]        ; t6-7
1124     pmulhrsw            m4, [pw_3196x2]             ; t4-5
1125
1126     paddw               m6, m7, m4
1127     psubw               m5, m7, m4
1128     pmulhrsw            m5, [pw_11585x2]            ; t5
1129     pmulhrsw            m6, [pw_11585x2]            ; t6
1130
1131     psubw               m0, m3, m7
1132     paddw               m7, m3
1133     psubw               m1, m3, m6
1134     paddw               m6, m3
1135     psubw               m2, m3, m5
1136     paddw               m5, m3
1137
1138 %if ARCH_X86_32
1139     SWAP                 0, 7
1140 %endif
1141     SCRATCH              7, 15, %4+12*%5
1142 %else
1143     mova                m6, [%1+ 2*%3]      ; IN(2)
1144     mova                m1, [%1+ 4*%3]      ; IN(4)
1145     mova                m7, [%1+ 6*%3]      ; IN(6)
1146 %if %2 <= 8
1147     pmulhrsw            m0, m1,  [pw_15137x2]       ; t3
1148     pmulhrsw            m1, [pw_6270x2]             ; t2
1149     pmulhrsw            m5, m6, [pw_16069x2]        ; t7
1150     pmulhrsw            m6, [pw_3196x2]             ; t4
1151     pmulhrsw            m4, m7, [pw_m9102x2]        ; t5
1152     pmulhrsw            m7, [pw_13623x2]            ; t6
1153 %else
1154     mova                m4, [%1+10*%3]      ; IN(10)
1155     mova                m0, [%1+12*%3]      ; IN(12)
1156     mova                m5, [%1+14*%3]      ; IN(14)
1157
1158     VP9_UNPACK_MULSUB_2W_4X   1,   0, 15137,  6270, [pd_8192], 2, 3 ; t2,  t3
1159     VP9_UNPACK_MULSUB_2W_4X   6,   5, 16069,  3196, [pd_8192], 2, 3 ; t4,  t7
1160     VP9_UNPACK_MULSUB_2W_4X   4,   7,  9102, 13623, [pd_8192], 2, 3 ; t5,  t6
1161 %endif
1162
1163     SUMSUB_BA            w,  4,  6, 2       ; t4,  t5
1164     SUMSUB_BA            w,  7,  5, 2       ; t7,  t6
1165
1166 %if cpuflag(ssse3)
1167     SUMSUB_BA            w,  6,  5, 2
1168     pmulhrsw            m5, [pw_11585x2]                              ; t5
1169     pmulhrsw            m6, [pw_11585x2]                              ; t6
1170 %else
1171     VP9_UNPACK_MULSUB_2W_4X  5,  6, 11585, 11585, [pd_8192], 2, 3 ; t5,  t6
1172 %endif
1173
1174     SCRATCH              5, 15, %4+10*%5
1175     mova                m2, [%1+ 0*%3]      ; IN(0)
1176 %if %2 <= 8
1177     pmulhrsw            m2, [pw_11585x2]    ; t0 and t1
1178     psubw               m3, m2, m0
1179     paddw               m0, m2
1180
1181     SUMSUB_BA            w,  7,  0, 5       ; t0,  t7
1182 %else
1183     mova                m3, [%1+ 8*%3]      ; IN(8)
1184
1185     ; from 3 stages back
1186 %if cpuflag(ssse3)
1187     SUMSUB_BA            w,  3,  2, 5
1188     pmulhrsw            m3, [pw_11585x2]    ; t0
1189     pmulhrsw            m2, [pw_11585x2]    ; t1
1190 %else
1191     mova        [%1+ 0*%3], m0
1192     VP9_UNPACK_MULSUB_2W_4X  2,  3, 11585,  11585, [pd_8192], 5, 0 ; t0, t1
1193     mova                m0, [%1+ 0*%3]
1194 %endif
1195
1196     ; from 2 stages back
1197     SUMSUB_BA            w,  0,  3, 5      ; t0,  t3
1198
1199     SUMSUB_BA            w,  7,  0, 5      ; t0,  t7
1200 %endif
1201     UNSCRATCH            5, 15, %4+10*%5
1202 %if ARCH_X86_32
1203     SWAP                 0, 7
1204 %endif
1205     SCRATCH              7, 15, %4+12*%5
1206     SUMSUB_BA            w,  1,  2, 7       ; t1,  t2
1207
1208     ; from 1 stage back
1209     SUMSUB_BA            w,  6,  1, 7       ; t1,  t6
1210     SUMSUB_BA            w,  5,  2, 7       ; t2,  t5
1211 %endif
1212     SUMSUB_BA            w,  4,  3, 7       ; t3,  t4
1213
1214 %if ARCH_X86_64
1215     SWAP                 0, 8
1216     SWAP                 1, 9
1217     SWAP                 2, 10
1218     SWAP                 3, 11
1219     SWAP                 4, 12
1220     SWAP                 5, 13
1221     SWAP                 6, 14
1222
1223     SUMSUB_BA            w,  0, 15, 7       ; t0, t15
1224     SUMSUB_BA            w,  1, 14, 7       ; t1, t14
1225     SUMSUB_BA            w,  2, 13, 7       ; t2, t13
1226     SUMSUB_BA            w,  3, 12, 7       ; t3, t12
1227     SUMSUB_BA            w,  4, 11, 7       ; t4, t11
1228     SUMSUB_BA            w,  5, 10, 7       ; t5, t10
1229 %else
1230     SWAP                 1, 6
1231     SWAP                 2, 5
1232     SWAP                 3, 4
1233     mova        [%4+14*%5], m6
1234
1235 %macro %%SUMSUB_BA_STORE 5 ; reg, from_mem, to_mem, scratch, scratch_stride
1236     mova                m6, [%4+%2*%5]
1237     SUMSUB_BA            w,  6, %1, 7
1238     SWAP                %1, 6
1239     mova        [%4+%3*%5], m6
1240 %endmacro
1241
1242     %%SUMSUB_BA_STORE    0,  1,  1, %4, %5  ; t0, t15
1243     %%SUMSUB_BA_STORE    1,  3,  3, %4, %5  ; t1, t14
1244     %%SUMSUB_BA_STORE    2,  5,  5, %4, %5  ; t2, t13
1245     %%SUMSUB_BA_STORE    3,  7,  7, %4, %5  ; t3, t12
1246     %%SUMSUB_BA_STORE    4,  9,  9, %4, %5  ; t4, t11
1247     %%SUMSUB_BA_STORE    5, 11, 11, %4, %5  ; t5, t10
1248 %endif
1249 %endmacro
1250
1251 %macro VP9_IDCT16_1D 2-3 16 ; src, pass, nnzc
1252 %if %2 == 1
1253     VP9_IDCT16_1D_START %1, %3, 32, tmpq, 16
1254
1255 %if ARCH_X86_64
1256     ; backup a different register
1257     mova                m7, [tmpq+15*16]
1258     mova      [tmpq+ 1*16], m15
1259
1260     SUMSUB_BA            w,  6,  9, 15      ; t6, t9
1261     SUMSUB_BA            w,  7,  8, 15      ; t7, t8
1262
1263     TRANSPOSE8x8W        0, 1, 2, 3, 4, 5, 6, 7, 15
1264     mova        [tmpq+  0], m0
1265     mova        [tmpq+ 32], m1
1266     mova        [tmpq+ 64], m2
1267     mova        [tmpq+ 96], m3
1268     mova        [tmpq+128], m4
1269     mova        [tmpq+160], m5
1270     mova        [tmpq+192], m6
1271     mova        [tmpq+224], m7
1272
1273     mova               m15, [tmpq+ 1*16]
1274     TRANSPOSE8x8W        8, 9, 10, 11, 12, 13, 14, 15, 0
1275     mova        [tmpq+ 16], m8
1276     mova        [tmpq+ 48], m9
1277     mova        [tmpq+ 80], m10
1278     mova        [tmpq+112], m11
1279     mova        [tmpq+144], m12
1280     mova        [tmpq+176], m13
1281     mova        [tmpq+208], m14
1282     mova        [tmpq+240], m15
1283 %else
1284     mova                m6, [tmpq+13*16]
1285     mova                m7, [tmpq+14*16]
1286     SUMSUB_BA            w, 6, 7                ; t6, t9
1287     mova      [tmpq+14*16], m6
1288     mova      [tmpq+13*16], m7
1289     mova                m7, [tmpq+15*16]
1290     mova                m6, [tmpq+12*16]
1291     SUMSUB_BA            w, 7, 6                ; t7, t8
1292     mova      [tmpq+15*16], m6
1293
1294     TRANSPOSE8x8W       0, 1, 2, 3, 4, 5, 6, 7, [tmpq+14*16], [tmpq+ 8*16], 1
1295     mova     [tmpq+ 0*16], m0
1296     mova     [tmpq+ 2*16], m1
1297     mova     [tmpq+ 4*16], m2
1298     mova     [tmpq+ 6*16], m3
1299     mova     [tmpq+10*16], m5
1300     mova     [tmpq+12*16], m6
1301     mova     [tmpq+14*16], m7
1302
1303     mova                m0, [tmpq+15*16]
1304     mova                m1, [tmpq+13*16]
1305     mova                m2, [tmpq+11*16]
1306     mova                m3, [tmpq+ 9*16]
1307     mova                m4, [tmpq+ 7*16]
1308     mova                m5, [tmpq+ 5*16]
1309     mova                m7, [tmpq+ 1*16]
1310     TRANSPOSE8x8W       0, 1, 2, 3, 4, 5, 6, 7, [tmpq+ 3*16], [tmpq+ 9*16], 1
1311     mova     [tmpq+ 1*16], m0
1312     mova     [tmpq+ 3*16], m1
1313     mova     [tmpq+ 5*16], m2
1314     mova     [tmpq+ 7*16], m3
1315     mova     [tmpq+11*16], m5
1316     mova     [tmpq+13*16], m6
1317     mova     [tmpq+15*16], m7
1318 %endif
1319 %else ; %2 == 2
1320     VP9_IDCT16_1D_START %1, %3, 32, %1, 32
1321
1322 %if cpuflag(ssse3)
1323 %define ROUND_REG [pw_512]
1324 %else
1325 %define ROUND_REG [pw_32]
1326 %endif
1327
1328     pxor                m7, m7
1329 %if ARCH_X86_64
1330     ; backup more registers
1331     mova        [%1+ 2*32], m8
1332     mova        [%1+ 3*32], m9
1333
1334     VP9_IDCT8_WRITEx2    0,  1, 8, 9, 7, ROUND_REG, 6
1335     lea               dstq, [dstq+strideq*2]
1336     VP9_IDCT8_WRITEx2    2,  3, 8, 9, 7, ROUND_REG, 6
1337     lea               dstq, [dstq+strideq*2]
1338     VP9_IDCT8_WRITEx2    4,  5, 8, 9, 7, ROUND_REG, 6
1339     lea               dstq, [dstq+strideq*2]
1340
1341     ; restore from cache
1342     SWAP                 0, 7               ; move zero from m7 to m0
1343     mova                m7, [%1+15*32]
1344     mova                m8, [%1+ 2*32]
1345     mova                m9, [%1+ 3*32]
1346
1347     SUMSUB_BA            w,  6,  9, 3       ; t6, t9
1348     SUMSUB_BA            w,  7,  8, 3       ; t7, t8
1349
1350     VP9_IDCT8_WRITEx2    6,  7, 3, 4, 0, ROUND_REG, 6
1351     lea               dstq, [dstq+strideq*2]
1352     VP9_IDCT8_WRITEx2    8,  9, 3, 4, 0, ROUND_REG, 6
1353     lea               dstq, [dstq+strideq*2]
1354     VP9_IDCT8_WRITEx2   10, 11, 1, 2, 0, ROUND_REG, 6
1355     lea               dstq, [dstq+strideq*2]
1356     VP9_IDCT8_WRITEx2   12, 13, 1, 2, 0, ROUND_REG, 6
1357     lea               dstq, [dstq+strideq*2]
1358     VP9_IDCT8_WRITEx2   14, 15, 1, 2, 0, ROUND_REG, 6
1359 %else
1360     mova      [tmpq+ 0*32], m5
1361
1362     VP9_IDCT8_WRITEx2    0,  1, 5, 6, 7, ROUND_REG, 6
1363     lea               dstq, [dstq+strideq*2]
1364     VP9_IDCT8_WRITEx2    2,  3, 5, 6, 7, ROUND_REG, 6
1365     lea               dstq, [dstq+strideq*2]
1366
1367     SWAP                 0, 7               ; move zero from m7 to m0
1368     mova                m5, [tmpq+ 0*32]
1369
1370     VP9_IDCT8_WRITEx2    4,  5, 1, 2, 0, ROUND_REG, 6
1371     lea               dstq, [dstq+strideq*2]
1372
1373     mova                m4, [tmpq+13*32]
1374     mova                m7, [tmpq+14*32]
1375     mova                m5, [tmpq+15*32]
1376     mova                m6, [tmpq+12*32]
1377     SUMSUB_BADC w, 4, 7, 5, 6, 1
1378
1379     VP9_IDCT8_WRITEx2    4,  5, 1, 2, 0, ROUND_REG, 6
1380     lea               dstq, [dstq+strideq*2]
1381     VP9_IDCT8_WRITEx2    6,  7, 1, 2, 0, ROUND_REG, 6
1382     lea               dstq, [dstq+strideq*2]
1383
1384     mova                m4, [tmpq+11*32]
1385     mova                m5, [tmpq+ 9*32]
1386     mova                m6, [tmpq+ 7*32]
1387     mova                m7, [tmpq+ 5*32]
1388
1389     VP9_IDCT8_WRITEx2    4,  5, 1, 2, 0, ROUND_REG, 6
1390     lea               dstq, [dstq+strideq*2]
1391     VP9_IDCT8_WRITEx2    6,  7, 1, 2, 0, ROUND_REG, 6
1392     lea               dstq, [dstq+strideq*2]
1393
1394     mova                m4, [tmpq+ 3*32]
1395     mova                m5, [tmpq+ 1*32]
1396
1397     VP9_IDCT8_WRITEx2    4,  5, 1, 2, 0, ROUND_REG, 6
1398     lea               dstq, [dstq+strideq*2]
1399 %endif
1400
1401 %undef ROUND_REG
1402 %endif ; %2 == 1/2
1403 %endmacro
1404
1405 %macro VP9_STORE_2XFULL 6-7 strideq; dc, tmp1, tmp2, tmp3, tmp4, zero, stride
1406     mova               m%3, [dstq]
1407     mova               m%5, [dstq+%7]
1408     punpcklbw          m%2, m%3, m%6
1409     punpckhbw          m%3, m%6
1410     punpcklbw          m%4, m%5, m%6
1411     punpckhbw          m%5, m%6
1412     paddw              m%2, m%1
1413     paddw              m%3, m%1
1414     paddw              m%4, m%1
1415     paddw              m%5, m%1
1416     packuswb           m%2, m%3
1417     packuswb           m%4, m%5
1418     mova            [dstq], m%2
1419     mova         [dstq+%7], m%4
1420 %endmacro
1421
1422 %macro VP9_IDCT_IDCT_16x16_ADD_XMM 1
1423 INIT_XMM %1
1424 cglobal vp9_idct_idct_16x16_add, 4, 6, 16, 512, dst, stride, block, eob
1425 %if cpuflag(ssse3)
1426     ; 2x2=eob=3, 4x4=eob=10
1427     cmp eobd, 38
1428     jg .idctfull
1429     cmp eobd, 1 ; faster path for when only DC is set
1430     jne .idct8x8
1431 %else
1432     cmp eobd, 1 ; faster path for when only DC is set
1433     jg .idctfull
1434 %endif
1435
1436     ; dc-only
1437 %if cpuflag(ssse3)
1438     movd                m0, [blockq]
1439     mova                m1, [pw_11585x2]
1440     pmulhrsw            m0, m1
1441     pmulhrsw            m0, m1
1442 %else
1443     DEFINE_ARGS dst, stride, block, coef
1444     movsx            coefd, word [blockq]
1445     imul             coefd, 11585
1446     add              coefd, 8192
1447     sar              coefd, 14
1448     imul             coefd, 11585
1449     add              coefd, (32 << 14) + 8192
1450     sar              coefd, 14 + 6
1451     movd                m0, coefd
1452 %endif
1453     SPLATW              m0, m0, q0000
1454 %if cpuflag(ssse3)
1455     pmulhrsw            m0, [pw_512]
1456 %endif
1457     pxor                m5, m5
1458     movd          [blockq], m5
1459 %rep 7
1460     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5
1461     lea               dstq, [dstq+2*strideq]
1462 %endrep
1463     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5
1464     RET
1465
1466     DEFINE_ARGS dst, stride, block, cnt, dst_bak, tmp
1467 %if cpuflag(ssse3)
1468 .idct8x8:
1469     mov               tmpq, rsp
1470     VP9_IDCT16_1D   blockq, 1, 8
1471
1472     mov               cntd, 2
1473     mov           dst_bakq, dstq
1474 .loop2_8x8:
1475     VP9_IDCT16_1D     tmpq, 2, 8
1476     lea               dstq, [dst_bakq+8]
1477     add               tmpq, 16
1478     dec               cntd
1479     jg .loop2_8x8
1480
1481     ; at the end of the loop, m0 should still be zero
1482     ; use that to zero out block coefficients
1483     ZERO_BLOCK      blockq, 32, 8, m0
1484     RET
1485 %endif
1486
1487 .idctfull:
1488     mov               cntd, 2
1489     mov               tmpq, rsp
1490 .loop1_full:
1491     VP9_IDCT16_1D   blockq, 1
1492     add             blockq, 16
1493     add               tmpq, 256
1494     dec               cntd
1495     jg .loop1_full
1496     sub             blockq, 32
1497
1498     mov               cntd, 2
1499     mov               tmpq, rsp
1500     mov           dst_bakq, dstq
1501 .loop2_full:
1502     VP9_IDCT16_1D     tmpq, 2
1503     lea               dstq, [dst_bakq+8]
1504     add               tmpq, 16
1505     dec               cntd
1506     jg .loop2_full
1507
1508     ; at the end of the loop, m0 should still be zero
1509     ; use that to zero out block coefficients
1510     ZERO_BLOCK      blockq, 32, 16, m0
1511     RET
1512 %endmacro
1513
1514 VP9_IDCT_IDCT_16x16_ADD_XMM sse2
1515 VP9_IDCT_IDCT_16x16_ADD_XMM ssse3
1516 VP9_IDCT_IDCT_16x16_ADD_XMM avx
1517
1518 ;---------------------------------------------------------------------------------------------
1519 ; void vp9_iadst_iadst_16x16_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
1520 ;---------------------------------------------------------------------------------------------
1521
1522 %macro VP9_IADST16_1D 2 ; src, pass
1523 %assign %%str 16*%2
1524     mova                m0, [%1+ 0*32]  ; in0
1525     mova                m1, [%1+15*32]  ; in15
1526     mova                m2, [%1+ 7*32]  ; in7
1527     mova                m3, [%1+ 8*32]  ; in8
1528
1529     VP9_UNPACK_MULSUB_2D_4X  1,  0,  4,  5, 16364,   804    ; m1/4=t1[d], m0/5=t0[d]
1530     VP9_UNPACK_MULSUB_2D_4X  2,  3,  7,  6, 11003, 12140    ; m2/7=t9[d], m3/6=t8[d]
1531     SCRATCH              4, 8, tmpq+ 0*%%str
1532     VP9_RND_SH_SUMSUB_BA     3,  0,  6,  5,  4, [pd_8192]   ; m3=t0[w], m0=t8[w]
1533     UNSCRATCH            4, 8, tmpq+ 0*%%str
1534     VP9_RND_SH_SUMSUB_BA     2,  1,  7,  4,  5, [pd_8192]   ; m2=t1[w], m1=t9[w]
1535
1536     SCRATCH              0, 10, tmpq+ 0*%%str
1537     SCRATCH              1, 11, tmpq+15*%%str
1538     mova   [tmpq+ 7*%%str], m2
1539     mova   [tmpq+ 8*%%str], m3
1540
1541     mova                m1, [%1+ 2*32]  ; in2
1542     mova                m0, [%1+13*32]  ; in13
1543     mova                m3, [%1+ 5*32]  ; in5
1544     mova                m2, [%1+10*32]  ; in10
1545
1546     VP9_UNPACK_MULSUB_2D_4X  0,  1,  6,  7, 15893,  3981    ; m0/6=t3[d], m1/7=t2[d]
1547     VP9_UNPACK_MULSUB_2D_4X  3,  2,  4,  5,  8423, 14053    ; m3/4=t11[d], m2/5=t10[d]
1548     SCRATCH              4, 12, tmpq+ 2*%%str
1549     VP9_RND_SH_SUMSUB_BA     2,  1,  5,  7,  4, [pd_8192]   ; m2=t2[w], m1=t10[w]
1550     UNSCRATCH            4, 12, tmpq+ 2*%%str
1551     VP9_RND_SH_SUMSUB_BA     3,  0,  4,  6,  5, [pd_8192]   ; m3=t3[w], m0=t11[w]
1552
1553     SCRATCH              0, 12, tmpq+ 2*%%str
1554     SCRATCH              1, 13, tmpq+13*%%str
1555     mova   [tmpq+ 5*%%str], m2
1556     mova   [tmpq+10*%%str], m3
1557
1558     mova                m2, [%1+ 4*32]  ; in4
1559     mova                m3, [%1+11*32]  ; in11
1560     mova                m0, [%1+ 3*32]  ; in3
1561     mova                m1, [%1+12*32]  ; in12
1562
1563     VP9_UNPACK_MULSUB_2D_4X  3,  2,  7,  6, 14811,  7005    ; m3/7=t5[d], m2/6=t4[d]
1564     VP9_UNPACK_MULSUB_2D_4X  0,  1,  4,  5,  5520, 15426    ; m0/4=t13[d], m1/5=t12[d]
1565     SCRATCH              4, 9, tmpq+ 4*%%str
1566     VP9_RND_SH_SUMSUB_BA     1,  2,  5,  6,  4, [pd_8192]   ; m1=t4[w], m2=t12[w]
1567     UNSCRATCH            4, 9, tmpq+ 4*%%str
1568     VP9_RND_SH_SUMSUB_BA     0,  3,  4,  7,  6, [pd_8192]   ; m0=t5[w], m3=t13[w]
1569
1570     SCRATCH              0,  8, tmpq+ 4*%%str
1571     mova   [tmpq+11*%%str], m1          ; t4:m1->r11
1572     UNSCRATCH            0, 10, tmpq+ 0*%%str
1573     UNSCRATCH            1, 11, tmpq+15*%%str
1574
1575     ; round 2 interleaved part 1
1576     VP9_UNPACK_MULSUB_2D_4X  0,  1,  6,  7, 16069,  3196    ; m1/7=t8[d], m0/6=t9[d]
1577     VP9_UNPACK_MULSUB_2D_4X  3,  2,  5,  4,  3196, 16069    ; m3/5=t12[d], m2/4=t13[d]
1578     SCRATCH              4, 9, tmpq+ 3*%%str
1579     VP9_RND_SH_SUMSUB_BA     3,  1,  5,  7,  4, [pd_8192]   ; m3=t8[w], m1=t12[w]
1580     UNSCRATCH            4, 9, tmpq+ 3*%%str
1581     VP9_RND_SH_SUMSUB_BA     2,  0,  4,  6,  5, [pd_8192]   ; m2=t9[w], m0=t13[w]
1582
1583     SCRATCH              0, 10, tmpq+ 0*%%str
1584     SCRATCH              1, 11, tmpq+15*%%str
1585     SCRATCH              2, 14, tmpq+ 3*%%str
1586     SCRATCH              3, 15, tmpq+12*%%str
1587
1588     mova                m2, [%1+ 6*32]  ; in6
1589     mova                m3, [%1+ 9*32]  ; in9
1590     mova                m0, [%1+ 1*32]  ; in1
1591     mova                m1, [%1+14*32]  ; in14
1592
1593     VP9_UNPACK_MULSUB_2D_4X  3,  2,  7,  6, 13160,  9760    ; m3/7=t7[d], m2/6=t6[d]
1594     VP9_UNPACK_MULSUB_2D_4X  0,  1,  4,  5,  2404, 16207    ; m0/4=t15[d], m1/5=t14[d]
1595     SCRATCH              4, 9, tmpq+ 6*%%str
1596     VP9_RND_SH_SUMSUB_BA     1,  2,  5,  6,  4, [pd_8192]   ; m1=t6[w], m2=t14[w]
1597     UNSCRATCH            4, 9, tmpq+ 6*%%str
1598     VP9_RND_SH_SUMSUB_BA     0,  3,  4,  7,  6, [pd_8192]   ; m0=t7[w], m3=t15[w]
1599
1600     ; r8=t0, r7=t1, r5=t2, r10=t3, r11=t4, m8|r4=t5, m1=t6, m0=t7
1601     ; m10|r0=t8, m11|r15=t9, m13|r13=t10, m12|r2=t11, m14|r3=t12, m15|r12=t13, m2=t14, m3=t15
1602
1603     UNSCRATCH            4, 12, tmpq+ 2*%%str
1604     UNSCRATCH            5, 13, tmpq+13*%%str
1605     SCRATCH              0, 12, tmpq+ 1*%%str
1606     SCRATCH              1, 13, tmpq+14*%%str
1607
1608     ; remainder of round 2 (rest of t8-15)
1609     VP9_UNPACK_MULSUB_2D_4X  5,  4,  6,  7,  9102, 13623    ; m5/6=t11[d], m4/7=t10[d]
1610     VP9_UNPACK_MULSUB_2D_4X  3,  2,  1,  0, 13623,  9102    ; m3/1=t14[d], m2/0=t15[d]
1611     SCRATCH              0, 9, tmpq+ 6*%%str
1612     VP9_RND_SH_SUMSUB_BA     3,  4,  1,  7,  0, [pd_8192]   ; m3=t10[w], m4=t14[w]
1613     UNSCRATCH            0, 9, tmpq+ 6*%%str
1614     VP9_RND_SH_SUMSUB_BA     2,  5,  0,  6,  1, [pd_8192]   ; m2=t11[w], m5=t15[w]
1615
1616     ; m15|r12=t8, m14|r3=t9, m3=t10, m2=t11, m11|r15=t12, m10|r0=t13, m4=t14, m5=t15
1617
1618     UNSCRATCH            6, 14, tmpq+ 3*%%str
1619     UNSCRATCH            7, 15, tmpq+12*%%str
1620
1621     SUMSUB_BA                w,  3,  7,  1
1622     PSIGNW                  m3, [pw_m1]                     ; m3=out1[w], m7=t10[w]
1623     SUMSUB_BA                w,  2,  6,  1                  ; m2=out14[w], m6=t11[w]
1624
1625 %if cpuflag(ssse3)
1626     SUMSUB_BA                w,  7,  6,  1
1627     pmulhrsw                m7, [pw_11585x2]                ; m7=out6[w]
1628     pmulhrsw                m6, [pw_11585x2]                ; m6=out9[w]
1629 %else
1630     VP9_UNPACK_MULSUB_2W_4X  6,  7, 11585, 11585, [pd_8192], 1, 0
1631 %endif
1632
1633     mova       [tmpq+ 3*%%str], m6
1634     mova       [tmpq+ 6*%%str], m7
1635     UNSCRATCH                6, 10, tmpq+ 0*%%str
1636     UNSCRATCH                7, 11, tmpq+15*%%str
1637     mova       [tmpq+13*%%str], m2
1638     SCRATCH                  3, 11, tmpq+ 9*%%str
1639
1640     VP9_UNPACK_MULSUB_2D_4X  7,  6,  2,  3, 15137,  6270    ; m6/3=t13[d], m7/2=t12[d]
1641     VP9_UNPACK_MULSUB_2D_4X  5,  4,  1,  0,  6270, 15137    ; m5/1=t14[d], m4/0=t15[d]
1642     SCRATCH              0, 9, tmpq+ 2*%%str
1643     VP9_RND_SH_SUMSUB_BA     5,  6,  1,  3,  0, [pd_8192]   ; m5=out2[w], m6=t14[w]
1644     UNSCRATCH            0, 9, tmpq+ 2*%%str
1645     VP9_RND_SH_SUMSUB_BA     4,  7,  0,  2,  1, [pd_8192]
1646     PSIGNW                  m4, [pw_m1]                     ; m4=out13[w], m7=t15[w]
1647
1648 %if cpuflag(ssse3)
1649     SUMSUB_BA                w,  7,  6,  1
1650     pmulhrsw                m7, [pw_m11585x2]               ; m7=out5[w]
1651     pmulhrsw                m6, [pw_11585x2]                ; m6=out10[w]
1652 %else
1653     PSIGNW                  m7, [pw_m1]
1654     VP9_UNPACK_MULSUB_2W_4X  7,  6, 11585, 11585, [pd_8192], 1, 0
1655 %endif
1656
1657     ; m11|r13=out1, m5=out2, m7=out5, r15=out6, r3=out9, m6=out10, m4=out13, r2=out14
1658
1659     mova                    m2, [tmpq+ 8*%%str]
1660     mova                    m3, [tmpq+ 7*%%str]
1661     mova                    m1, [tmpq+11*%%str]
1662     mova       [tmpq+ 7*%%str], m6
1663     mova       [tmpq+11*%%str], m4
1664     mova                    m4, [tmpq+ 5*%%str]
1665     SCRATCH                  5, 14, tmpq+ 5*%%str
1666     SCRATCH                  7, 15, tmpq+ 8*%%str
1667     UNSCRATCH                6,  8, tmpq+ 4*%%str
1668     UNSCRATCH                5, 12, tmpq+ 1*%%str
1669     UNSCRATCH                7, 13, tmpq+14*%%str
1670
1671     ; m2=t0, m3=t1, m9=t2, m0=t3, m1=t4, m8=t5, m13=t6, m12=t7
1672     ; m11|r13=out1, m5=out2, m7=out5, r15=out6, r3=out9, r10=out10, r11=out13, r2=out14
1673
1674     SUMSUB_BA                w,  1,  2, 0                   ; m1=t0[w], m2=t4[w]
1675     mova                    m0, [tmpq+10*%%str]
1676     SCRATCH                  1, 12, tmpq+ 1*%%str
1677     SUMSUB_BA                w,  6,  3, 1                   ; m8=t1[w], m3=t5[w]
1678     SCRATCH                  6, 13, tmpq+ 4*%%str
1679     SUMSUB_BA                w,  7,  4, 1                   ; m13=t2[w], m9=t6[w]
1680     SCRATCH                  7,  8, tmpq+10*%%str
1681     SUMSUB_BA                w,  5,  0, 1                   ; m12=t3[w], m0=t7[w]
1682     SCRATCH                  5,  9, tmpq+14*%%str
1683
1684     VP9_UNPACK_MULSUB_2D_4X  2,  3,  7,  5, 15137,  6270    ; m2/6=t5[d], m3/10=t4[d]
1685     VP9_UNPACK_MULSUB_2D_4X  0,  4,  1,  6,  6270, 15137    ; m0/14=t6[d], m9/15=t7[d]
1686     SCRATCH                  6, 10, tmpq+ 0*%%str
1687     VP9_RND_SH_SUMSUB_BA     0,  3,  1,  5,  6, [pd_8192]
1688     UNSCRATCH                6, 10, tmpq+ 0*%%str
1689     PSIGNW                  m0, [pw_m1]                     ; m0=out3[w], m3=t6[w]
1690     VP9_RND_SH_SUMSUB_BA     4,  2,  6,  7,  5, [pd_8192]   ; m9=out12[w], m2=t7[w]
1691
1692     UNSCRATCH                1,  8, tmpq+10*%%str
1693     UNSCRATCH                5,  9, tmpq+14*%%str
1694     UNSCRATCH                6, 12, tmpq+ 1*%%str
1695     UNSCRATCH                7, 13, tmpq+ 4*%%str
1696     SCRATCH                  4,  9, tmpq+14*%%str
1697
1698     SUMSUB_BA                w,  1,  6,  4                  ; m13=out0[w], m1=t2[w]
1699     SUMSUB_BA                w,  5,  7,  4
1700     PSIGNW                  m5, [pw_m1]                     ; m12=out15[w], m8=t3[w]
1701
1702 %if cpuflag(ssse3)
1703     SUMSUB_BA               w,   7,  6,  4
1704     pmulhrsw                m7, [pw_m11585x2]               ; m8=out7[w]
1705     pmulhrsw                m6, [pw_11585x2]                ; m1=out8[w]
1706     SUMSUB_BA                w,  3,  2,  4
1707     pmulhrsw                m3, [pw_11585x2]                ; m3=out4[w]
1708     pmulhrsw                m2, [pw_11585x2]                ; m2=out11[w]
1709 %else
1710     SCRATCH                  5,  8, tmpq+10*%%str
1711     PSIGNW                  m7, [pw_m1]
1712     VP9_UNPACK_MULSUB_2W_4X  7,  6, 11585, 11585, [pd_8192],  5,  4
1713     VP9_UNPACK_MULSUB_2W_4X  2,  3, 11585, 11585, [pd_8192],  5,  4
1714     UNSCRATCH                5,  8, tmpq+10*%%str
1715 %endif
1716
1717     ; m13=out0, m0=out3, m3=out4, m8=out7, m1=out8, m2=out11, m9=out12, m12=out15
1718     ; m11|r13=out1, m5=out2, m7=out5, r15=out6, r3=out9, r10=out10, r11=out13, r2=out14
1719
1720 %if %2 == 1
1721 %if ARCH_X86_64
1722     mova                   m13, [tmpq+ 6*%%str]
1723     TRANSPOSE8x8W            1, 11, 14, 0, 3, 15, 13, 7, 10
1724     mova          [tmpq+ 0*16], m1
1725     mova          [tmpq+ 2*16], m11
1726     mova          [tmpq+ 4*16], m14
1727     mova          [tmpq+ 6*16], m0
1728     mova                    m1, [tmpq+ 3*%%str]
1729     mova                   m11, [tmpq+ 7*%%str]
1730     mova                   m14, [tmpq+11*%%str]
1731     mova                    m0, [tmpq+13*%%str]
1732     mova          [tmpq+ 8*16], m3
1733     mova          [tmpq+10*16], m15
1734     mova          [tmpq+12*16], m13
1735     mova          [tmpq+14*16], m7
1736
1737     TRANSPOSE8x8W            6, 1, 11, 2, 9, 14, 0, 5, 10
1738     mova          [tmpq+ 1*16], m6
1739     mova          [tmpq+ 3*16], m1
1740     mova          [tmpq+ 5*16], m11
1741     mova          [tmpq+ 7*16], m2
1742     mova          [tmpq+ 9*16], m9
1743     mova          [tmpq+11*16], m14
1744     mova          [tmpq+13*16], m0
1745     mova          [tmpq+15*16], m5
1746 %else
1747     mova       [tmpq+12*%%str], m2
1748     mova       [tmpq+ 1*%%str], m5
1749     mova       [tmpq+15*%%str], m6
1750     mova                    m2, [tmpq+ 9*%%str]
1751     mova                    m5, [tmpq+ 5*%%str]
1752     mova                    m6, [tmpq+ 8*%%str]
1753     TRANSPOSE8x8W            1, 2, 5, 0, 3, 6, 4, 7, [tmpq+ 6*%%str], [tmpq+ 8*%%str], 1
1754     mova          [tmpq+ 0*16], m1
1755     mova          [tmpq+ 2*16], m2
1756     mova          [tmpq+ 4*16], m5
1757     mova          [tmpq+ 6*16], m0
1758     mova          [tmpq+10*16], m6
1759     mova                    m3, [tmpq+12*%%str]
1760     mova          [tmpq+12*16], m4
1761     mova                    m4, [tmpq+14*%%str]
1762     mova          [tmpq+14*16], m7
1763
1764     mova                    m0, [tmpq+15*%%str]
1765     mova                    m1, [tmpq+ 3*%%str]
1766     mova                    m2, [tmpq+ 7*%%str]
1767     mova                    m5, [tmpq+11*%%str]
1768     mova                    m7, [tmpq+ 1*%%str]
1769     TRANSPOSE8x8W            0, 1, 2, 3, 4, 5, 6, 7, [tmpq+13*%%str], [tmpq+ 9*%%str], 1
1770     mova          [tmpq+ 1*16], m0
1771     mova          [tmpq+ 3*16], m1
1772     mova          [tmpq+ 5*16], m2
1773     mova          [tmpq+ 7*16], m3
1774     mova          [tmpq+11*16], m5
1775     mova          [tmpq+13*16], m6
1776     mova          [tmpq+15*16], m7
1777 %endif
1778 %else
1779     pxor                    m4, m4
1780
1781 %if cpuflag(ssse3)
1782 %define ROUND_REG [pw_512]
1783 %else
1784 %define ROUND_REG [pw_32]
1785 %endif
1786
1787 %if ARCH_X86_64
1788     mova                   m12, [tmpq+ 6*%%str]
1789     VP9_IDCT8_WRITEx2        1, 11, 10,  8,  4, ROUND_REG, 6
1790     lea                   dstq, [dstq+strideq*2]
1791     VP9_IDCT8_WRITEx2       14,  0, 10,  8,  4, ROUND_REG, 6
1792     lea                   dstq, [dstq+strideq*2]
1793     VP9_IDCT8_WRITEx2        3, 15, 10,  8,  4, ROUND_REG, 6
1794     lea                   dstq, [dstq+strideq*2]
1795     VP9_IDCT8_WRITEx2       12,  7, 10,  8,  4, ROUND_REG, 6
1796     lea                   dstq, [dstq+strideq*2]
1797
1798     mova                    m1, [tmpq+ 3*%%str]
1799     mova                   m11, [tmpq+ 7*%%str]
1800     mova                   m14, [tmpq+11*%%str]
1801     mova                    m0, [tmpq+13*%%str]
1802
1803     VP9_IDCT8_WRITEx2        6,  1, 10,  8,  4, ROUND_REG, 6
1804     lea                   dstq, [dstq+strideq*2]
1805     VP9_IDCT8_WRITEx2       11,  2, 10,  8,  4, ROUND_REG, 6
1806     lea                   dstq, [dstq+strideq*2]
1807     VP9_IDCT8_WRITEx2        9, 14, 10,  8,  4, ROUND_REG, 6
1808     lea                   dstq, [dstq+strideq*2]
1809     VP9_IDCT8_WRITEx2        0,  5, 10,  8,  4, ROUND_REG, 6
1810 %else
1811     mova       [tmpq+ 0*%%str], m2
1812     mova       [tmpq+ 1*%%str], m5
1813     mova       [tmpq+ 2*%%str], m6
1814     mova                    m2, [tmpq+ 9*%%str]
1815     VP9_IDCT8_WRITEx2        1,  2,  5,  6,  4, ROUND_REG, 6
1816     lea                   dstq, [dstq+strideq*2]
1817     mova                    m5, [tmpq+ 5*%%str]
1818     VP9_IDCT8_WRITEx2        5,  0,  1,  2,  4, ROUND_REG, 6
1819     lea                   dstq, [dstq+strideq*2]
1820     mova                    m5, [tmpq+ 8*%%str]
1821     VP9_IDCT8_WRITEx2        3,  5,  1,  2,  4, ROUND_REG, 6
1822     lea                   dstq, [dstq+strideq*2]
1823     mova                    m5, [tmpq+ 6*%%str]
1824     VP9_IDCT8_WRITEx2        5,  7,  1,  2,  4, ROUND_REG, 6
1825     lea                   dstq, [dstq+strideq*2]
1826
1827     mova                    m0, [tmpq+ 2*%%str]
1828     mova                    m3, [tmpq+ 3*%%str]
1829     VP9_IDCT8_WRITEx2        0,  3,  1,  2,  4, ROUND_REG, 6
1830     lea                   dstq, [dstq+strideq*2]
1831     mova                    m0, [tmpq+ 7*%%str]
1832     mova                    m3, [tmpq+ 0*%%str]
1833     VP9_IDCT8_WRITEx2        0,  3,  1,  2,  4, ROUND_REG, 6
1834     lea                   dstq, [dstq+strideq*2]
1835     mova                    m0, [tmpq+14*%%str]
1836     mova                    m3, [tmpq+11*%%str]
1837     VP9_IDCT8_WRITEx2        0,  3,  1,  2,  4, ROUND_REG, 6
1838     lea                   dstq, [dstq+strideq*2]
1839     mova                    m0, [tmpq+13*%%str]
1840     mova                    m3, [tmpq+ 1*%%str]
1841     VP9_IDCT8_WRITEx2        0,  3,  1,  2,  4, ROUND_REG, 6
1842 %endif
1843
1844     SWAP                     0,  4 ; zero
1845 %undef ROUND_REG
1846 %endif
1847 %endmacro
1848
1849 %macro IADST16_FN 5
1850 INIT_XMM %5
1851 cglobal vp9_%1_%3_16x16_add, 3, 6, 16, 512, dst, stride, block, cnt, dst_bak, tmp
1852     mov               cntd, 2
1853     mov               tmpq, rsp
1854 .loop1_full:
1855     VP9_%2_1D       blockq, 1
1856     add             blockq, 16
1857     add               tmpq, 256
1858     dec               cntd
1859     jg .loop1_full
1860     sub             blockq, 32
1861
1862     mov               cntd, 2
1863     mov               tmpq, rsp
1864     mov           dst_bakq, dstq
1865 .loop2_full:
1866     VP9_%4_1D         tmpq, 2
1867     lea               dstq, [dst_bakq+8]
1868     add               tmpq, 16
1869     dec               cntd
1870     jg .loop2_full
1871
1872     ; at the end of the loop, m0 should still be zero
1873     ; use that to zero out block coefficients
1874     ZERO_BLOCK      blockq, 32, 16, m0
1875     RET
1876 %endmacro
1877
1878 %define PSIGNW PSIGNW_MMX
1879 IADST16_FN idct,  IDCT16,  iadst, IADST16, sse2
1880 IADST16_FN iadst, IADST16, idct,  IDCT16,  sse2
1881 IADST16_FN iadst, IADST16, iadst, IADST16, sse2
1882 %define PSIGNW PSIGNW_SSSE3
1883 IADST16_FN idct,  IDCT16,  iadst, IADST16, ssse3
1884 IADST16_FN iadst, IADST16, idct,  IDCT16,  ssse3
1885 IADST16_FN iadst, IADST16, iadst, IADST16, ssse3
1886 IADST16_FN idct,  IDCT16,  iadst, IADST16, avx
1887 IADST16_FN iadst, IADST16, idct,  IDCT16,  avx
1888 IADST16_FN iadst, IADST16, iadst, IADST16, avx
1889 %undef PSIGNW
1890
1891 ;---------------------------------------------------------------------------------------------
1892 ; void vp9_idct_idct_32x32_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
1893 ;---------------------------------------------------------------------------------------------
1894
1895 %macro VP9_IDCT32_1D 2-3 32 ; src, pass, nnzc
1896 %assign %%str 16*%2*%2
1897     ; first do t0-15, this can be done identical to idct16x16
1898     VP9_IDCT16_1D_START %1, %3/2, 64*2, tmpq, 2*%%str
1899
1900     ; store everything on stack to make space available for t16-31
1901     ; we store interleaved with the output of the second half (t16-31)
1902     ; so we don't need to allocate extra stack space
1903     mova    [tmpq+ 0*%%str], m0     ; t0
1904     mova    [tmpq+ 4*%%str], m1     ; t1
1905     mova    [tmpq+ 8*%%str], m2     ; t2
1906     mova    [tmpq+12*%%str], m3     ; t3
1907     mova    [tmpq+16*%%str], m4     ; t4
1908     mova    [tmpq+20*%%str], m5     ; t5
1909 %if ARCH_X86_64
1910     mova    [tmpq+22*%%str], m10    ; t10
1911     mova    [tmpq+18*%%str], m11    ; t11
1912     mova    [tmpq+14*%%str], m12    ; t12
1913     mova    [tmpq+10*%%str], m13    ; t13
1914     mova    [tmpq+ 6*%%str], m14    ; t14
1915     mova    [tmpq+ 2*%%str], m15    ; t15
1916 %endif
1917
1918     mova                m0, [tmpq+ 30*%%str]
1919     UNSCRATCH            1,  6, tmpq+26*%%str
1920     UNSCRATCH            2,  8, tmpq+24*%%str
1921     UNSCRATCH            3,  9, tmpq+28*%%str
1922     SUMSUB_BA            w,  1,  3, 4       ; t6, t9
1923     SUMSUB_BA            w,  0,  2, 4       ; t7, t8
1924
1925     mova    [tmpq+24*%%str], m1     ; t6
1926     mova    [tmpq+28*%%str], m0     ; t7
1927     mova    [tmpq+30*%%str], m2     ; t8
1928     mova    [tmpq+26*%%str], m3     ; t9
1929
1930     ; then, secondly, do t16-31
1931 %if %3 <= 8
1932     mova                 m4, [%1+ 1*64]
1933     mova                 m7, [%1+ 7*64]
1934
1935     pmulhrsw             m1,  m4, [pw_16364x2] ;t31
1936     pmulhrsw             m4, [pw_804x2] ;t16
1937
1938     VP9_UNPACK_MULSUB_2W_4X   5,  0,  1,  4, 16069,  3196, [pd_8192], 6,  2 ; t17, t30
1939
1940     pmulhrsw             m3,  m7, [pw_m5520x2] ;t19
1941     pmulhrsw             m7, [pw_15426x2] ;t28
1942
1943     SCRATCH               4, 13, tmpq+ 1*%%str
1944     SCRATCH               5, 12, tmpq+15*%%str
1945
1946     VP9_UNPACK_MULSUB_2W_4X   2,  6,  7,  3, 3196, m16069, [pd_8192], 4,  5 ; t18, t29
1947 %else
1948     mova                 m0, [%1+ 1*64]
1949     mova                 m1, [%1+15*64]
1950 %if %3 <= 16
1951     pmulhrsw             m5, m0, [pw_16364x2]
1952     pmulhrsw             m0, [pw_804x2]
1953     pmulhrsw             m4, m1, [pw_m11003x2]
1954     pmulhrsw             m1, [pw_12140x2]
1955 %else
1956     mova                 m4, [%1+17*64]
1957     mova                 m5, [%1+31*64]
1958
1959     VP9_UNPACK_MULSUB_2W_4X   0,  5, 16364,   804, [pd_8192], 2, 3 ; t16, t31
1960     VP9_UNPACK_MULSUB_2W_4X   4,  1, 11003, 12140, [pd_8192], 2, 3 ; t17, t30
1961 %endif
1962     SUMSUB_BA             w,  4,  0,  2
1963     SUMSUB_BA             w,  1,  5,  2
1964
1965     VP9_UNPACK_MULSUB_2W_4X   5,  0, 16069,  3196, [pd_8192], 2, 3 ; t17, t30
1966
1967     SCRATCH               4, 13, tmpq+ 1*%%str
1968     SCRATCH               5, 12, tmpq+15*%%str
1969
1970     mova                 m2, [%1+ 7*64]
1971     mova                 m3, [%1+ 9*64]
1972 %if %3 <= 16
1973     pmulhrsw             m7,  m3, [pw_14811x2]
1974     pmulhrsw             m3, [pw_7005x2]
1975     pmulhrsw             m6,  m2, [pw_m5520x2]
1976     pmulhrsw             m2, [pw_15426x2]
1977 %else
1978     mova                 m7, [%1+23*64]
1979     mova                 m6, [%1+25*64]
1980
1981     VP9_UNPACK_MULSUB_2W_4X   3,  7, 14811,  7005, [pd_8192], 4, 5 ; t18, t29
1982     VP9_UNPACK_MULSUB_2W_4X   6,  2,  5520, 15426, [pd_8192], 4, 5 ; t19, t28
1983 %endif
1984     SUMSUB_BA             w,  3,  6,  4
1985     SUMSUB_BA             w,  7,  2,  4
1986
1987     VP9_UNPACK_MULSUB_2W_4X   2,  6, 3196, m16069, [pd_8192], 4, 5 ; t18, t29
1988 %endif
1989
1990     UNSCRATCH             5, 12, tmpq+15*%%str
1991     SUMSUB_BA             w,  6,  0,  4
1992     mova    [tmpq+25*%%str], m6             ; t19
1993     UNSCRATCH             4, 13, tmpq+ 1*%%str
1994     SUMSUB_BA             w,  7,  1,  6
1995     SUMSUB_BA             w,  3,  4,  6
1996     mova    [tmpq+23*%%str], m3             ; t16
1997     SUMSUB_BA             w,  2,  5,  6
1998
1999     VP9_UNPACK_MULSUB_2W_4X   0,  5, 15137,  6270, [pd_8192], 6, 3 ; t18, t29
2000     VP9_UNPACK_MULSUB_2W_4X   1,  4, 15137,  6270, [pd_8192], 6, 3 ; t19, t28
2001
2002     SCRATCH               0, 10, tmpq+ 1*%%str
2003     SCRATCH               1, 11, tmpq+ 7*%%str
2004     SCRATCH               2,  9, tmpq+ 9*%%str
2005     SCRATCH               4, 14, tmpq+15*%%str
2006     SCRATCH               5, 15, tmpq+17*%%str
2007     SCRATCH               7, 13, tmpq+31*%%str
2008
2009 %if %3 <= 8
2010     mova                 m0, [%1+ 5*64]
2011     mova                 m3, [%1+ 3*64]
2012
2013     pmulhrsw             m5,  m0, [pw_15893x2] ;t27
2014     pmulhrsw             m0, [pw_3981x2] ;t20
2015
2016     VP9_UNPACK_MULSUB_2W_4X   1,  4,  5,  0,  9102, 13623, [pd_8192], 7,  2 ; t21, t26
2017
2018     pmulhrsw             m6,  m3, [pw_m2404x2] ;t23
2019     pmulhrsw             m3, [pw_16207x2] ;t24
2020
2021     SCRATCH               5,  8, tmpq+ 5*%%str
2022     SCRATCH               4, 12, tmpq+11*%%str
2023
2024     VP9_UNPACK_MULSUB_2W_4X   7,  2,  3,  6, 13623, m9102, [pd_8192], 4, 5 ; t22, t25
2025 %else
2026     mova                 m4, [%1+ 5*64]
2027     mova                 m5, [%1+11*64]
2028 %if %3 <= 16
2029     pmulhrsw             m1, m4, [pw_15893x2]
2030     pmulhrsw             m4, [pw_3981x2]
2031     pmulhrsw             m0, m5, [pw_m8423x2]
2032     pmulhrsw             m5, [pw_14053x2]
2033 %else
2034     mova                 m0, [%1+21*64]
2035     mova                 m1, [%1+27*64]
2036
2037     VP9_UNPACK_MULSUB_2W_4X   4,  1, 15893,  3981, [pd_8192], 2, 3 ; t20, t27
2038     VP9_UNPACK_MULSUB_2W_4X   0,  5,  8423, 14053, [pd_8192], 2, 3 ; t21, t26
2039 %endif
2040     SUMSUB_BA             w,  0,  4,  2
2041     SUMSUB_BA             w,  5,  1,  2
2042
2043     VP9_UNPACK_MULSUB_2W_4X   1,  4,  9102, 13623, [pd_8192], 2, 3 ; t21, t26
2044
2045     SCRATCH               5,  8, tmpq+ 5*%%str
2046     SCRATCH               4, 12, tmpq+11*%%str
2047
2048     mova                 m7, [%1+ 3*64]
2049     mova                 m6, [%1+13*64]
2050 %if %3 <= 16
2051     pmulhrsw             m3, m6, [pw_13160x2]
2052     pmulhrsw             m6, [pw_9760x2]
2053     pmulhrsw             m2, m7, [pw_m2404x2]
2054     pmulhrsw             m7, [pw_16207x2]
2055 %else
2056     mova                 m2, [%1+29*64]
2057     mova                 m3, [%1+19*64]
2058     VP9_UNPACK_MULSUB_2W_4X   6,  3, 13160,  9760, [pd_8192], 4, 5 ; t22, t25
2059     VP9_UNPACK_MULSUB_2W_4X   2,  7,  2404, 16207, [pd_8192], 4, 5 ; t23, t24
2060 %endif
2061     SUMSUB_BA             w,  6,  2,  4
2062     SUMSUB_BA             w,  3,  7,  4
2063
2064     VP9_UNPACK_MULSUB_2W_4X   7,  2, 13623, m9102, [pd_8192], 4, 5 ; t22, t25
2065 %endif
2066
2067     ; m4=t16, m5=t17, m9=t18, m8=t19, m0=t20, m1=t21, m13=t22, m12=t23,
2068     ; m3=t24, m2=t25, m14=t26, m15=t27, m7=t28, m6=t29, m10=t30, m11=t31
2069
2070     UNSCRATCH             4, 12, tmpq+11*%%str
2071     SUMSUB_BA             w,  0,  6, 5
2072     SUMSUB_BA             w,  4,  2, 5
2073     UNSCRATCH             5,  8, tmpq+ 5*%%str
2074     SCRATCH               4,  8, tmpq+11*%%str
2075     SUMSUB_BA             w,  1,  7, 4
2076     SUMSUB_BA             w,  5,  3, 4
2077     SCRATCH               5, 12, tmpq+ 5*%%str
2078
2079     VP9_UNPACK_MULSUB_2W_4X   3,  6, 6270, m15137, [pd_8192], 4, 5 ; t20, t27
2080     VP9_UNPACK_MULSUB_2W_4X   2,  7, 6270, m15137, [pd_8192], 4, 5 ; t21, t26
2081
2082     ; m8[s]=t16, m9=t17, m5=t18, m4[s]=t19, m12=t20, m13=t21, m1=t22, m0=t23,
2083     ; m15=t24, m14=t25, m2=t26, m3=t27, m11=t28, m10=t29, m6=t30, m7=t31
2084
2085     UNSCRATCH             5,  9, tmpq+ 9*%%str
2086     mova                 m4, [tmpq+23*%%str] ; t16
2087 %if ARCH_X86_64
2088     SUMSUB_BA             w,  1,  5,  9
2089     SUMSUB_BA             w,  0,  4,  9
2090 %else
2091     SUMSUB_BADC           w,  1,  5,  0,  4
2092 %endif
2093     mova    [tmpq+29*%%str], m1     ; t17
2094     mova    [tmpq+21*%%str], m0     ; t16
2095     UNSCRATCH             0, 10, tmpq+ 1*%%str
2096     UNSCRATCH             1, 11, tmpq+ 7*%%str
2097 %if ARCH_X86_64
2098     SUMSUB_BA             w,  2,  0,  9
2099     SUMSUB_BA             w,  3,  1,  9
2100 %else
2101     SUMSUB_BADC           w,  2,  0,  3,  1
2102 %endif
2103     mova    [tmpq+ 9*%%str], m2     ; t18
2104     mova    [tmpq+13*%%str], m3     ; t19
2105     SCRATCH               0, 10, tmpq+23*%%str
2106     SCRATCH               1, 11, tmpq+27*%%str
2107
2108     UNSCRATCH             2, 14, tmpq+15*%%str
2109     UNSCRATCH             3, 15, tmpq+17*%%str
2110     SUMSUB_BA             w,  6,  2, 0
2111     SUMSUB_BA             w,  7,  3, 0
2112     SCRATCH               6, 14, tmpq+ 3*%%str
2113     SCRATCH               7, 15, tmpq+ 7*%%str
2114
2115     UNSCRATCH             0,  8, tmpq+11*%%str
2116     mova                 m1, [tmpq+25*%%str] ; t19
2117     UNSCRATCH             6, 12, tmpq+ 5*%%str
2118     UNSCRATCH             7, 13, tmpq+31*%%str
2119 %if ARCH_X86_64
2120     SUMSUB_BA             w,  0,  1,  9
2121     SUMSUB_BA             w,  6,  7,  9
2122 %else
2123     SUMSUB_BADC           w,  0,  1,  6,  7
2124 %endif
2125
2126     ; m0=t16, m1=t17, m2=t18, m3=t19, m11=t20, m10=t21, m9=t22, m8=t23,
2127     ; m7=t24, m6=t25, m5=t26, m4=t27, m12=t28, m13=t29, m14=t30, m15=t31
2128
2129 %if cpuflag(ssse3)
2130 %if ARCH_X86_64
2131     SUMSUB_BA             w,  4,  7,  8
2132     SUMSUB_BA             w,  5,  1,  8
2133 %else
2134     SUMSUB_BADC           w,  4,  7,  5,  1
2135 %endif
2136
2137     pmulhrsw             m7, [pw_11585x2]
2138     pmulhrsw             m4, [pw_11585x2]
2139     pmulhrsw             m1, [pw_11585x2]
2140     pmulhrsw             m5, [pw_11585x2]
2141
2142     mova    [tmpq+ 5*%%str], m7     ; t23
2143     SCRATCH               1, 13, tmpq+25*%%str
2144     UNSCRATCH             7, 10, tmpq+23*%%str
2145     UNSCRATCH             1, 11, tmpq+27*%%str
2146
2147 %if ARCH_X86_64
2148     SUMSUB_BA             w,  7,  3, 10
2149     SUMSUB_BA             w,  1,  2, 10
2150 %else
2151     SUMSUB_BADC           w,  7,  3,  1,  2
2152 %endif
2153
2154     pmulhrsw             m3, [pw_11585x2]
2155     pmulhrsw             m7, [pw_11585x2]
2156     pmulhrsw             m2, [pw_11585x2]
2157     pmulhrsw             m1, [pw_11585x2]
2158 %else
2159     SCRATCH               0,  8, tmpq+15*%%str
2160     SCRATCH               6,  9, tmpq+17*%%str
2161     VP9_UNPACK_MULSUB_2W_4X  7,  4, 11585, 11585, [pd_8192], 0, 6
2162     mova    [tmpq+ 5*%%str], m7     ; t23
2163     UNSCRATCH             7, 10, tmpq+23*%%str
2164     VP9_UNPACK_MULSUB_2W_4X  1,  5, 11585, 11585, [pd_8192], 0, 6
2165     SCRATCH               1, 13, tmpq+25*%%str
2166     UNSCRATCH             1, 11, tmpq+27*%%str
2167     VP9_UNPACK_MULSUB_2W_4X  3,  7, 11585, 11585, [pd_8192], 0, 6
2168     VP9_UNPACK_MULSUB_2W_4X  2,  1, 11585, 11585, [pd_8192], 0, 6
2169     UNSCRATCH             0,  8, tmpq+15*%%str
2170     UNSCRATCH             6,  9, tmpq+17*%%str
2171 %endif
2172
2173     ; m0=t16, m1=t17, m2=t18, m3=t19, m4=t20, m5=t21, m6=t22, m7=t23,
2174     ; m8=t24, m9=t25, m10=t26, m11=t27, m12=t28, m13=t29, m14=t30, m15=t31
2175
2176     ; then do final pass to sumsub+store the two halves
2177 %if %2 == 1
2178     mova    [tmpq+17*%%str], m2     ; t20
2179     mova    [tmpq+ 1*%%str], m3     ; t21
2180 %if ARCH_X86_64
2181     mova    [tmpq+25*%%str], m13    ; t22
2182
2183     mova                 m8, [tmpq+ 0*%%str] ; t0
2184     mova                 m9, [tmpq+ 4*%%str] ; t1
2185     mova                m12, [tmpq+ 8*%%str] ; t2
2186     mova                m11, [tmpq+12*%%str] ; t3
2187     mova                 m2, [tmpq+16*%%str] ; t4
2188     mova                 m3, [tmpq+20*%%str] ; t5
2189     mova                m13, [tmpq+24*%%str] ; t6
2190
2191     SUMSUB_BA             w,  6,  8,  10
2192     mova    [tmpq+ 3*%%str], m8              ; t15
2193     mova                m10, [tmpq+28*%%str] ; t7
2194     SUMSUB_BA             w,  0,  9,  8
2195     SUMSUB_BA             w, 15, 12,  8
2196     SUMSUB_BA             w, 14, 11,  8
2197     SUMSUB_BA             w,  1,  2,  8
2198     SUMSUB_BA             w,  7,  3,  8
2199     SUMSUB_BA             w,  5, 13,  8
2200     SUMSUB_BA             w,  4, 10,  8
2201
2202     TRANSPOSE8x8W         6, 0, 15, 14, 1, 7, 5, 4, 8
2203     mova    [tmpq+ 0*%%str], m6
2204     mova    [tmpq+ 4*%%str], m0
2205     mova    [tmpq+ 8*%%str], m15
2206     mova    [tmpq+12*%%str], m14
2207     mova    [tmpq+16*%%str], m1
2208     mova    [tmpq+20*%%str], m7
2209     mova    [tmpq+24*%%str], m5
2210     mova    [tmpq+28*%%str], m4
2211
2212     mova                  m8, [tmpq+ 3*%%str] ; t15
2213     TRANSPOSE8x8W         10, 13, 3, 2, 11, 12, 9, 8, 0
2214     mova    [tmpq+ 3*%%str], m10
2215     mova    [tmpq+ 7*%%str], m13
2216     mova    [tmpq+11*%%str], m3
2217     mova    [tmpq+15*%%str], m2
2218     mova    [tmpq+19*%%str], m11
2219     mova    [tmpq+23*%%str], m12
2220     mova    [tmpq+27*%%str], m9
2221     mova    [tmpq+31*%%str], m8
2222
2223     mova                m15, [tmpq+30*%%str] ; t8
2224     mova                m14, [tmpq+26*%%str] ; t9
2225     mova                m13, [tmpq+22*%%str] ; t10
2226     mova                m12, [tmpq+18*%%str] ; t11
2227     mova                m11, [tmpq+14*%%str] ; t12
2228     mova                m10, [tmpq+10*%%str] ; t13
2229     mova                 m9, [tmpq+ 6*%%str] ; t14
2230     mova                 m8, [tmpq+ 2*%%str] ; t15
2231     mova                 m7, [tmpq+21*%%str] ; t16
2232     mova                 m6, [tmpq+29*%%str] ; t17
2233     mova                 m5, [tmpq+ 9*%%str] ; t18
2234     mova                 m4, [tmpq+13*%%str] ; t19
2235     mova                 m3, [tmpq+17*%%str] ; t20
2236     mova                 m2, [tmpq+ 1*%%str] ; t21
2237     mova                 m1, [tmpq+25*%%str] ; t22
2238
2239     SUMSUB_BA             w,  7,  8, 0
2240     mova    [tmpq+ 2*%%str], m8
2241     mova                 m0, [tmpq+ 5*%%str] ; t23
2242     SUMSUB_BA             w,  6,  9, 8
2243     SUMSUB_BA             w,  5, 10, 8
2244     SUMSUB_BA             w,  4, 11, 8
2245     SUMSUB_BA             w,  3, 12, 8
2246     SUMSUB_BA             w,  2, 13, 8
2247     SUMSUB_BA             w,  1, 14, 8
2248     SUMSUB_BA             w,  0, 15, 8
2249
2250     TRANSPOSE8x8W         0, 1, 2, 3, 4, 5, 6, 7, 8
2251     mova    [tmpq+ 1*%%str], m0
2252     mova    [tmpq+ 5*%%str], m1
2253     mova    [tmpq+ 9*%%str], m2
2254     mova    [tmpq+13*%%str], m3
2255     mova    [tmpq+17*%%str], m4
2256     mova    [tmpq+21*%%str], m5
2257     mova    [tmpq+25*%%str], m6
2258     mova    [tmpq+29*%%str], m7
2259
2260     mova                 m8, [tmpq+ 2*%%str]
2261     TRANSPOSE8x8W         8, 9, 10, 11, 12, 13, 14, 15, 0
2262     mova    [tmpq+ 2*%%str], m8
2263     mova    [tmpq+ 6*%%str], m9
2264     mova    [tmpq+10*%%str], m10
2265     mova    [tmpq+14*%%str], m11
2266     mova    [tmpq+18*%%str], m12
2267     mova    [tmpq+22*%%str], m13
2268     mova    [tmpq+26*%%str], m14
2269     mova    [tmpq+30*%%str], m15
2270 %else
2271     mova                 m2, [tmpq+24*%%str] ; t6
2272     mova                 m3, [tmpq+28*%%str] ; t7
2273     SUMSUB_BADC           w,  5,  2,  4,  3
2274     mova    [tmpq+24*%%str], m5
2275     mova    [tmpq+23*%%str], m2
2276     mova    [tmpq+28*%%str], m4
2277     mova    [tmpq+19*%%str], m3
2278
2279     mova                 m2, [tmpq+16*%%str] ; t4
2280     mova                 m3, [tmpq+20*%%str] ; t5
2281     SUMSUB_BA             w,  1,  2,  5
2282     SUMSUB_BA             w,  7,  3,  5
2283     mova    [tmpq+15*%%str], m2
2284     mova    [tmpq+11*%%str], m3
2285
2286     mova                 m2, [tmpq+ 0*%%str] ; t0
2287     mova                 m3, [tmpq+ 4*%%str] ; t1
2288     SUMSUB_BA             w,  6,  2,  5
2289     SUMSUB_BA             w,  0,  3,  5
2290     mova    [tmpq+31*%%str], m2
2291     mova    [tmpq+27*%%str], m3
2292
2293     mova                 m2, [tmpq+ 8*%%str] ; t2
2294     mova                 m3, [tmpq+12*%%str] ; t3
2295     mova                 m5, [tmpq+ 7*%%str]
2296     mova                 m4, [tmpq+ 3*%%str]
2297     SUMSUB_BADC           w,  5,  2,  4,  3
2298     mova    [tmpq+ 7*%%str], m2
2299     mova    [tmpq+ 3*%%str], m3
2300
2301     mova                 m3, [tmpq+28*%%str]
2302     TRANSPOSE8x8W         6, 0, 5, 4, 1, 7, 2, 3, [tmpq+24*%%str], [tmpq+16*%%str], 1
2303     mova    [tmpq+ 0*%%str], m6
2304     mova    [tmpq+ 4*%%str], m0
2305     mova    [tmpq+ 8*%%str], m5
2306     mova    [tmpq+12*%%str], m4
2307     mova    [tmpq+20*%%str], m7
2308     mova    [tmpq+24*%%str], m2
2309     mova    [tmpq+28*%%str], m3
2310
2311     mova                 m6, [tmpq+19*%%str]
2312     mova                 m0, [tmpq+23*%%str]
2313     mova                 m5, [tmpq+11*%%str]
2314     mova                 m4, [tmpq+15*%%str]
2315     mova                 m1, [tmpq+ 3*%%str]
2316     mova                 m7, [tmpq+ 7*%%str]
2317     mova                 m3, [tmpq+31*%%str]
2318     TRANSPOSE8x8W         6, 0, 5, 4, 1, 7, 2, 3, [tmpq+27*%%str], [tmpq+19*%%str], 1
2319     mova    [tmpq+ 3*%%str], m6
2320     mova    [tmpq+ 7*%%str], m0
2321     mova    [tmpq+11*%%str], m5
2322     mova    [tmpq+15*%%str], m4
2323     mova    [tmpq+23*%%str], m7
2324     mova    [tmpq+27*%%str], m2
2325     mova    [tmpq+31*%%str], m3
2326
2327     mova                 m1, [tmpq+ 6*%%str] ; t14
2328     mova                 m0, [tmpq+ 2*%%str] ; t15
2329     mova                 m7, [tmpq+21*%%str] ; t16
2330     mova                 m6, [tmpq+29*%%str] ; t17
2331     SUMSUB_BA             w,  7,  0,  2
2332     SUMSUB_BA             w,  6,  1,  2
2333     mova    [tmpq+29*%%str], m7
2334     mova    [tmpq+ 2*%%str], m0
2335     mova    [tmpq+21*%%str], m6
2336     mova    [tmpq+ 6*%%str], m1
2337
2338     mova                 m1, [tmpq+14*%%str] ; t12
2339     mova                 m0, [tmpq+10*%%str] ; t13
2340     mova                 m5, [tmpq+ 9*%%str] ; t18
2341     mova                 m4, [tmpq+13*%%str] ; t19
2342     SUMSUB_BA             w,  5,  0,  2
2343     SUMSUB_BA             w,  4,  1,  2
2344     mova     [tmpq+10*%%str], m0
2345     mova     [tmpq+14*%%str], m1
2346
2347     mova                 m1, [tmpq+22*%%str] ; t10
2348     mova                 m0, [tmpq+18*%%str] ; t11
2349     mova                 m3, [tmpq+17*%%str] ; t20
2350     mova                 m2, [tmpq+ 1*%%str] ; t21
2351     SUMSUB_BA             w,  3,  0,  6
2352     SUMSUB_BA             w,  2,  1,  6
2353     mova     [tmpq+18*%%str], m0
2354     mova     [tmpq+22*%%str], m1
2355
2356     mova                 m7, [tmpq+30*%%str] ; t8
2357     mova                 m6, [tmpq+26*%%str] ; t9
2358     mova                 m1, [tmpq+25*%%str] ; t22
2359     mova                 m0, [tmpq+ 5*%%str] ; t23
2360     SUMSUB_BADC           w,  1,  6,  0,  7
2361     mova     [tmpq+26*%%str], m6
2362     mova     [tmpq+30*%%str], m7
2363
2364     mova                 m7, [tmpq+29*%%str]
2365     TRANSPOSE8x8W         0, 1, 2, 3, 4, 5, 6, 7, [tmpq+21*%%str], [tmpq+17*%%str], 1
2366     mova    [tmpq+ 1*%%str], m0
2367     mova    [tmpq+ 5*%%str], m1
2368     mova    [tmpq+ 9*%%str], m2
2369     mova    [tmpq+13*%%str], m3
2370     mova    [tmpq+21*%%str], m5
2371     mova    [tmpq+25*%%str], m6
2372     mova    [tmpq+29*%%str], m7
2373
2374     mova                 m0, [tmpq+ 2*%%str]
2375     mova                 m1, [tmpq+ 6*%%str]
2376     mova                 m2, [tmpq+10*%%str]
2377     mova                 m3, [tmpq+14*%%str]
2378     mova                 m4, [tmpq+18*%%str]
2379     mova                 m5, [tmpq+22*%%str]
2380     mova                 m7, [tmpq+30*%%str]
2381     TRANSPOSE8x8W         0, 1, 2, 3, 4, 5, 6, 7, [tmpq+26*%%str], [tmpq+18*%%str], 1
2382     mova    [tmpq+ 2*%%str], m0
2383     mova    [tmpq+ 6*%%str], m1
2384     mova    [tmpq+10*%%str], m2
2385     mova    [tmpq+14*%%str], m3
2386     mova    [tmpq+22*%%str], m5
2387     mova    [tmpq+26*%%str], m6
2388     mova    [tmpq+30*%%str], m7
2389 %endif
2390 %else
2391     ; t0-7 is in [tmpq+{0,4,8,12,16,20,24,28}*%%str]
2392     ; t8-15 is in [tmpq+{2,6,10,14,18,22,26,30}*%%str]
2393     ; t16-19 and t23 is in [tmpq+{1,5,9,13,29}*%%str]
2394     ; t20-22 is in m4-6
2395     ; t24-31 is in m8-15
2396
2397 %if cpuflag(ssse3)
2398 %define ROUND_REG [pw_512]
2399 %else
2400 %define ROUND_REG [pw_32]
2401 %endif
2402
2403 %macro %%STORE_2X2 7-8 1 ; src[1-4], tmp[1-2], zero, inc_dst_ptrs
2404     SUMSUB_BA            w, %4, %1, %5
2405     SUMSUB_BA            w, %3, %2, %5
2406     VP9_IDCT8_WRITEx2   %4, %3, %5, %6, %7, ROUND_REG, 6
2407 %if %8 == 1
2408     add               dstq, stride2q
2409 %endif
2410     VP9_IDCT8_WRITEx2   %2, %1, %5, %6, %7, ROUND_REG, 6, dst_endq
2411 %if %8 == 1
2412     sub           dst_endq, stride2q
2413 %endif
2414 %endmacro
2415
2416 %if ARCH_X86_64
2417     pxor               m10, m10
2418
2419     ; store t0-1 and t30-31
2420     mova                m8, [tmpq+ 0*%%str]
2421     mova                m9, [tmpq+ 4*%%str]
2422     %%STORE_2X2          8,  9,  0,  6, 12, 11, 10
2423
2424     ; store t2-3 and t28-29
2425     mova                m8, [tmpq+ 8*%%str]
2426     mova                m9, [tmpq+12*%%str]
2427     %%STORE_2X2          8,  9, 14, 15, 12, 11, 10
2428
2429     ; store t4-5 and t26-27
2430     mova                m8, [tmpq+16*%%str]
2431     mova                m9, [tmpq+20*%%str]
2432     %%STORE_2X2          8,  9,  7,  1, 12, 11, 10
2433
2434     ; store t6-7 and t24-25
2435     mova                m8, [tmpq+24*%%str]
2436     mova                m9, [tmpq+28*%%str]
2437     %%STORE_2X2          8,  9,  4,  5, 12, 11, 10
2438
2439     ; store t8-9 and t22-23
2440     mova                m8, [tmpq+30*%%str]
2441     mova                m9, [tmpq+26*%%str]
2442     mova                m0, [tmpq+ 5*%%str]
2443     %%STORE_2X2          8,  9, 13,  0, 12, 11, 10
2444
2445     ; store t10-11 and t20-21
2446     mova                m8, [tmpq+22*%%str]
2447     mova                m9, [tmpq+18*%%str]
2448     %%STORE_2X2          8,  9,  2,  3, 12, 11, 10
2449
2450     ; store t12-13 and t18-19
2451     mova                m8, [tmpq+14*%%str]
2452     mova                m9, [tmpq+10*%%str]
2453     mova                m5, [tmpq+13*%%str]
2454     mova                m4, [tmpq+ 9*%%str]
2455     %%STORE_2X2          8,  9,  4,  5, 12, 11, 10
2456
2457     ; store t14-17
2458     mova                m8, [tmpq+ 6*%%str]
2459     mova                m9, [tmpq+ 2*%%str]
2460     mova                m5, [tmpq+29*%%str]
2461     mova                m4, [tmpq+21*%%str]
2462     %%STORE_2X2          8,  9,  4,  5, 12, 11, 10, 0
2463
2464     SWAP                 1, 10 ; zero
2465 %else
2466     mova   [tmpq+ 1*%%str], m1
2467     mova   [tmpq+11*%%str], m2
2468     mova   [tmpq+15*%%str], m3
2469     mova   [tmpq+17*%%str], m4
2470     mova   [tmpq+19*%%str], m5
2471     pxor                m1, m1
2472
2473     ; store t0-1 and t30-31
2474     mova                m2, [tmpq+ 0*%%str]
2475     mova                m3, [tmpq+ 4*%%str]
2476     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2477
2478     ; store t2-3 and t28-29
2479     mova                m2, [tmpq+ 8*%%str]
2480     mova                m3, [tmpq+12*%%str]
2481     mova                m0, [tmpq+ 3*%%str]
2482     mova                m6, [tmpq+ 7*%%str]
2483     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2484
2485     ; store t4-5 and t26-27
2486     mova                m2, [tmpq+16*%%str]
2487     mova                m3, [tmpq+20*%%str]
2488     mova                m0, [tmpq+ 1*%%str]
2489     %%STORE_2X2          2,  3,  7,  0, 4, 5, 1
2490
2491     ; store t6-7 and t24-25
2492     mova                m2, [tmpq+24*%%str]
2493     mova                m3, [tmpq+28*%%str]
2494     mova                m0, [tmpq+17*%%str]
2495     mova                m6, [tmpq+19*%%str]
2496     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2497
2498     ; store t8-9 and t22-23
2499     mova                m2, [tmpq+30*%%str]
2500     mova                m3, [tmpq+26*%%str]
2501     mova                m0, [tmpq+25*%%str]
2502     mova                m6, [tmpq+ 5*%%str]
2503     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2504
2505     ; store t10-11 and t20-21
2506     mova                m2, [tmpq+22*%%str]
2507     mova                m3, [tmpq+18*%%str]
2508     mova                m0, [tmpq+11*%%str]
2509     mova                m6, [tmpq+15*%%str]
2510     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2511
2512     ; store t12-13 and t18-19
2513     mova                m2, [tmpq+14*%%str]
2514     mova                m3, [tmpq+10*%%str]
2515     mova                m6, [tmpq+13*%%str]
2516     mova                m0, [tmpq+ 9*%%str]
2517     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1
2518
2519     ; store t14-17
2520     mova                m2, [tmpq+ 6*%%str]
2521     mova                m3, [tmpq+ 2*%%str]
2522     mova                m6, [tmpq+29*%%str]
2523     mova                m0, [tmpq+21*%%str]
2524     %%STORE_2X2          2,  3,  0,  6, 4, 5, 1, 0
2525 %endif
2526 %undef ROUND_REG
2527 %endif
2528 %endmacro
2529
2530 %macro VP9_IDCT_IDCT_32x32_ADD_XMM 1
2531 INIT_XMM %1
2532 cglobal vp9_idct_idct_32x32_add, 0, 6 + ARCH_X86_64 * 3, 16, 2048, dst, stride, block, eob
2533     movifnidn         eobd, dword eobm
2534 %if cpuflag(ssse3)
2535     cmp eobd, 135
2536     jg .idctfull
2537     cmp eobd, 34
2538     jg .idct16x16
2539     cmp eobd, 1
2540     jg .idct8x8
2541 %else
2542     cmp eobd, 1
2543     jg .idctfull
2544 %endif
2545
2546     ; dc-only case
2547     movifnidn       blockq, blockmp
2548     movifnidn         dstq, dstmp
2549     movifnidn      strideq, stridemp
2550 %if cpuflag(ssse3)
2551     movd                m0, [blockq]
2552     mova                m1, [pw_11585x2]
2553     pmulhrsw            m0, m1
2554     pmulhrsw            m0, m1
2555 %else
2556     DEFINE_ARGS dst, stride, block, coef
2557     movsx            coefd, word [blockq]
2558     imul             coefd, 11585
2559     add              coefd, 8192
2560     sar              coefd, 14
2561     imul             coefd, 11585
2562     add              coefd, (32 << 14) + 8192
2563     sar              coefd, 14 + 6
2564     movd                m0, coefd
2565 %endif
2566     SPLATW              m0, m0, q0000
2567 %if cpuflag(ssse3)
2568     pmulhrsw            m0, [pw_512]
2569 %endif
2570     pxor                m5, m5
2571     movd          [blockq], m5
2572 %rep 31
2573     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5, mmsize
2574     add               dstq, strideq
2575 %endrep
2576     VP9_STORE_2XFULL    0, 1, 2, 3, 4, 5, mmsize
2577     RET
2578
2579 %if ARCH_X86_64
2580     DEFINE_ARGS dst_bak, stride, block, cnt, dst, stride30, dst_end, stride2, tmp
2581 %else
2582 %define dst_bakq r0mp
2583 %endif
2584 %if cpuflag(ssse3)
2585 .idct8x8:
2586 %if ARCH_X86_32
2587     DEFINE_ARGS block, u1, u2, u3, u4, tmp
2588     mov             blockq, r2mp
2589 %endif
2590     mov               tmpq, rsp
2591     VP9_IDCT32_1D   blockq, 1, 8
2592
2593 %if ARCH_X86_32
2594     DEFINE_ARGS dst, stride, stride30, dst_end, stride2, tmp
2595     mov            strideq, r1mp
2596 %define cntd dword r3m
2597 %endif
2598     mov          stride30q, strideq         ; stride
2599     lea           stride2q, [strideq*2]     ; stride*2
2600     shl          stride30q, 5               ; stride*32
2601     mov               cntd, 4
2602     sub          stride30q, stride2q        ; stride*30
2603 .loop2_8x8:
2604     mov               dstq, dst_bakq
2605     lea           dst_endq, [dstq+stride30q]
2606     VP9_IDCT32_1D     tmpq, 2, 8
2607     add           dst_bakq, 8
2608     add               tmpq, 16
2609     dec               cntd
2610     jg .loop2_8x8
2611
2612     ; at the end of the loop, m7 should still be zero
2613     ; use that to zero out block coefficients
2614 %if ARCH_X86_32
2615     DEFINE_ARGS block
2616     mov             blockq, r2mp
2617 %endif
2618     ZERO_BLOCK      blockq, 64,  8, m1
2619     RET
2620
2621 .idct16x16:
2622 %if ARCH_X86_32
2623     DEFINE_ARGS block, tmp, cnt
2624     mov             blockq, r2mp
2625 %endif
2626     mov               cntd, 2
2627     mov               tmpq, rsp
2628 .loop1_16x16:
2629     VP9_IDCT32_1D   blockq, 1, 16
2630     add             blockq, 16
2631     add               tmpq, 512
2632     dec               cntd
2633     jg .loop1_16x16
2634
2635 %if ARCH_X86_64
2636     sub             blockq, 32
2637 %else
2638     DEFINE_ARGS dst, stride, stride30, dst_end, stride2, tmp
2639     mov            strideq, r1mp
2640 %define cntd dword r3m
2641 %endif
2642
2643     mov          stride30q, strideq         ; stride
2644     lea           stride2q, [strideq*2]     ; stride*2
2645     shl          stride30q, 5               ; stride*32
2646     mov               cntd, 4
2647     mov               tmpq, rsp
2648     sub          stride30q, stride2q        ; stride*30
2649 .loop2_16x16:
2650     mov               dstq, dst_bakq
2651     lea           dst_endq, [dstq+stride30q]
2652     VP9_IDCT32_1D     tmpq, 2, 16
2653     add           dst_bakq, 8
2654     add               tmpq, 16
2655     dec               cntd
2656     jg .loop2_16x16
2657
2658     ; at the end of the loop, m7 should still be zero
2659     ; use that to zero out block coefficients
2660 %if ARCH_X86_32
2661     DEFINE_ARGS block
2662     mov             blockq, r2mp
2663 %endif
2664     ZERO_BLOCK      blockq, 64, 16, m1
2665     RET
2666 %endif
2667
2668 .idctfull:
2669 %if ARCH_X86_32
2670     DEFINE_ARGS block, tmp, cnt
2671     mov             blockq, r2mp
2672 %endif
2673     mov               cntd, 4
2674     mov               tmpq, rsp
2675 .loop1_full:
2676     VP9_IDCT32_1D   blockq, 1
2677     add             blockq, 16
2678     add               tmpq, 512
2679     dec               cntd
2680     jg .loop1_full
2681
2682 %if ARCH_X86_64
2683     sub             blockq, 64
2684 %else
2685     DEFINE_ARGS dst, stride, stride30, dst_end, stride2, tmp
2686     mov            strideq, r1mp
2687 %define cntd dword r3m
2688 %endif
2689
2690     mov          stride30q, strideq         ; stride
2691     lea           stride2q, [strideq*2]     ; stride*2
2692     shl          stride30q, 5               ; stride*32
2693     mov               cntd, 4
2694     mov               tmpq, rsp
2695     sub          stride30q, stride2q        ; stride*30
2696 .loop2_full:
2697     mov               dstq, dst_bakq
2698     lea           dst_endq, [dstq+stride30q]
2699     VP9_IDCT32_1D     tmpq, 2
2700     add           dst_bakq, 8
2701     add               tmpq, 16
2702     dec               cntd
2703     jg .loop2_full
2704
2705     ; at the end of the loop, m7 should still be zero
2706     ; use that to zero out block coefficients
2707 %if ARCH_X86_32
2708     DEFINE_ARGS block
2709     mov             blockq, r2mp
2710 %endif
2711     ZERO_BLOCK      blockq, 64, 32, m1
2712     RET
2713 %endmacro
2714
2715 VP9_IDCT_IDCT_32x32_ADD_XMM sse2
2716 VP9_IDCT_IDCT_32x32_ADD_XMM ssse3
2717 VP9_IDCT_IDCT_32x32_ADD_XMM avx