]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
b48bfbb71498a90043355ef36cde17582bda6619
[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 INIT_XMM
895 %define PALIGNR PALIGNR_MMX
896 SCAN_8x8 sse2
897 %define PALIGNR PALIGNR_SSSE3
898 SCAN_8x8 ssse3
899
900 ;-----------------------------------------------------------------------------
901 ; void zigzag_scan_8x8_frame( int16_t level[64], int16_t dct[8][8] )
902 ;-----------------------------------------------------------------------------
903 cglobal zigzag_scan_8x8_frame_mmxext, 2,2
904     movq       mm0, [r1]
905     movq       mm1, [r1+2*8]
906     movq       mm2, [r1+2*14]
907     movq       mm3, [r1+2*21]
908     movq       mm4, [r1+2*28]
909     movq       mm5, mm0
910     movq       mm6, mm1
911     psrlq      mm0, 16
912     punpckldq  mm1, mm1
913     punpcklwd  mm5, mm6
914     punpckhwd  mm1, mm3
915     punpckhwd  mm6, mm0
916     punpckldq  mm5, mm0
917     movq       mm7, [r1+2*52]
918     movq       mm0, [r1+2*60]
919     punpckhwd  mm1, mm2
920     punpcklwd  mm2, mm4
921     punpckhwd  mm4, mm3
922     punpckldq  mm3, mm3
923     punpckhwd  mm3, mm2
924     movq      [r0], mm5
925     movq  [r0+2*4], mm1
926     movq  [r0+2*8], mm6
927     punpcklwd  mm6, mm0
928     punpcklwd  mm6, mm7
929     movq       mm1, [r1+2*32]
930     movq       mm5, [r1+2*39]
931     movq       mm2, [r1+2*46]
932     movq [r0+2*35], mm3
933     movq [r0+2*47], mm4
934     punpckhwd  mm7, mm0
935     psllq      mm0, 16
936     movq       mm3, mm5
937     punpcklwd  mm5, mm1
938     punpckhwd  mm1, mm2
939     punpckhdq  mm3, mm3
940     movq [r0+2*52], mm6
941     movq [r0+2*13], mm5
942     movq       mm4, [r1+2*11]
943     movq       mm6, [r1+2*25]
944     punpcklwd  mm5, mm7
945     punpcklwd  mm1, mm3
946     punpckhdq  mm0, mm7
947     movq       mm3, [r1+2*4]
948     movq       mm7, [r1+2*18]
949     punpcklwd  mm2, mm5
950     movq [r0+2*25], mm1
951     movq       mm1, mm4
952     movq       mm5, mm6
953     punpcklwd  mm4, mm3
954     punpcklwd  mm6, mm7
955     punpckhwd  mm1, mm3
956     punpckhwd  mm5, mm7
957     movq       mm3, mm6
958     movq       mm7, mm5
959     punpckldq  mm6, mm4
960     punpckldq  mm5, mm1
961     punpckhdq  mm3, mm4
962     punpckhdq  mm7, mm1
963     movq       mm4, [r1+2*35]
964     movq       mm1, [r1+2*49]
965     pshufw     mm6, mm6, 0x1b
966     pshufw     mm5, mm5, 0x1b
967     movq [r0+2*60], mm0
968     movq [r0+2*56], mm2
969     movq       mm0, [r1+2*42]
970     movq       mm2, [r1+2*56]
971     movq [r0+2*17], mm3
972     movq [r0+2*32], mm7
973     movq [r0+2*10], mm6
974     movq [r0+2*21], mm5
975     movq       mm3, mm0
976     movq       mm7, mm2
977     punpcklwd  mm0, mm4
978     punpcklwd  mm2, mm1
979     punpckhwd  mm3, mm4
980     punpckhwd  mm7, mm1
981     movq       mm4, mm2
982     movq       mm1, mm7
983     punpckhdq  mm2, mm0
984     punpckhdq  mm7, mm3
985     punpckldq  mm4, mm0
986     punpckldq  mm1, mm3
987     pshufw     mm2, mm2, 0x1b
988     pshufw     mm7, mm7, 0x1b
989     movq [r0+2*28], mm4
990     movq [r0+2*43], mm1
991     movq [r0+2*39], mm2
992     movq [r0+2*50], mm7
993     RET
994
995 ;-----------------------------------------------------------------------------
996 ; void zigzag_scan_4x4_frame( int16_t level[16], int16_t dct[4][4] )
997 ;-----------------------------------------------------------------------------
998 cglobal zigzag_scan_4x4_frame_mmx, 2,2
999     movq       mm0, [r1]
1000     movq       mm1, [r1+8]
1001     movq       mm2, [r1+16]
1002     movq       mm3, [r1+24]
1003     movq       mm4, mm0
1004     movq       mm5, mm1
1005     movq       mm6, mm2
1006     movq       mm7, mm3
1007     psllq      mm3, 16
1008     psrlq      mm0, 16
1009     punpckldq  mm2, mm2
1010     punpckhdq  mm1, mm1
1011     punpcklwd  mm4, mm5
1012     punpcklwd  mm5, mm3
1013     punpckldq  mm4, mm0
1014     punpckhwd  mm5, mm2
1015     punpckhwd  mm0, mm6
1016     punpckhwd  mm6, mm7
1017     punpcklwd  mm1, mm0
1018     punpckhdq  mm3, mm6
1019     movq      [r0], mm4
1020     movq    [r0+8], mm5
1021     movq   [r0+16], mm1
1022     movq   [r0+24], mm3
1023     RET
1024
1025 ;-----------------------------------------------------------------------------
1026 ; void zigzag_scan_4x4_frame( int16_t level[16], int16_t dct[4][4] )
1027 ;-----------------------------------------------------------------------------
1028 cglobal zigzag_scan_4x4_frame_ssse3, 2,2
1029     movdqa    xmm1, [r1+16]
1030     movdqa    xmm0, [r1]
1031     pshufb    xmm1, [pb_scan4frameb]
1032     pshufb    xmm0, [pb_scan4framea]
1033     movdqa    xmm2, xmm1
1034     psrldq    xmm1, 6
1035     palignr   xmm2, xmm0, 6
1036     pslldq    xmm0, 10
1037     palignr   xmm1, xmm0, 10
1038     movdqa    [r0], xmm2
1039     movdqa [r0+16], xmm1
1040     RET
1041
1042 ;-----------------------------------------------------------------------------
1043 ; void zigzag_scan_4x4_field( int16_t level[16], int16_t dct[4][4] )
1044 ;-----------------------------------------------------------------------------
1045 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
1046 cglobal zigzag_scan_4x4_field_mmxext, 2,3
1047     pshufw     mm0, [r1+4], 0xd2
1048     movq       mm1, [r1+16]
1049     movq       mm2, [r1+24]
1050     movq    [r0+4], mm0
1051     movq   [r0+16], mm1
1052     movq   [r0+24], mm2
1053     mov        r2d, [r1]
1054     mov       [r0], r2d
1055     mov        r2d, [r1+12]
1056     mov    [r0+12], r2d
1057     RET
1058
1059 ;-----------------------------------------------------------------------------
1060 ; void zigzag_scan_8x8_field( int16_t level[64], int16_t dct[8][8] )
1061 ;-----------------------------------------------------------------------------
1062
1063 ; Output order:
1064 ;  0  1  2  8  9  3  4 10
1065 ; 16 11  5  6  7 12 17 24
1066 ; 18 13 14 15 19 25 32 26
1067 ; 20 21 22 23 27 33 40 34
1068 ; 28 29 30 31 35 41 48 42
1069 ; 36 37 38 39 43 49 50 44
1070 ; 45 46 47 51 56 57 52 53
1071 ; 54 55 58 59 60 61 62 63
1072
1073 cglobal zigzag_scan_8x8_field_mmxext, 2,3
1074     movq       mm0, [r1+2*0]        ; 03 02 01 00
1075     movq       mm1, [r1+2*4]        ; 07 06 05 04
1076     movq       mm2, [r1+2*8]        ; 11 10 09 08
1077     pshufw     mm3, mm0, 011111111b ; 03 03 03 03
1078     movd        r2, mm2             ; 09 08
1079     pshufw     mm2, mm2, 000111001b ; 08 11 10 09
1080     punpcklwd  mm3, mm1             ; 05 03 04 03
1081     pinsrw     mm0, r2, 3           ; 08 02 01 00
1082     movq       mm4, mm2
1083     punpcklwd  mm2, mm3             ; 04 10 03 09
1084     pshufw     mm2, mm2, 010110100b ; 10 04 03 09
1085     movq  [r0+2*0], mm0             ; 08 02 01 00
1086     movq  [r0+2*4], mm2             ; 10 04 03 09
1087     movq       mm3, [r1+2*12]       ; 15 14 13 12
1088     movq       mm5, [r1+2*16]       ; 19 18 17 16
1089     punpckldq  mm6, mm5             ; 17 16 XX XX
1090     psrlq      mm1, 16              ; XX 07 06 05
1091     punpckhwd  mm6, mm4             ; 08 17 11 16
1092     punpckldq  mm6, mm1             ; 06 05 11 16
1093     movq  [r0+2*8], mm6             ; 06 05 11 16
1094     psrlq      mm1, 16              ; XX XX 07 06
1095     punpcklwd  mm1, mm5             ; 17 07 16 06
1096     movq       mm0, [r1+2*20]       ; 23 22 21 20
1097     movq       mm2, [r1+2*24]       ; 27 26 25 24
1098     movq       mm6, mm3
1099     punpckhdq  mm1, mm1             ; 17 07 17 07
1100     punpcklwd  mm6, mm2             ; 25 13 24 12
1101     pextrw      r2, mm5, 2
1102     movq [r0+2*24], mm0             ; 23 22 21 20
1103     punpcklwd  mm1, mm6             ; 24 17 12 07
1104     movq [r0+2*12], mm1
1105     pinsrw     mm3, r2, 0           ; 15 14 13 18
1106     movq [r0+2*16], mm3             ; 15 14 13 18
1107     movq       mm7, [r1+2*28]
1108     movq       mm0, [r1+2*32]       ; 35 34 33 32
1109     psrlq      mm5, 48              ; XX XX XX 19
1110     pshufw     mm1, mm2, 011111001b ; 27 27 26 25
1111     punpcklwd  mm5, mm0             ; 33 XX 32 19
1112     psrlq      mm2, 48              ; XX XX XX 27
1113     punpcklwd  mm5, mm1             ; 26 32 25 19
1114     movq [r0+2*32], mm7
1115     movq [r0+2*20], mm5             ; 26 32 25 19
1116     movq       mm7, [r1+2*36]
1117     movq       mm1, [r1+2*40]       ; 43 42 41 40
1118     pshufw     mm3, mm0, 011111001b ; 35 35 34 33
1119     punpcklwd  mm2, mm1             ; 41 XX 40 27
1120     movq [r0+2*40], mm7
1121     punpcklwd  mm2, mm3             ; 34 40 33 27
1122     movq [r0+2*28], mm2
1123     movq       mm7, [r1+2*44]       ; 47 46 45 44
1124     movq       mm2, [r1+2*48]       ; 51 50 49 48
1125     psrlq      mm0, 48              ; XX XX XX 35
1126     punpcklwd  mm0, mm2             ; 49 XX 48 35
1127     pshufw     mm3, mm1, 011111001b ; 43 43 42 41
1128     punpcklwd  mm0, mm3             ; 42 48 41 35
1129     movq [r0+2*36], mm0
1130     pextrw      r2, mm2, 3          ; 51
1131     psrlq      mm1, 48              ; XX XX XX 43
1132     punpcklwd  mm1, mm7             ; 45 XX 44 43
1133     psrlq      mm2, 16              ; XX 51 50 49
1134     punpcklwd  mm1, mm2             ; 50 44 49 43
1135     pshufw     mm1, mm1, 010110100b ; 44 50 49 43
1136     movq [r0+2*44], mm1
1137     psrlq      mm7, 16              ; XX 47 46 45
1138     pinsrw     mm7, r2, 3           ; 51 47 46 45
1139     movq [r0+2*48], mm7
1140     movq       mm0, [r1+2*56]       ; 59 58 57 56
1141     movq       mm1, [r1+2*52]       ; 55 54 53 52
1142     movq       mm2, mm0
1143     movq       mm7, [r1+2*60]
1144     punpckldq  mm2, mm1             ; 53 52 57 56
1145     punpckhdq  mm1, mm0             ; 59 58 55 54
1146     movq [r0+2*52], mm2
1147     movq [r0+2*56], mm1
1148     movq [r0+2*60], mm7
1149     RET
1150
1151 ;-----------------------------------------------------------------------------
1152 ; void zigzag_sub_4x4_frame( int16_t level[16], const uint8_t *src, uint8_t *dst )
1153 ;-----------------------------------------------------------------------------
1154 %macro ZIGZAG_SUB_4x4 2
1155 %ifidn %1, ac
1156 cglobal zigzag_sub_4x4%1_%2_ssse3, 4,4,8
1157 %else
1158 cglobal zigzag_sub_4x4%1_%2_ssse3, 3,3,8
1159 %endif
1160     movd      xmm0, [r1+0*FENC_STRIDE]
1161     movd      xmm1, [r1+1*FENC_STRIDE]
1162     movd      xmm2, [r1+2*FENC_STRIDE]
1163     movd      xmm3, [r1+3*FENC_STRIDE]
1164     movd      xmm4, [r2+0*FDEC_STRIDE]
1165     movd      xmm5, [r2+1*FDEC_STRIDE]
1166     movd      xmm6, [r2+2*FDEC_STRIDE]
1167     movd      xmm7, [r2+3*FDEC_STRIDE]
1168     movd      [r2+0*FDEC_STRIDE], xmm0
1169     movd      [r2+1*FDEC_STRIDE], xmm1
1170     movd      [r2+2*FDEC_STRIDE], xmm2
1171     movd      [r2+3*FDEC_STRIDE], xmm3
1172     punpckldq xmm0, xmm1
1173     punpckldq xmm2, xmm3
1174     punpckldq xmm4, xmm5
1175     punpckldq xmm6, xmm7
1176     punpcklqdq xmm0, xmm2
1177     punpcklqdq xmm4, xmm6
1178 %ifidn %2, frame
1179     movdqa    xmm7, [pb_sub4frame]
1180 %else
1181     movdqa    xmm7, [pb_sub4field]
1182 %endif
1183     pshufb    xmm0, xmm7
1184     pshufb    xmm4, xmm7
1185     pxor      xmm6, xmm6
1186     movdqa    xmm1, xmm0
1187     movdqa    xmm5, xmm4
1188     punpcklbw xmm0, xmm6
1189     punpckhbw xmm1, xmm6
1190     punpcklbw xmm4, xmm6
1191     punpckhbw xmm5, xmm6
1192     psubw     xmm0, xmm4
1193     psubw     xmm1, xmm5
1194 %ifidn %1, ac
1195     movd       r2d, xmm0
1196     pand      xmm0, [pb_subacmask]
1197 %endif
1198     movdqa    [r0], xmm0
1199     pxor      xmm2, xmm2
1200     movdqa [r0+16], xmm1
1201     por       xmm0, xmm1
1202     pcmpeqb   xmm0, xmm2
1203     pmovmskb   eax, xmm0
1204 %ifidn %1, ac
1205     mov       [r3], r2w
1206 %endif
1207     sub        eax, 0xffff
1208     shr        eax, 31
1209     RET
1210 %endmacro
1211
1212 ZIGZAG_SUB_4x4   , frame
1213 ZIGZAG_SUB_4x4 ac, frame
1214 ZIGZAG_SUB_4x4   , field
1215 ZIGZAG_SUB_4x4 ac, field
1216
1217 ;-----------------------------------------------------------------------------
1218 ; void zigzag_interleave_8x8_cavlc( int16_t *dst, int16_t *src, uint8_t *nnz )
1219 ;-----------------------------------------------------------------------------
1220
1221 %macro INTERLEAVE 1
1222     movq   m0, [r1+%1*4+ 0]
1223     movq   m1, [r1+%1*4+ 8]
1224     movq   m2, [r1+%1*4+16]
1225     movq   m3, [r1+%1*4+24]
1226     TRANSPOSE4x4W 0,1,2,3,4
1227     movq   [r0+%1+ 0], m0
1228     movq   [r0+%1+32], m1
1229     movq   [r0+%1+64], m2
1230     movq   [r0+%1+96], m3
1231 %if %1
1232     packsswb m0, m1
1233     por    m6, m2
1234     por    m7, m3
1235     por    m5, m0
1236 %else
1237     packsswb m0, m1
1238     SWAP   m5, m0
1239     SWAP   m6, m2
1240     SWAP   m7, m3
1241 %endif
1242 %endmacro
1243
1244 INIT_MMX
1245 cglobal zigzag_interleave_8x8_cavlc_mmx, 3,3
1246     INTERLEAVE  0
1247     INTERLEAVE  8
1248     INTERLEAVE 16
1249     INTERLEAVE 24
1250     packsswb m6, m7
1251     packsswb m5, m6
1252     packsswb m5, m5
1253     pxor     m0, m0
1254     pcmpeqb  m5, m0
1255     paddb    m5, [pb_1]
1256     movd    r0d, m5
1257     mov  [r2+0], r0w
1258     shr     r0d, 16
1259     mov  [r2+8], r0w
1260     RET
1261
1262 %macro INTERLEAVE_XMM 1
1263     mova   m0, [r1+%1*4+ 0]
1264     mova   m1, [r1+%1*4+16]
1265     mova   m4, [r1+%1*4+32]
1266     mova   m5, [r1+%1*4+48]
1267     SBUTTERFLY wd, 0, 1, 6
1268     SBUTTERFLY wd, 4, 5, 7
1269     SBUTTERFLY wd, 0, 1, 6
1270     SBUTTERFLY wd, 4, 5, 7
1271     movq   [r0+%1+  0], m0
1272     movhps [r0+%1+ 32], m0
1273     movq   [r0+%1+ 64], m1
1274     movhps [r0+%1+ 96], m1
1275     movq   [r0+%1+  8], m4
1276     movhps [r0+%1+ 40], m4
1277     movq   [r0+%1+ 72], m5
1278     movhps [r0+%1+104], m5
1279 %if %1
1280     por    m2, m0
1281     por    m3, m1
1282     por    m2, m4
1283     por    m3, m5
1284 %else
1285     SWAP 0,2
1286     SWAP 3,1
1287     por    m2, m4
1288     por    m3, m5
1289 %endif
1290 %endmacro
1291
1292 INIT_XMM
1293 cglobal zigzag_interleave_8x8_cavlc_sse2, 3,3,8
1294     INTERLEAVE_XMM  0
1295     INTERLEAVE_XMM 16
1296     packsswb m2, m3
1297     pxor     m5, m5
1298     packsswb m2, m2
1299     packsswb m2, m2
1300     pcmpeqb  m5, m2
1301     paddb    m5, [pb_1]
1302     movd    r0d, m5
1303     mov  [r2+0], r0w
1304     shr     r0d, 16
1305     mov  [r2+8], r0w
1306     RET
1307