SSE2 zigzag_interleave
[x262.git] / common / x86 / dct-a.asm
1 ;*****************************************************************************
2 ;* dct-a.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2008 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 ;*
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 hsub_mul: times 8 db 1, -1
33 pb_sub4frame:   db 0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15
34 pb_scan4framea: db 12,13,6,7,14,15,0,1,8,9,2,3,4,5,10,11
35 pb_scan4frameb: db 0,1,8,9,2,3,4,5,10,11,12,13,6,7,14,15
36 pb_idctdc_unpack: db 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3
37 pb_idctdc_unpack2: db 4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7
38 pb_1: times 16 db 1
39
40 SECTION .text
41
42 %macro WALSH4_1D 5
43     SUMSUB_BADC m%4, m%3, m%2, m%1, m%5
44     SUMSUB_BADC m%4, m%2, m%3, m%1, m%5
45     SWAP %1, %4, %3
46 %endmacro
47
48 %macro SUMSUB_17BIT 4 ; a, b, tmp, 0x8000
49     movq  m%3, m%4
50     pxor  m%1, m%4
51     psubw m%3, m%2
52     pxor  m%2, m%4
53     pavgw m%3, m%1
54     pavgw m%2, m%1
55     pxor  m%3, m%4
56     pxor  m%2, m%4
57     SWAP %1, %2, %3
58 %endmacro
59
60 INIT_MMX
61 ;-----------------------------------------------------------------------------
62 ; void x264_dct4x4dc_mmx( int16_t d[4][4] )
63 ;-----------------------------------------------------------------------------
64 cglobal x264_dct4x4dc_mmx, 1,1
65     movq   m3, [r0+24]
66     movq   m2, [r0+16]
67     movq   m1, [r0+ 8]
68     movq   m0, [r0+ 0]
69     movq   m7, [pw_8000 GLOBAL] ; convert to unsigned and back, so that pavgw works
70     WALSH4_1D  0,1,2,3,4
71     TRANSPOSE4x4W 0,1,2,3,4
72     SUMSUB_BADC m1, m0, m3, m2, m4
73     SWAP 0, 1
74     SWAP 2, 3
75     SUMSUB_17BIT 0,2,4,7
76     SUMSUB_17BIT 1,3,5,7
77     movq  [r0+0], m0
78     movq  [r0+8], m2
79     movq [r0+16], m3
80     movq [r0+24], m1
81     RET
82
83 ;-----------------------------------------------------------------------------
84 ; void x264_idct4x4dc_mmx( int16_t d[4][4] )
85 ;-----------------------------------------------------------------------------
86 cglobal x264_idct4x4dc_mmx, 1,1
87     movq   m3, [r0+24]
88     movq   m2, [r0+16]
89     movq   m1, [r0+ 8]
90     movq   m0, [r0+ 0]
91     WALSH4_1D  0,1,2,3,4
92     TRANSPOSE4x4W 0,1,2,3,4
93     WALSH4_1D  0,1,2,3,4
94     movq  [r0+ 0], m0
95     movq  [r0+ 8], m1
96     movq  [r0+16], m2
97     movq  [r0+24], m3
98     RET
99
100 %macro SUB_DCT4 1
101 ;-----------------------------------------------------------------------------
102 ; void x264_sub4x4_dct_mmx( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
103 ;-----------------------------------------------------------------------------
104 cglobal x264_sub4x4_dct_%1, 3,3
105 %ifidn %1, mmx
106 .skip_prologue:
107     LOAD_DIFF  m0, m4, m5, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
108     LOAD_DIFF  m3, m4, m5, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
109     LOAD_DIFF  m1, m4, m5, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
110     LOAD_DIFF  m2, m4, m5, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
111 %else
112     mova m5, [hsub_mul GLOBAL]
113     LOAD_DIFF8x4_SSSE3 0, 3, 1, 2, 4, 5, r1, r2
114 %endif
115     DCT4_1D 0,1,2,3,4
116     TRANSPOSE4x4W 0,1,2,3,4
117     DCT4_1D 0,1,2,3,4
118     movq  [r0+ 0], m0
119     movq  [r0+ 8], m1
120     movq  [r0+16], m2
121     movq  [r0+24], m3
122     RET
123 %endmacro
124
125 SUB_DCT4 mmx
126 SUB_DCT4 ssse3
127
128 ;-----------------------------------------------------------------------------
129 ; void x264_add4x4_idct_mmx( uint8_t *p_dst, int16_t dct[4][4] )
130 ;-----------------------------------------------------------------------------
131 cglobal x264_add4x4_idct_mmx, 2,2
132     pxor m7, m7
133 .skip_prologue:
134     movq  m1, [r1+ 8]
135     movq  m3, [r1+24]
136     movq  m2, [r1+16]
137     movq  m0, [r1+ 0]
138     IDCT4_1D 0,1,2,3,4,5
139     TRANSPOSE4x4W 0,1,2,3,4
140     paddw m0, [pw_32 GLOBAL]
141     IDCT4_1D 0,1,2,3,4,5
142     STORE_DIFF  m0, m4, m7, [r0+0*FDEC_STRIDE]
143     STORE_DIFF  m1, m4, m7, [r0+1*FDEC_STRIDE]
144     STORE_DIFF  m2, m4, m7, [r0+2*FDEC_STRIDE]
145     STORE_DIFF  m3, m4, m7, [r0+3*FDEC_STRIDE]
146     RET
147
148 ;-----------------------------------------------------------------------------
149 ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
150 ;-----------------------------------------------------------------------------
151 %macro SUB_NxN_DCT 6
152 cglobal %1, 3,3,11
153 %if mmsize == 8
154     pxor m7, m7
155 %else
156     add r2, 4*FDEC_STRIDE
157     mova m7, [hsub_mul GLOBAL]
158 %endif
159 .skip_prologue:
160 %ifdef WIN64
161     sub  rsp, 8
162 %endif
163     call %2
164     add  r0, %3
165     add  r1, %4-%5-%6*FENC_STRIDE
166     add  r2, %4-%5-%6*FDEC_STRIDE
167     call %2
168     add  r0, %3
169     add  r1, (%4-%6)*FENC_STRIDE-%5-%4
170     add  r2, (%4-%6)*FDEC_STRIDE-%5-%4
171     call %2
172     add  r0, %3
173     add  r1, %4-%5-%6*FENC_STRIDE
174     add  r2, %4-%5-%6*FDEC_STRIDE
175 %ifdef WIN64
176     add  rsp, 8
177     call %2
178     RET
179 %else
180     jmp  %2
181 %endif
182 %endmacro
183
184 ;-----------------------------------------------------------------------------
185 ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
186 ;-----------------------------------------------------------------------------
187 %macro ADD_NxN_IDCT 6-7
188 cglobal %1, 2,2,11
189     pxor m7, m7
190 %if mmsize==16
191     add  r0, 4*FDEC_STRIDE
192 %endif
193 .skip_prologue:
194 %ifdef WIN64
195     sub  rsp, 8
196 %endif
197     call %2
198     add  r0, %4-%5-%6*FDEC_STRIDE
199     add  r1, %3
200     call %2
201     add  r0, (%4-%6)*FDEC_STRIDE-%5-%4
202     add  r1, %3
203     call %2
204     add  r0, %4-%5-%6*FDEC_STRIDE
205     add  r1, %3
206 %ifdef WIN64
207     add  rsp, 8
208     call %2
209     RET
210 %else
211     jmp  %2
212 %endif
213 %endmacro
214
215 %ifndef ARCH_X86_64
216 SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx.skip_prologue,  32, 4, 0, 0
217 ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx.skip_prologue, 32, 4, 0, 0
218 SUB_NxN_DCT  x264_sub16x16_dct_mmx,  x264_sub8x8_dct_mmx.skip_prologue,  32, 8, 4, 4
219 ADD_NxN_IDCT x264_add16x16_idct_mmx, x264_add8x8_idct_mmx.skip_prologue, 32, 8, 4, 4
220
221 cextern x264_sub8x8_dct8_mmx.skip_prologue
222 cextern x264_add8x8_idct8_mmx.skip_prologue
223 SUB_NxN_DCT  x264_sub16x16_dct8_mmx,  x264_sub8x8_dct8_mmx.skip_prologue,  128, 8, 0, 0
224 ADD_NxN_IDCT x264_add16x16_idct8_mmx, x264_add8x8_idct8_mmx.skip_prologue, 128, 8, 0, 0
225 %endif
226
227 INIT_XMM
228
229 cextern x264_sub8x8_dct_sse2.skip_prologue
230 cextern x264_sub8x8_dct_ssse3.skip_prologue
231 SUB_NxN_DCT  x264_sub16x16_dct_sse2, x264_sub8x8_dct_sse2.skip_prologue, 128, 8, 0, 0
232 SUB_NxN_DCT  x264_sub16x16_dct_ssse3, x264_sub8x8_dct_ssse3.skip_prologue, 128, 8, 0, 0
233 cextern x264_add8x8_idct_sse2.skip_prologue
234 ADD_NxN_IDCT x264_add16x16_idct_sse2, x264_add8x8_idct_sse2.skip_prologue, 2*64, 8, 0, 0
235
236 cextern x264_sub8x8_dct8_sse2.skip_prologue
237 cextern x264_add8x8_idct8_sse2.skip_prologue
238 SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2.skip_prologue,  128, 8, 0, 0
239 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2.skip_prologue, 128, 8, 0, 0
240
241 cextern x264_sub8x8_dct8_ssse3.skip_prologue
242 SUB_NxN_DCT  x264_sub16x16_dct8_ssse3,  x264_sub8x8_dct8_ssse3.skip_prologue,  128, 8, 0, 0
243
244
245 ;-----------------------------------------------------------------------------
246 ; void add8x8_idct_dc( uint8_t *p_dst, int16_t *dct2x2 )
247 ;-----------------------------------------------------------------------------
248
249 %macro ADD_DC 3
250     movq      mm4, [%3+FDEC_STRIDE*0]
251     movq      mm5, [%3+FDEC_STRIDE*1]
252     movq      mm6, [%3+FDEC_STRIDE*2]
253     paddusb   mm4, %1
254     paddusb   mm5, %1
255     paddusb   mm6, %1
256     paddusb    %1, [%3+FDEC_STRIDE*3]
257     psubusb   mm4, %2
258     psubusb   mm5, %2
259     psubusb   mm6, %2
260     psubusb    %1, %2
261     movq      [%3+FDEC_STRIDE*0], mm4
262     movq      [%3+FDEC_STRIDE*1], mm5
263     movq      [%3+FDEC_STRIDE*2], mm6
264     movq      [%3+FDEC_STRIDE*3], %1
265 %endmacro
266
267 cglobal x264_add8x8_idct_dc_mmx, 2,2
268     movq      mm0, [r1]
269     pxor      mm1, mm1
270     add        r0, FDEC_STRIDE*4
271     paddw     mm0, [pw_32 GLOBAL]
272     psraw     mm0, 6
273     psubw     mm1, mm0
274     packuswb  mm0, mm0
275     packuswb  mm1, mm1
276     punpcklbw mm0, mm0
277     punpcklbw mm1, mm1
278     pshufw    mm2, mm0, 0xFA
279     pshufw    mm3, mm1, 0xFA
280     punpcklbw mm0, mm0
281     punpcklbw mm1, mm1
282     ADD_DC    mm0, mm1, r0-FDEC_STRIDE*4
283     ADD_DC    mm2, mm3, r0
284     RET
285
286 cglobal x264_add8x8_idct_dc_ssse3, 2,2
287     movq      xmm0, [r1]
288     pxor      xmm1, xmm1
289     add         r0, FDEC_STRIDE*4
290     paddw     xmm0, [pw_32 GLOBAL]
291     psraw     xmm0, 6
292     psubw     xmm1, xmm0
293     movdqa    xmm5, [pb_idctdc_unpack GLOBAL]
294     packuswb  xmm0, xmm0
295     packuswb  xmm1, xmm1
296     pshufb    xmm0, xmm5
297     pshufb    xmm1, xmm5
298     movq      xmm2, [r0+FDEC_STRIDE*-4]
299     movq      xmm3, [r0+FDEC_STRIDE*-3]
300     movq      xmm4, [r0+FDEC_STRIDE*-2]
301     movq      xmm5, [r0+FDEC_STRIDE*-1]
302     movhps    xmm2, [r0+FDEC_STRIDE* 0]
303     movhps    xmm3, [r0+FDEC_STRIDE* 1]
304     movhps    xmm4, [r0+FDEC_STRIDE* 2]
305     movhps    xmm5, [r0+FDEC_STRIDE* 3]
306     paddusb   xmm2, xmm0
307     paddusb   xmm3, xmm0
308     paddusb   xmm4, xmm0
309     paddusb   xmm5, xmm0
310     psubusb   xmm2, xmm1
311     psubusb   xmm3, xmm1
312     psubusb   xmm4, xmm1
313     psubusb   xmm5, xmm1
314     movq      [r0+FDEC_STRIDE*-4], xmm2
315     movq      [r0+FDEC_STRIDE*-3], xmm3
316     movq      [r0+FDEC_STRIDE*-2], xmm4
317     movq      [r0+FDEC_STRIDE*-1], xmm5
318     movhps    [r0+FDEC_STRIDE* 0], xmm2
319     movhps    [r0+FDEC_STRIDE* 1], xmm3
320     movhps    [r0+FDEC_STRIDE* 2], xmm4
321     movhps    [r0+FDEC_STRIDE* 3], xmm5
322     RET
323
324 cglobal x264_add16x16_idct_dc_mmx, 2,3
325     mov       r2, 4
326 .loop:
327     movq      mm0, [r1]
328     pxor      mm1, mm1
329     paddw     mm0, [pw_32 GLOBAL]
330     psraw     mm0, 6
331     psubw     mm1, mm0
332     packuswb  mm0, mm0
333     packuswb  mm1, mm1
334     punpcklbw mm0, mm0
335     punpcklbw mm1, mm1
336     pshufw    mm2, mm0, 0xFA
337     pshufw    mm3, mm1, 0xFA
338     punpcklbw mm0, mm0
339     punpcklbw mm1, mm1
340     ADD_DC    mm0, mm1, r0
341     ADD_DC    mm2, mm3, r0+8
342     add       r1, 8
343     add       r0, FDEC_STRIDE*4
344     dec       r2
345     jg .loop
346     REP_RET
347
348 %macro IDCT_DC_STORE 3
349     movdqa    xmm4, [r0+%1+FDEC_STRIDE*0]
350     movdqa    xmm5, [r0+%1+FDEC_STRIDE*1]
351     movdqa    xmm6, [r0+%1+FDEC_STRIDE*2]
352     movdqa    xmm7, [r0+%1+FDEC_STRIDE*3]
353     paddusb   xmm4, %2
354     paddusb   xmm5, %2
355     paddusb   xmm6, %2
356     paddusb   xmm7, %2
357     psubusb   xmm4, %3
358     psubusb   xmm5, %3
359     psubusb   xmm6, %3
360     psubusb   xmm7, %3
361     movdqa    [r0+%1+FDEC_STRIDE*0], xmm4
362     movdqa    [r0+%1+FDEC_STRIDE*1], xmm5
363     movdqa    [r0+%1+FDEC_STRIDE*2], xmm6
364     movdqa    [r0+%1+FDEC_STRIDE*3], xmm7
365 %endmacro
366
367 cglobal x264_add16x16_idct_dc_sse2, 2,2,8
368     call .loop
369     add       r0, FDEC_STRIDE*4
370 %ifdef WIN64
371     call .loop
372     RET
373 %endif
374 .loop:
375     add       r0, FDEC_STRIDE*4
376     movq      xmm0, [r1+0]
377     movq      xmm2, [r1+8]
378     add       r1, 16
379     punpcklwd xmm0, xmm0
380     punpcklwd xmm2, xmm2
381     pxor      xmm1, xmm1
382     pxor      xmm3, xmm3
383     paddw     xmm0, [pw_32 GLOBAL]
384     paddw     xmm2, [pw_32 GLOBAL]
385     psraw     xmm0, 6
386     psraw     xmm2, 6
387     psubw     xmm1, xmm0
388     psubw     xmm3, xmm2
389     packuswb  xmm0, xmm1
390     packuswb  xmm2, xmm3
391     movdqa    xmm1, xmm0
392     movdqa    xmm3, xmm2
393     punpcklbw xmm0, xmm0
394     punpcklbw xmm2, xmm2
395     punpckhbw xmm1, xmm1
396     punpckhbw xmm3, xmm3
397     IDCT_DC_STORE FDEC_STRIDE*-4, xmm0, xmm1
398     IDCT_DC_STORE 0, xmm2, xmm3
399     ret
400
401 cglobal x264_add16x16_idct_dc_ssse3, 2,2,8
402     call .loop
403     add       r0, FDEC_STRIDE*4
404 %ifdef WIN64
405     call .loop
406     RET
407 %endif
408 .loop:
409     add       r0, FDEC_STRIDE*4
410     movdqa    xmm0, [r1]
411     add       r1, 16
412     pxor      xmm1, xmm1
413     paddw     xmm0, [pw_32 GLOBAL]
414     psraw     xmm0, 6
415     psubw     xmm1, xmm0
416     movdqa    xmm5, [ pb_idctdc_unpack GLOBAL]
417     movdqa    xmm6, [pb_idctdc_unpack2 GLOBAL]
418     packuswb  xmm0, xmm0
419     packuswb  xmm1, xmm1
420     movdqa    xmm2, xmm0
421     movdqa    xmm3, xmm1
422     pshufb    xmm0, xmm5
423     pshufb    xmm2, xmm6
424     pshufb    xmm1, xmm5
425     pshufb    xmm3, xmm6
426     IDCT_DC_STORE FDEC_STRIDE*-4, xmm0, xmm1
427     IDCT_DC_STORE 0, xmm2, xmm3
428     ret
429
430 ;-----------------------------------------------------------------------------
431 ; void x264_zigzag_scan_8x8_frame_ssse3( int16_t level[64], int16_t dct[8][8] )
432 ;-----------------------------------------------------------------------------
433 %macro SCAN_8x8 1
434 cglobal x264_zigzag_scan_8x8_frame_%1, 2,2,8
435     movdqa    xmm0, [r1]
436     movdqa    xmm1, [r1+16]
437     movdq2q    mm0, xmm0
438     PALIGNR   xmm1, xmm1, 14, xmm2
439     movdq2q    mm1, xmm1
440
441     movdqa    xmm2, [r1+32]
442     movdqa    xmm3, [r1+48]
443     PALIGNR   xmm2, xmm2, 12, xmm4
444     movdq2q    mm2, xmm2
445     PALIGNR   xmm3, xmm3, 10, xmm4
446     movdq2q    mm3, xmm3
447
448     punpckhwd xmm0, xmm1
449     punpckhwd xmm2, xmm3
450
451     movq       mm4, mm1
452     movq       mm5, mm1
453     movq       mm6, mm2
454     movq       mm7, mm3
455     punpckhwd  mm1, mm0
456     psllq      mm0, 16
457     psrlq      mm3, 16
458     punpckhdq  mm1, mm1
459     punpckhdq  mm2, mm0
460     punpcklwd  mm0, mm4
461     punpckhwd  mm4, mm3
462     punpcklwd  mm4, mm2
463     punpckhdq  mm0, mm2
464     punpcklwd  mm6, mm3
465     punpcklwd  mm5, mm7
466     punpcklwd  mm5, mm6
467
468     movdqa    xmm4, [r1+64]
469     movdqa    xmm5, [r1+80]
470     movdqa    xmm6, [r1+96]
471     movdqa    xmm7, [r1+112]
472
473     movq [r0+2*00], mm0
474     movq [r0+2*04], mm4
475     movd [r0+2*08], mm1
476     movq [r0+2*36], mm5
477     movq [r0+2*46], mm6
478
479     PALIGNR   xmm4, xmm4, 14, xmm3
480     movdq2q    mm4, xmm4
481     PALIGNR   xmm5, xmm5, 12, xmm3
482     movdq2q    mm5, xmm5
483     PALIGNR   xmm6, xmm6, 10, xmm3
484     movdq2q    mm6, xmm6
485 %ifidn %1, ssse3
486     PALIGNR   xmm7, xmm7, 8, xmm3
487     movdq2q    mm7, xmm7
488 %else
489     movhlps   xmm3, xmm7
490     punpcklqdq xmm7, xmm7
491     movdq2q    mm7, xmm3
492 %endif
493
494     punpckhwd xmm4, xmm5
495     punpckhwd xmm6, xmm7
496
497     movq       mm0, mm4
498     movq       mm1, mm5
499     movq       mm3, mm7
500     punpcklwd  mm7, mm6
501     psrlq      mm6, 16
502     punpcklwd  mm4, mm6
503     punpcklwd  mm5, mm4
504     punpckhdq  mm4, mm3
505     punpcklwd  mm3, mm6
506     punpckhwd  mm3, mm4
507     punpckhwd  mm0, mm1
508     punpckldq  mm4, mm0
509     punpckhdq  mm0, mm6
510     pshufw     mm4, mm4, 0x6c
511
512     movq [r0+2*14], mm4
513     movq [r0+2*25], mm0
514     movd [r0+2*54], mm7
515     movq [r0+2*56], mm5
516     movq [r0+2*60], mm3
517
518     movdqa    xmm3, xmm0
519     movdqa    xmm7, xmm4
520     punpckldq xmm0, xmm2
521     punpckldq xmm4, xmm6
522     punpckhdq xmm3, xmm2
523     punpckhdq xmm7, xmm6
524     pshufhw   xmm0, xmm0, 0x1b
525     pshuflw   xmm4, xmm4, 0x1b
526     pshufhw   xmm3, xmm3, 0x1b
527     pshuflw   xmm7, xmm7, 0x1b
528
529     movlps [r0+2*10], xmm0
530     movhps [r0+2*17], xmm0
531     movlps [r0+2*21], xmm3
532     movlps [r0+2*28], xmm4
533     movhps [r0+2*32], xmm3
534     movhps [r0+2*39], xmm4
535     movlps [r0+2*43], xmm7
536     movhps [r0+2*50], xmm7
537
538     RET
539 %endmacro
540
541 INIT_XMM
542 %define PALIGNR PALIGNR_MMX
543 SCAN_8x8 sse2
544 %define PALIGNR PALIGNR_SSSE3
545 SCAN_8x8 ssse3
546
547 ;-----------------------------------------------------------------------------
548 ; void x264_zigzag_scan_8x8_frame_mmxext( int16_t level[64], int16_t dct[8][8] )
549 ;-----------------------------------------------------------------------------
550 cglobal x264_zigzag_scan_8x8_frame_mmxext, 2,2
551     movq       mm0, [r1]
552     movq       mm1, [r1+2*8]
553     movq       mm2, [r1+2*14]
554     movq       mm3, [r1+2*21]
555     movq       mm4, [r1+2*28]
556     movq       mm5, mm0
557     movq       mm6, mm1
558     psrlq      mm0, 16
559     punpckldq  mm1, mm1
560     punpcklwd  mm5, mm6
561     punpckhwd  mm1, mm3
562     punpckhwd  mm6, mm0
563     punpckldq  mm5, mm0
564     movq       mm7, [r1+2*52]
565     movq       mm0, [r1+2*60]
566     punpckhwd  mm1, mm2
567     punpcklwd  mm2, mm4
568     punpckhwd  mm4, mm3
569     punpckldq  mm3, mm3
570     punpckhwd  mm3, mm2
571     movq      [r0], mm5
572     movq  [r0+2*4], mm1
573     movq  [r0+2*8], mm6
574     punpcklwd  mm6, mm0
575     punpcklwd  mm6, mm7
576     movq       mm1, [r1+2*32]
577     movq       mm5, [r1+2*39]
578     movq       mm2, [r1+2*46]
579     movq [r0+2*35], mm3
580     movq [r0+2*47], mm4
581     punpckhwd  mm7, mm0
582     psllq      mm0, 16
583     movq       mm3, mm5
584     punpcklwd  mm5, mm1
585     punpckhwd  mm1, mm2
586     punpckhdq  mm3, mm3
587     movq [r0+2*52], mm6
588     movq [r0+2*13], mm5
589     movq       mm4, [r1+2*11]
590     movq       mm6, [r1+2*25]
591     punpcklwd  mm5, mm7
592     punpcklwd  mm1, mm3
593     punpckhdq  mm0, mm7
594     movq       mm3, [r1+2*4]
595     movq       mm7, [r1+2*18]
596     punpcklwd  mm2, mm5
597     movq [r0+2*25], mm1
598     movq       mm1, mm4
599     movq       mm5, mm6
600     punpcklwd  mm4, mm3
601     punpcklwd  mm6, mm7
602     punpckhwd  mm1, mm3
603     punpckhwd  mm5, mm7
604     movq       mm3, mm6
605     movq       mm7, mm5
606     punpckldq  mm6, mm4
607     punpckldq  mm5, mm1
608     punpckhdq  mm3, mm4
609     punpckhdq  mm7, mm1
610     movq       mm4, [r1+2*35]
611     movq       mm1, [r1+2*49]
612     pshufw     mm6, mm6, 0x1b
613     pshufw     mm5, mm5, 0x1b
614     movq [r0+2*60], mm0
615     movq [r0+2*56], mm2
616     movq       mm0, [r1+2*42]
617     movq       mm2, [r1+2*56]
618     movq [r0+2*17], mm3
619     movq [r0+2*32], mm7
620     movq [r0+2*10], mm6
621     movq [r0+2*21], mm5
622     movq       mm3, mm0
623     movq       mm7, mm2
624     punpcklwd  mm0, mm4
625     punpcklwd  mm2, mm1
626     punpckhwd  mm3, mm4
627     punpckhwd  mm7, mm1
628     movq       mm4, mm2
629     movq       mm1, mm7
630     punpckhdq  mm2, mm0
631     punpckhdq  mm7, mm3
632     punpckldq  mm4, mm0
633     punpckldq  mm1, mm3
634     pshufw     mm2, mm2, 0x1b
635     pshufw     mm7, mm7, 0x1b
636     movq [r0+2*28], mm4
637     movq [r0+2*43], mm1
638     movq [r0+2*39], mm2
639     movq [r0+2*50], mm7
640     RET
641
642 ;-----------------------------------------------------------------------------
643 ; void x264_zigzag_scan_4x4_frame_mmx( int16_t level[16], int16_t dct[4][4] )
644 ;-----------------------------------------------------------------------------
645 cglobal x264_zigzag_scan_4x4_frame_mmx, 2,2
646     movq       mm0, [r1]
647     movq       mm1, [r1+8]
648     movq       mm2, [r1+16]
649     movq       mm3, [r1+24]
650     movq       mm4, mm0
651     movq       mm5, mm1
652     movq       mm6, mm2
653     movq       mm7, mm3
654     psllq      mm3, 16
655     psrlq      mm0, 16
656     punpckldq  mm2, mm2
657     punpckhdq  mm1, mm1
658     punpcklwd  mm4, mm5
659     punpcklwd  mm5, mm3
660     punpckldq  mm4, mm0
661     punpckhwd  mm5, mm2
662     punpckhwd  mm0, mm6
663     punpckhwd  mm6, mm7
664     punpcklwd  mm1, mm0
665     punpckhdq  mm3, mm6
666     movq      [r0], mm4
667     movq    [r0+8], mm5
668     movq   [r0+16], mm1
669     movq   [r0+24], mm3
670     RET
671
672 ;-----------------------------------------------------------------------------
673 ; void x264_zigzag_scan_4x4_frame_ssse3( int16_t level[16], int16_t dct[4][4] )
674 ;-----------------------------------------------------------------------------
675 cglobal x264_zigzag_scan_4x4_frame_ssse3, 2,2
676     movdqa    xmm1, [r1+16]
677     movdqa    xmm0, [r1]
678     pshufb    xmm1, [pb_scan4frameb GLOBAL]
679     pshufb    xmm0, [pb_scan4framea GLOBAL]
680     movdqa    xmm2, xmm1
681     psrldq    xmm1, 6
682     palignr   xmm2, xmm0, 6
683     pslldq    xmm0, 10
684     palignr   xmm1, xmm0, 10
685     movdqa    [r0], xmm2
686     movdqa [r0+16], xmm1
687     RET
688
689 ;-----------------------------------------------------------------------------
690 ; void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] )
691 ;-----------------------------------------------------------------------------
692 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
693 cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
694     pshufw     mm0, [r1+4], 0xd2
695     movq       mm1, [r1+16]
696     movq       mm2, [r1+24]
697     movq    [r0+4], mm0
698     movq   [r0+16], mm1
699     movq   [r0+24], mm2
700     mov        r2d, [r1]
701     mov       [r0], r2d
702     mov        r2d, [r1+12]
703     mov    [r0+12], r2d
704     RET
705
706 ;-----------------------------------------------------------------------------
707 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
708 ;-----------------------------------------------------------------------------
709 cglobal x264_zigzag_sub_4x4_frame_ssse3, 3,3,8
710     movd      xmm0, [r1+0*FENC_STRIDE]
711     movd      xmm1, [r1+1*FENC_STRIDE]
712     movd      xmm2, [r1+2*FENC_STRIDE]
713     movd      xmm3, [r1+3*FENC_STRIDE]
714     movd      xmm4, [r2+0*FDEC_STRIDE]
715     movd      xmm5, [r2+1*FDEC_STRIDE]
716     movd      xmm6, [r2+2*FDEC_STRIDE]
717     movd      xmm7, [r2+3*FDEC_STRIDE]
718     movd      [r2+0*FDEC_STRIDE], xmm0
719     movd      [r2+1*FDEC_STRIDE], xmm1
720     movd      [r2+2*FDEC_STRIDE], xmm2
721     movd      [r2+3*FDEC_STRIDE], xmm3
722     punpckldq xmm0, xmm1
723     punpckldq xmm2, xmm3
724     punpckldq xmm4, xmm5
725     punpckldq xmm6, xmm7
726     punpcklqdq xmm0, xmm2
727     punpcklqdq xmm4, xmm6
728     movdqa    xmm7, [pb_sub4frame GLOBAL]
729     pshufb    xmm0, xmm7
730     pshufb    xmm4, xmm7
731     pxor      xmm6, xmm6
732     movdqa    xmm1, xmm0
733     movdqa    xmm5, xmm4
734     punpcklbw xmm0, xmm6
735     punpckhbw xmm1, xmm6
736     punpcklbw xmm4, xmm6
737     punpckhbw xmm5, xmm6
738     psubw     xmm0, xmm4
739     psubw     xmm1, xmm5
740     movdqa    [r0], xmm0
741     movdqa [r0+16], xmm1
742     RET
743
744 ;-----------------------------------------------------------------------------
745 ; void x264_zigzag_interleave_8x8_cavlc_mmx( int16_t *dst, int16_t *src, uint8_t *nnz )
746 ;-----------------------------------------------------------------------------
747
748 %macro INTERLEAVE 1
749     movq   m0, [r1+%1*4+ 0]
750     movq   m1, [r1+%1*4+ 8]
751     movq   m2, [r1+%1*4+16]
752     movq   m3, [r1+%1*4+24]
753     TRANSPOSE4x4W 0,1,2,3,4
754     movq   [r0+%1+ 0], m0
755     movq   [r0+%1+32], m1
756     movq   [r0+%1+64], m2
757     movq   [r0+%1+96], m3
758 %if %1
759     packsswb m0, m1
760     por    m6, m2
761     por    m7, m3
762     por    m5, m0
763 %else
764     packsswb m0, m1
765     SWAP   m5, m0
766     SWAP   m6, m2
767     SWAP   m7, m3
768 %endif
769 %endmacro
770
771 INIT_MMX
772 cglobal x264_zigzag_interleave_8x8_cavlc_mmx, 3,3
773     INTERLEAVE  0
774     INTERLEAVE  8
775     INTERLEAVE 16
776     INTERLEAVE 24
777     packsswb m6, m7
778     packsswb m5, m6
779     packsswb m5, m5
780     pxor     m0, m0
781     pcmpeqb  m5, m0
782     paddb    m5, [pb_1 GLOBAL]
783     movd    r0d, m5
784     mov  [r2+0], r0w
785     shr     r0d, 16
786     mov  [r2+8], r0w
787     RET
788
789 %macro INTERLEAVE_XMM 1
790     mova   m0, [r1+%1*4+ 0]
791     mova   m1, [r1+%1*4+16]
792     mova   m4, [r1+%1*4+32]
793     mova   m5, [r1+%1*4+48]
794     SBUTTERFLY wd, 0, 1, 6
795     SBUTTERFLY wd, 4, 5, 7
796     SBUTTERFLY wd, 0, 1, 6
797     SBUTTERFLY wd, 4, 5, 7
798     movq   [r0+%1+  0], m0
799     movhps [r0+%1+ 32], m0
800     movq   [r0+%1+ 64], m1
801     movhps [r0+%1+ 96], m1
802     movq   [r0+%1+  8], m4
803     movhps [r0+%1+ 40], m4
804     movq   [r0+%1+ 72], m5
805     movhps [r0+%1+104], m5
806 %if %1
807     por    m2, m0
808     por    m3, m1
809     por    m2, m4
810     por    m3, m5
811 %else
812     SWAP 0,2
813     SWAP 3,1
814     por    m2, m4
815     por    m3, m5
816 %endif
817 %endmacro
818
819 INIT_XMM
820 cglobal x264_zigzag_interleave_8x8_cavlc_sse2, 3,3,8
821     INTERLEAVE_XMM  0
822     INTERLEAVE_XMM 16
823     packsswb m2, m3
824     pxor     m5, m5
825     packsswb m2, m2
826     packsswb m2, m2
827     pcmpeqb  m5, m2
828     paddb    m5, [pb_1 GLOBAL]
829     movd    r0d, m5
830     mov  [r2+0], r0w
831     shr     r0d, 16
832     mov  [r2+8], r0w
833     RET
834