]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
454f53f1f5c4c65f8641dbde2721ab6195c17bc9
[x264] / common / x86 / dct-a.asm
1 ;*****************************************************************************
2 ;* dct-a.asm: x86 transform and zigzag
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2016 x264 project
5 ;*
6 ;* Authors: Holger Lubitz <holger@lubitz.org>
7 ;*          Loren Merritt <lorenm@u.washington.edu>
8 ;*          Laurent Aimar <fenrir@via.ecp.fr>
9 ;*          Min Chen <chenm001.163.com>
10 ;*          Fiona Glaser <fiona@x264.com>
11 ;*
12 ;* This program is free software; you can redistribute it and/or modify
13 ;* it under the terms of the GNU General Public License as published by
14 ;* the Free Software Foundation; either version 2 of the License, or
15 ;* (at your option) any later version.
16 ;*
17 ;* This program is distributed in the hope that it will be useful,
18 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;* GNU General Public License for more details.
21 ;*
22 ;* You should have received a copy of the GNU General Public License
23 ;* along with this program; if not, write to the Free Software
24 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
25 ;*
26 ;* This program is also available under a commercial proprietary license.
27 ;* For more information, contact us at licensing@x264.com.
28 ;*****************************************************************************
29
30 %include "x86inc.asm"
31 %include "x86util.asm"
32
33 SECTION_RODATA 32
34 pw_ppmmmmpp:    dw 1,1,-1,-1,-1,-1,1,1
35 pb_sub4frame:   db 0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15
36 pb_sub4field:   db 0,4,1,8,12,5,9,13,2,6,10,14,3,7,11,15
37 pb_subacmask:   dw 0,-1,-1,-1,-1,-1,-1,-1
38 pb_scan4framea: SHUFFLE_MASK_W 6,3,7,0,4,1,2,5
39 pb_scan4frameb: SHUFFLE_MASK_W 0,4,1,2,5,6,3,7
40 pb_scan4frame2a: SHUFFLE_MASK_W 0,4,1,2,5,8,12,9
41 pb_scan4frame2b: SHUFFLE_MASK_W 6,3,7,10,13,14,11,15
42
43 pb_scan8framet1: SHUFFLE_MASK_W 0,  1,  6,  7,  8,  9, 13, 14
44 pb_scan8framet2: SHUFFLE_MASK_W 2 , 3,  4,  7,  9, 15, 10, 14
45 pb_scan8framet3: SHUFFLE_MASK_W 0,  1,  5,  6,  8, 11, 12, 13
46 pb_scan8framet4: SHUFFLE_MASK_W 0,  3,  4,  5,  8, 11, 12, 15
47 pb_scan8framet5: SHUFFLE_MASK_W 1,  2,  6,  7,  9, 10, 13, 14
48 pb_scan8framet6: SHUFFLE_MASK_W 0,  3,  4,  5, 10, 11, 12, 15
49 pb_scan8framet7: SHUFFLE_MASK_W 1,  2,  6,  7,  8,  9, 14, 15
50 pb_scan8framet8: SHUFFLE_MASK_W 0,  1,  2,  7,  8, 10, 11, 14
51 pb_scan8framet9: SHUFFLE_MASK_W 1,  4,  5,  7,  8, 13, 14, 15
52
53 pb_scan8frame1: SHUFFLE_MASK_W  0,  8,  1,  2,  9, 12,  4, 13
54 pb_scan8frame2: SHUFFLE_MASK_W  4,  0,  1,  5,  8, 10, 12, 14
55 pb_scan8frame3: SHUFFLE_MASK_W 12, 10,  8,  6,  2,  3,  7,  9
56 pb_scan8frame4: SHUFFLE_MASK_W  0,  1,  8, 12,  4, 13,  9,  2
57 pb_scan8frame5: SHUFFLE_MASK_W  5, 14, 10,  3, 11, 15,  6,  7
58 pb_scan8frame6: SHUFFLE_MASK_W  6,  8, 12, 13,  9,  7,  5,  3
59 pb_scan8frame7: SHUFFLE_MASK_W  1,  3,  5,  7, 10, 14, 15, 11
60 pb_scan8frame8: SHUFFLE_MASK_W  10, 3, 11, 14,  5,  6, 15,  7
61
62 pb_scan8field1 : SHUFFLE_MASK_W    0,   1,   2,   8,   9,   3,   4,  10
63 pb_scan8field2a: SHUFFLE_MASK_W 0x80,  11,   5,   6,   7,  12,0x80,0x80
64 pb_scan8field2b: SHUFFLE_MASK_W    0,0x80,0x80,0x80,0x80,0x80,   1,   8
65 pb_scan8field3a: SHUFFLE_MASK_W   10,   5,   6,   7,  11,0x80,0x80,0x80
66 pb_scan8field3b: SHUFFLE_MASK_W 0x80,0x80,0x80,0x80,0x80,   1,   8,   2
67 pb_scan8field4a: SHUFFLE_MASK_W    4,   5,   6,   7,  11,0x80,0x80,0x80
68 pb_scan8field6 : SHUFFLE_MASK_W    4,   5,   6,   7,  11,0x80,0x80,  12
69 pb_scan8field7 : SHUFFLE_MASK_W    5,   6,   7,  11,0x80,0x80,  12,  13
70
71 SECTION .text
72
73 cextern pw_32_0
74 cextern pw_32
75 cextern pw_512
76 cextern pw_8000
77 cextern pw_pixel_max
78 cextern hsub_mul
79 cextern pb_1
80 cextern pw_1
81 cextern pd_1
82 cextern pd_32
83 cextern pw_ppppmmmm
84 cextern pw_pmpmpmpm
85 cextern deinterleave_shufd
86 cextern pb_unpackbd1
87 cextern pb_unpackbd2
88
89 %macro WALSH4_1D 6
90     SUMSUB_BADC %1, %5, %4, %3, %2, %6
91     SUMSUB_BADC %1, %5, %3, %4, %2, %6
92     SWAP %2, %5, %4
93 %endmacro
94
95 %macro SUMSUB_17BIT 4 ; a, b, tmp, 0x8000
96     movq  m%3, m%4
97     pxor  m%1, m%4
98     psubw m%3, m%2
99     pxor  m%2, m%4
100     pavgw m%3, m%1
101     pavgw m%2, m%1
102     pxor  m%3, m%4
103     pxor  m%2, m%4
104     SWAP %1, %2, %3
105 %endmacro
106
107 %macro DCT_UNPACK 3
108     punpcklwd %3, %1
109     punpckhwd %2, %1
110     psrad     %3, 16
111     psrad     %2, 16
112     SWAP      %1, %3
113 %endmacro
114
115 %if HIGH_BIT_DEPTH
116 ;-----------------------------------------------------------------------------
117 ; void dct4x4dc( dctcoef d[4][4] )
118 ;-----------------------------------------------------------------------------
119 %macro DCT4x4_DC 0
120 cglobal dct4x4dc, 1,1,5
121     mova   m0, [r0+ 0]
122     mova   m1, [r0+16]
123     mova   m2, [r0+32]
124     mova   m3, [r0+48]
125     WALSH4_1D  d, 0,1,2,3,4
126     TRANSPOSE4x4D 0,1,2,3,4
127     paddd  m0, [pd_1]
128     WALSH4_1D  d, 0,1,2,3,4
129     psrad  m0, 1
130     psrad  m1, 1
131     psrad  m2, 1
132     psrad  m3, 1
133     mova [r0+ 0], m0
134     mova [r0+16], m1
135     mova [r0+32], m2
136     mova [r0+48], m3
137     RET
138 %endmacro ; DCT4x4_DC
139
140 INIT_XMM sse2
141 DCT4x4_DC
142 INIT_XMM avx
143 DCT4x4_DC
144 %else
145
146 INIT_MMX mmx2
147 cglobal dct4x4dc, 1,1
148     movq   m3, [r0+24]
149     movq   m2, [r0+16]
150     movq   m1, [r0+ 8]
151     movq   m0, [r0+ 0]
152     movq   m7, [pw_8000] ; convert to unsigned and back, so that pavgw works
153     WALSH4_1D  w, 0,1,2,3,4
154     TRANSPOSE4x4W 0,1,2,3,4
155     SUMSUB_BADC w, 1, 0, 3, 2, 4
156     SWAP 0, 1
157     SWAP 2, 3
158     SUMSUB_17BIT 0,2,4,7
159     SUMSUB_17BIT 1,3,5,7
160     movq  [r0+0], m0
161     movq  [r0+8], m2
162     movq [r0+16], m3
163     movq [r0+24], m1
164     RET
165 %endif ; HIGH_BIT_DEPTH
166
167 %if HIGH_BIT_DEPTH
168 ;-----------------------------------------------------------------------------
169 ; void idct4x4dc( int32_t d[4][4] )
170 ;-----------------------------------------------------------------------------
171 %macro IDCT4x4DC 0
172 cglobal idct4x4dc, 1,1
173     mova   m3, [r0+48]
174     mova   m2, [r0+32]
175     mova   m1, [r0+16]
176     mova   m0, [r0+ 0]
177     WALSH4_1D  d,0,1,2,3,4
178     TRANSPOSE4x4D 0,1,2,3,4
179     WALSH4_1D  d,0,1,2,3,4
180     mova  [r0+ 0], m0
181     mova  [r0+16], m1
182     mova  [r0+32], m2
183     mova  [r0+48], m3
184     RET
185 %endmacro ; IDCT4x4DC
186
187 INIT_XMM sse2
188 IDCT4x4DC
189 INIT_XMM avx
190 IDCT4x4DC
191 %else
192
193 ;-----------------------------------------------------------------------------
194 ; void idct4x4dc( int16_t d[4][4] )
195 ;-----------------------------------------------------------------------------
196 INIT_MMX mmx
197 cglobal idct4x4dc, 1,1
198     movq   m3, [r0+24]
199     movq   m2, [r0+16]
200     movq   m1, [r0+ 8]
201     movq   m0, [r0+ 0]
202     WALSH4_1D  w,0,1,2,3,4
203     TRANSPOSE4x4W 0,1,2,3,4
204     WALSH4_1D  w,0,1,2,3,4
205     movq  [r0+ 0], m0
206     movq  [r0+ 8], m1
207     movq  [r0+16], m2
208     movq  [r0+24], m3
209     RET
210 %endif ; HIGH_BIT_DEPTH
211
212 ;-----------------------------------------------------------------------------
213 ; void dct2x4dc( dctcoef dct[8], dctcoef dct4x4[8][16] )
214 ;-----------------------------------------------------------------------------
215 %if WIN64
216     DECLARE_REG_TMP 6 ; Avoid some REX prefixes to reduce code size
217 %else
218     DECLARE_REG_TMP 2
219 %endif
220
221 %macro INSERT_COEFF 3 ; dst, src, imm
222     %if %3
223         %if HIGH_BIT_DEPTH
224             %if cpuflag(sse4)
225                 pinsrd %1, %2, %3
226             %elif %3 == 2
227                 movd       m2, %2
228             %elif %3 == 1
229                 punpckldq  %1, %2
230             %else
231                 punpckldq  m2, %2
232                 punpcklqdq %1, m2
233             %endif
234         %else
235             %if %3 == 2
236                 punpckldq  %1, %2
237             %else
238                 pinsrw %1, %2, %3
239             %endif
240         %endif
241     %else
242         movd %1, %2
243     %endif
244     %if HIGH_BIT_DEPTH
245         mov %2, t0d
246     %else
247         mov %2, t0w
248     %endif
249 %endmacro
250
251 %macro DCT2x4DC 2
252 cglobal dct2x4dc, 2,3
253     xor          t0d, t0d
254     INSERT_COEFF  m0, [r1+0*16*SIZEOF_DCTCOEF], 0
255     INSERT_COEFF  m0, [r1+1*16*SIZEOF_DCTCOEF], 2
256     add           r1, 4*16*SIZEOF_DCTCOEF
257     INSERT_COEFF  m0, [r1-2*16*SIZEOF_DCTCOEF], 1
258     INSERT_COEFF  m0, [r1-1*16*SIZEOF_DCTCOEF], 3
259     INSERT_COEFF  m1, [r1+0*16*SIZEOF_DCTCOEF], 0
260     INSERT_COEFF  m1, [r1+1*16*SIZEOF_DCTCOEF], 2
261     INSERT_COEFF  m1, [r1+2*16*SIZEOF_DCTCOEF], 1
262     INSERT_COEFF  m1, [r1+3*16*SIZEOF_DCTCOEF], 3
263     SUMSUB_BA     %1, 1, 0, 2
264     SBUTTERFLY    %2, 1, 0, 2
265     SUMSUB_BA     %1, 0, 1, 2
266     SBUTTERFLY    %2, 0, 1, 2
267     SUMSUB_BA     %1, 1, 0, 2
268     pshuf%1       m0, m0, q1032
269     mova        [r0], m1
270     mova [r0+mmsize], m0
271     RET
272 %endmacro
273
274 %if HIGH_BIT_DEPTH
275 INIT_XMM sse2
276 DCT2x4DC d, dq
277 INIT_XMM avx
278 DCT2x4DC d, dq
279 %else
280 INIT_MMX mmx2
281 DCT2x4DC w, wd
282 %endif
283
284 %if HIGH_BIT_DEPTH
285 ;-----------------------------------------------------------------------------
286 ; void sub4x4_dct( dctcoef dct[4][4], pixel *pix1, pixel *pix2 )
287 ;-----------------------------------------------------------------------------
288 INIT_MMX mmx
289 cglobal sub4x4_dct, 3,3
290 .skip_prologue:
291     LOAD_DIFF  m0, m4, none, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
292     LOAD_DIFF  m3, m4, none, [r1+6*FENC_STRIDE], [r2+6*FDEC_STRIDE]
293     LOAD_DIFF  m1, m4, none, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
294     LOAD_DIFF  m2, m4, none, [r1+4*FENC_STRIDE], [r2+4*FDEC_STRIDE]
295     DCT4_1D 0,1,2,3,4
296     TRANSPOSE4x4W 0,1,2,3,4
297
298     SUMSUB_BADC w, 3, 0, 2, 1
299     SUMSUB_BA   w, 2, 3, 4
300     DCT_UNPACK m2, m4, m5
301     DCT_UNPACK m3, m6, m7
302     mova  [r0+ 0], m2 ; s03 + s12
303     mova  [r0+ 8], m4
304     mova  [r0+32], m3 ; s03 - s12
305     mova  [r0+40], m6
306
307     DCT_UNPACK m0, m2, m4
308     DCT_UNPACK m1, m3, m5
309     SUMSUB2_AB  d, 0, 1, 4
310     SUMSUB2_AB  d, 2, 3, 5
311     mova  [r0+16], m0 ; d03*2 + d12
312     mova  [r0+24], m2
313     mova  [r0+48], m4 ; d03 - 2*d12
314     mova  [r0+56], m5
315     RET
316 %else
317
318 %macro SUB_DCT4 0
319 cglobal sub4x4_dct, 3,3
320 .skip_prologue:
321 %if cpuflag(ssse3)
322     mova m5, [hsub_mul]
323 %endif
324     LOAD_DIFF8x4 0, 3, 1, 2, 4, 5, r1, r2
325     DCT4_1D 0,1,2,3,4
326     TRANSPOSE4x4W 0,1,2,3,4
327     DCT4_1D 0,1,2,3,4
328     movq  [r0+ 0], m0
329     movq  [r0+ 8], m1
330     movq  [r0+16], m2
331     movq  [r0+24], m3
332     RET
333 %endmacro
334
335 INIT_MMX mmx
336 SUB_DCT4
337 INIT_MMX ssse3
338 SUB_DCT4
339 %endif ; HIGH_BIT_DEPTH
340
341 %if HIGH_BIT_DEPTH
342 ;-----------------------------------------------------------------------------
343 ; void add4x4_idct( pixel *p_dst, dctcoef dct[4][4] )
344 ;-----------------------------------------------------------------------------
345 %macro STORE_DIFFx2 6
346     psrad     %1, 6
347     psrad     %2, 6
348     packssdw  %1, %2
349     movq      %3, %5
350     movhps    %3, %6
351     paddsw    %1, %3
352     CLIPW     %1, %4, [pw_pixel_max]
353     movq      %5, %1
354     movhps    %6, %1
355 %endmacro
356
357 %macro ADD4x4_IDCT 0
358 cglobal add4x4_idct, 2,2,6
359     add   r0, 2*FDEC_STRIDEB
360 .skip_prologue:
361     mova  m1, [r1+16]
362     mova  m3, [r1+48]
363     mova  m2, [r1+32]
364     mova  m0, [r1+ 0]
365     IDCT4_1D d,0,1,2,3,4,5
366     TRANSPOSE4x4D 0,1,2,3,4
367     paddd m0, [pd_32]
368     IDCT4_1D d,0,1,2,3,4,5
369     pxor  m5, m5
370     STORE_DIFFx2 m0, m1, m4, m5, [r0-2*FDEC_STRIDEB], [r0-1*FDEC_STRIDEB]
371     STORE_DIFFx2 m2, m3, m4, m5, [r0+0*FDEC_STRIDEB], [r0+1*FDEC_STRIDEB]
372     RET
373 %endmacro
374
375 INIT_XMM sse2
376 ADD4x4_IDCT
377 INIT_XMM avx
378 ADD4x4_IDCT
379
380 %else ; !HIGH_BIT_DEPTH
381
382 INIT_MMX mmx
383 cglobal add4x4_idct, 2,2
384     pxor m7, m7
385 .skip_prologue:
386     movq  m1, [r1+ 8]
387     movq  m3, [r1+24]
388     movq  m2, [r1+16]
389     movq  m0, [r1+ 0]
390     IDCT4_1D w,0,1,2,3,4,5
391     TRANSPOSE4x4W 0,1,2,3,4
392     paddw m0, [pw_32]
393     IDCT4_1D w,0,1,2,3,4,5
394     STORE_DIFF  m0, m4, m7, [r0+0*FDEC_STRIDE]
395     STORE_DIFF  m1, m4, m7, [r0+1*FDEC_STRIDE]
396     STORE_DIFF  m2, m4, m7, [r0+2*FDEC_STRIDE]
397     STORE_DIFF  m3, m4, m7, [r0+3*FDEC_STRIDE]
398     RET
399
400 %macro ADD4x4 0
401 cglobal add4x4_idct, 2,2,6
402     mova      m1, [r1+0x00]     ; row1/row0
403     mova      m3, [r1+0x10]     ; row3/row2
404     psraw     m0, m1, 1         ; row1>>1/...
405     psraw     m2, m3, 1         ; row3>>1/...
406     movsd     m0, m1            ; row1>>1/row0
407     movsd     m2, m3            ; row3>>1/row2
408     psubw     m0, m3            ; row1>>1-row3/row0-2
409     paddw     m2, m1            ; row3>>1+row1/row0+2
410     SBUTTERFLY2 wd, 0, 2, 1
411     SUMSUB_BA w, 2, 0, 1
412     pshuflw   m1, m2, q2301
413     pshufhw   m2, m2, q2301
414     punpckldq m1, m0
415     punpckhdq m2, m0
416     SWAP       0, 1
417
418     mova      m1, [pw_32_0]
419     paddw     m1, m0            ; row1/row0 corrected
420     psraw     m0, 1             ; row1>>1/...
421     psraw     m3, m2, 1         ; row3>>1/...
422     movsd     m0, m1            ; row1>>1/row0
423     movsd     m3, m2            ; row3>>1/row2
424     psubw     m0, m2            ; row1>>1-row3/row0-2
425     paddw     m3, m1            ; row3>>1+row1/row0+2
426     SBUTTERFLY2 qdq, 0, 3, 1
427     SUMSUB_BA w, 3, 0, 1
428
429     movd      m4, [r0+FDEC_STRIDE*0]
430     movd      m1, [r0+FDEC_STRIDE*1]
431     movd      m2, [r0+FDEC_STRIDE*2]
432     movd      m5, [r0+FDEC_STRIDE*3]
433     punpckldq m1, m4            ; row0/row1
434     pxor      m4, m4
435     punpckldq m2, m5            ; row3/row2
436     punpcklbw m1, m4
437     psraw     m3, 6
438     punpcklbw m2, m4
439     psraw     m0, 6
440     paddsw    m3, m1
441     paddsw    m0, m2
442     packuswb  m0, m3            ; row0/row1/row3/row2
443     pextrd   [r0+FDEC_STRIDE*0], m0, 3
444     pextrd   [r0+FDEC_STRIDE*1], m0, 2
445     movd     [r0+FDEC_STRIDE*2], m0
446     pextrd   [r0+FDEC_STRIDE*3], m0, 1
447     RET
448 %endmacro ; ADD4x4
449
450 INIT_XMM sse4
451 ADD4x4
452 INIT_XMM avx
453 ADD4x4
454
455 %macro STOREx2_AVX2 9
456     movq      xm%3, [r0+%5*FDEC_STRIDE]
457     vinserti128 m%3, m%3, [r0+%6*FDEC_STRIDE], 1
458     movq      xm%4, [r0+%7*FDEC_STRIDE]
459     vinserti128 m%4, m%4, [r0+%8*FDEC_STRIDE], 1
460     punpcklbw  m%3, m%9
461     punpcklbw  m%4, m%9
462     psraw      m%1, 6
463     psraw      m%2, 6
464     paddsw     m%1, m%3
465     paddsw     m%2, m%4
466     packuswb   m%1, m%2
467     vextracti128 xm%2, m%1, 1
468     movq   [r0+%5*FDEC_STRIDE], xm%1
469     movq   [r0+%6*FDEC_STRIDE], xm%2
470     movhps [r0+%7*FDEC_STRIDE], xm%1
471     movhps [r0+%8*FDEC_STRIDE], xm%2
472 %endmacro
473
474 INIT_YMM avx2
475 cglobal add8x8_idct, 2,3,8
476     add    r0, 4*FDEC_STRIDE
477     pxor   m7, m7
478     TAIL_CALL .skip_prologue, 0
479 global current_function %+ .skip_prologue
480 .skip_prologue:
481     ; TRANSPOSE4x4Q
482     mova       xm0, [r1+ 0]
483     mova       xm1, [r1+32]
484     mova       xm2, [r1+16]
485     mova       xm3, [r1+48]
486     vinserti128 m0, m0, [r1+ 64], 1
487     vinserti128 m1, m1, [r1+ 96], 1
488     vinserti128 m2, m2, [r1+ 80], 1
489     vinserti128 m3, m3, [r1+112], 1
490     SBUTTERFLY qdq, 0, 1, 4
491     SBUTTERFLY qdq, 2, 3, 4
492     IDCT4_1D w,0,1,2,3,4,5
493     TRANSPOSE2x4x4W 0,1,2,3,4
494     paddw m0, [pw_32]
495     IDCT4_1D w,0,1,2,3,4,5
496     STOREx2_AVX2 0, 1, 4, 5, -4, 0, -3, 1, 7
497     STOREx2_AVX2 2, 3, 4, 5, -2, 2, -1, 3, 7
498     ret
499
500 ; 2xdst, 2xtmp, 4xsrcrow, 1xzero
501 %macro LOAD_DIFF8x2_AVX2 9
502     movq    xm%1, [r1+%5*FENC_STRIDE]
503     movq    xm%2, [r1+%6*FENC_STRIDE]
504     vinserti128 m%1, m%1, [r1+%7*FENC_STRIDE], 1
505     vinserti128 m%2, m%2, [r1+%8*FENC_STRIDE], 1
506     punpcklbw m%1, m%9
507     punpcklbw m%2, m%9
508     movq    xm%3, [r2+(%5-4)*FDEC_STRIDE]
509     movq    xm%4, [r2+(%6-4)*FDEC_STRIDE]
510     vinserti128 m%3, m%3, [r2+(%7-4)*FDEC_STRIDE], 1
511     vinserti128 m%4, m%4, [r2+(%8-4)*FDEC_STRIDE], 1
512     punpcklbw m%3, m%9
513     punpcklbw m%4, m%9
514     psubw    m%1, m%3
515     psubw    m%2, m%4
516 %endmacro
517
518 ; 4x src, 1x tmp
519 %macro STORE8_DCT_AVX2 5
520     SBUTTERFLY qdq, %1, %2, %5
521     SBUTTERFLY qdq, %3, %4, %5
522     mova [r0+  0], xm%1
523     mova [r0+ 16], xm%3
524     mova [r0+ 32], xm%2
525     mova [r0+ 48], xm%4
526     vextracti128 [r0+ 64], m%1, 1
527     vextracti128 [r0+ 80], m%3, 1
528     vextracti128 [r0+ 96], m%2, 1
529     vextracti128 [r0+112], m%4, 1
530 %endmacro
531
532 %macro STORE16_DCT_AVX2 5
533     SBUTTERFLY qdq, %1, %2, %5
534     SBUTTERFLY qdq, %3, %4, %5
535     mova [r0+ 0-128], xm%1
536     mova [r0+16-128], xm%3
537     mova [r0+32-128], xm%2
538     mova [r0+48-128], xm%4
539     vextracti128 [r0+ 0], m%1, 1
540     vextracti128 [r0+16], m%3, 1
541     vextracti128 [r0+32], m%2, 1
542     vextracti128 [r0+48], m%4, 1
543 %endmacro
544
545 INIT_YMM avx2
546 cglobal sub8x8_dct, 3,3,7
547     pxor m6, m6
548     add r2, 4*FDEC_STRIDE
549     LOAD_DIFF8x2_AVX2 0, 1, 4, 5, 0, 1, 4, 5, 6
550     LOAD_DIFF8x2_AVX2 2, 3, 4, 5, 2, 3, 6, 7, 6
551     DCT4_1D 0, 1, 2, 3, 4
552     TRANSPOSE2x4x4W 0, 1, 2, 3, 4
553     DCT4_1D 0, 1, 2, 3, 4
554     STORE8_DCT_AVX2 0, 1, 2, 3, 4
555     RET
556
557 INIT_YMM avx2
558 cglobal sub16x16_dct, 3,3,6
559     add r0, 128
560     add r2, 4*FDEC_STRIDE
561     call .sub16x4_dct
562     add r0, 64
563     add r1, 4*FENC_STRIDE
564     add r2, 4*FDEC_STRIDE
565     call .sub16x4_dct
566     add r0, 256-64
567     add r1, 4*FENC_STRIDE
568     add r2, 4*FDEC_STRIDE
569     call .sub16x4_dct
570     add r0, 64
571     add r1, 4*FENC_STRIDE
572     add r2, 4*FDEC_STRIDE
573     call .sub16x4_dct
574     RET
575 .sub16x4_dct:
576     LOAD_DIFF16x2_AVX2 0, 1, 4, 5, 0, 1
577     LOAD_DIFF16x2_AVX2 2, 3, 4, 5, 2, 3
578     DCT4_1D 0, 1, 2, 3, 4
579     TRANSPOSE2x4x4W 0, 1, 2, 3, 4
580     DCT4_1D 0, 1, 2, 3, 4
581     STORE16_DCT_AVX2 0, 1, 2, 3, 4
582     ret
583 %endif ; HIGH_BIT_DEPTH
584
585 INIT_MMX
586 ;-----------------------------------------------------------------------------
587 ; void sub8x8_dct( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
588 ;-----------------------------------------------------------------------------
589 %macro SUB_NxN_DCT 7
590 cglobal %1, 3,3,%7
591 %if HIGH_BIT_DEPTH == 0
592 %if mmsize == 8
593     pxor m7, m7
594 %else
595     add r2, 4*FDEC_STRIDE
596     mova m7, [hsub_mul]
597 %endif
598 %endif ; !HIGH_BIT_DEPTH
599 .skip_prologue:
600     call %2.skip_prologue
601     add  r0, %3
602     add  r1, %4-%5-%6*FENC_STRIDE
603     add  r2, %4-%5-%6*FDEC_STRIDE
604     call %2.skip_prologue
605     add  r0, %3
606     add  r1, (%4-%6)*FENC_STRIDE-%5-%4
607     add  r2, (%4-%6)*FDEC_STRIDE-%5-%4
608     call %2.skip_prologue
609     add  r0, %3
610     add  r1, %4-%5-%6*FENC_STRIDE
611     add  r2, %4-%5-%6*FDEC_STRIDE
612     TAIL_CALL %2.skip_prologue, 1
613 %endmacro
614
615 ;-----------------------------------------------------------------------------
616 ; void add8x8_idct( uint8_t *pix, int16_t dct[4][4][4] )
617 ;-----------------------------------------------------------------------------
618 %macro ADD_NxN_IDCT 6-7
619 %if HIGH_BIT_DEPTH
620 cglobal %1, 2,2,%7
621 %if %3==256
622     add r1, 128
623 %endif
624 %else
625 cglobal %1, 2,2,11
626     pxor m7, m7
627 %endif
628 %if mmsize>=16 && %3!=256
629     add  r0, 4*FDEC_STRIDE
630 %endif
631 .skip_prologue:
632     call %2.skip_prologue
633     add  r0, %4-%5-%6*FDEC_STRIDE
634     add  r1, %3
635     call %2.skip_prologue
636     add  r0, (%4-%6)*FDEC_STRIDE-%5-%4
637     add  r1, %3
638     call %2.skip_prologue
639     add  r0, %4-%5-%6*FDEC_STRIDE
640     add  r1, %3
641     TAIL_CALL %2.skip_prologue, 1
642 %endmacro
643
644 %if HIGH_BIT_DEPTH
645 INIT_MMX
646 SUB_NxN_DCT  sub8x8_dct_mmx,     sub4x4_dct_mmx,   64,  8, 0, 0, 0
647 SUB_NxN_DCT  sub16x16_dct_mmx,   sub8x8_dct_mmx,   64, 16, 8, 8, 0
648 INIT_XMM
649 ADD_NxN_IDCT add8x8_idct_sse2,   add4x4_idct_sse2, 64,  8, 0, 0, 6
650 ADD_NxN_IDCT add16x16_idct_sse2, add8x8_idct_sse2, 64, 16, 8, 8, 6
651 ADD_NxN_IDCT add8x8_idct_avx,    add4x4_idct_avx,  64,  8, 0, 0, 6
652 ADD_NxN_IDCT add16x16_idct_avx,  add8x8_idct_avx,  64, 16, 8, 8, 6
653 cextern add8x8_idct8_sse2.skip_prologue
654 cextern add8x8_idct8_avx.skip_prologue
655 ADD_NxN_IDCT add16x16_idct8_sse2, add8x8_idct8_sse2, 256, 16, 0, 0, 16
656 ADD_NxN_IDCT add16x16_idct8_avx,  add8x8_idct8_avx,  256, 16, 0, 0, 16
657 cextern sub8x8_dct8_sse2.skip_prologue
658 cextern sub8x8_dct8_sse4.skip_prologue
659 cextern sub8x8_dct8_avx.skip_prologue
660 SUB_NxN_DCT  sub16x16_dct8_sse2, sub8x8_dct8_sse2, 256, 16, 0, 0, 14
661 SUB_NxN_DCT  sub16x16_dct8_sse4, sub8x8_dct8_sse4, 256, 16, 0, 0, 14
662 SUB_NxN_DCT  sub16x16_dct8_avx,  sub8x8_dct8_avx,  256, 16, 0, 0, 14
663 %else ; !HIGH_BIT_DEPTH
664 %if ARCH_X86_64 == 0
665 INIT_MMX
666 SUB_NxN_DCT  sub8x8_dct_mmx,     sub4x4_dct_mmx,   32, 4, 0, 0, 0
667 ADD_NxN_IDCT add8x8_idct_mmx,    add4x4_idct_mmx,  32, 4, 0, 0
668 SUB_NxN_DCT  sub16x16_dct_mmx,   sub8x8_dct_mmx,   32, 8, 4, 4, 0
669 ADD_NxN_IDCT add16x16_idct_mmx,  add8x8_idct_mmx,  32, 8, 4, 4
670
671 cextern sub8x8_dct8_mmx.skip_prologue
672 cextern add8x8_idct8_mmx.skip_prologue
673 SUB_NxN_DCT  sub16x16_dct8_mmx,  sub8x8_dct8_mmx,  128, 8, 0, 0, 0
674 ADD_NxN_IDCT add16x16_idct8_mmx, add8x8_idct8_mmx, 128, 8, 0, 0
675 %endif
676
677 INIT_XMM
678 cextern sub8x8_dct_sse2.skip_prologue
679 cextern sub8x8_dct_ssse3.skip_prologue
680 cextern sub8x8_dct_avx.skip_prologue
681 cextern sub8x8_dct_xop.skip_prologue
682 SUB_NxN_DCT  sub16x16_dct_sse2,  sub8x8_dct_sse2,  128, 8, 0, 0, 10
683 SUB_NxN_DCT  sub16x16_dct_ssse3, sub8x8_dct_ssse3, 128, 8, 0, 0, 10
684 SUB_NxN_DCT  sub16x16_dct_avx,   sub8x8_dct_avx,   128, 8, 0, 0, 10
685 SUB_NxN_DCT  sub16x16_dct_xop,   sub8x8_dct_xop,   128, 8, 0, 0, 10
686
687 cextern add8x8_idct_sse2.skip_prologue
688 cextern add8x8_idct_avx.skip_prologue
689 ADD_NxN_IDCT add16x16_idct_sse2, add8x8_idct_sse2, 128, 8, 0, 0
690 ADD_NxN_IDCT add16x16_idct_avx,  add8x8_idct_avx,  128, 8, 0, 0
691
692 cextern add8x8_idct8_sse2.skip_prologue
693 cextern add8x8_idct8_avx.skip_prologue
694 ADD_NxN_IDCT add16x16_idct8_sse2, add8x8_idct8_sse2, 128, 8, 0, 0
695 ADD_NxN_IDCT add16x16_idct8_avx,  add8x8_idct8_avx,  128, 8, 0, 0
696
697 cextern sub8x8_dct8_sse2.skip_prologue
698 cextern sub8x8_dct8_ssse3.skip_prologue
699 cextern sub8x8_dct8_avx.skip_prologue
700 SUB_NxN_DCT  sub16x16_dct8_sse2,  sub8x8_dct8_sse2,  128, 8, 0, 0, 11
701 SUB_NxN_DCT  sub16x16_dct8_ssse3, sub8x8_dct8_ssse3, 128, 8, 0, 0, 11
702 SUB_NxN_DCT  sub16x16_dct8_avx,   sub8x8_dct8_avx,   128, 8, 0, 0, 11
703
704 INIT_YMM
705 ADD_NxN_IDCT add16x16_idct_avx2, add8x8_idct_avx2, 128, 8, 0, 0
706 %endif ; HIGH_BIT_DEPTH
707
708 %if HIGH_BIT_DEPTH
709 ;-----------------------------------------------------------------------------
710 ; void add8x8_idct_dc( pixel *p_dst, dctcoef *dct2x2 )
711 ;-----------------------------------------------------------------------------
712 %macro ADD_DC 2
713     mova    m0, [%1+FDEC_STRIDEB*0] ; 8pixels
714     mova    m1, [%1+FDEC_STRIDEB*1]
715     mova    m2, [%1+FDEC_STRIDEB*2]
716     paddsw  m0, %2
717     paddsw  m1, %2
718     paddsw  m2, %2
719     paddsw  %2, [%1+FDEC_STRIDEB*3]
720     CLIPW   m0, m5, m6
721     CLIPW   m1, m5, m6
722     CLIPW   m2, m5, m6
723     CLIPW   %2, m5, m6
724     mova    [%1+FDEC_STRIDEB*0], m0
725     mova    [%1+FDEC_STRIDEB*1], m1
726     mova    [%1+FDEC_STRIDEB*2], m2
727     mova    [%1+FDEC_STRIDEB*3], %2
728 %endmacro
729
730 %macro ADD_IDCT_DC 0
731 cglobal add8x8_idct_dc, 2,2,7
732     mova        m6, [pw_pixel_max]
733     pxor        m5, m5
734     mova        m3, [r1]
735     paddd       m3, [pd_32]
736     psrad       m3, 6         ; dc0   0 dc1   0 dc2   0 dc3   0
737     pshuflw     m4, m3, q2200 ; dc0 dc0 dc1 dc1   _   _   _   _
738     pshufhw     m3, m3, q2200 ;   _   _   _   _ dc2 dc2 dc3 dc3
739     pshufd      m4, m4, q1100 ; dc0 dc0 dc0 dc0 dc1 dc1 dc1 dc1
740     pshufd      m3, m3, q3322 ; dc2 dc2 dc2 dc2 dc3 dc3 dc3 dc3
741     ADD_DC r0+FDEC_STRIDEB*0, m4
742     ADD_DC r0+FDEC_STRIDEB*4, m3
743     RET
744
745 cglobal add16x16_idct_dc, 2,3,8
746     mov         r2, 4
747     mova        m6, [pw_pixel_max]
748     mova        m7, [pd_32]
749     pxor        m5, m5
750 .loop:
751     mova        m3, [r1]
752     paddd       m3, m7
753     psrad       m3, 6         ; dc0   0 dc1   0 dc2   0 dc3   0
754     pshuflw     m4, m3, q2200 ; dc0 dc0 dc1 dc1   _   _   _   _
755     pshufhw     m3, m3, q2200 ;   _   _   _   _ dc2 dc2 dc3 dc3
756     pshufd      m4, m4, q1100 ; dc0 dc0 dc0 dc0 dc1 dc1 dc1 dc1
757     pshufd      m3, m3, q3322 ; dc2 dc2 dc2 dc2 dc3 dc3 dc3 dc3
758     ADD_DC r0+FDEC_STRIDEB*0, m4
759     ADD_DC r0+SIZEOF_PIXEL*8, m3
760     add         r1, 16
761     add         r0, 4*FDEC_STRIDEB
762     dec         r2
763     jg .loop
764     RET
765 %endmacro ; ADD_IDCT_DC
766
767 INIT_XMM sse2
768 ADD_IDCT_DC
769 INIT_XMM avx
770 ADD_IDCT_DC
771
772 %else ;!HIGH_BIT_DEPTH
773 %macro ADD_DC 3
774     mova    m4, [%3+FDEC_STRIDE*0]
775     mova    m5, [%3+FDEC_STRIDE*1]
776     mova    m6, [%3+FDEC_STRIDE*2]
777     paddusb m4, %1
778     paddusb m5, %1
779     paddusb m6, %1
780     paddusb %1, [%3+FDEC_STRIDE*3]
781     psubusb m4, %2
782     psubusb m5, %2
783     psubusb m6, %2
784     psubusb %1, %2
785     mova [%3+FDEC_STRIDE*0], m4
786     mova [%3+FDEC_STRIDE*1], m5
787     mova [%3+FDEC_STRIDE*2], m6
788     mova [%3+FDEC_STRIDE*3], %1
789 %endmacro
790
791 INIT_MMX mmx2
792 cglobal add8x8_idct_dc, 2,2
793     mova      m0, [r1]
794     pxor      m1, m1
795     add       r0, FDEC_STRIDE*4
796     paddw     m0, [pw_32]
797     psraw     m0, 6
798     psubw     m1, m0
799     packuswb  m0, m0
800     packuswb  m1, m1
801     punpcklbw m0, m0
802     punpcklbw m1, m1
803     pshufw    m2, m0, q3322
804     pshufw    m3, m1, q3322
805     punpcklbw m0, m0
806     punpcklbw m1, m1
807     ADD_DC    m0, m1, r0-FDEC_STRIDE*4
808     ADD_DC    m2, m3, r0
809     RET
810
811 INIT_XMM ssse3
812 cglobal add8x8_idct_dc, 2,2
813     movh     m0, [r1]
814     pxor     m1, m1
815     add      r0, FDEC_STRIDE*4
816     pmulhrsw m0, [pw_512]
817     psubw    m1, m0
818     mova     m5, [pb_unpackbd1]
819     packuswb m0, m0
820     packuswb m1, m1
821     pshufb   m0, m5
822     pshufb   m1, m5
823     movh     m2, [r0+FDEC_STRIDE*-4]
824     movh     m3, [r0+FDEC_STRIDE*-3]
825     movh     m4, [r0+FDEC_STRIDE*-2]
826     movh     m5, [r0+FDEC_STRIDE*-1]
827     movhps   m2, [r0+FDEC_STRIDE* 0]
828     movhps   m3, [r0+FDEC_STRIDE* 1]
829     movhps   m4, [r0+FDEC_STRIDE* 2]
830     movhps   m5, [r0+FDEC_STRIDE* 3]
831     paddusb  m2, m0
832     paddusb  m3, m0
833     paddusb  m4, m0
834     paddusb  m5, m0
835     psubusb  m2, m1
836     psubusb  m3, m1
837     psubusb  m4, m1
838     psubusb  m5, m1
839     movh   [r0+FDEC_STRIDE*-4], m2
840     movh   [r0+FDEC_STRIDE*-3], m3
841     movh   [r0+FDEC_STRIDE*-2], m4
842     movh   [r0+FDEC_STRIDE*-1], m5
843     movhps [r0+FDEC_STRIDE* 0], m2
844     movhps [r0+FDEC_STRIDE* 1], m3
845     movhps [r0+FDEC_STRIDE* 2], m4
846     movhps [r0+FDEC_STRIDE* 3], m5
847     RET
848
849 INIT_MMX mmx2
850 cglobal add16x16_idct_dc, 2,3
851     mov       r2, 4
852 .loop:
853     mova      m0, [r1]
854     pxor      m1, m1
855     paddw     m0, [pw_32]
856     psraw     m0, 6
857     psubw     m1, m0
858     packuswb  m0, m0
859     packuswb  m1, m1
860     punpcklbw m0, m0
861     punpcklbw m1, m1
862     pshufw    m2, m0, q3322
863     pshufw    m3, m1, q3322
864     punpcklbw m0, m0
865     punpcklbw m1, m1
866     ADD_DC    m0, m1, r0
867     ADD_DC    m2, m3, r0+8
868     add       r1, 8
869     add       r0, FDEC_STRIDE*4
870     dec       r2
871     jg .loop
872     RET
873
874 INIT_XMM sse2
875 cglobal add16x16_idct_dc, 2,2,8
876     call .loop
877     add       r0, FDEC_STRIDE*4
878     TAIL_CALL .loop, 0
879 .loop:
880     add       r0, FDEC_STRIDE*4
881     movq      m0, [r1+0]
882     movq      m2, [r1+8]
883     add       r1, 16
884     punpcklwd m0, m0
885     punpcklwd m2, m2
886     pxor      m3, m3
887     paddw     m0, [pw_32]
888     paddw     m2, [pw_32]
889     psraw     m0, 6
890     psraw     m2, 6
891     psubw     m1, m3, m0
892     packuswb  m0, m1
893     psubw     m3, m2
894     punpckhbw m1, m0, m0
895     packuswb  m2, m3
896     punpckhbw m3, m2, m2
897     punpcklbw m0, m0
898     punpcklbw m2, m2
899     ADD_DC    m0, m1, r0+FDEC_STRIDE*-4
900     ADD_DC    m2, m3, r0
901     ret
902
903 %macro ADD16x16 0
904 cglobal add16x16_idct_dc, 2,2,8
905     call .loop
906     add      r0, FDEC_STRIDE*4
907     TAIL_CALL .loop, 0
908 .loop:
909     add      r0, FDEC_STRIDE*4
910     mova     m0, [r1]
911     add      r1, 16
912     pxor     m1, m1
913     pmulhrsw m0, [pw_512]
914     psubw    m1, m0
915     mova     m5, [pb_unpackbd1]
916     mova     m6, [pb_unpackbd2]
917     packuswb m0, m0
918     packuswb m1, m1
919     pshufb   m2, m0, m6
920     pshufb   m0, m5
921     pshufb   m3, m1, m6
922     pshufb   m1, m5
923     ADD_DC   m0, m1, r0+FDEC_STRIDE*-4
924     ADD_DC   m2, m3, r0
925     ret
926 %endmacro ; ADD16x16
927
928 INIT_XMM ssse3
929 ADD16x16
930 INIT_XMM avx
931 ADD16x16
932
933 %macro ADD_DC_AVX2 3
934     mova   xm4, [r0+FDEC_STRIDE*0+%3]
935     mova   xm5, [r0+FDEC_STRIDE*1+%3]
936     vinserti128 m4, m4, [r2+FDEC_STRIDE*0+%3], 1
937     vinserti128 m5, m5, [r2+FDEC_STRIDE*1+%3], 1
938     paddusb m4, %1
939     paddusb m5, %1
940     psubusb m4, %2
941     psubusb m5, %2
942     mova [r0+FDEC_STRIDE*0+%3], xm4
943     mova [r0+FDEC_STRIDE*1+%3], xm5
944     vextracti128 [r2+FDEC_STRIDE*0+%3], m4, 1
945     vextracti128 [r2+FDEC_STRIDE*1+%3], m5, 1
946 %endmacro
947
948 INIT_YMM avx2
949 cglobal add16x16_idct_dc, 2,3,6
950     add      r0, FDEC_STRIDE*4
951     mova     m0, [r1]
952     pxor     m1, m1
953     pmulhrsw m0, [pw_512]
954     psubw    m1, m0
955     mova     m4, [pb_unpackbd1]
956     mova     m5, [pb_unpackbd2]
957     packuswb m0, m0
958     packuswb m1, m1
959     pshufb   m2, m0, m4      ; row0, row2
960     pshufb   m3, m1, m4      ; row0, row2
961     pshufb   m0, m5          ; row1, row3
962     pshufb   m1, m5          ; row1, row3
963     lea      r2, [r0+FDEC_STRIDE*8]
964     ADD_DC_AVX2 m2, m3, FDEC_STRIDE*-4
965     ADD_DC_AVX2 m2, m3, FDEC_STRIDE*-2
966     ADD_DC_AVX2 m0, m1, FDEC_STRIDE* 0
967     ADD_DC_AVX2 m0, m1, FDEC_STRIDE* 2
968     RET
969
970 %endif ; HIGH_BIT_DEPTH
971
972 ;-----------------------------------------------------------------------------
973 ; void sub8x8_dct_dc( int16_t dct[2][2], uint8_t *pix1, uint8_t *pix2 )
974 ;-----------------------------------------------------------------------------
975
976 %macro DCTDC_2ROW_MMX 4
977     mova      %1, [r1+FENC_STRIDE*(0+%3)]
978     mova      m1, [r1+FENC_STRIDE*(1+%3)]
979     mova      m2, [r2+FDEC_STRIDE*(0+%4)]
980     mova      m3, [r2+FDEC_STRIDE*(1+%4)]
981     mova      %2, %1
982     punpckldq %1, m1
983     punpckhdq %2, m1
984     mova      m1, m2
985     punpckldq m2, m3
986     punpckhdq m1, m3
987     pxor      m3, m3
988     psadbw    %1, m3
989     psadbw    %2, m3
990     psadbw    m2, m3
991     psadbw    m1, m3
992     psubw     %1, m2
993     psubw     %2, m1
994 %endmacro
995
996 %macro DCT2x2 2 ; reg s1/s0, reg s3/s2 (!=m0/m1)
997     PSHUFLW   m1, %1, q2200  ;  s1  s1  s0  s0
998     PSHUFLW   m0, %2, q2301  ;  s3  __  s2  __
999     paddw     m1, %2         ;  s1 s13  s0 s02
1000     psubw     m1, m0         ; d13 s13 d02 s02
1001     PSHUFLW   m0, m1, q1010  ; d02 s02 d02 s02
1002     psrlq     m1, 32         ;  __  __ d13 s13
1003     paddw     m0, m1         ; d02 s02 d02+d13 s02+s13
1004     psllq     m1, 32         ; d13 s13
1005     psubw     m0, m1         ; d02-d13 s02-s13 d02+d13 s02+s13
1006 %endmacro
1007
1008 %if HIGH_BIT_DEPTH == 0
1009 INIT_MMX mmx2
1010 cglobal sub8x8_dct_dc, 3,3
1011     DCTDC_2ROW_MMX m0, m4, 0, 0
1012     DCTDC_2ROW_MMX m5, m6, 2, 2
1013     paddw     m0, m5
1014     paddw     m4, m6
1015     punpckldq m0, m4
1016     add       r2, FDEC_STRIDE*4
1017     DCTDC_2ROW_MMX m7, m4, 4, 0
1018     DCTDC_2ROW_MMX m5, m6, 6, 2
1019     paddw     m7, m5
1020     paddw     m4, m6
1021     punpckldq m7, m4
1022     DCT2x2    m0, m7
1023     mova    [r0], m0
1024     ret
1025
1026 %macro DCTDC_2ROW_SSE2 4
1027     movh      m1, [r1+FENC_STRIDE*(0+%1)]
1028     movh      m2, [r1+FENC_STRIDE*(1+%1)]
1029     punpckldq m1, m2
1030     movh      m2, [r2+FDEC_STRIDE*(0+%2)]
1031     punpckldq m2, [r2+FDEC_STRIDE*(1+%2)]
1032     psadbw    m1, m0
1033     psadbw    m2, m0
1034     ACCUM  paddd, %4, 1, %3
1035     psubd    m%4, m2
1036 %endmacro
1037
1038 INIT_XMM sse2
1039 cglobal sub8x8_dct_dc, 3,3
1040     pxor     m0, m0
1041     DCTDC_2ROW_SSE2 0, 0, 0, 3
1042     DCTDC_2ROW_SSE2 2, 2, 1, 3
1043     add      r2, FDEC_STRIDE*4
1044     DCTDC_2ROW_SSE2 4, 0, 0, 4
1045     DCTDC_2ROW_SSE2 6, 2, 1, 4
1046     packssdw m3, m3
1047     packssdw m4, m4
1048     DCT2x2   m3, m4
1049     movq   [r0], m0
1050     RET
1051
1052 %macro SUB8x16_DCT_DC 0
1053 cglobal sub8x16_dct_dc, 3,3
1054     pxor       m0, m0
1055     DCTDC_2ROW_SSE2 0, 0, 0, 3
1056     DCTDC_2ROW_SSE2 2, 2, 1, 3
1057     add        r1, FENC_STRIDE*8
1058     add        r2, FDEC_STRIDE*8
1059     DCTDC_2ROW_SSE2 -4, -4, 0, 4
1060     DCTDC_2ROW_SSE2 -2, -2, 1, 4
1061     shufps     m3, m4, q2020
1062     DCTDC_2ROW_SSE2 0, 0, 0, 5
1063     DCTDC_2ROW_SSE2 2, 2, 1, 5
1064     add        r2, FDEC_STRIDE*4
1065     DCTDC_2ROW_SSE2 4, 0, 0, 4
1066     DCTDC_2ROW_SSE2 6, 2, 1, 4
1067     shufps     m5, m4, q2020
1068 %if cpuflag(ssse3)
1069     %define %%sign psignw
1070 %else
1071     %define %%sign pmullw
1072 %endif
1073     SUMSUB_BA d, 5, 3, 0
1074     packssdw   m5, m3
1075     pshuflw    m0, m5, q2301
1076     pshufhw    m0, m0, q2301
1077     %%sign     m5, [pw_pmpmpmpm]
1078     paddw      m0, m5
1079     pshufd     m1, m0, q1320
1080     pshufd     m0, m0, q0231
1081     %%sign     m1, [pw_ppppmmmm]
1082     paddw      m0, m1
1083     mova     [r0], m0
1084     RET
1085 %endmacro ; SUB8x16_DCT_DC
1086
1087 INIT_XMM sse2
1088 SUB8x16_DCT_DC
1089 INIT_XMM ssse3
1090 SUB8x16_DCT_DC
1091
1092 %endif ; !HIGH_BIT_DEPTH
1093
1094 %macro DCTDC_4ROW_SSE2 2
1095     mova       %1, [r1+FENC_STRIDEB*%2]
1096     mova       m0, [r2+FDEC_STRIDEB*%2]
1097 %assign Y (%2+1)
1098 %rep 3
1099     paddw      %1, [r1+FENC_STRIDEB*Y]
1100     paddw      m0, [r2+FDEC_STRIDEB*Y]
1101 %assign Y (Y+1)
1102 %endrep
1103     psubw      %1, m0
1104     pshufd     m0, %1, q2301
1105     paddw      %1, m0
1106 %endmacro
1107
1108 %if HIGH_BIT_DEPTH
1109 %macro SUB8x8_DCT_DC_10 0
1110 cglobal sub8x8_dct_dc, 3,3,3
1111     DCTDC_4ROW_SSE2 m1, 0
1112     DCTDC_4ROW_SSE2 m2, 4
1113     mova       m0, [pw_ppmmmmpp]
1114     pmaddwd    m1, m0
1115     pmaddwd    m2, m0
1116     pshufd     m0, m1, q2200      ; -1 -1 +0 +0
1117     pshufd     m1, m1, q0033      ; +0 +0 +1 +1
1118     paddd      m1, m0
1119     pshufd     m0, m2, q1023      ; -2 +2 -3 +3
1120     paddd      m1, m2
1121     paddd      m1, m0
1122     mova     [r0], m1
1123     RET
1124 %endmacro
1125 INIT_XMM sse2
1126 SUB8x8_DCT_DC_10
1127
1128 %macro SUB8x16_DCT_DC_10 0
1129 cglobal sub8x16_dct_dc, 3,3,6
1130     DCTDC_4ROW_SSE2 m1, 0
1131     DCTDC_4ROW_SSE2 m2, 4
1132     DCTDC_4ROW_SSE2 m3, 8
1133     DCTDC_4ROW_SSE2 m4, 12
1134     mova       m0, [pw_ppmmmmpp]
1135     pmaddwd    m1, m0
1136     pmaddwd    m2, m0
1137     pshufd     m5, m1, q2200      ; -1 -1 +0 +0
1138     pshufd     m1, m1, q0033      ; +0 +0 +1 +1
1139     paddd      m1, m5
1140     pshufd     m5, m2, q1023      ; -2 +2 -3 +3
1141     paddd      m1, m2
1142     paddd      m1, m5             ; a6 a2 a4 a0
1143     pmaddwd    m3, m0
1144     pmaddwd    m4, m0
1145     pshufd     m5, m3, q2200
1146     pshufd     m3, m3, q0033
1147     paddd      m3, m5
1148     pshufd     m5, m4, q1023
1149     paddd      m3, m4
1150     paddd      m3, m5             ; a7 a3 a5 a1
1151     paddd      m0, m1, m3
1152     psubd      m1, m3
1153     pshufd     m0, m0, q3120
1154     pshufd     m1, m1, q3120
1155     punpcklqdq m2, m0, m1
1156     punpckhqdq m1, m0
1157     mova  [r0+ 0], m2
1158     mova  [r0+16], m1
1159     RET
1160 %endmacro
1161 INIT_XMM sse2
1162 SUB8x16_DCT_DC_10
1163 INIT_XMM avx
1164 SUB8x16_DCT_DC_10
1165 %endif
1166
1167 ;-----------------------------------------------------------------------------
1168 ; void zigzag_scan_8x8_frame( int16_t level[64], int16_t dct[8][8] )
1169 ;-----------------------------------------------------------------------------
1170 %macro SCAN_8x8 0
1171 cglobal zigzag_scan_8x8_frame, 2,2,8
1172     movdqa    xmm0, [r1]
1173     movdqa    xmm1, [r1+16]
1174     movdq2q    mm0, xmm0
1175     PALIGNR   xmm1, xmm1, 14, xmm2
1176     movdq2q    mm1, xmm1
1177
1178     movdqa    xmm2, [r1+32]
1179     movdqa    xmm3, [r1+48]
1180     PALIGNR   xmm2, xmm2, 12, xmm4
1181     movdq2q    mm2, xmm2
1182     PALIGNR   xmm3, xmm3, 10, xmm4
1183     movdq2q    mm3, xmm3
1184
1185     punpckhwd xmm0, xmm1
1186     punpckhwd xmm2, xmm3
1187
1188     movq       mm4, mm1
1189     movq       mm5, mm1
1190     movq       mm6, mm2
1191     movq       mm7, mm3
1192     punpckhwd  mm1, mm0
1193     psllq      mm0, 16
1194     psrlq      mm3, 16
1195     punpckhdq  mm1, mm1
1196     punpckhdq  mm2, mm0
1197     punpcklwd  mm0, mm4
1198     punpckhwd  mm4, mm3
1199     punpcklwd  mm4, mm2
1200     punpckhdq  mm0, mm2
1201     punpcklwd  mm6, mm3
1202     punpcklwd  mm5, mm7
1203     punpcklwd  mm5, mm6
1204
1205     movdqa    xmm4, [r1+64]
1206     movdqa    xmm5, [r1+80]
1207     movdqa    xmm6, [r1+96]
1208     movdqa    xmm7, [r1+112]
1209
1210     movq [r0+2*00], mm0
1211     movq [r0+2*04], mm4
1212     movd [r0+2*08], mm1
1213     movq [r0+2*36], mm5
1214     movq [r0+2*46], mm6
1215
1216     PALIGNR   xmm4, xmm4, 14, xmm3
1217     movdq2q    mm4, xmm4
1218     PALIGNR   xmm5, xmm5, 12, xmm3
1219     movdq2q    mm5, xmm5
1220     PALIGNR   xmm6, xmm6, 10, xmm3
1221     movdq2q    mm6, xmm6
1222 %if cpuflag(ssse3)
1223     PALIGNR   xmm7, xmm7, 8, xmm3
1224     movdq2q    mm7, xmm7
1225 %else
1226     movhlps   xmm3, xmm7
1227     punpcklqdq xmm7, xmm7
1228     movdq2q    mm7, xmm3
1229 %endif
1230
1231     punpckhwd xmm4, xmm5
1232     punpckhwd xmm6, xmm7
1233
1234     movq       mm0, mm4
1235     movq       mm1, mm5
1236     movq       mm3, mm7
1237     punpcklwd  mm7, mm6
1238     psrlq      mm6, 16
1239     punpcklwd  mm4, mm6
1240     punpcklwd  mm5, mm4
1241     punpckhdq  mm4, mm3
1242     punpcklwd  mm3, mm6
1243     punpckhwd  mm3, mm4
1244     punpckhwd  mm0, mm1
1245     punpckldq  mm4, mm0
1246     punpckhdq  mm0, mm6
1247     pshufw     mm4, mm4, q1230
1248
1249     movq [r0+2*14], mm4
1250     movq [r0+2*25], mm0
1251     movd [r0+2*54], mm7
1252     movq [r0+2*56], mm5
1253     movq [r0+2*60], mm3
1254
1255     punpckhdq xmm3, xmm0, xmm2
1256     punpckldq xmm0, xmm2
1257     punpckhdq xmm7, xmm4, xmm6
1258     punpckldq xmm4, xmm6
1259     pshufhw   xmm0, xmm0, q0123
1260     pshuflw   xmm4, xmm4, q0123
1261     pshufhw   xmm3, xmm3, q0123
1262     pshuflw   xmm7, xmm7, q0123
1263
1264     movlps [r0+2*10], xmm0
1265     movhps [r0+2*17], xmm0
1266     movlps [r0+2*21], xmm3
1267     movlps [r0+2*28], xmm4
1268     movhps [r0+2*32], xmm3
1269     movhps [r0+2*39], xmm4
1270     movlps [r0+2*43], xmm7
1271     movhps [r0+2*50], xmm7
1272
1273     RET
1274 %endmacro
1275
1276 %if HIGH_BIT_DEPTH == 0
1277 INIT_XMM sse2
1278 SCAN_8x8
1279 INIT_XMM ssse3
1280 SCAN_8x8
1281 %endif
1282
1283 ;-----------------------------------------------------------------------------
1284 ; void zigzag_scan_8x8_frame( dctcoef level[64], dctcoef dct[8][8] )
1285 ;-----------------------------------------------------------------------------
1286 ; Output order:
1287 ;  0  8  1  2  9 16 24 17
1288 ; 10  3  4 11 18 25 32 40
1289 ; 33 26 19 12  5  6 13 20
1290 ; 27 34 41 48 56 49 42 35
1291 ; 28 21 14  7 15 22 29 36
1292 ; 43 50 57 58 51 44 37 30
1293 ; 23 31 38 45 52 59 60 53
1294 ; 46 39 47 54 61 62 55 63
1295 %macro SCAN_8x8_FRAME 5
1296 cglobal zigzag_scan_8x8_frame, 2,2,8
1297     mova        m0, [r1]
1298     mova        m1, [r1+ 8*SIZEOF_DCTCOEF]
1299     movu        m2, [r1+14*SIZEOF_DCTCOEF]
1300     movu        m3, [r1+21*SIZEOF_DCTCOEF]
1301     mova        m4, [r1+28*SIZEOF_DCTCOEF]
1302     punpckl%4   m5, m0, m1
1303     psrl%2      m0, %1
1304     punpckh%4   m6, m1, m0
1305     punpckl%3   m5, m0
1306     punpckl%3   m1, m1
1307     punpckh%4   m1, m3
1308     mova        m7, [r1+52*SIZEOF_DCTCOEF]
1309     mova        m0, [r1+60*SIZEOF_DCTCOEF]
1310     punpckh%4   m1, m2
1311     punpckl%4   m2, m4
1312     punpckh%4   m4, m3
1313     punpckl%3   m3, m3
1314     punpckh%4   m3, m2
1315     mova      [r0], m5
1316     mova  [r0+ 4*SIZEOF_DCTCOEF], m1
1317     mova  [r0+ 8*SIZEOF_DCTCOEF], m6
1318     punpckl%4   m6, m0
1319     punpckl%4   m6, m7
1320     mova        m1, [r1+32*SIZEOF_DCTCOEF]
1321     movu        m5, [r1+39*SIZEOF_DCTCOEF]
1322     movu        m2, [r1+46*SIZEOF_DCTCOEF]
1323     movu [r0+35*SIZEOF_DCTCOEF], m3
1324     movu [r0+47*SIZEOF_DCTCOEF], m4
1325     punpckh%4   m7, m0
1326     psll%2      m0, %1
1327     punpckh%3   m3, m5, m5
1328     punpckl%4   m5, m1
1329     punpckh%4   m1, m2
1330     mova [r0+52*SIZEOF_DCTCOEF], m6
1331     movu [r0+13*SIZEOF_DCTCOEF], m5
1332     movu        m4, [r1+11*SIZEOF_DCTCOEF]
1333     movu        m6, [r1+25*SIZEOF_DCTCOEF]
1334     punpckl%4   m5, m7
1335     punpckl%4   m1, m3
1336     punpckh%3   m0, m7
1337     mova        m3, [r1+ 4*SIZEOF_DCTCOEF]
1338     movu        m7, [r1+18*SIZEOF_DCTCOEF]
1339     punpckl%4   m2, m5
1340     movu [r0+25*SIZEOF_DCTCOEF], m1
1341     mova        m1, m4
1342     mova        m5, m6
1343     punpckl%4   m4, m3
1344     punpckl%4   m6, m7
1345     punpckh%4   m1, m3
1346     punpckh%4   m5, m7
1347     punpckh%3   m3, m6, m4
1348     punpckh%3   m7, m5, m1
1349     punpckl%3   m6, m4
1350     punpckl%3   m5, m1
1351     movu        m4, [r1+35*SIZEOF_DCTCOEF]
1352     movu        m1, [r1+49*SIZEOF_DCTCOEF]
1353     pshuf%5     m6, m6, q0123
1354     pshuf%5     m5, m5, q0123
1355     mova [r0+60*SIZEOF_DCTCOEF], m0
1356     mova [r0+56*SIZEOF_DCTCOEF], m2
1357     movu        m0, [r1+42*SIZEOF_DCTCOEF]
1358     mova        m2, [r1+56*SIZEOF_DCTCOEF]
1359     movu [r0+17*SIZEOF_DCTCOEF], m3
1360     mova [r0+32*SIZEOF_DCTCOEF], m7
1361     movu [r0+10*SIZEOF_DCTCOEF], m6
1362     movu [r0+21*SIZEOF_DCTCOEF], m5
1363     punpckh%4   m3, m0, m4
1364     punpckh%4   m7, m2, m1
1365     punpckl%4   m0, m4
1366     punpckl%4   m2, m1
1367     punpckl%3   m4, m2, m0
1368     punpckl%3   m1, m7, m3
1369     punpckh%3   m2, m0
1370     punpckh%3   m7, m3
1371     pshuf%5     m2, m2, q0123
1372     pshuf%5     m7, m7, q0123
1373     mova [r0+28*SIZEOF_DCTCOEF], m4
1374     movu [r0+43*SIZEOF_DCTCOEF], m1
1375     movu [r0+39*SIZEOF_DCTCOEF], m2
1376     movu [r0+50*SIZEOF_DCTCOEF], m7
1377     RET
1378 %endmacro
1379
1380 %if HIGH_BIT_DEPTH
1381 INIT_XMM sse2
1382 SCAN_8x8_FRAME 4 , dq, qdq, dq, d
1383 INIT_XMM avx
1384 SCAN_8x8_FRAME 4 , dq, qdq, dq, d
1385 %else
1386 INIT_MMX mmx2
1387 SCAN_8x8_FRAME 16, q , dq , wd, w
1388 %endif
1389
1390 ;-----------------------------------------------------------------------------
1391 ; void zigzag_scan_4x4_frame( dctcoef level[16], dctcoef dct[4][4] )
1392 ;-----------------------------------------------------------------------------
1393 %macro SCAN_4x4 4
1394 cglobal zigzag_scan_4x4_frame, 2,2,6
1395     mova      m0, [r1+ 0*SIZEOF_DCTCOEF]
1396     mova      m1, [r1+ 4*SIZEOF_DCTCOEF]
1397     mova      m2, [r1+ 8*SIZEOF_DCTCOEF]
1398     mova      m3, [r1+12*SIZEOF_DCTCOEF]
1399     punpckl%4 m4, m0, m1
1400     psrl%2    m0, %1
1401     punpckl%3 m4, m0
1402     mova  [r0+ 0*SIZEOF_DCTCOEF], m4
1403     punpckh%4 m0, m2
1404     punpckh%4 m4, m2, m3
1405     psll%2    m3, %1
1406     punpckl%3 m2, m2
1407     punpckl%4 m5, m1, m3
1408     punpckh%3 m1, m1
1409     punpckh%4 m5, m2
1410     punpckl%4 m1, m0
1411     punpckh%3 m3, m4
1412     mova [r0+ 4*SIZEOF_DCTCOEF], m5
1413     mova [r0+ 8*SIZEOF_DCTCOEF], m1
1414     mova [r0+12*SIZEOF_DCTCOEF], m3
1415     RET
1416 %endmacro
1417
1418 %if HIGH_BIT_DEPTH
1419 INIT_XMM sse2
1420 SCAN_4x4  4, dq, qdq, dq
1421 INIT_XMM avx
1422 SCAN_4x4  4, dq, qdq, dq
1423 %else
1424 INIT_MMX mmx
1425 SCAN_4x4 16, q , dq , wd
1426
1427 ;-----------------------------------------------------------------------------
1428 ; void zigzag_scan_4x4_frame( int16_t level[16], int16_t dct[4][4] )
1429 ;-----------------------------------------------------------------------------
1430 %macro SCAN_4x4_FRAME 0
1431 cglobal zigzag_scan_4x4_frame, 2,2
1432     mova    m1, [r1+16]
1433     mova    m0, [r1+ 0]
1434     pshufb  m1, [pb_scan4frameb]
1435     pshufb  m0, [pb_scan4framea]
1436     psrldq  m2, m1, 6
1437     palignr m1, m0, 6
1438     pslldq  m0, 10
1439     palignr m2, m0, 10
1440     mova [r0+ 0], m1
1441     mova [r0+16], m2
1442     RET
1443 %endmacro
1444
1445 INIT_XMM ssse3
1446 SCAN_4x4_FRAME
1447 INIT_XMM avx
1448 SCAN_4x4_FRAME
1449
1450 INIT_XMM xop
1451 cglobal zigzag_scan_4x4_frame, 2,2
1452     mova   m0, [r1+ 0]
1453     mova   m1, [r1+16]
1454     vpperm m2, m0, m1, [pb_scan4frame2a]
1455     vpperm m1, m0, m1, [pb_scan4frame2b]
1456     mova [r0+ 0], m2
1457     mova [r0+16], m1
1458     RET
1459 %endif ; !HIGH_BIT_DEPTH
1460
1461 %if HIGH_BIT_DEPTH
1462 ;-----------------------------------------------------------------------------
1463 ; void zigzag_scan_4x4_field( int32_t level[16], int32_t dct[4][4] )
1464 ;-----------------------------------------------------------------------------
1465 INIT_XMM sse2
1466 cglobal zigzag_scan_4x4_field, 2,3
1467     movu       m4, [r1+ 8]
1468     pshufd     m0, m4, q3102
1469     mova       m1, [r1+32]
1470     mova       m2, [r1+48]
1471     movu  [r0+ 8], m0
1472     mova  [r0+32], m1
1473     mova  [r0+48], m2
1474     movq      mm0, [r1]
1475     movq     [r0], mm0
1476     movq      mm0, [r1+24]
1477     movq  [r0+24], mm0
1478     RET
1479 %else
1480 ;-----------------------------------------------------------------------------
1481 ; void zigzag_scan_4x4_field( int16_t level[16], int16_t dct[4][4] )
1482 ;-----------------------------------------------------------------------------
1483 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
1484 INIT_MMX mmx2
1485 cglobal zigzag_scan_4x4_field, 2,3
1486     pshufw      m0, [r1+4], q3102
1487     mova        m1, [r1+16]
1488     mova        m2, [r1+24]
1489     movu    [r0+4], m0
1490     mova   [r0+16], m1
1491     mova   [r0+24], m2
1492     mov        r2d, [r1]
1493     mov       [r0], r2d
1494     mov        r2d, [r1+12]
1495     mov    [r0+12], r2d
1496     RET
1497 %endif ; HIGH_BIT_DEPTH
1498
1499 ;-----------------------------------------------------------------------------
1500 ; void zigzag_scan_8x8_field( int16_t level[64], int16_t dct[8][8] )
1501 ;-----------------------------------------------------------------------------
1502 ; Output order:
1503 ;  0  1  2  8  9  3  4 10
1504 ; 16 11  5  6  7 12 17 24
1505 ; 18 13 14 15 19 25 32 26
1506 ; 20 21 22 23 27 33 40 34
1507 ; 28 29 30 31 35 41 48 42
1508 ; 36 37 38 39 43 49 50 44
1509 ; 45 46 47 51 56 57 52 53
1510 ; 54 55 58 59 60 61 62 63
1511 %undef SCAN_8x8
1512 %macro SCAN_8x8 5
1513 cglobal zigzag_scan_8x8_field, 2,3,8
1514     mova       m0, [r1+ 0*SIZEOF_DCTCOEF]       ; 03 02 01 00
1515     mova       m1, [r1+ 4*SIZEOF_DCTCOEF]       ; 07 06 05 04
1516     mova       m2, [r1+ 8*SIZEOF_DCTCOEF]       ; 11 10 09 08
1517     pshuf%1    m3, m0, q3333                    ; 03 03 03 03
1518     movd      r2d, m2                           ; 09 08
1519     pshuf%1    m2, m2, q0321                    ; 08 11 10 09
1520     punpckl%2  m3, m1                           ; 05 03 04 03
1521     pinsr%1    m0, r2d, 3                       ; 08 02 01 00
1522     punpckl%2  m4, m2, m3                       ; 04 10 03 09
1523     pshuf%1    m4, m4, q2310                    ; 10 04 03 09
1524     mova  [r0+ 0*SIZEOF_DCTCOEF], m0            ; 08 02 01 00
1525     mova  [r0+ 4*SIZEOF_DCTCOEF], m4            ; 10 04 03 09
1526     mova       m3, [r1+12*SIZEOF_DCTCOEF]       ; 15 14 13 12
1527     mova       m5, [r1+16*SIZEOF_DCTCOEF]       ; 19 18 17 16
1528     punpckl%3  m6, m5                           ; 17 16 XX XX
1529     psrl%4     m1, %5                           ; XX 07 06 05
1530     punpckh%2  m6, m2                           ; 08 17 11 16
1531     punpckl%3  m6, m1                           ; 06 05 11 16
1532     mova  [r0+ 8*SIZEOF_DCTCOEF], m6            ; 06 05 11 16
1533     psrl%4     m1, %5                           ; XX XX 07 06
1534     punpckl%2  m1, m5                           ; 17 07 16 06
1535     mova       m0, [r1+20*SIZEOF_DCTCOEF]       ; 23 22 21 20
1536     mova       m2, [r1+24*SIZEOF_DCTCOEF]       ; 27 26 25 24
1537     punpckh%3  m1, m1                           ; 17 07 17 07
1538     punpckl%2  m6, m3, m2                       ; 25 13 24 12
1539     pextr%1    r2d, m5, 2
1540     mova [r0+24*SIZEOF_DCTCOEF], m0             ; 23 22 21 20
1541     punpckl%2  m1, m6                           ; 24 17 12 07
1542     mova [r0+12*SIZEOF_DCTCOEF], m1
1543     pinsr%1    m3, r2d, 0                       ; 15 14 13 18
1544     mova [r0+16*SIZEOF_DCTCOEF], m3             ; 15 14 13 18
1545     mova       m7, [r1+28*SIZEOF_DCTCOEF]
1546     mova       m0, [r1+32*SIZEOF_DCTCOEF]       ; 35 34 33 32
1547     psrl%4     m5, %5*3                         ; XX XX XX 19
1548     pshuf%1    m1, m2, q3321                    ; 27 27 26 25
1549     punpckl%2  m5, m0                           ; 33 XX 32 19
1550     psrl%4     m2, %5*3                         ; XX XX XX 27
1551     punpckl%2  m5, m1                           ; 26 32 25 19
1552     mova [r0+32*SIZEOF_DCTCOEF], m7
1553     mova [r0+20*SIZEOF_DCTCOEF], m5             ; 26 32 25 19
1554     mova       m7, [r1+36*SIZEOF_DCTCOEF]
1555     mova       m1, [r1+40*SIZEOF_DCTCOEF]       ; 43 42 41 40
1556     pshuf%1    m3, m0, q3321                    ; 35 35 34 33
1557     punpckl%2  m2, m1                           ; 41 XX 40 27
1558     mova [r0+40*SIZEOF_DCTCOEF], m7
1559     punpckl%2  m2, m3                           ; 34 40 33 27
1560     mova [r0+28*SIZEOF_DCTCOEF], m2
1561     mova       m7, [r1+44*SIZEOF_DCTCOEF]       ; 47 46 45 44
1562     mova       m2, [r1+48*SIZEOF_DCTCOEF]       ; 51 50 49 48
1563     psrl%4     m0, %5*3                         ; XX XX XX 35
1564     punpckl%2  m0, m2                           ; 49 XX 48 35
1565     pshuf%1    m3, m1, q3321                    ; 43 43 42 41
1566     punpckl%2  m0, m3                           ; 42 48 41 35
1567     mova [r0+36*SIZEOF_DCTCOEF], m0
1568     pextr%1     r2d, m2, 3                      ; 51
1569     psrl%4      m1, %5*3                        ; XX XX XX 43
1570     punpckl%2   m1, m7                          ; 45 XX 44 43
1571     psrl%4      m2, %5                          ; XX 51 50 49
1572     punpckl%2   m1, m2                          ; 50 44 49 43
1573     pshuf%1     m1, m1, q2310                   ; 44 50 49 43
1574     mova [r0+44*SIZEOF_DCTCOEF], m1
1575     psrl%4      m7, %5                          ; XX 47 46 45
1576     pinsr%1     m7, r2d, 3                      ; 51 47 46 45
1577     mova [r0+48*SIZEOF_DCTCOEF], m7
1578     mova        m0, [r1+56*SIZEOF_DCTCOEF]      ; 59 58 57 56
1579     mova        m1, [r1+52*SIZEOF_DCTCOEF]      ; 55 54 53 52
1580     mova        m7, [r1+60*SIZEOF_DCTCOEF]
1581     punpckl%3   m2, m0, m1                      ; 53 52 57 56
1582     punpckh%3   m1, m0                          ; 59 58 55 54
1583     mova [r0+52*SIZEOF_DCTCOEF], m2
1584     mova [r0+56*SIZEOF_DCTCOEF], m1
1585     mova [r0+60*SIZEOF_DCTCOEF], m7
1586     RET
1587 %endmacro
1588 %if HIGH_BIT_DEPTH
1589 INIT_XMM sse4
1590 SCAN_8x8 d, dq, qdq, dq, 4
1591 INIT_XMM avx
1592 SCAN_8x8 d, dq, qdq, dq, 4
1593 %else
1594 INIT_MMX mmx2
1595 SCAN_8x8 w, wd, dq , q , 16
1596 %endif
1597
1598 ;-----------------------------------------------------------------------------
1599 ; void zigzag_sub_4x4_frame( int16_t level[16], const uint8_t *src, uint8_t *dst )
1600 ;-----------------------------------------------------------------------------
1601 %macro ZIGZAG_SUB_4x4 2
1602 %ifidn %1, ac
1603 cglobal zigzag_sub_4x4%1_%2, 4,4,8
1604 %else
1605 cglobal zigzag_sub_4x4%1_%2, 3,3,8
1606 %endif
1607     movd      m0, [r1+0*FENC_STRIDE]
1608     movd      m1, [r1+1*FENC_STRIDE]
1609     movd      m2, [r1+2*FENC_STRIDE]
1610     movd      m3, [r1+3*FENC_STRIDE]
1611     movd      m4, [r2+0*FDEC_STRIDE]
1612     movd      m5, [r2+1*FDEC_STRIDE]
1613     movd      m6, [r2+2*FDEC_STRIDE]
1614     movd      m7, [r2+3*FDEC_STRIDE]
1615     movd [r2+0*FDEC_STRIDE], m0
1616     movd [r2+1*FDEC_STRIDE], m1
1617     movd [r2+2*FDEC_STRIDE], m2
1618     movd [r2+3*FDEC_STRIDE], m3
1619     punpckldq  m0, m1
1620     punpckldq  m2, m3
1621     punpckldq  m4, m5
1622     punpckldq  m6, m7
1623     punpcklqdq m0, m2
1624     punpcklqdq m4, m6
1625     mova      m7, [pb_sub4%2]
1626     pshufb    m0, m7
1627     pshufb    m4, m7
1628     mova      m7, [hsub_mul]
1629     punpckhbw m1, m0, m4
1630     punpcklbw m0, m4
1631     pmaddubsw m1, m7
1632     pmaddubsw m0, m7
1633 %ifidn %1, ac
1634     movd     r2d, m0
1635     pand      m0, [pb_subacmask]
1636 %endif
1637     mova [r0+ 0], m0
1638     por       m0, m1
1639     pxor      m2, m2
1640     mova [r0+16], m1
1641     pcmpeqb   m0, m2
1642     pmovmskb eax, m0
1643 %ifidn %1, ac
1644     mov     [r3], r2w
1645 %endif
1646     sub      eax, 0xffff
1647     shr      eax, 31
1648     RET
1649 %endmacro
1650
1651 %if HIGH_BIT_DEPTH == 0
1652 INIT_XMM ssse3
1653 ZIGZAG_SUB_4x4   , frame
1654 ZIGZAG_SUB_4x4 ac, frame
1655 ZIGZAG_SUB_4x4   , field
1656 ZIGZAG_SUB_4x4 ac, field
1657 INIT_XMM avx
1658 ZIGZAG_SUB_4x4   , frame
1659 ZIGZAG_SUB_4x4 ac, frame
1660 ZIGZAG_SUB_4x4   , field
1661 ZIGZAG_SUB_4x4 ac, field
1662 %endif ; !HIGH_BIT_DEPTH
1663
1664 %if HIGH_BIT_DEPTH == 0
1665 INIT_XMM xop
1666 cglobal zigzag_scan_8x8_field, 2,3,7
1667     lea        r2, [pb_scan8field1]
1668     %define off(m) (r2+m-pb_scan8field1)
1669     mova       m0, [r1+  0]
1670     mova       m1, [r1+ 16]
1671     vpperm     m5, m0, m1, [off(pb_scan8field1)]
1672     mova [r0+  0], m5
1673     vpperm     m0, m0, m1, [off(pb_scan8field2a)]
1674     mova       m2, [r1+ 32]
1675     mova       m3, [r1+ 48]
1676     vpperm     m5, m2, m3, [off(pb_scan8field2b)]
1677     por        m5, m0
1678     mova [r0+ 16], m5
1679     mova       m4, [off(pb_scan8field3b)]
1680     vpperm     m1, m1, m2, [off(pb_scan8field3a)]
1681     mova       m0, [r1+ 64]
1682     vpperm     m5, m3, m0, m4
1683     por        m5, m1
1684     mova [r0+ 32], m5
1685     ; 4b, 5b are the same as pb_scan8field3b.
1686     ; 5a is the same as pb_scan8field4a.
1687     mova       m5, [off(pb_scan8field4a)]
1688     vpperm     m2, m2, m3, m5
1689     mova       m1, [r1+ 80]
1690     vpperm     m6, m0, m1, m4
1691     por        m6, m2
1692     mova [r0+ 48], m6
1693     vpperm     m3, m3, m0, m5
1694     mova       m2, [r1+ 96]
1695     vpperm     m5, m1, m2, m4
1696     por        m5, m3
1697     mova [r0+ 64], m5
1698     vpperm     m5, m0, m1, [off(pb_scan8field6)]
1699     mova [r0+ 80], m5
1700     vpperm     m5, m1, m2, [off(pb_scan8field7)]
1701     mov       r2d, [r1+ 98]
1702     mov  [r0+ 90], r2d
1703     mova [r0+ 96], m5
1704     mova       m3, [r1+112]
1705     movd [r0+104], m3
1706     mov       r2d, [r1+108]
1707     mova [r0+112], m3
1708     mov  [r0+112], r2d
1709     %undef off
1710     RET
1711
1712 cglobal zigzag_scan_8x8_frame, 2,3,8
1713     lea        r2, [pb_scan8frame1]
1714     %define off(m) (r2+m-pb_scan8frame1)
1715     mova       m7, [r1+ 16]
1716     mova       m3, [r1+ 32]
1717     vpperm     m7, m7, m3, [off(pb_scan8framet1)] ;  8  9 14 15 16 17 21 22
1718     mova       m2, [r1+ 48]
1719     vpperm     m0, m3, m2, [off(pb_scan8framet2)] ; 18 19 20 23 25 31 26 30
1720     mova       m1, [r1+ 80]
1721     mova       m4, [r1+ 64]
1722     vpperm     m3, m4, m1, [off(pb_scan8framet3)] ; 32 33 37 38 40 43 44 45
1723     vpperm     m6, m0, m3, [off(pb_scan8framet4)] ; 18 23 25 31 32 38 40 45
1724     vpperm     m5, m0, m3, [off(pb_scan8framet5)] ; 19 20 26 30 33 37 43 44
1725     vpperm     m3, m2, m4, [off(pb_scan8framet6)] ; 24 27 28 29 34 35 36 39
1726     mova       m4, [r1+ 96]
1727     vpperm     m4, m1, m4, [off(pb_scan8framet7)] ; 41 42 46 47 48 49 54 55
1728     mova       m1, [r1+  0]
1729     vpperm     m2, m1, m3, [off(pb_scan8framet8)] ;  0  1  2  7 24 28 29 36
1730     vpperm     m1, m2, m7, [off(pb_scan8frame1)]  ;  0  8  1  2  9 16 24 17
1731     mova [r0+  0], m1
1732     movh       m0, [r1+  6]
1733     movhps     m0, [r1+ 20]                       ;  3  4  5  6 10 11 12 13
1734     vpperm     m1, m0, m6, [off(pb_scan8frame2)]  ; 10  3  4 11 18 25 32 40
1735     mova [r0+ 16], m1
1736     vpperm     m1, m0, m5, [off(pb_scan8frame3)]  ; 33 26 19 12  5  6 13 20
1737     mova [r0+ 32], m1
1738     vpperm     m1, m2, m7, [off(pb_scan8frame5)]  ; 28 21 14  7 15 22 29 36
1739     mova [r0+ 64], m1
1740     movh       m0, [r1+100]
1741     movhps     m0, [r1+114]                       ; 50 51 52 53 57 58 59 60
1742     vpperm     m1, m5, m0, [off(pb_scan8frame6)]  ; 43 50 57 58 51 44 37 30
1743     mova [r0+ 80], m1
1744     vpperm     m1, m6, m0, [off(pb_scan8frame7)]  ; 23 31 38 45 52 59 60 53
1745     mova [r0+ 96], m1
1746     mova       m1, [r1+112]
1747     vpperm     m0, m3, m1, [off(pb_scan8framet9)] ; 27 34 35 39 56 61 62 63
1748     vpperm     m1, m0, m4, [off(pb_scan8frame4)]  ; 27 34 41 48 56 49 42 35
1749     mova [r0+ 48], m1
1750     vpperm     m1, m0, m4, [off(pb_scan8frame8)]  ; 46 39 47 54 61 62 55 63
1751     mova [r0+112], m1
1752     %undef off
1753     RET
1754 %endif
1755
1756 ;-----------------------------------------------------------------------------
1757 ; void zigzag_interleave_8x8_cavlc( int16_t *dst, int16_t *src, uint8_t *nnz )
1758 ;-----------------------------------------------------------------------------
1759 %macro INTERLEAVE 2
1760     mova     m0, [r1+(%1*4+ 0)*SIZEOF_PIXEL]
1761     mova     m1, [r1+(%1*4+ 8)*SIZEOF_PIXEL]
1762     mova     m2, [r1+(%1*4+16)*SIZEOF_PIXEL]
1763     mova     m3, [r1+(%1*4+24)*SIZEOF_PIXEL]
1764     TRANSPOSE4x4%2 0,1,2,3,4
1765     mova     [r0+(%1+ 0)*SIZEOF_PIXEL], m0
1766     mova     [r0+(%1+32)*SIZEOF_PIXEL], m1
1767     mova     [r0+(%1+64)*SIZEOF_PIXEL], m2
1768     mova     [r0+(%1+96)*SIZEOF_PIXEL], m3
1769     packsswb m0, m1
1770     ACCUM   por, 6, 2, %1
1771     ACCUM   por, 7, 3, %1
1772     ACCUM   por, 5, 0, %1
1773 %endmacro
1774
1775 %macro ZIGZAG_8x8_CAVLC 1
1776 cglobal zigzag_interleave_8x8_cavlc, 3,3,8
1777     INTERLEAVE  0, %1
1778     INTERLEAVE  8, %1
1779     INTERLEAVE 16, %1
1780     INTERLEAVE 24, %1
1781     packsswb   m6, m7
1782     packsswb   m5, m6
1783     packsswb   m5, m5
1784     pxor       m0, m0
1785 %if HIGH_BIT_DEPTH
1786     packsswb   m5, m5
1787 %endif
1788     pcmpeqb    m5, m0
1789     paddb      m5, [pb_1]
1790     movd      r0d, m5
1791     mov    [r2+0], r0w
1792     shr       r0d, 16
1793     mov    [r2+8], r0w
1794     RET
1795 %endmacro
1796
1797 %if HIGH_BIT_DEPTH
1798 INIT_XMM sse2
1799 ZIGZAG_8x8_CAVLC D
1800 INIT_XMM avx
1801 ZIGZAG_8x8_CAVLC D
1802 %else
1803 INIT_MMX mmx
1804 ZIGZAG_8x8_CAVLC W
1805 %endif
1806
1807 %macro INTERLEAVE_XMM 1
1808     mova   m0, [r1+%1*4+ 0]
1809     mova   m1, [r1+%1*4+16]
1810     mova   m4, [r1+%1*4+32]
1811     mova   m5, [r1+%1*4+48]
1812     SBUTTERFLY wd, 0, 1, 6
1813     SBUTTERFLY wd, 4, 5, 7
1814     SBUTTERFLY wd, 0, 1, 6
1815     SBUTTERFLY wd, 4, 5, 7
1816     movh   [r0+%1+  0], m0
1817     movhps [r0+%1+ 32], m0
1818     movh   [r0+%1+ 64], m1
1819     movhps [r0+%1+ 96], m1
1820     movh   [r0+%1+  8], m4
1821     movhps [r0+%1+ 40], m4
1822     movh   [r0+%1+ 72], m5
1823     movhps [r0+%1+104], m5
1824     ACCUM por, 2, 0, %1
1825     ACCUM por, 3, 1, %1
1826     por    m2, m4
1827     por    m3, m5
1828 %endmacro
1829
1830 %if HIGH_BIT_DEPTH == 0
1831 %macro ZIGZAG_8x8_CAVLC 0
1832 cglobal zigzag_interleave_8x8_cavlc, 3,3,8
1833     INTERLEAVE_XMM  0
1834     INTERLEAVE_XMM 16
1835     packsswb m2, m3
1836     pxor     m5, m5
1837     packsswb m2, m2
1838     packsswb m2, m2
1839     pcmpeqb  m5, m2
1840     paddb    m5, [pb_1]
1841     movd    r0d, m5
1842     mov  [r2+0], r0w
1843     shr     r0d, 16
1844     mov  [r2+8], r0w
1845     RET
1846 %endmacro
1847
1848 INIT_XMM sse2
1849 ZIGZAG_8x8_CAVLC
1850 INIT_XMM avx
1851 ZIGZAG_8x8_CAVLC
1852
1853 INIT_YMM avx2
1854 cglobal zigzag_interleave_8x8_cavlc, 3,3,6
1855     mova   m0, [r1+ 0]
1856     mova   m1, [r1+32]
1857     mova   m2, [r1+64]
1858     mova   m3, [r1+96]
1859     mova   m5, [deinterleave_shufd]
1860     SBUTTERFLY wd, 0, 1, 4
1861     SBUTTERFLY wd, 2, 3, 4
1862     SBUTTERFLY wd, 0, 1, 4
1863     SBUTTERFLY wd, 2, 3, 4
1864     vpermd m0, m5, m0
1865     vpermd m1, m5, m1
1866     vpermd m2, m5, m2
1867     vpermd m3, m5, m3
1868     mova [r0+  0], xm0
1869     mova [r0+ 16], xm2
1870     vextracti128 [r0+ 32], m0, 1
1871     vextracti128 [r0+ 48], m2, 1
1872     mova [r0+ 64], xm1
1873     mova [r0+ 80], xm3
1874     vextracti128 [r0+ 96], m1, 1
1875     vextracti128 [r0+112], m3, 1
1876
1877     packsswb m0, m2          ; nnz0, nnz1
1878     packsswb m1, m3          ; nnz2, nnz3
1879     packsswb m0, m1          ; {nnz0,nnz2}, {nnz1,nnz3}
1880     vpermq   m0, m0, q3120   ; {nnz0,nnz1}, {nnz2,nnz3}
1881     pxor     m5, m5
1882     pcmpeqq  m0, m5
1883     pmovmskb r0d, m0
1884     not     r0d
1885     and     r0d, 0x01010101
1886     mov  [r2+0], r0w
1887     shr     r0d, 16
1888     mov  [r2+8], r0w
1889     RET
1890 %endif ; !HIGH_BIT_DEPTH