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