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