]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
Much faster chroma encoding and other opts
[x264] / common / x86 / dct-a.asm
1 ;*****************************************************************************
2 ;* dct-a.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2008 x264 project
5 ;*
6 ;* Authors: Laurent Aimar <fenrir@via.ecp.fr>
7 ;*          Loren Merritt <lorenm@u.washington.edu>
8 ;*          Holger Lubitz <hal@duncan.ol.sub.de>
9 ;*          Min Chen <chenm001.163.com>
10 ;*
11 ;* This program is free software; you can redistribute it and/or modify
12 ;* it under the terms of the GNU General Public License as published by
13 ;* the Free Software Foundation; either version 2 of the License, or
14 ;* (at your option) any later version.
15 ;*
16 ;* This program is distributed in the hope that it will be useful,
17 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;* GNU General Public License for more details.
20 ;*
21 ;* You should have received a copy of the GNU General Public License
22 ;* along with this program; if not, write to the Free Software
23 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
24 ;*****************************************************************************
25
26 %include "x86inc.asm"
27 %include "x86util.asm"
28
29 SECTION_RODATA
30 pw_32: times 8 dw 32
31 pw_8000: times 8 dw 0x8000
32 pb_sub4frame:   db 0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15
33 pb_scan4framea: db 12,13,6,7,14,15,0,1,8,9,2,3,4,5,10,11
34 pb_scan4frameb: db 0,1,8,9,2,3,4,5,10,11,12,13,6,7,14,15
35 pb_idctdc_unpack: db 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3
36
37 SECTION .text
38
39 %macro HADAMARD4_1D 4
40     SUMSUB_BADC m%2, m%1, m%4, m%3
41     SUMSUB_BADC m%4, m%2, m%3, m%1
42     SWAP %1, %4, %3
43 %endmacro
44
45 %macro SUMSUB_17BIT 4 ; a, b, tmp, 0x8000
46     movq  m%3, m%4
47     paddw m%1, m%4
48     psubw m%3, m%2
49     paddw m%2, m%4
50     pavgw m%3, m%1
51     pavgw m%2, m%1
52     psubw m%3, m%4
53     psubw m%2, m%4
54     SWAP %1, %2, %3
55 %endmacro
56
57 ;-----------------------------------------------------------------------------
58 ; void x264_dct4x4dc_mmx( int16_t d[4][4] )
59 ;-----------------------------------------------------------------------------
60 cglobal x264_dct4x4dc_mmx, 1,1
61     movq   m0, [r0+ 0]
62     movq   m1, [r0+ 8]
63     movq   m2, [r0+16]
64     movq   m3, [r0+24]
65     movq   m7, [pw_8000 GLOBAL] ; convert to unsigned and back, so that pavgw works
66     HADAMARD4_1D  0,1,2,3
67     TRANSPOSE4x4W 0,1,2,3,4
68     SUMSUB_BADC m1, m0, m3, m2
69     SWAP 0,1
70     SWAP 2,3
71     SUMSUB_17BIT 0,2,4,7
72     SUMSUB_17BIT 1,3,5,7
73     movq  [r0+0], m0
74     movq  [r0+8], m2
75     movq [r0+16], m3
76     movq [r0+24], m1
77     RET
78
79 ;-----------------------------------------------------------------------------
80 ; void x264_idct4x4dc_mmx( int16_t d[4][4] )
81 ;-----------------------------------------------------------------------------
82 cglobal x264_idct4x4dc_mmx, 1,1
83     movq  m0, [r0+ 0]
84     movq  m1, [r0+ 8]
85     movq  m2, [r0+16]
86     movq  m3, [r0+24]
87     HADAMARD4_1D  0,1,2,3
88     TRANSPOSE4x4W 0,1,2,3,4
89     HADAMARD4_1D  0,1,2,3
90     movq  [r0+ 0], m0
91     movq  [r0+ 8], m1
92     movq  [r0+16], m2
93     movq  [r0+24], m3
94     RET
95
96 %macro DCT4_1D 5
97     SUMSUB_BADC m%4, m%1, m%3, m%2
98     SUMSUB_BA   m%3, m%4
99     SUMSUB2_AB  m%1, m%2, m%5
100     SWAP %1, %3, %4, %5, %2
101 %endmacro
102
103 %macro IDCT4_1D 6
104     SUMSUB_BA   m%3, m%1
105     SUMSUBD2_AB m%2, m%4, m%6, m%5
106     SUMSUB_BADC m%2, m%3, m%5, m%1
107     SWAP %1, %2, %5, %4, %3
108 %endmacro
109
110 ;-----------------------------------------------------------------------------
111 ; void x264_sub4x4_dct_mmx( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
112 ;-----------------------------------------------------------------------------
113 cglobal x264_sub4x4_dct_mmx, 3,3
114 .skip_prologue:
115 %macro SUB_DCT4 1
116     LOAD_DIFF  m0, m6, m7, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
117     LOAD_DIFF  m1, m6, m7, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
118     LOAD_DIFF  m2, m6, m7, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
119     LOAD_DIFF  m3, m6, m7, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
120     DCT4_1D 0,1,2,3,4
121     TRANSPOSE%1 0,1,2,3,4
122     DCT4_1D 0,1,2,3,4
123     movq  [r0+ 0], m0
124     movq  [r0+ 8], m1
125     movq  [r0+16], m2
126     movq  [r0+24], m3
127 %endmacro
128     SUB_DCT4 4x4W
129     RET
130
131 ;-----------------------------------------------------------------------------
132 ; void x264_add4x4_idct_mmx( uint8_t *p_dst, int16_t dct[4][4] )
133 ;-----------------------------------------------------------------------------
134 cglobal x264_add4x4_idct_mmx, 2,2
135 .skip_prologue:
136     movq  m0, [r1+ 0]
137     movq  m1, [r1+ 8]
138     movq  m2, [r1+16]
139     movq  m3, [r1+24]
140 %macro ADD_IDCT4 1
141     IDCT4_1D 0,1,2,3,4,5
142     TRANSPOSE%1 0,1,2,3,4
143     paddw m0, [pw_32 GLOBAL]
144     IDCT4_1D 0,1,2,3,4,5
145     pxor  m7, m7
146     STORE_DIFF  m0, m4, m7, [r0+0*FDEC_STRIDE]
147     STORE_DIFF  m1, m4, m7, [r0+1*FDEC_STRIDE]
148     STORE_DIFF  m2, m4, m7, [r0+2*FDEC_STRIDE]
149     STORE_DIFF  m3, m4, m7, [r0+3*FDEC_STRIDE]
150 %endmacro
151     ADD_IDCT4 4x4W
152     RET
153
154 INIT_XMM
155
156 cglobal x264_sub8x8_dct_sse2, 3,3
157 .skip_prologue:
158     call .8x4
159     add  r0, 64
160     add  r1, 4*FENC_STRIDE
161     add  r2, 4*FDEC_STRIDE
162 .8x4:
163     SUB_DCT4 2x4x4W
164     movhps [r0+32], m0
165     movhps [r0+40], m1
166     movhps [r0+48], m2
167     movhps [r0+56], m3
168     ret
169
170 cglobal x264_add8x8_idct_sse2, 2,2
171 .skip_prologue:
172     call .8x4
173     add  r1, 64
174     add  r0, 4*FDEC_STRIDE
175 .8x4:
176     movq   m0, [r1+ 0]
177     movq   m1, [r1+ 8]
178     movq   m2, [r1+16]
179     movq   m3, [r1+24]
180     movhps m0, [r1+32]
181     movhps m1, [r1+40]
182     movhps m2, [r1+48]
183     movhps m3, [r1+56]
184     ADD_IDCT4 2x4x4W
185     ret
186
187 ;-----------------------------------------------------------------------------
188 ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
189 ;-----------------------------------------------------------------------------
190 %macro SUB_NxN_DCT 6
191 cglobal %1, 3,3
192 .skip_prologue:
193     call %2
194     add  r0, %3
195     add  r1, %4-%5-%6*FENC_STRIDE
196     add  r2, %4-%5-%6*FDEC_STRIDE
197     call %2
198     add  r0, %3
199     add  r1, (%4-%6)*FENC_STRIDE-%5-%4
200     add  r2, (%4-%6)*FDEC_STRIDE-%5-%4
201     call %2
202     add  r0, %3
203     add  r1, %4-%5-%6*FENC_STRIDE
204     add  r2, %4-%5-%6*FDEC_STRIDE
205     jmp  %2
206 %endmacro
207
208 ;-----------------------------------------------------------------------------
209 ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
210 ;-----------------------------------------------------------------------------
211 %macro ADD_NxN_IDCT 6
212 cglobal %1, 2,2
213 .skip_prologue:
214     call %2
215     add  r0, %4-%5-%6*FDEC_STRIDE
216     add  r1, %3
217     call %2
218     add  r0, (%4-%6)*FDEC_STRIDE-%5-%4
219     add  r1, %3
220     call %2
221     add  r0, %4-%5-%6*FDEC_STRIDE
222     add  r1, %3
223     jmp  %2
224 %endmacro
225
226 %ifndef ARCH_X86_64
227 SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx  %+ .skip_prologue, 32, 4, 0, 0
228 ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx %+ .skip_prologue, 32, 4, 0, 0
229 SUB_NxN_DCT  x264_sub16x16_dct_mmx,  x264_sub8x8_dct_mmx  %+ .skip_prologue, 32, 8, 4, 4
230 ADD_NxN_IDCT x264_add16x16_idct_mmx, x264_add8x8_idct_mmx %+ .skip_prologue, 32, 8, 4, 4
231
232 cextern x264_sub8x8_dct8_mmx.skip_prologue
233 cextern x264_add8x8_idct8_mmx.skip_prologue
234 SUB_NxN_DCT  x264_sub16x16_dct8_mmx,  x264_sub8x8_dct8_mmx  %+ .skip_prologue, 128, 8, 0, 0
235 ADD_NxN_IDCT x264_add16x16_idct8_mmx, x264_add8x8_idct8_mmx %+ .skip_prologue, 128, 8, 0, 0
236 %define x264_sub8x8_dct8_sse2 x264_sub8x8_dct8_sse2.skip_prologue
237 %define x264_add8x8_idct8_sse2 x264_add8x8_idct8_sse2.skip_prologue
238 %endif
239
240 SUB_NxN_DCT  x264_sub16x16_dct_sse2,  x264_sub8x8_dct_sse2  %+ .skip_prologue, 64, 8, 0, 4
241 ADD_NxN_IDCT x264_add16x16_idct_sse2, x264_add8x8_idct_sse2 %+ .skip_prologue, 64, 8, 0, 4
242
243 cextern x264_sub8x8_dct8_sse2
244 cextern x264_add8x8_idct8_sse2
245 SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2,  128, 8, 0, 0
246 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2, 128, 8, 0, 0
247
248 ;-----------------------------------------------------------------------------
249 ; void add8x8_idct_dc( uint8_t *p_dst, int16_t *dct2x2 )
250 ;-----------------------------------------------------------------------------
251
252 %macro ADD_DC 3
253     movq      mm4, [%3+FDEC_STRIDE*0]
254     movq      mm5, [%3+FDEC_STRIDE*1]
255     movq      mm6, [%3+FDEC_STRIDE*2]
256     paddusb   mm4, %1
257     paddusb   mm5, %1
258     paddusb   mm6, %1
259     paddusb    %1, [%3+FDEC_STRIDE*3]
260     psubusb   mm4, %2
261     psubusb   mm5, %2
262     psubusb   mm6, %2
263     psubusb    %1, %2
264     movq      [%3+FDEC_STRIDE*0], mm4
265     movq      [%3+FDEC_STRIDE*1], mm5
266     movq      [%3+FDEC_STRIDE*2], mm6
267     movq      [%3+FDEC_STRIDE*3], %1
268 %endmacro
269
270 cglobal x264_add8x8_idct_dc_mmx, 2,2
271     movq      mm0, [r1]
272     pxor      mm1, mm1
273     add        r0, FDEC_STRIDE*4
274     paddw     mm0, [pw_32 GLOBAL]
275     psraw     mm0, 6
276     psubw     mm1, mm0
277     packuswb  mm0, mm0
278     packuswb  mm1, mm1
279     punpcklbw mm0, mm0
280     punpcklbw mm1, mm1
281     pshufw    mm2, mm0, 0xFA
282     pshufw    mm3, mm1, 0xFA
283     punpcklbw mm0, mm0
284     punpcklbw mm1, mm1
285     ADD_DC    mm0, mm1, r0-FDEC_STRIDE*4
286     ADD_DC    mm2, mm3, r0
287     ret
288
289 cglobal x264_add8x8_idct_dc_ssse3, 2,2
290     movq      xmm0, [r1]
291     pxor      xmm1, xmm1
292     add         r0, FDEC_STRIDE*4
293     paddw     xmm0, [pw_32 GLOBAL]
294     psraw     xmm0, 6
295     psubw     xmm1, xmm0
296     movdqa    xmm5, [pb_idctdc_unpack GLOBAL]
297     packuswb  xmm0, xmm0
298     packuswb  xmm1, xmm1
299     pshufb    xmm0, xmm5
300     pshufb    xmm1, xmm5
301     movq      xmm2, [r0+FDEC_STRIDE*-4]
302     movq      xmm3, [r0+FDEC_STRIDE*-3]
303     movq      xmm4, [r0+FDEC_STRIDE*-2]
304     movq      xmm5, [r0+FDEC_STRIDE*-1]
305     movhps    xmm2, [r0+FDEC_STRIDE* 0]
306     movhps    xmm3, [r0+FDEC_STRIDE* 1]
307     movhps    xmm4, [r0+FDEC_STRIDE* 2]
308     movhps    xmm5, [r0+FDEC_STRIDE* 3]
309     paddusb   xmm2, xmm0
310     paddusb   xmm3, xmm0
311     paddusb   xmm4, xmm0
312     paddusb   xmm5, xmm0
313     psubusb   xmm2, xmm1
314     psubusb   xmm3, xmm1
315     psubusb   xmm4, xmm1
316     psubusb   xmm5, xmm1
317     movq      [r0+FDEC_STRIDE*-4], xmm2
318     movq      [r0+FDEC_STRIDE*-3], xmm3
319     movq      [r0+FDEC_STRIDE*-2], xmm4
320     movq      [r0+FDEC_STRIDE*-1], xmm5
321     movhps    [r0+FDEC_STRIDE* 0], xmm2
322     movhps    [r0+FDEC_STRIDE* 1], xmm3
323     movhps    [r0+FDEC_STRIDE* 2], xmm4
324     movhps    [r0+FDEC_STRIDE* 3], xmm5
325     ret
326
327 ;-----------------------------------------------------------------------------
328 ; void x264_zigzag_scan_8x8_frame_ssse3( int16_t level[64], int16_t dct[8][8] )
329 ;-----------------------------------------------------------------------------
330 %macro SCAN_8x8 1
331 cglobal x264_zigzag_scan_8x8_frame_%1, 2,2
332     movdqa    xmm0, [r1]
333     movdqa    xmm1, [r1+16]
334     movdq2q    mm0, xmm0
335     PALIGNR   xmm1, xmm1, 14, xmm2
336     movdq2q    mm1, xmm1
337
338     movdqa    xmm2, [r1+32]
339     movdqa    xmm3, [r1+48]
340     PALIGNR   xmm2, xmm2, 12, xmm4
341     movdq2q    mm2, xmm2
342     PALIGNR   xmm3, xmm3, 10, xmm4
343     movdq2q    mm3, xmm3
344
345     punpckhwd xmm0, xmm1
346     punpckhwd xmm2, xmm3
347
348     movq       mm4, mm1
349     movq       mm5, mm1
350     movq       mm6, mm2
351     movq       mm7, mm3
352     punpckhwd  mm1, mm0
353     psllq      mm0, 16
354     psrlq      mm3, 16
355     punpckhdq  mm1, mm1
356     punpckhdq  mm2, mm0
357     punpcklwd  mm0, mm4
358     punpckhwd  mm4, mm3
359     punpcklwd  mm4, mm2
360     punpckhdq  mm0, mm2
361     punpcklwd  mm6, mm3
362     punpcklwd  mm5, mm7
363     punpcklwd  mm5, mm6
364
365     movdqa    xmm4, [r1+64]
366     movdqa    xmm5, [r1+80]
367     movdqa    xmm6, [r1+96]
368     movdqa    xmm7, [r1+112]
369
370     movq [r0+2*00], mm0
371     movq [r0+2*04], mm4
372     movd [r0+2*08], mm1
373     movq [r0+2*36], mm5
374     movq [r0+2*46], mm6
375
376     PALIGNR   xmm4, xmm4, 14, xmm3
377     movdq2q    mm4, xmm4
378     PALIGNR   xmm5, xmm5, 12, xmm3
379     movdq2q    mm5, xmm5
380     PALIGNR   xmm6, xmm6, 10, xmm3
381     movdq2q    mm6, xmm6
382 %ifidn %1, ssse3
383     PALIGNR   xmm7, xmm7, 8, xmm3
384     movdq2q    mm7, xmm7
385 %else
386     movhlps   xmm3, xmm7
387     punpcklqdq xmm7, xmm7
388     movdq2q    mm7, xmm3
389 %endif
390
391     punpckhwd xmm4, xmm5
392     punpckhwd xmm6, xmm7
393
394     movq       mm0, mm4
395     movq       mm1, mm5
396     movq       mm3, mm7
397     punpcklwd  mm7, mm6
398     psrlq      mm6, 16
399     punpcklwd  mm4, mm6
400     punpcklwd  mm5, mm4
401     punpckhdq  mm4, mm3
402     punpcklwd  mm3, mm6
403     punpckhwd  mm3, mm4
404     punpckhwd  mm0, mm1
405     punpckldq  mm4, mm0
406     punpckhdq  mm0, mm6
407     pshufw     mm4, mm4, 0x6c
408
409     movq [r0+2*14], mm4
410     movq [r0+2*25], mm0
411     movd [r0+2*54], mm7
412     movq [r0+2*56], mm5
413     movq [r0+2*60], mm3
414
415     movdqa    xmm3, xmm0
416     movdqa    xmm7, xmm4
417     punpckldq xmm0, xmm2
418     punpckldq xmm4, xmm6
419     punpckhdq xmm3, xmm2
420     punpckhdq xmm7, xmm6
421     pshufhw   xmm0, xmm0, 0x1b
422     pshuflw   xmm4, xmm4, 0x1b
423     pshufhw   xmm3, xmm3, 0x1b
424     pshuflw   xmm7, xmm7, 0x1b
425
426     movlps [r0+2*10], xmm0
427     movhps [r0+2*17], xmm0
428     movlps [r0+2*21], xmm3
429     movlps [r0+2*28], xmm4
430     movhps [r0+2*32], xmm3
431     movhps [r0+2*39], xmm4
432     movlps [r0+2*43], xmm7
433     movhps [r0+2*50], xmm7
434
435     RET
436 %endmacro
437
438 INIT_XMM
439 %define PALIGNR PALIGNR_MMX
440 SCAN_8x8 sse2
441 %define PALIGNR PALIGNR_SSSE3
442 SCAN_8x8 ssse3
443
444 ;-----------------------------------------------------------------------------
445 ; void x264_zigzag_scan_8x8_frame_mmxext( int16_t level[64], int16_t dct[8][8] )
446 ;-----------------------------------------------------------------------------
447 cglobal x264_zigzag_scan_8x8_frame_mmxext, 2,2
448     movq       mm0, [r1]
449     movq       mm1, [r1+2*8]
450     movq       mm2, [r1+2*14]
451     movq       mm3, [r1+2*21]
452     movq       mm4, [r1+2*28]
453     movq       mm5, mm0
454     movq       mm6, mm1
455     psrlq      mm0, 16
456     punpckldq  mm1, mm1
457     punpcklwd  mm5, mm6
458     punpckhwd  mm1, mm3
459     punpckhwd  mm6, mm0
460     punpckldq  mm5, mm0
461     movq       mm7, [r1+2*52]
462     movq       mm0, [r1+2*60]
463     punpckhwd  mm1, mm2
464     punpcklwd  mm2, mm4
465     punpckhwd  mm4, mm3
466     punpckldq  mm3, mm3
467     punpckhwd  mm3, mm2
468     movq      [r0], mm5
469     movq  [r0+2*4], mm1
470     movq  [r0+2*8], mm6
471     punpcklwd  mm6, mm0
472     punpcklwd  mm6, mm7
473     movq       mm1, [r1+2*32]
474     movq       mm5, [r1+2*39]
475     movq       mm2, [r1+2*46]
476     movq [r0+2*35], mm3
477     movq [r0+2*47], mm4
478     punpckhwd  mm7, mm0
479     psllq      mm0, 16
480     movq       mm3, mm5
481     punpcklwd  mm5, mm1
482     punpckhwd  mm1, mm2
483     punpckhdq  mm3, mm3
484     movq [r0+2*52], mm6
485     movq [r0+2*13], mm5
486     movq       mm4, [r1+2*11]
487     movq       mm6, [r1+2*25]
488     punpcklwd  mm5, mm7
489     punpcklwd  mm1, mm3
490     punpckhdq  mm0, mm7
491     movq       mm3, [r1+2*4]
492     movq       mm7, [r1+2*18]
493     punpcklwd  mm2, mm5
494     movq [r0+2*25], mm1
495     movq       mm1, mm4
496     movq       mm5, mm6
497     punpcklwd  mm4, mm3
498     punpcklwd  mm6, mm7
499     punpckhwd  mm1, mm3
500     punpckhwd  mm5, mm7
501     movq       mm3, mm6
502     movq       mm7, mm5
503     punpckldq  mm6, mm4
504     punpckldq  mm5, mm1
505     punpckhdq  mm3, mm4
506     punpckhdq  mm7, mm1
507     movq       mm4, [r1+2*35]
508     movq       mm1, [r1+2*49]
509     pshufw     mm6, mm6, 0x1b
510     pshufw     mm5, mm5, 0x1b
511     movq [r0+2*60], mm0
512     movq [r0+2*56], mm2
513     movq       mm0, [r1+2*42]
514     movq       mm2, [r1+2*56]
515     movq [r0+2*17], mm3
516     movq [r0+2*32], mm7
517     movq [r0+2*10], mm6
518     movq [r0+2*21], mm5
519     movq       mm3, mm0
520     movq       mm7, mm2
521     punpcklwd  mm0, mm4
522     punpcklwd  mm2, mm1
523     punpckhwd  mm3, mm4
524     punpckhwd  mm7, mm1
525     movq       mm4, mm2
526     movq       mm1, mm7
527     punpckhdq  mm2, mm0
528     punpckhdq  mm7, mm3
529     punpckldq  mm4, mm0
530     punpckldq  mm1, mm3
531     pshufw     mm2, mm2, 0x1b
532     pshufw     mm7, mm7, 0x1b
533     movq [r0+2*28], mm4
534     movq [r0+2*43], mm1
535     movq [r0+2*39], mm2
536     movq [r0+2*50], mm7
537     RET
538
539 ;-----------------------------------------------------------------------------
540 ; void x264_zigzag_scan_4x4_frame_mmx( int16_t level[16], int16_t dct[4][4] )
541 ;-----------------------------------------------------------------------------
542 cglobal x264_zigzag_scan_4x4_frame_mmx, 2,2
543     movq       mm0, [r1]
544     movq       mm1, [r1+8]
545     movq       mm2, [r1+16]
546     movq       mm3, [r1+24]
547     movq       mm4, mm0
548     movq       mm5, mm1
549     movq       mm6, mm2
550     movq       mm7, mm3
551     psllq      mm3, 16
552     psrlq      mm0, 16
553     punpckldq  mm2, mm2
554     punpckhdq  mm1, mm1
555     punpcklwd  mm4, mm5
556     punpcklwd  mm5, mm3
557     punpckldq  mm4, mm0
558     punpckhwd  mm5, mm2
559     punpckhwd  mm0, mm6
560     punpckhwd  mm6, mm7
561     punpcklwd  mm1, mm0
562     punpckhdq  mm3, mm6
563     movq      [r0], mm4
564     movq    [r0+8], mm5
565     movq   [r0+16], mm1
566     movq   [r0+24], mm3
567     RET
568
569 ;-----------------------------------------------------------------------------
570 ; void x264_zigzag_scan_4x4_frame_ssse3( int16_t level[16], int16_t dct[4][4] )
571 ;-----------------------------------------------------------------------------
572 cglobal x264_zigzag_scan_4x4_frame_ssse3, 2,2
573     movdqa    xmm1, [r1+16]
574     movdqa    xmm0, [r1]
575     pshufb    xmm1, [pb_scan4frameb GLOBAL]
576     pshufb    xmm0, [pb_scan4framea GLOBAL]
577     movdqa    xmm2, xmm1
578     psrldq    xmm1, 6
579     palignr   xmm2, xmm0, 6
580     pslldq    xmm0, 10
581     palignr   xmm1, xmm0, 10
582     movdqa    [r0], xmm2
583     movdqa [r0+16], xmm1
584     RET
585
586 ;-----------------------------------------------------------------------------
587 ; void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] )
588 ;-----------------------------------------------------------------------------
589 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
590 cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
591     pshufw     mm0, [r1+4], 0xd2
592     movq       mm1, [r1+16]
593     movq       mm2, [r1+24]
594     movq    [r0+4], mm0
595     movq   [r0+16], mm1
596     movq   [r0+24], mm2
597     mov        r2d, [r1]
598     mov       [r0], r2d
599     mov        r2d, [r1+12]
600     mov    [r0+12], r2d
601     RET
602
603 ;-----------------------------------------------------------------------------
604 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
605 ;-----------------------------------------------------------------------------
606 cglobal x264_zigzag_sub_4x4_frame_ssse3, 3,3
607     movd      xmm0, [r1+0*FENC_STRIDE]
608     movd      xmm1, [r1+1*FENC_STRIDE]
609     movd      xmm2, [r1+2*FENC_STRIDE]
610     movd      xmm3, [r1+3*FENC_STRIDE]
611     movd      xmm4, [r2+0*FDEC_STRIDE]
612     movd      xmm5, [r2+1*FDEC_STRIDE]
613     movd      xmm6, [r2+2*FDEC_STRIDE]
614     movd      xmm7, [r2+3*FDEC_STRIDE]
615     movd      [r2+0*FDEC_STRIDE], xmm0
616     movd      [r2+1*FDEC_STRIDE], xmm1
617     movd      [r2+2*FDEC_STRIDE], xmm2
618     movd      [r2+3*FDEC_STRIDE], xmm3
619     punpckldq xmm0, xmm1
620     punpckldq xmm2, xmm3
621     punpckldq xmm4, xmm5
622     punpckldq xmm6, xmm7
623     punpcklqdq xmm0, xmm2
624     punpcklqdq xmm4, xmm6
625     movdqa    xmm7, [pb_sub4frame GLOBAL]
626     pshufb    xmm0, xmm7
627     pshufb    xmm4, xmm7
628     pxor      xmm6, xmm6
629     movdqa    xmm1, xmm0
630     movdqa    xmm5, xmm4
631     punpcklbw xmm0, xmm6
632     punpckhbw xmm1, xmm6
633     punpcklbw xmm4, xmm6
634     punpckhbw xmm5, xmm6
635     psubw     xmm0, xmm4
636     psubw     xmm1, xmm5
637     movdqa    [r0], xmm0
638     movdqa [r0+16], xmm1
639     RET
640
641 INIT_MMX
642 cglobal x264_zigzag_interleave_8x8_cavlc_mmx, 2,3
643     mov    r2d, 24
644 .loop:
645     movq   m0, [r1+r2*4+ 0]
646     movq   m1, [r1+r2*4+ 8]
647     movq   m2, [r1+r2*4+16]
648     movq   m3, [r1+r2*4+24]
649     TRANSPOSE4x4W 0,1,2,3,4
650     movq   [r0+r2+ 0], m0
651     movq   [r0+r2+32], m1
652     movq   [r0+r2+64], m2
653     movq   [r0+r2+96], m3
654     sub    r2d, 8
655     jge .loop
656     REP_RET