]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
Add AVX functions where 3+ arg commands are useful
[x264] / common / x86 / dct-a.asm
1 ;*****************************************************************************
2 ;* dct-a.asm: x86 transform and zigzag
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2011 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 %macro SHUFFLE_16BIT 8
34     %rep 8
35         db %1*2
36         db %1*2+1
37         %rotate 1
38     %endrep
39 %endmacro
40
41 SECTION_RODATA
42 pb_sub4frame:   db 0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15
43 pb_sub4field:   db 0,4,1,8,12,5,9,13,2,6,10,14,3,7,11,15
44 pb_subacmask:   dw 0,-1,-1,-1,-1,-1,-1,-1
45 pb_scan4framea: SHUFFLE_16BIT 6,3,7,0,4,1,2,5
46 pb_scan4frameb: SHUFFLE_16BIT 0,4,1,2,5,6,3,7
47 pb_idctdc_unpack: db 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3
48 pb_idctdc_unpack2: db 4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7
49
50 SECTION .text
51
52 cextern pw_32_0
53 cextern pw_32
54 cextern pw_8000
55 cextern pw_pixel_max
56 cextern hsub_mul
57 cextern pb_1
58 cextern pw_1
59 cextern pd_1
60 cextern pd_32
61
62 %macro WALSH4_1D 6
63     SUMSUB_BADC %1, %5, %4, %3, %2, %6
64     SUMSUB_BADC %1, %5, %3, %4, %2, %6
65     SWAP %2, %5, %4
66 %endmacro
67
68 %macro SUMSUB_17BIT 4 ; a, b, tmp, 0x8000
69     movq  m%3, m%4
70     pxor  m%1, m%4
71     psubw m%3, m%2
72     pxor  m%2, m%4
73     pavgw m%3, m%1
74     pavgw m%2, m%1
75     pxor  m%3, m%4
76     pxor  m%2, m%4
77     SWAP %1, %2, %3
78 %endmacro
79
80 %macro DCT_UNPACK 3
81     punpcklwd %3, %1
82     punpckhwd %2, %1
83     psrad     %3, 16
84     psrad     %2, 16
85     SWAP      %1, %3
86 %endmacro
87
88 %ifdef HIGH_BIT_DEPTH
89 ;-----------------------------------------------------------------------------
90 ; void dct4x4dc( dctcoef d[4][4] )
91 ;-----------------------------------------------------------------------------
92 %macro DCT4x4_DC 1
93 cglobal dct4x4dc_%1, 1,1,5
94     mova   m0, [r0+ 0]
95     mova   m1, [r0+16]
96     mova   m2, [r0+32]
97     mova   m3, [r0+48]
98     WALSH4_1D  d, 0,1,2,3,4
99     TRANSPOSE4x4D 0,1,2,3,4
100     paddd  m0, [pd_1]
101     WALSH4_1D  d, 0,1,2,3,4
102     psrad  m0, 1
103     psrad  m1, 1
104     psrad  m2, 1
105     psrad  m3, 1
106     mova [r0+ 0], m0
107     mova [r0+16], m1
108     mova [r0+32], m2
109     mova [r0+48], m3
110     RET
111 %endmacro ; DCT4x4_DC
112
113 INIT_XMM
114 DCT4x4_DC sse2
115 INIT_AVX
116 DCT4x4_DC avx
117 %else
118
119 INIT_MMX
120 cglobal dct4x4dc_mmx, 1,1
121     movq   m3, [r0+24]
122     movq   m2, [r0+16]
123     movq   m1, [r0+ 8]
124     movq   m0, [r0+ 0]
125     movq   m7, [pw_8000] ; convert to unsigned and back, so that pavgw works
126     WALSH4_1D  w, 0,1,2,3,4
127     TRANSPOSE4x4W 0,1,2,3,4
128     SUMSUB_BADC w, 1, 0, 3, 2, 4
129     SWAP 0, 1
130     SWAP 2, 3
131     SUMSUB_17BIT 0,2,4,7
132     SUMSUB_17BIT 1,3,5,7
133     movq  [r0+0], m0
134     movq  [r0+8], m2
135     movq [r0+16], m3
136     movq [r0+24], m1
137     RET
138 %endif ; HIGH_BIT_DEPTH
139
140 %ifdef HIGH_BIT_DEPTH
141 ;-----------------------------------------------------------------------------
142 ; void idct4x4dc( int32_t d[4][4] )
143 ;-----------------------------------------------------------------------------
144 %macro IDCT4x4DC 1
145 cglobal idct4x4dc_%1, 1,1
146     mova   m3, [r0+48]
147     mova   m2, [r0+32]
148     mova   m1, [r0+16]
149     mova   m0, [r0+ 0]
150     WALSH4_1D  d,0,1,2,3,4
151     TRANSPOSE4x4D 0,1,2,3,4
152     WALSH4_1D  d,0,1,2,3,4
153     mova  [r0+ 0], m0
154     mova  [r0+16], m1
155     mova  [r0+32], m2
156     mova  [r0+48], m3
157     RET
158 %endmacro ; IDCT4x4DC
159
160 INIT_XMM
161 IDCT4x4DC sse2
162 INIT_AVX
163 IDCT4x4DC avx
164 %else
165
166 INIT_MMX
167 ;-----------------------------------------------------------------------------
168 ; void idct4x4dc( int16_t d[4][4] )
169 ;-----------------------------------------------------------------------------
170 cglobal idct4x4dc_mmx, 1,1
171     movq   m3, [r0+24]
172     movq   m2, [r0+16]
173     movq   m1, [r0+ 8]
174     movq   m0, [r0+ 0]
175     WALSH4_1D  w,0,1,2,3,4
176     TRANSPOSE4x4W 0,1,2,3,4
177     WALSH4_1D  w,0,1,2,3,4
178     movq  [r0+ 0], m0
179     movq  [r0+ 8], m1
180     movq  [r0+16], m2
181     movq  [r0+24], m3
182     RET
183 %endif ; HIGH_BIT_DEPTH
184
185 INIT_MMX
186 %ifdef HIGH_BIT_DEPTH
187 ;-----------------------------------------------------------------------------
188 ; void sub4x4_dct( dctcoef dct[4][4], pixel *pix1, pixel *pix2 )
189 ;-----------------------------------------------------------------------------
190 cglobal sub4x4_dct_mmx, 3,3
191 .skip_prologue:
192     LOAD_DIFF  m0, m4, none, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
193     LOAD_DIFF  m3, m4, none, [r1+6*FENC_STRIDE], [r2+6*FDEC_STRIDE]
194     LOAD_DIFF  m1, m4, none, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
195     LOAD_DIFF  m2, m4, none, [r1+4*FENC_STRIDE], [r2+4*FDEC_STRIDE]
196     DCT4_1D 0,1,2,3,4
197     TRANSPOSE4x4W 0,1,2,3,4
198
199     SUMSUB_BADC w, 3, 0, 2, 1
200     SUMSUB_BA   w, 2, 3, 4
201     DCT_UNPACK m2, m4, m5
202     DCT_UNPACK m3, m6, m7
203     mova  [r0+ 0], m2 ; s03 + s12
204     mova  [r0+ 8], m4
205     mova  [r0+32], m3 ; s03 - s12
206     mova  [r0+40], m6
207
208     DCT_UNPACK m0, m2, m4
209     DCT_UNPACK m1, m3, m5
210     SUMSUB2_AB  d, 0, 1, 4
211     SUMSUB2_AB  d, 2, 3, 5
212     mova  [r0+16], m0 ; d03*2 + d12
213     mova  [r0+24], m2
214     mova  [r0+48], m4 ; d03 - 2*d12
215     mova  [r0+56], m5
216     RET
217 %else
218
219 %macro SUB_DCT4 1
220 cglobal sub4x4_dct_%1, 3,3
221 %ifidn %1, mmx
222 .skip_prologue:
223     LOAD_DIFF  m0, m4, m5, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
224     LOAD_DIFF  m3, m4, m5, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
225     LOAD_DIFF  m1, m4, m5, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
226     LOAD_DIFF  m2, m4, m5, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
227 %else
228     mova m5, [hsub_mul]
229     LOAD_DIFF8x4_SSSE3 0, 3, 1, 2, 4, 5, r1, r2
230 %endif
231     DCT4_1D 0,1,2,3,4
232     TRANSPOSE4x4W 0,1,2,3,4
233     DCT4_1D 0,1,2,3,4
234     movq  [r0+ 0], m0
235     movq  [r0+ 8], m1
236     movq  [r0+16], m2
237     movq  [r0+24], m3
238     RET
239 %endmacro
240
241 SUB_DCT4 mmx
242 SUB_DCT4 ssse3
243 %endif ; HIGH_BIT_DEPTH
244
245 %ifdef HIGH_BIT_DEPTH
246 ;-----------------------------------------------------------------------------
247 ; void add4x4_idct( pixel *p_dst, dctcoef dct[4][4] )
248 ;-----------------------------------------------------------------------------
249 %macro STORE_DIFFx2 6
250     psrad     %1, 6
251     psrad     %2, 6
252     packssdw  %1, %2
253     movq      %3, %5
254     movhps    %3, %6
255     paddsw    %1, %3
256     CLIPW     %1, %4, [pw_pixel_max]
257     movq      %5, %1
258     movhps    %6, %1
259 %endmacro
260
261 %macro ADD4x4_IDCT 1
262 cglobal add4x4_idct_%1, 2,2,6
263     add   r0, 4*FDEC_STRIDE
264 .skip_prologue:
265     mova  m1, [r1+16]
266     mova  m3, [r1+48]
267     mova  m2, [r1+32]
268     mova  m0, [r1+ 0]
269     IDCT4_1D d,0,1,2,3,4,5
270     TRANSPOSE4x4D 0,1,2,3,4
271     paddd m0, [pd_32]
272     IDCT4_1D d,0,1,2,3,4,5
273     pxor  m5, m5
274     STORE_DIFFx2 m0, m1, m4, m5, [r0-4*FDEC_STRIDE], [r0-2*FDEC_STRIDE]
275     STORE_DIFFx2 m2, m3, m4, m5, [r0+0*FDEC_STRIDE], [r0+2*FDEC_STRIDE]
276     RET
277 %endmacro
278
279 INIT_XMM
280 ADD4x4_IDCT sse2
281 INIT_AVX
282 ADD4x4_IDCT avx
283
284 %else ; !HIGH_BIT_DEPTH
285
286 cglobal add4x4_idct_mmx, 2,2
287     pxor m7, m7
288 .skip_prologue:
289     movq  m1, [r1+ 8]
290     movq  m3, [r1+24]
291     movq  m2, [r1+16]
292     movq  m0, [r1+ 0]
293     IDCT4_1D w,0,1,2,3,4,5
294     TRANSPOSE4x4W 0,1,2,3,4
295     paddw m0, [pw_32]
296     IDCT4_1D w,0,1,2,3,4,5
297     STORE_DIFF  m0, m4, m7, [r0+0*FDEC_STRIDE]
298     STORE_DIFF  m1, m4, m7, [r0+1*FDEC_STRIDE]
299     STORE_DIFF  m2, m4, m7, [r0+2*FDEC_STRIDE]
300     STORE_DIFF  m3, m4, m7, [r0+3*FDEC_STRIDE]
301     RET
302
303 %macro ADD4x4 1
304 cglobal add4x4_idct_%1, 2,2,6
305     mova      m1, [r1+0x00]     ; row1/row0
306     mova      m3, [r1+0x10]     ; row3/row2
307     psraw     m0, m1, 1         ; row1>>1/...
308     psraw     m2, m3, 1         ; row3>>1/...
309     movsd     m0, m1            ; row1>>1/row0
310     movsd     m2, m3            ; row3>>1/row2
311     psubw     m0, m3            ; row1>>1-row3/row0-2
312     paddw     m2, m1            ; row3>>1+row1/row0+2
313     SBUTTERFLY2 wd, 0, 2, 1
314     SUMSUB_BA w, 2, 0, 1
315     pshuflw   m1, m2, 10110001b
316     pshufhw   m2, m2, 10110001b
317     punpckldq m1, m0
318     punpckhdq m2, m0
319     SWAP       0, 1
320
321     mova      m1, [pw_32_0]
322     paddw     m1, m0            ; row1/row0 corrected
323     psraw     m0, 1             ; row1>>1/...
324     psraw     m3, m2, 1         ; row3>>1/...
325     movsd     m0, m1            ; row1>>1/row0
326     movsd     m3, m2            ; row3>>1/row2
327     psubw     m0, m2            ; row1>>1-row3/row0-2
328     paddw     m3, m1            ; row3>>1+row1/row0+2
329     SBUTTERFLY2 qdq, 0, 3, 1
330     SUMSUB_BA w, 3, 0, 1
331
332     movd      m4, [r0+FDEC_STRIDE*0]
333     movd      m1, [r0+FDEC_STRIDE*1]
334     movd      m2, [r0+FDEC_STRIDE*2]
335     movd      m5, [r0+FDEC_STRIDE*3]
336     punpckldq m1, m4            ; row0/row1
337     pxor      m4, m4
338     punpckldq m2, m5            ; row3/row2
339     punpcklbw m1, m4
340     psraw     m3, 6
341     punpcklbw m2, m4
342     psraw     m0, 6
343     paddsw    m3, m1
344     paddsw    m0, m2
345     packuswb  m0, m3            ; row0/row1/row3/row2
346     pextrd   [r0+FDEC_STRIDE*0], m0, 3
347     pextrd   [r0+FDEC_STRIDE*1], m0, 2
348     movd     [r0+FDEC_STRIDE*2], m0
349     pextrd   [r0+FDEC_STRIDE*3], m0, 1
350     RET
351 %endmacro ; ADD4x4
352
353 INIT_XMM
354 ADD4x4 sse4
355 INIT_AVX
356 ADD4x4 avx
357 %endif ; HIGH_BIT_DEPTH
358
359 INIT_MMX
360 ;-----------------------------------------------------------------------------
361 ; void sub8x8_dct( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
362 ;-----------------------------------------------------------------------------
363 %macro SUB_NxN_DCT 6
364 cglobal %1, 3,3,11*(mmsize/16)
365 %ifndef HIGH_BIT_DEPTH
366 %if mmsize == 8
367     pxor m7, m7
368 %else
369     add r2, 4*FDEC_STRIDE
370     mova m7, [hsub_mul]
371 %endif
372 %endif ; !HIGH_BIT_DEPTH
373 .skip_prologue:
374 %ifdef WIN64
375     sub  rsp, 8
376 %endif
377     call %2
378     add  r0, %3
379     add  r1, %4-%5-%6*FENC_STRIDE
380     add  r2, %4-%5-%6*FDEC_STRIDE
381     call %2
382     add  r0, %3
383     add  r1, (%4-%6)*FENC_STRIDE-%5-%4
384     add  r2, (%4-%6)*FDEC_STRIDE-%5-%4
385     call %2
386     add  r0, %3
387     add  r1, %4-%5-%6*FENC_STRIDE
388     add  r2, %4-%5-%6*FDEC_STRIDE
389 %ifdef WIN64
390     call %2
391     add  rsp, 8
392     RET
393 %else
394     jmp  %2
395 %endif
396 %endmacro
397
398 ;-----------------------------------------------------------------------------
399 ; void add8x8_idct( uint8_t *pix, int16_t dct[4][4][4] )
400 ;-----------------------------------------------------------------------------
401 %macro ADD_NxN_IDCT 6-7
402 %ifdef HIGH_BIT_DEPTH
403 cglobal %1, 2,2,6*(mmsize/16)
404 %else
405 cglobal %1, 2,2,11*(mmsize/16)
406     pxor m7, m7
407 %endif
408 %if mmsize==16
409     add  r0, 4*FDEC_STRIDE
410 %endif
411 .skip_prologue:
412 %ifdef WIN64
413     sub  rsp, 8
414 %endif
415     call %2
416     add  r0, %4-%5-%6*FDEC_STRIDE
417     add  r1, %3
418     call %2
419     add  r0, (%4-%6)*FDEC_STRIDE-%5-%4
420     add  r1, %3
421     call %2
422     add  r0, %4-%5-%6*FDEC_STRIDE
423     add  r1, %3
424 %ifdef WIN64
425     call %2
426     add  rsp, 8
427     RET
428 %else
429     jmp  %2
430 %endif
431 %endmacro
432
433 %ifdef HIGH_BIT_DEPTH
434 INIT_MMX
435 SUB_NxN_DCT  sub8x8_dct_mmx,    sub4x4_dct_mmx.skip_prologue,  64,  8, 0, 0
436 SUB_NxN_DCT  sub16x16_dct_mmx,  sub8x8_dct_mmx.skip_prologue,  64, 16, 8, 8
437 INIT_XMM
438 ADD_NxN_IDCT add8x8_idct_sse2,  add4x4_idct_sse2.skip_prologue,64,  8, 0, 0
439 ADD_NxN_IDCT add16x16_idct_sse2,add8x8_idct_sse2.skip_prologue,64, 16, 8, 8
440 INIT_AVX
441 ADD_NxN_IDCT add8x8_idct_avx,   add4x4_idct_avx.skip_prologue, 64,  8, 0, 0
442 ADD_NxN_IDCT add16x16_idct_avx ,add8x8_idct_avx.skip_prologue, 64, 16, 8, 8
443 %else ; !HIGH_BIT_DEPTH
444 %ifndef ARCH_X86_64
445 SUB_NxN_DCT  sub8x8_dct_mmx,    sub4x4_dct_mmx.skip_prologue,  32, 4, 0, 0
446 ADD_NxN_IDCT add8x8_idct_mmx,   add4x4_idct_mmx.skip_prologue, 32, 4, 0, 0
447 SUB_NxN_DCT  sub16x16_dct_mmx,  sub8x8_dct_mmx.skip_prologue,  32, 8, 4, 4
448 ADD_NxN_IDCT add16x16_idct_mmx, add8x8_idct_mmx.skip_prologue, 32, 8, 4, 4
449
450 cextern sub8x8_dct8_mmx.skip_prologue
451 cextern add8x8_idct8_mmx.skip_prologue
452 SUB_NxN_DCT  sub16x16_dct8_mmx,  sub8x8_dct8_mmx.skip_prologue,  128, 8, 0, 0
453 ADD_NxN_IDCT add16x16_idct8_mmx, add8x8_idct8_mmx.skip_prologue, 128, 8, 0, 0
454 %endif
455
456 INIT_XMM
457 cextern sub8x8_dct_sse2.skip_prologue
458 cextern sub8x8_dct_ssse3.skip_prologue
459 cextern sub8x8_dct_avx.skip_prologue
460 SUB_NxN_DCT  sub16x16_dct_sse2,  sub8x8_dct_sse2.skip_prologue,  128, 8, 0, 0
461 SUB_NxN_DCT  sub16x16_dct_ssse3, sub8x8_dct_ssse3.skip_prologue, 128, 8, 0, 0
462 SUB_NxN_DCT  sub16x16_dct_avx,   sub8x8_dct_avx.skip_prologue,   128, 8, 0, 0
463
464 cextern add8x8_idct_sse2.skip_prologue
465 cextern add8x8_idct_avx.skip_prologue
466 ADD_NxN_IDCT add16x16_idct_sse2, add8x8_idct_sse2.skip_prologue, 128, 8, 0, 0
467 ADD_NxN_IDCT add16x16_idct_avx,  add8x8_idct_avx.skip_prologue,  128, 8, 0, 0
468
469 cextern add8x8_idct8_sse2.skip_prologue
470 cextern add8x8_idct8_avx.skip_prologue
471 ADD_NxN_IDCT add16x16_idct8_sse2, add8x8_idct8_sse2.skip_prologue, 128, 8, 0, 0
472 ADD_NxN_IDCT add16x16_idct8_avx,  add8x8_idct8_avx.skip_prologue,  128, 8, 0, 0
473
474 cextern sub8x8_dct8_sse2.skip_prologue
475 cextern sub8x8_dct8_ssse3.skip_prologue
476 cextern sub8x8_dct8_avx.skip_prologue
477 SUB_NxN_DCT  sub16x16_dct8_sse2,  sub8x8_dct8_sse2.skip_prologue,  128, 8, 0, 0
478 SUB_NxN_DCT  sub16x16_dct8_ssse3, sub8x8_dct8_ssse3.skip_prologue, 128, 8, 0, 0
479 SUB_NxN_DCT  sub16x16_dct8_avx,   sub8x8_dct8_avx.skip_prologue,   128, 8, 0, 0
480 %endif ; HIGH_BIT_DEPTH
481
482 %ifdef HIGH_BIT_DEPTH
483 INIT_XMM
484 ;-----------------------------------------------------------------------------
485 ; void add8x8_idct_dc( pixel *p_dst, dctcoef *dct2x2 )
486 ;-----------------------------------------------------------------------------
487 %macro ADD_DC 2
488     mova    m0, [%1+FDEC_STRIDEB*0] ; 8pixels
489     mova    m1, [%1+FDEC_STRIDEB*1]
490     mova    m2, [%1+FDEC_STRIDEB*2]
491     paddsw  m0, %2
492     paddsw  m1, %2
493     paddsw  m2, %2
494     paddsw  %2, [%1+FDEC_STRIDEB*3]
495     CLIPW   m0, m5, m6
496     CLIPW   m1, m5, m6
497     CLIPW   m2, m5, m6
498     CLIPW   %2, m5, m6
499     mova    [%1+FDEC_STRIDEB*0], m0
500     mova    [%1+FDEC_STRIDEB*1], m1
501     mova    [%1+FDEC_STRIDEB*2], m2
502     mova    [%1+FDEC_STRIDEB*3], %2
503 %endmacro
504
505 %macro ADD_IDCT_DC 1
506 cglobal add8x8_idct_dc_%1, 2,2,7
507     mova        m6, [pw_pixel_max]
508     pxor        m5, m5
509     mova        m3, [r1]
510     paddd       m3, [pd_32]
511     psrad       m3, 6             ; dc0   0 dc1   0 dc2   0 dc3   0
512     pshuflw     m4, m3, 10100000b ; dc0 dc0 dc1 dc1   _   _   _   _
513     pshufhw     m3, m3, 10100000b ;   _   _   _   _ dc2 dc2 dc3 dc3
514     pshufd      m4, m4, 01010000b ; dc0 dc0 dc0 dc0 dc1 dc1 dc1 dc1
515     pshufd      m3, m3, 11111010b ; dc2 dc2 dc2 dc2 dc3 dc3 dc3 dc3
516     ADD_DC r0+FDEC_STRIDEB*0, m4
517     ADD_DC r0+FDEC_STRIDEB*4, m3
518     RET
519
520 cglobal add16x16_idct_dc_%1, 2,3,8
521     mov         r2, 4
522     mova        m6, [pw_pixel_max]
523     mova        m7, [pd_32]
524     pxor        m5, m5
525 .loop
526     mova        m3, [r1]
527     paddd       m3, m7
528     psrad       m3, 6             ; dc0   0 dc1   0 dc2   0 dc3   0
529     pshuflw     m4, m3, 10100000b ; dc0 dc0 dc1 dc1   _   _   _   _
530     pshufhw     m3, m3, 10100000b ;   _   _   _   _ dc2 dc2 dc3 dc3
531     pshufd      m4, m4, 01010000b ; dc0 dc0 dc0 dc0 dc1 dc1 dc1 dc1
532     pshufd      m3, m3, 11111010b ; dc2 dc2 dc2 dc2 dc3 dc3 dc3 dc3
533     ADD_DC r0+FDEC_STRIDEB*0, m4
534     ADD_DC r0+SIZEOF_PIXEL*8, m3
535     add         r1, 16
536     add         r0, 4*FDEC_STRIDEB
537     dec         r2
538     jg .loop
539     REP_RET
540 %endmacro ; ADD_IDCT_DC
541
542 INIT_XMM
543 ADD_IDCT_DC sse2
544 INIT_AVX
545 ADD_IDCT_DC avx
546
547 %else ;!HIGH_BIT_DEPTH
548 %macro ADD_DC 3
549     movq      mm4, [%3+FDEC_STRIDE*0]
550     movq      mm5, [%3+FDEC_STRIDE*1]
551     movq      mm6, [%3+FDEC_STRIDE*2]
552     paddusb   mm4, %1
553     paddusb   mm5, %1
554     paddusb   mm6, %1
555     paddusb    %1, [%3+FDEC_STRIDE*3]
556     psubusb   mm4, %2
557     psubusb   mm5, %2
558     psubusb   mm6, %2
559     psubusb    %1, %2
560     movq      [%3+FDEC_STRIDE*0], mm4
561     movq      [%3+FDEC_STRIDE*1], mm5
562     movq      [%3+FDEC_STRIDE*2], mm6
563     movq      [%3+FDEC_STRIDE*3], %1
564 %endmacro
565
566 cglobal add8x8_idct_dc_mmx, 2,2
567     movq      mm0, [r1]
568     pxor      mm1, mm1
569     add        r0, FDEC_STRIDE*4
570     paddw     mm0, [pw_32]
571     psraw     mm0, 6
572     psubw     mm1, mm0
573     packuswb  mm0, mm0
574     packuswb  mm1, mm1
575     punpcklbw mm0, mm0
576     punpcklbw mm1, mm1
577     pshufw    mm2, mm0, 0xFA
578     pshufw    mm3, mm1, 0xFA
579     punpcklbw mm0, mm0
580     punpcklbw mm1, mm1
581     ADD_DC    mm0, mm1, r0-FDEC_STRIDE*4
582     ADD_DC    mm2, mm3, r0
583     RET
584
585 cglobal add8x8_idct_dc_ssse3, 2,2
586     movq      xmm0, [r1]
587     pxor      xmm1, xmm1
588     add         r0, FDEC_STRIDE*4
589     paddw     xmm0, [pw_32]
590     psraw     xmm0, 6
591     psubw     xmm1, xmm0
592     movdqa    xmm5, [pb_idctdc_unpack]
593     packuswb  xmm0, xmm0
594     packuswb  xmm1, xmm1
595     pshufb    xmm0, xmm5
596     pshufb    xmm1, xmm5
597     movq      xmm2, [r0+FDEC_STRIDE*-4]
598     movq      xmm3, [r0+FDEC_STRIDE*-3]
599     movq      xmm4, [r0+FDEC_STRIDE*-2]
600     movq      xmm5, [r0+FDEC_STRIDE*-1]
601     movhps    xmm2, [r0+FDEC_STRIDE* 0]
602     movhps    xmm3, [r0+FDEC_STRIDE* 1]
603     movhps    xmm4, [r0+FDEC_STRIDE* 2]
604     movhps    xmm5, [r0+FDEC_STRIDE* 3]
605     paddusb   xmm2, xmm0
606     paddusb   xmm3, xmm0
607     paddusb   xmm4, xmm0
608     paddusb   xmm5, xmm0
609     psubusb   xmm2, xmm1
610     psubusb   xmm3, xmm1
611     psubusb   xmm4, xmm1
612     psubusb   xmm5, xmm1
613     movq      [r0+FDEC_STRIDE*-4], xmm2
614     movq      [r0+FDEC_STRIDE*-3], xmm3
615     movq      [r0+FDEC_STRIDE*-2], xmm4
616     movq      [r0+FDEC_STRIDE*-1], xmm5
617     movhps    [r0+FDEC_STRIDE* 0], xmm2
618     movhps    [r0+FDEC_STRIDE* 1], xmm3
619     movhps    [r0+FDEC_STRIDE* 2], xmm4
620     movhps    [r0+FDEC_STRIDE* 3], xmm5
621     RET
622
623 cglobal add16x16_idct_dc_mmx, 2,3
624     mov       r2, 4
625 .loop:
626     movq      mm0, [r1]
627     pxor      mm1, mm1
628     paddw     mm0, [pw_32]
629     psraw     mm0, 6
630     psubw     mm1, mm0
631     packuswb  mm0, mm0
632     packuswb  mm1, mm1
633     punpcklbw mm0, mm0
634     punpcklbw mm1, mm1
635     pshufw    mm2, mm0, 0xFA
636     pshufw    mm3, mm1, 0xFA
637     punpcklbw mm0, mm0
638     punpcklbw mm1, mm1
639     ADD_DC    mm0, mm1, r0
640     ADD_DC    mm2, mm3, r0+8
641     add       r1, 8
642     add       r0, FDEC_STRIDE*4
643     dec       r2
644     jg .loop
645     REP_RET
646
647 %macro IDCT_DC_STORE 3
648     movdqa    xmm4, [r0+%1+FDEC_STRIDE*0]
649     movdqa    xmm5, [r0+%1+FDEC_STRIDE*1]
650     movdqa    xmm6, [r0+%1+FDEC_STRIDE*2]
651     movdqa    xmm7, [r0+%1+FDEC_STRIDE*3]
652     paddusb   xmm4, %2
653     paddusb   xmm5, %2
654     paddusb   xmm6, %2
655     paddusb   xmm7, %2
656     psubusb   xmm4, %3
657     psubusb   xmm5, %3
658     psubusb   xmm6, %3
659     psubusb   xmm7, %3
660     movdqa    [r0+%1+FDEC_STRIDE*0], xmm4
661     movdqa    [r0+%1+FDEC_STRIDE*1], xmm5
662     movdqa    [r0+%1+FDEC_STRIDE*2], xmm6
663     movdqa    [r0+%1+FDEC_STRIDE*3], xmm7
664 %endmacro
665
666 cglobal add16x16_idct_dc_sse2, 2,2,8
667     call .loop
668     add       r0, FDEC_STRIDE*4
669 %ifdef WIN64
670     call .loop
671     RET
672 %endif
673 .loop:
674     add       r0, FDEC_STRIDE*4
675     movq      xmm0, [r1+0]
676     movq      xmm2, [r1+8]
677     add       r1, 16
678     punpcklwd xmm0, xmm0
679     punpcklwd xmm2, xmm2
680     pxor      xmm3, xmm3
681     paddw     xmm0, [pw_32]
682     paddw     xmm2, [pw_32]
683     psraw     xmm0, 6
684     psraw     xmm2, 6
685     psubw     xmm1, xmm3, xmm0
686     packuswb  xmm0, xmm1
687     psubw     xmm3, xmm2
688     punpckhbw xmm1, xmm0, xmm0
689     packuswb  xmm2, xmm3
690     punpckhbw xmm3, xmm2, xmm2
691     punpcklbw xmm0, xmm0
692     punpcklbw xmm2, xmm2
693     IDCT_DC_STORE FDEC_STRIDE*-4, xmm0, xmm1
694     IDCT_DC_STORE 0, xmm2, xmm3
695     ret
696
697 %macro ADD16x16 1
698 cglobal add16x16_idct_dc_%1, 2,2,8
699     call .loop
700     add       r0, FDEC_STRIDE*4
701 %ifdef WIN64
702     call .loop
703     RET
704 %endif
705 .loop:
706     add       r0, FDEC_STRIDE*4
707     movdqa    xmm0, [r1]
708     add       r1, 16
709     pxor      xmm1, xmm1
710     paddw     xmm0, [pw_32]
711     psraw     xmm0, 6
712     psubw     xmm1, xmm0
713     movdqa    xmm5, [ pb_idctdc_unpack]
714     movdqa    xmm6, [pb_idctdc_unpack2]
715     packuswb  xmm0, xmm0
716     packuswb  xmm1, xmm1
717     pshufb    xmm2, xmm0, xmm6
718     pshufb    xmm0, xmm5
719     pshufb    xmm3, xmm1, xmm6
720     pshufb    xmm1, xmm5
721     IDCT_DC_STORE FDEC_STRIDE*-4, xmm0, xmm1
722     IDCT_DC_STORE 0, xmm2, xmm3
723     ret
724 %endmacro ; ADD16x16
725
726 INIT_XMM
727 ADD16x16 ssse3
728 INIT_AVX
729 ADD16x16 avx
730
731 %endif ; HIGH_BIT_DEPTH
732
733 ;-----------------------------------------------------------------------------
734 ; void sub8x8_dct_dc( int16_t dct[2][2], uint8_t *pix1, uint8_t *pix2 )
735 ;-----------------------------------------------------------------------------
736
737 %macro DCTDC_2ROW_MMX 3
738     movq      %1, [r1+FENC_STRIDE*(0+%3)]
739     movq      m1, [r1+FENC_STRIDE*(1+%3)]
740     movq      m2, [r2+FDEC_STRIDE*(0+%3)]
741     movq      m3, [r2+FDEC_STRIDE*(1+%3)]
742     movq      %2, %1
743     punpckldq %1, m1
744     punpckhdq %2, m1
745     movq      m1, m2
746     punpckldq m2, m3
747     punpckhdq m1, m3
748     pxor      m3, m3
749     psadbw    %1, m3
750     psadbw    %2, m3
751     psadbw    m2, m3
752     psadbw    m1, m3
753     psubw     %1, m2
754     psubw     %2, m1
755 %endmacro
756
757 %macro DCT2x2 2 ; reg s1/s0 (!=m1), reg s3/s2
758     pshufw    mm1, %1, 10100000b  ;  s1  s1  s0  s0
759     pshufw    mm0, %2, 10110001b  ;  s3  __  s2  __
760     paddw     mm1, %2             ;  s1 s13  s0 s02
761     psubw     mm1, mm0            ; d13 s13 d02 s02
762     pshufw    mm0, mm1, 01000100b ; d02 s02 d02 s02
763     psrlq     mm1, 32             ;  __  __ d13 s13
764     paddw     mm0, mm1            ; d02 s02 d02+d13 s02+s13
765     psllq     mm1, 32             ; d13 s13
766     psubw     mm0, mm1            ; d02-d13 s02-s13 d02+d13 s02+s13
767 %endmacro
768
769 INIT_MMX
770 cglobal sub8x8_dct_dc_mmxext, 3,3
771     DCTDC_2ROW_MMX m0, m4, 0
772     DCTDC_2ROW_MMX m5, m6, 2
773     paddw     m0, m5
774     paddw     m4, m6
775     punpckldq m0, m4
776     add       r1, FENC_STRIDE*4
777     add       r2, FDEC_STRIDE*4
778     DCTDC_2ROW_MMX m7, m4, 0
779     DCTDC_2ROW_MMX m5, m6, 2
780     paddw     m7, m5
781     paddw     m4, m6
782     punpckldq m7, m4
783     DCT2x2    m0, m7
784     movq    [r0], m0
785     ret
786
787 INIT_XMM
788 %macro DCTDC_2ROW_SSE2 3
789     movq      m0, [r1+FENC_STRIDE*(0+%1)]
790     movq      m1, [r1+FENC_STRIDE*(1+%1)]
791     movq      m2, [r2+FDEC_STRIDE*(0+%1)]
792     movq      m3, [r2+FDEC_STRIDE*(1+%1)]
793     punpckldq m0, m1
794     punpckldq m2, m3
795     psadbw    m0, m7
796     psadbw    m2, m7
797 %if %2
798     paddw     %3, m0
799     paddw     m6, m2
800 %else
801     SWAP      %3, m0
802     SWAP      m6, m2
803 %endif
804 %endmacro
805
806 cglobal sub8x8_dct_dc_sse2, 3,3,8
807     pxor     m7, m7
808     DCTDC_2ROW_SSE2 0, 0, m4
809     DCTDC_2ROW_SSE2 2, 1, m4
810     add      r1, FENC_STRIDE*4
811     add      r2, FDEC_STRIDE*4
812     psubd    m4, m6
813     DCTDC_2ROW_SSE2 0, 0, m5
814     DCTDC_2ROW_SSE2 2, 1, m5
815     psubd    m5, m6
816     packssdw m4, m5
817     movhlps  m5, m4
818     movdq2q mm0, m4
819     movdq2q mm7, m5
820     DCT2x2  mm0, mm7
821     movq   [r0], mm0
822     RET
823
824 ;-----------------------------------------------------------------------------
825 ; void zigzag_scan_8x8_frame( int16_t level[64], int16_t dct[8][8] )
826 ;-----------------------------------------------------------------------------
827 %macro SCAN_8x8 1
828 cglobal zigzag_scan_8x8_frame_%1, 2,2,8
829     movdqa    xmm0, [r1]
830     movdqa    xmm1, [r1+16]
831     movdq2q    mm0, xmm0
832     PALIGNR   xmm1, xmm1, 14, xmm2
833     movdq2q    mm1, xmm1
834
835     movdqa    xmm2, [r1+32]
836     movdqa    xmm3, [r1+48]
837     PALIGNR   xmm2, xmm2, 12, xmm4
838     movdq2q    mm2, xmm2
839     PALIGNR   xmm3, xmm3, 10, xmm4
840     movdq2q    mm3, xmm3
841
842     punpckhwd xmm0, xmm1
843     punpckhwd xmm2, xmm3
844
845     movq       mm4, mm1
846     movq       mm5, mm1
847     movq       mm6, mm2
848     movq       mm7, mm3
849     punpckhwd  mm1, mm0
850     psllq      mm0, 16
851     psrlq      mm3, 16
852     punpckhdq  mm1, mm1
853     punpckhdq  mm2, mm0
854     punpcklwd  mm0, mm4
855     punpckhwd  mm4, mm3
856     punpcklwd  mm4, mm2
857     punpckhdq  mm0, mm2
858     punpcklwd  mm6, mm3
859     punpcklwd  mm5, mm7
860     punpcklwd  mm5, mm6
861
862     movdqa    xmm4, [r1+64]
863     movdqa    xmm5, [r1+80]
864     movdqa    xmm6, [r1+96]
865     movdqa    xmm7, [r1+112]
866
867     movq [r0+2*00], mm0
868     movq [r0+2*04], mm4
869     movd [r0+2*08], mm1
870     movq [r0+2*36], mm5
871     movq [r0+2*46], mm6
872
873     PALIGNR   xmm4, xmm4, 14, xmm3
874     movdq2q    mm4, xmm4
875     PALIGNR   xmm5, xmm5, 12, xmm3
876     movdq2q    mm5, xmm5
877     PALIGNR   xmm6, xmm6, 10, xmm3
878     movdq2q    mm6, xmm6
879 %ifnidn %1, sse2
880     PALIGNR   xmm7, xmm7, 8, xmm3
881     movdq2q    mm7, xmm7
882 %else
883     movhlps   xmm3, xmm7
884     punpcklqdq xmm7, xmm7
885     movdq2q    mm7, xmm3
886 %endif
887
888     punpckhwd xmm4, xmm5
889     punpckhwd xmm6, xmm7
890
891     movq       mm0, mm4
892     movq       mm1, mm5
893     movq       mm3, mm7
894     punpcklwd  mm7, mm6
895     psrlq      mm6, 16
896     punpcklwd  mm4, mm6
897     punpcklwd  mm5, mm4
898     punpckhdq  mm4, mm3
899     punpcklwd  mm3, mm6
900     punpckhwd  mm3, mm4
901     punpckhwd  mm0, mm1
902     punpckldq  mm4, mm0
903     punpckhdq  mm0, mm6
904     pshufw     mm4, mm4, 0x6c
905
906     movq [r0+2*14], mm4
907     movq [r0+2*25], mm0
908     movd [r0+2*54], mm7
909     movq [r0+2*56], mm5
910     movq [r0+2*60], mm3
911
912     punpckhdq xmm3, xmm0, xmm2
913     punpckldq xmm0, xmm2
914     punpckhdq xmm7, xmm4, xmm6
915     punpckldq xmm4, xmm6
916     pshufhw   xmm0, xmm0, 0x1b
917     pshuflw   xmm4, xmm4, 0x1b
918     pshufhw   xmm3, xmm3, 0x1b
919     pshuflw   xmm7, xmm7, 0x1b
920
921     movlps [r0+2*10], xmm0
922     movhps [r0+2*17], xmm0
923     movlps [r0+2*21], xmm3
924     movlps [r0+2*28], xmm4
925     movhps [r0+2*32], xmm3
926     movhps [r0+2*39], xmm4
927     movlps [r0+2*43], xmm7
928     movhps [r0+2*50], xmm7
929
930     RET
931 %endmacro
932
933 %ifndef HIGH_BIT_DEPTH
934 INIT_XMM
935 %define PALIGNR PALIGNR_MMX
936 SCAN_8x8 sse2
937 %define PALIGNR PALIGNR_SSSE3
938 SCAN_8x8 ssse3
939 %endif
940
941 ;-----------------------------------------------------------------------------
942 ; void zigzag_scan_8x8_frame( dctcoef level[64], dctcoef dct[8][8] )
943 ;-----------------------------------------------------------------------------
944 %macro SCAN_8x8_FRAME 6
945 cglobal zigzag_scan_8x8_frame_%1, 2,2,8*(mmsize/16)
946     mova        m0, [r1]
947     mova        m1, [r1+ 8*SIZEOF_DCTCOEF]
948     movu        m2, [r1+14*SIZEOF_DCTCOEF]
949     movu        m3, [r1+21*SIZEOF_DCTCOEF]
950     mova        m4, [r1+28*SIZEOF_DCTCOEF]
951     punpckl%5   m5, m0, m1
952     psrl%3      m0, %2
953     punpckh%5   m6, m1, m0
954     punpckl%4   m5, m0
955     punpckl%4   m1, m1
956     punpckh%5   m1, m3
957     mova        m7, [r1+52*SIZEOF_DCTCOEF]
958     mova        m0, [r1+60*SIZEOF_DCTCOEF]
959     punpckh%5   m1, m2
960     punpckl%5   m2, m4
961     punpckh%5   m4, m3
962     punpckl%4   m3, m3
963     punpckh%5   m3, m2
964     mova      [r0], m5
965     mova  [r0+ 4*SIZEOF_DCTCOEF], m1
966     mova  [r0+ 8*SIZEOF_DCTCOEF], m6
967     punpckl%5   m6, m0
968     punpckl%5   m6, m7
969     mova        m1, [r1+32*SIZEOF_DCTCOEF]
970     movu        m5, [r1+39*SIZEOF_DCTCOEF]
971     movu        m2, [r1+46*SIZEOF_DCTCOEF]
972     movu [r0+35*SIZEOF_DCTCOEF], m3
973     movu [r0+47*SIZEOF_DCTCOEF], m4
974     punpckh%5   m7, m0
975     psll%3      m0, %2
976     punpckh%4   m3, m5, m5
977     punpckl%5   m5, m1
978     punpckh%5   m1, m2
979     mova [r0+52*SIZEOF_DCTCOEF], m6
980     movu [r0+13*SIZEOF_DCTCOEF], m5
981     movu        m4, [r1+11*SIZEOF_DCTCOEF]
982     movu        m6, [r1+25*SIZEOF_DCTCOEF]
983     punpckl%5   m5, m7
984     punpckl%5   m1, m3
985     punpckh%4   m0, m7
986     mova        m3, [r1+ 4*SIZEOF_DCTCOEF]
987     movu        m7, [r1+18*SIZEOF_DCTCOEF]
988     punpckl%5   m2, m5
989     movu [r0+25*SIZEOF_DCTCOEF], m1
990     mova        m1, m4
991     mova        m5, m6
992     punpckl%5   m4, m3
993     punpckl%5   m6, m7
994     punpckh%5   m1, m3
995     punpckh%5   m5, m7
996     punpckh%4   m3, m6, m4
997     punpckh%4   m7, m5, m1
998     punpckl%4   m6, m4
999     punpckl%4   m5, m1
1000     movu        m4, [r1+35*SIZEOF_DCTCOEF]
1001     movu        m1, [r1+49*SIZEOF_DCTCOEF]
1002     pshuf%6     m6, m6, 0x1b
1003     pshuf%6     m5, m5, 0x1b
1004     mova [r0+60*SIZEOF_DCTCOEF], m0
1005     mova [r0+56*SIZEOF_DCTCOEF], m2
1006     movu        m0, [r1+42*SIZEOF_DCTCOEF]
1007     mova        m2, [r1+56*SIZEOF_DCTCOEF]
1008     movu [r0+17*SIZEOF_DCTCOEF], m3
1009     mova [r0+32*SIZEOF_DCTCOEF], m7
1010     movu [r0+10*SIZEOF_DCTCOEF], m6
1011     movu [r0+21*SIZEOF_DCTCOEF], m5
1012     punpckh%5   m3, m0, m4
1013     punpckh%5   m7, m2, m1
1014     punpckl%5   m0, m4
1015     punpckl%5   m2, m1
1016     punpckl%4   m4, m2, m0
1017     punpckl%4   m1, m7, m3
1018     punpckh%4   m2, m0
1019     punpckh%4   m7, m3
1020     pshuf%6     m2, m2, 0x1b
1021     pshuf%6     m7, m7, 0x1b
1022     mova [r0+28*SIZEOF_DCTCOEF], m4
1023     movu [r0+43*SIZEOF_DCTCOEF], m1
1024     movu [r0+39*SIZEOF_DCTCOEF], m2
1025     movu [r0+50*SIZEOF_DCTCOEF], m7
1026     RET
1027 %endmacro
1028
1029 %ifdef HIGH_BIT_DEPTH
1030 INIT_XMM
1031 SCAN_8x8_FRAME sse2  , 4 , dq, qdq, dq, d
1032 INIT_AVX
1033 SCAN_8x8_FRAME avx   , 4 , dq, qdq, dq, d
1034 %else
1035 INIT_MMX
1036 SCAN_8x8_FRAME mmxext, 16, q , dq , wd, w
1037 %endif
1038
1039 ;-----------------------------------------------------------------------------
1040 ; void zigzag_scan_4x4_frame( dctcoef level[16], dctcoef dct[4][4] )
1041 ;-----------------------------------------------------------------------------
1042 %macro SCAN_4x4 5
1043 cglobal zigzag_scan_4x4_frame_%1, 2,2,8*(mmsize)/16
1044     mova       m0, [r1]
1045     mova       m1, [r1+ 4*SIZEOF_DCTCOEF]
1046     mova       m2, [r1+ 8*SIZEOF_DCTCOEF]
1047     mova       m3, [r1+12*SIZEOF_DCTCOEF]
1048     punpckl%5  m4, m0, m1
1049     mova       m5, m1
1050     mova       m6, m2
1051     mova       m7, m3
1052     psll%3     m3, %2
1053     psrl%3     m0, %2
1054     punpckl%4  m2, m2
1055     punpckh%4  m1, m1
1056     punpckl%5  m5, m3
1057     punpckl%4  m4, m0
1058     punpckh%5  m5, m2
1059     punpckh%5  m0, m6
1060     punpckh%5  m6, m7
1061     punpckl%5  m1, m0
1062     punpckh%4  m3, m6
1063     mova     [r0], m4
1064     mova  [r0+ 4*SIZEOF_DCTCOEF], m5
1065     mova  [r0+ 8*SIZEOF_DCTCOEF], m1
1066     mova  [r0+12*SIZEOF_DCTCOEF], m3
1067     RET
1068 %endmacro
1069
1070 %ifdef HIGH_BIT_DEPTH
1071 INIT_XMM
1072 SCAN_4x4 sse2, 4 , dq, qdq, dq
1073 INIT_AVX
1074 SCAN_4x4 avx , 4 , dq, qdq, dq
1075 %else
1076 INIT_MMX
1077 SCAN_4x4 mmx , 16, q , dq , wd
1078
1079 ;-----------------------------------------------------------------------------
1080 ; void zigzag_scan_4x4_frame( int16_t level[16], int16_t dct[4][4] )
1081 ;-----------------------------------------------------------------------------
1082 %macro SCAN_4x4_FRAME 1
1083 cglobal zigzag_scan_4x4_frame_%1, 2,2
1084     movdqa    xmm1, [r1+16]
1085     movdqa    xmm0, [r1]
1086     pshufb    xmm1, [pb_scan4frameb]
1087     pshufb    xmm0, [pb_scan4framea]
1088     psrldq    xmm2, xmm1, 6
1089     palignr   xmm1, xmm0, 6
1090     pslldq    xmm0, 10
1091     palignr   xmm2, xmm0, 10
1092     movdqa    [r0], xmm1
1093     movdqa [r0+16], xmm2
1094     RET
1095 %endmacro
1096
1097 INIT_XMM
1098 SCAN_4x4_FRAME ssse3
1099 INIT_AVX
1100 SCAN_4x4_FRAME avx
1101 %endif ; !HIGH_BIT_DEPTH
1102
1103 %ifdef HIGH_BIT_DEPTH
1104 INIT_XMM
1105 ;-----------------------------------------------------------------------------
1106 ; void zigzag_scan_4x4_field( int32_t level[16], int32_t dct[4][4] )
1107 ;-----------------------------------------------------------------------------
1108 cglobal zigzag_scan_4x4_field_sse2, 2,3
1109     movu       m4, [r1+8]
1110     pshufd     m0, m4, 0xd2
1111     mova       m1, [r1+32]
1112     mova       m2, [r1+48]
1113     movu   [r0+8], m0
1114     mova  [r0+32], m1
1115     mova  [r0+48], m2
1116     movq      mm0, [r1]
1117     movq     [r0], mm0
1118     movq      mm0, [r1+24]
1119     movq  [r0+24], mm0
1120     RET
1121 %else
1122 ;-----------------------------------------------------------------------------
1123 ; void zigzag_scan_4x4_field( int16_t level[16], int16_t dct[4][4] )
1124 ;-----------------------------------------------------------------------------
1125 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
1126 cglobal zigzag_scan_4x4_field_mmxext, 2,3
1127     pshufw     mm0, [r1+4], 0xd2
1128     movq       mm1, [r1+16]
1129     movq       mm2, [r1+24]
1130     movq    [r0+4], mm0
1131     movq   [r0+16], mm1
1132     movq   [r0+24], mm2
1133     mov        r2d, [r1]
1134     mov       [r0], r2d
1135     mov        r2d, [r1+12]
1136     mov    [r0+12], r2d
1137     RET
1138 %endif ; HIGH_BIT_DEPTH
1139
1140 ;-----------------------------------------------------------------------------
1141 ; void zigzag_scan_8x8_field( int16_t level[64], int16_t dct[8][8] )
1142 ;-----------------------------------------------------------------------------
1143 ; Output order:
1144 ;  0  1  2  8  9  3  4 10
1145 ; 16 11  5  6  7 12 17 24
1146 ; 18 13 14 15 19 25 32 26
1147 ; 20 21 22 23 27 33 40 34
1148 ; 28 29 30 31 35 41 48 42
1149 ; 36 37 38 39 43 49 50 44
1150 ; 45 46 47 51 56 57 52 53
1151 ; 54 55 58 59 60 61 62 63
1152 %undef SCAN_8x8
1153 %macro SCAN_8x8 6
1154 cglobal zigzag_scan_8x8_field_%1, 2,3,8*(mmsize/16)
1155     mova       m0, [r1+ 0*SIZEOF_DCTCOEF]       ; 03 02 01 00
1156     mova       m1, [r1+ 4*SIZEOF_DCTCOEF]       ; 07 06 05 04
1157     mova       m2, [r1+ 8*SIZEOF_DCTCOEF]       ; 11 10 09 08
1158     pshuf%2    m3, m0, 011111111b               ; 03 03 03 03
1159     movd       r2, m2                           ; 09 08
1160     pshuf%2    m2, m2, 000111001b               ; 08 11 10 09
1161     punpckl%3  m3, m1                           ; 05 03 04 03
1162     pinsr%2    m0, r2d, 3                       ; 08 02 01 00
1163     punpckl%3  m4, m2, m3                       ; 04 10 03 09
1164     pshuf%2    m4, m4, 010110100b               ; 10 04 03 09
1165     mova  [r0+ 0*SIZEOF_DCTCOEF], m0            ; 08 02 01 00
1166     mova  [r0+ 4*SIZEOF_DCTCOEF], m4            ; 10 04 03 09
1167     mova       m3, [r1+12*SIZEOF_DCTCOEF]       ; 15 14 13 12
1168     mova       m5, [r1+16*SIZEOF_DCTCOEF]       ; 19 18 17 16
1169     punpckl%4  m6, m5                           ; 17 16 XX XX
1170     psrl%5     m1, %6                           ; XX 07 06 05
1171     punpckh%3  m6, m2                           ; 08 17 11 16
1172     punpckl%4  m6, m1                           ; 06 05 11 16
1173     mova  [r0+ 8*SIZEOF_DCTCOEF], m6            ; 06 05 11 16
1174     psrl%5     m1, %6                           ; XX XX 07 06
1175     punpckl%3  m1, m5                           ; 17 07 16 06
1176     mova       m0, [r1+20*SIZEOF_DCTCOEF]       ; 23 22 21 20
1177     mova       m2, [r1+24*SIZEOF_DCTCOEF]       ; 27 26 25 24
1178     punpckh%4  m1, m1                           ; 17 07 17 07
1179     punpckl%3  m6, m3, m2                       ; 25 13 24 12
1180     pextr%2    r2d, m5, 2
1181     mova [r0+24*SIZEOF_DCTCOEF], m0             ; 23 22 21 20
1182     punpckl%3  m1, m6                           ; 24 17 12 07
1183     mova [r0+12*SIZEOF_DCTCOEF], m1
1184     pinsr%2    m3, r2d, 0                       ; 15 14 13 18
1185     mova [r0+16*SIZEOF_DCTCOEF], m3             ; 15 14 13 18
1186     mova       m7, [r1+28*SIZEOF_DCTCOEF]
1187     mova       m0, [r1+32*SIZEOF_DCTCOEF]       ; 35 34 33 32
1188     psrl%5     m5, %6*3                         ; XX XX XX 19
1189     pshuf%2    m1, m2, 011111001b               ; 27 27 26 25
1190     punpckl%3  m5, m0                           ; 33 XX 32 19
1191     psrl%5     m2, %6*3                         ; XX XX XX 27
1192     punpckl%3  m5, m1                           ; 26 32 25 19
1193     mova [r0+32*SIZEOF_DCTCOEF], m7
1194     mova [r0+20*SIZEOF_DCTCOEF], m5             ; 26 32 25 19
1195     mova       m7, [r1+36*SIZEOF_DCTCOEF]
1196     mova       m1, [r1+40*SIZEOF_DCTCOEF]       ; 43 42 41 40
1197     pshuf%2    m3, m0, 011111001b               ; 35 35 34 33
1198     punpckl%3  m2, m1                           ; 41 XX 40 27
1199     mova [r0+40*SIZEOF_DCTCOEF], m7
1200     punpckl%3  m2, m3                           ; 34 40 33 27
1201     mova [r0+28*SIZEOF_DCTCOEF], m2
1202     mova       m7, [r1+44*SIZEOF_DCTCOEF]       ; 47 46 45 44
1203     mova       m2, [r1+48*SIZEOF_DCTCOEF]       ; 51 50 49 48
1204     psrl%5     m0, %6*3                         ; XX XX XX 35
1205     punpckl%3  m0, m2                           ; 49 XX 48 35
1206     pshuf%2    m3, m1, 011111001b               ; 43 43 42 41
1207     punpckl%3  m0, m3                           ; 42 48 41 35
1208     mova [r0+36*SIZEOF_DCTCOEF], m0
1209     pextr%2     r2d, m2, 3                      ; 51
1210     psrl%5      m1, %6*3                        ; XX XX XX 43
1211     punpckl%3   m1, m7                          ; 45 XX 44 43
1212     psrl%5      m2, %6                          ; XX 51 50 49
1213     punpckl%3   m1, m2                          ; 50 44 49 43
1214     pshuf%2     m1, m1, 010110100b              ; 44 50 49 43
1215     mova [r0+44*SIZEOF_DCTCOEF], m1
1216     psrl%5      m7, %6                          ; XX 47 46 45
1217     pinsr%2     m7, r2d, 3                      ; 51 47 46 45
1218     mova [r0+48*SIZEOF_DCTCOEF], m7
1219     mova        m0, [r1+56*SIZEOF_DCTCOEF]      ; 59 58 57 56
1220     mova        m1, [r1+52*SIZEOF_DCTCOEF]      ; 55 54 53 52
1221     mova        m7, [r1+60*SIZEOF_DCTCOEF]
1222     punpckl%4   m2, m0, m1                      ; 53 52 57 56
1223     punpckh%4   m1, m0                          ; 59 58 55 54
1224     mova [r0+52*SIZEOF_DCTCOEF], m2
1225     mova [r0+56*SIZEOF_DCTCOEF], m1
1226     mova [r0+60*SIZEOF_DCTCOEF], m7
1227     RET
1228 %endmacro
1229 %ifdef HIGH_BIT_DEPTH
1230 INIT_XMM
1231 SCAN_8x8 sse4  , d, dq, qdq, dq, 4
1232 INIT_AVX
1233 SCAN_8x8 avx   , d, dq, qdq, dq, 4
1234 %else
1235 INIT_MMX
1236 SCAN_8x8 mmxext, w, wd, dq , q , 16
1237 %endif
1238
1239 ;-----------------------------------------------------------------------------
1240 ; void zigzag_sub_4x4_frame( int16_t level[16], const uint8_t *src, uint8_t *dst )
1241 ;-----------------------------------------------------------------------------
1242 %macro ZIGZAG_SUB_4x4 3
1243 %ifidn %1, ac
1244 cglobal zigzag_sub_4x4%1_%2_%3, 4,4,8
1245 %else
1246 cglobal zigzag_sub_4x4%1_%2_%3, 3,3,8
1247 %endif
1248     movd      xmm0, [r1+0*FENC_STRIDE]
1249     movd      xmm1, [r1+1*FENC_STRIDE]
1250     movd      xmm2, [r1+2*FENC_STRIDE]
1251     movd      xmm3, [r1+3*FENC_STRIDE]
1252     movd      xmm4, [r2+0*FDEC_STRIDE]
1253     movd      xmm5, [r2+1*FDEC_STRIDE]
1254     movd      xmm6, [r2+2*FDEC_STRIDE]
1255     movd      xmm7, [r2+3*FDEC_STRIDE]
1256     movd      [r2+0*FDEC_STRIDE], xmm0
1257     movd      [r2+1*FDEC_STRIDE], xmm1
1258     movd      [r2+2*FDEC_STRIDE], xmm2
1259     movd      [r2+3*FDEC_STRIDE], xmm3
1260     punpckldq xmm0, xmm1
1261     punpckldq xmm2, xmm3
1262     punpckldq xmm4, xmm5
1263     punpckldq xmm6, xmm7
1264     punpcklqdq xmm0, xmm2
1265     punpcklqdq xmm4, xmm6
1266 %ifidn %2, frame
1267     movdqa    xmm7, [pb_sub4frame]
1268 %else
1269     movdqa    xmm7, [pb_sub4field]
1270 %endif
1271     pshufb    xmm0, xmm7
1272     pshufb    xmm4, xmm7
1273     pxor      xmm6, xmm6
1274     punpckhbw xmm1, xmm0, xmm6
1275     punpckhbw xmm5, xmm4, xmm6
1276     punpcklbw xmm0, xmm6
1277     punpcklbw xmm4, xmm6
1278     psubw     xmm0, xmm4
1279     psubw     xmm1, xmm5
1280 %ifidn %1, ac
1281     movd       r2d, xmm0
1282     pand      xmm0, [pb_subacmask]
1283 %endif
1284     movdqa    [r0], xmm0
1285     pxor      xmm2, xmm2
1286     movdqa [r0+16], xmm1
1287     por       xmm0, xmm1
1288     pcmpeqb   xmm0, xmm2
1289     pmovmskb   eax, xmm0
1290 %ifidn %1, ac
1291     mov       [r3], r2w
1292 %endif
1293     sub        eax, 0xffff
1294     shr        eax, 31
1295     RET
1296 %endmacro
1297
1298 INIT_XMM
1299 ZIGZAG_SUB_4x4   , frame, ssse3
1300 ZIGZAG_SUB_4x4 ac, frame, ssse3
1301 ZIGZAG_SUB_4x4   , field, ssse3
1302 ZIGZAG_SUB_4x4 ac, field, ssse3
1303 INIT_AVX
1304 ZIGZAG_SUB_4x4   , frame, avx
1305 ZIGZAG_SUB_4x4 ac, frame, avx
1306 ZIGZAG_SUB_4x4   , field, avx
1307 ZIGZAG_SUB_4x4 ac, field, avx
1308
1309 ;-----------------------------------------------------------------------------
1310 ; void zigzag_interleave_8x8_cavlc( int16_t *dst, int16_t *src, uint8_t *nnz )
1311 ;-----------------------------------------------------------------------------
1312 %macro INTERLEAVE 2
1313     mova     m0, [r1+(%1*4+ 0)*SIZEOF_PIXEL]
1314     mova     m1, [r1+(%1*4+ 8)*SIZEOF_PIXEL]
1315     mova     m2, [r1+(%1*4+16)*SIZEOF_PIXEL]
1316     mova     m3, [r1+(%1*4+24)*SIZEOF_PIXEL]
1317     TRANSPOSE4x4%2 0,1,2,3,4
1318     mova     [r0+(%1+ 0)*SIZEOF_PIXEL], m0
1319     mova     [r0+(%1+32)*SIZEOF_PIXEL], m1
1320     mova     [r0+(%1+64)*SIZEOF_PIXEL], m2
1321     mova     [r0+(%1+96)*SIZEOF_PIXEL], m3
1322     packsswb m0, m1
1323 %if %1
1324     por      m6, m2
1325     por      m7, m3
1326     por      m5, m0
1327 %else
1328     SWAP      5, 0
1329     SWAP      6, 2
1330     SWAP      7, 3
1331 %endif
1332 %endmacro
1333
1334 %macro ZIGZAG_8x8_CAVLC 2
1335 cglobal zigzag_interleave_8x8_cavlc_%1, 3,3,8*(mmsize/16)
1336     INTERLEAVE  0, %2
1337     INTERLEAVE  8, %2
1338     INTERLEAVE 16, %2
1339     INTERLEAVE 24, %2
1340     packsswb   m6, m7
1341     packsswb   m5, m6
1342     packsswb   m5, m5
1343     pxor       m0, m0
1344 %ifdef HIGH_BIT_DEPTH
1345     packsswb   m5, m5
1346 %endif
1347     pcmpeqb    m5, m0
1348     paddb      m5, [pb_1]
1349     movd      r0d, m5
1350     mov    [r2+0], r0w
1351     shr       r0d, 16
1352     mov    [r2+8], r0w
1353     RET
1354 %endmacro
1355
1356 %ifdef HIGH_BIT_DEPTH
1357 INIT_XMM
1358 ZIGZAG_8x8_CAVLC sse2, D
1359 INIT_AVX
1360 ZIGZAG_8x8_CAVLC avx , D
1361 %else
1362 INIT_MMX
1363 ZIGZAG_8x8_CAVLC mmx , W
1364 %endif
1365
1366 %macro INTERLEAVE_XMM 1
1367     mova   m0, [r1+%1*4+ 0]
1368     mova   m1, [r1+%1*4+16]
1369     mova   m4, [r1+%1*4+32]
1370     mova   m5, [r1+%1*4+48]
1371     SBUTTERFLY wd, 0, 1, 6
1372     SBUTTERFLY wd, 4, 5, 7
1373     SBUTTERFLY wd, 0, 1, 6
1374     SBUTTERFLY wd, 4, 5, 7
1375     movq   [r0+%1+  0], m0
1376     movhps [r0+%1+ 32], m0
1377     movq   [r0+%1+ 64], m1
1378     movhps [r0+%1+ 96], m1
1379     movq   [r0+%1+  8], m4
1380     movhps [r0+%1+ 40], m4
1381     movq   [r0+%1+ 72], m5
1382     movhps [r0+%1+104], m5
1383 %if %1
1384     por    m2, m0
1385     por    m3, m1
1386     por    m2, m4
1387     por    m3, m5
1388 %else
1389     SWAP 0,2
1390     SWAP 3,1
1391     por    m2, m4
1392     por    m3, m5
1393 %endif
1394 %endmacro
1395
1396 %ifndef HIGH_BIT_DEPTH
1397 %macro ZIGZAG_8x8_CAVLC 1
1398 cglobal zigzag_interleave_8x8_cavlc_%1, 3,3,8
1399     INTERLEAVE_XMM  0
1400     INTERLEAVE_XMM 16
1401     packsswb m2, m3
1402     pxor     m5, m5
1403     packsswb m2, m2
1404     packsswb m2, m2
1405     pcmpeqb  m5, m2
1406     paddb    m5, [pb_1]
1407     movd    r0d, m5
1408     mov  [r2+0], r0w
1409     shr     r0d, 16
1410     mov  [r2+8], r0w
1411     RET
1412 %endmacro
1413
1414 INIT_XMM
1415 ZIGZAG_8x8_CAVLC sse2
1416 INIT_AVX
1417 ZIGZAG_8x8_CAVLC avx
1418 %endif ; !HIGH_BIT_DEPTH