]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
Various minor missing changes from previous commits
[x264] / common / x86 / dct-a.asm
1 ;*****************************************************************************
2 ;* dct-a.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2008 x264 project
5 ;*
6 ;* Authors: 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 %macro SHUFFLE_16BIT 8
30     %rep 8
31         db %1*2
32         db %1*2+1
33         %rotate 1
34     %endrep
35 %endmacro
36
37 SECTION_RODATA
38 pw_32_0: times 4 dw 32
39          times 4 dw 0
40 pw_32: times 8 dw 32
41 pw_8000: times 8 dw 0x8000
42 hsub_mul: times 8 db 1, -1
43
44 pb_sub4frame:   db 0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15
45 pb_sub4field:   db 0,4,1,8,12,5,9,13,2,6,10,14,3,7,11,15
46 pb_subacmask:   dw 0,-1,-1,-1,-1,-1,-1,-1
47 pb_scan4framea: SHUFFLE_16BIT 6,3,7,0,4,1,2,5
48 pb_scan4frameb: SHUFFLE_16BIT 0,4,1,2,5,6,3,7
49 pb_idctdc_unpack: db 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3
50 pb_idctdc_unpack2: db 4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7
51 pb_1: times 16 db 1
52 pw_1: times 8 dw 1
53
54 SECTION .text
55
56 %macro WALSH4_1D 5
57     SUMSUB_BADC m%4, m%3, m%2, m%1, m%5
58     SUMSUB_BADC m%4, m%2, m%3, m%1, m%5
59     SWAP %1, %4, %3
60 %endmacro
61
62 %macro SUMSUB_17BIT 4 ; a, b, tmp, 0x8000
63     movq  m%3, m%4
64     pxor  m%1, m%4
65     psubw m%3, m%2
66     pxor  m%2, m%4
67     pavgw m%3, m%1
68     pavgw m%2, m%1
69     pxor  m%3, m%4
70     pxor  m%2, m%4
71     SWAP %1, %2, %3
72 %endmacro
73
74 INIT_MMX
75 ;-----------------------------------------------------------------------------
76 ; void x264_dct4x4dc_mmx( int16_t d[4][4] )
77 ;-----------------------------------------------------------------------------
78 cglobal x264_dct4x4dc_mmx, 1,1
79     movq   m3, [r0+24]
80     movq   m2, [r0+16]
81     movq   m1, [r0+ 8]
82     movq   m0, [r0+ 0]
83     movq   m7, [pw_8000 GLOBAL] ; convert to unsigned and back, so that pavgw works
84     WALSH4_1D  0,1,2,3,4
85     TRANSPOSE4x4W 0,1,2,3,4
86     SUMSUB_BADC m1, m0, m3, m2, m4
87     SWAP 0, 1
88     SWAP 2, 3
89     SUMSUB_17BIT 0,2,4,7
90     SUMSUB_17BIT 1,3,5,7
91     movq  [r0+0], m0
92     movq  [r0+8], m2
93     movq [r0+16], m3
94     movq [r0+24], m1
95     RET
96
97 ;-----------------------------------------------------------------------------
98 ; void x264_idct4x4dc_mmx( int16_t d[4][4] )
99 ;-----------------------------------------------------------------------------
100 cglobal x264_idct4x4dc_mmx, 1,1
101     movq   m3, [r0+24]
102     movq   m2, [r0+16]
103     movq   m1, [r0+ 8]
104     movq   m0, [r0+ 0]
105     WALSH4_1D  0,1,2,3,4
106     TRANSPOSE4x4W 0,1,2,3,4
107     WALSH4_1D  0,1,2,3,4
108     movq  [r0+ 0], m0
109     movq  [r0+ 8], m1
110     movq  [r0+16], m2
111     movq  [r0+24], m3
112     RET
113
114 %macro SUB_DCT4 1
115 ;-----------------------------------------------------------------------------
116 ; void x264_sub4x4_dct_mmx( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
117 ;-----------------------------------------------------------------------------
118 cglobal x264_sub4x4_dct_%1, 3,3
119 %ifidn %1, mmx
120 .skip_prologue:
121     LOAD_DIFF  m0, m4, m5, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
122     LOAD_DIFF  m3, m4, m5, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
123     LOAD_DIFF  m1, m4, m5, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
124     LOAD_DIFF  m2, m4, m5, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
125 %else
126     mova m5, [hsub_mul GLOBAL]
127     LOAD_DIFF8x4_SSSE3 0, 3, 1, 2, 4, 5, r1, r2
128 %endif
129     DCT4_1D 0,1,2,3,4
130     TRANSPOSE4x4W 0,1,2,3,4
131     DCT4_1D 0,1,2,3,4
132     movq  [r0+ 0], m0
133     movq  [r0+ 8], m1
134     movq  [r0+16], m2
135     movq  [r0+24], m3
136     RET
137 %endmacro
138
139 SUB_DCT4 mmx
140 SUB_DCT4 ssse3
141
142 ;-----------------------------------------------------------------------------
143 ; void x264_add4x4_idct_mmx( uint8_t *p_dst, int16_t dct[4][4] )
144 ;-----------------------------------------------------------------------------
145 cglobal x264_add4x4_idct_mmx, 2,2
146     pxor m7, m7
147 .skip_prologue:
148     movq  m1, [r1+ 8]
149     movq  m3, [r1+24]
150     movq  m2, [r1+16]
151     movq  m0, [r1+ 0]
152     IDCT4_1D 0,1,2,3,4,5
153     TRANSPOSE4x4W 0,1,2,3,4
154     paddw m0, [pw_32 GLOBAL]
155     IDCT4_1D 0,1,2,3,4,5
156     STORE_DIFF  m0, m4, m7, [r0+0*FDEC_STRIDE]
157     STORE_DIFF  m1, m4, m7, [r0+1*FDEC_STRIDE]
158     STORE_DIFF  m2, m4, m7, [r0+2*FDEC_STRIDE]
159     STORE_DIFF  m3, m4, m7, [r0+3*FDEC_STRIDE]
160     RET
161
162 INIT_XMM
163 cglobal x264_add4x4_idct_sse4, 2,2,6
164     mova      m0, [r1+0x00]     ; row1/row0
165     mova      m2, [r1+0x10]     ; row3/row2
166     mova      m1, m0            ; row1/row0
167     psraw     m0, 1             ; row1>>1/...
168     mova      m3, m2            ; row3/row2
169     psraw     m2, 1             ; row3>>1/...
170     movsd     m0, m1            ; row1>>1/row0
171     movsd     m2, m3            ; row3>>1/row2
172     psubw     m0, m3            ; row1>>1-row3/row0-2
173     paddw     m2, m1            ; row3>>1+row1/row0+2
174     SBUTTERFLY2 wd, 0, 2, 1
175     SUMSUB_BA m2, m0, m1
176     pshuflw   m1, m2, 10110001b
177     pshufhw   m2, m2, 10110001b
178     punpckldq m1, m0
179     punpckhdq m2, m0
180     SWAP 0, 1
181
182     mova      m1, [pw_32_0 GLOBAL]
183     paddw     m1, m0            ; row1/row0 corrected
184     psraw     m0, 1             ; row1>>1/...
185     mova      m3, m2            ; row3/row2
186     psraw     m2, 1             ; row3>>1/...
187     movsd     m0, m1            ; row1>>1/row0
188     movsd     m2, m3            ; row3>>1/row2
189     psubw     m0, m3            ; row1>>1-row3/row0-2
190     paddw     m2, m1            ; row3>>1+row1/row0+2
191     SBUTTERFLY2 qdq, 0, 2, 1
192     SUMSUB_BA m2, m0, m1
193
194     movd      m4, [r0+FDEC_STRIDE*0]
195     movd      m1, [r0+FDEC_STRIDE*1]
196     movd      m3, [r0+FDEC_STRIDE*2]
197     movd      m5, [r0+FDEC_STRIDE*3]
198     punpckldq m1, m4            ; row0/row1
199     pxor      m4, m4
200     punpckldq m3, m5            ; row3/row2
201     punpcklbw m1, m4
202     psraw     m2, 6
203     punpcklbw m3, m4
204     psraw     m0, 6
205     paddsw    m2, m1
206     paddsw    m0, m3
207     packuswb  m0, m2            ; row0/row1/row3/row2
208     pextrd   [r0+FDEC_STRIDE*0], m0, 3
209     pextrd   [r0+FDEC_STRIDE*1], m0, 2
210     movd     [r0+FDEC_STRIDE*2], m0
211     pextrd   [r0+FDEC_STRIDE*3], m0, 1
212     RET
213
214 INIT_MMX
215 ;-----------------------------------------------------------------------------
216 ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
217 ;-----------------------------------------------------------------------------
218 %macro SUB_NxN_DCT 6
219 cglobal %1, 3,3,11
220 %if mmsize == 8
221     pxor m7, m7
222 %else
223     add r2, 4*FDEC_STRIDE
224     mova m7, [hsub_mul GLOBAL]
225 %endif
226 .skip_prologue:
227 %ifdef WIN64
228     sub  rsp, 8
229 %endif
230     call %2
231     add  r0, %3
232     add  r1, %4-%5-%6*FENC_STRIDE
233     add  r2, %4-%5-%6*FDEC_STRIDE
234     call %2
235     add  r0, %3
236     add  r1, (%4-%6)*FENC_STRIDE-%5-%4
237     add  r2, (%4-%6)*FDEC_STRIDE-%5-%4
238     call %2
239     add  r0, %3
240     add  r1, %4-%5-%6*FENC_STRIDE
241     add  r2, %4-%5-%6*FDEC_STRIDE
242 %ifdef WIN64
243     add  rsp, 8
244     call %2
245     RET
246 %else
247     jmp  %2
248 %endif
249 %endmacro
250
251 ;-----------------------------------------------------------------------------
252 ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
253 ;-----------------------------------------------------------------------------
254 %macro ADD_NxN_IDCT 6-7
255 cglobal %1, 2,2,11
256     pxor m7, m7
257 %if mmsize==16
258     add  r0, 4*FDEC_STRIDE
259 %endif
260 .skip_prologue:
261 %ifdef WIN64
262     sub  rsp, 8
263 %endif
264     call %2
265     add  r0, %4-%5-%6*FDEC_STRIDE
266     add  r1, %3
267     call %2
268     add  r0, (%4-%6)*FDEC_STRIDE-%5-%4
269     add  r1, %3
270     call %2
271     add  r0, %4-%5-%6*FDEC_STRIDE
272     add  r1, %3
273 %ifdef WIN64
274     add  rsp, 8
275     call %2
276     RET
277 %else
278     jmp  %2
279 %endif
280 %endmacro
281
282 %ifndef ARCH_X86_64
283 SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx.skip_prologue,  32, 4, 0, 0
284 ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx.skip_prologue, 32, 4, 0, 0
285 SUB_NxN_DCT  x264_sub16x16_dct_mmx,  x264_sub8x8_dct_mmx.skip_prologue,  32, 8, 4, 4
286 ADD_NxN_IDCT x264_add16x16_idct_mmx, x264_add8x8_idct_mmx.skip_prologue, 32, 8, 4, 4
287
288 cextern x264_sub8x8_dct8_mmx.skip_prologue
289 cextern x264_add8x8_idct8_mmx.skip_prologue
290 SUB_NxN_DCT  x264_sub16x16_dct8_mmx,  x264_sub8x8_dct8_mmx.skip_prologue,  128, 8, 0, 0
291 ADD_NxN_IDCT x264_add16x16_idct8_mmx, x264_add8x8_idct8_mmx.skip_prologue, 128, 8, 0, 0
292 %endif
293
294 INIT_XMM
295
296 cextern x264_sub8x8_dct_sse2.skip_prologue
297 cextern x264_sub8x8_dct_ssse3.skip_prologue
298 SUB_NxN_DCT  x264_sub16x16_dct_sse2, x264_sub8x8_dct_sse2.skip_prologue, 128, 8, 0, 0
299 SUB_NxN_DCT  x264_sub16x16_dct_ssse3, x264_sub8x8_dct_ssse3.skip_prologue, 128, 8, 0, 0
300 cextern x264_add8x8_idct_sse2.skip_prologue
301 ADD_NxN_IDCT x264_add16x16_idct_sse2, x264_add8x8_idct_sse2.skip_prologue, 2*64, 8, 0, 0
302
303 cextern x264_sub8x8_dct8_sse2.skip_prologue
304 cextern x264_add8x8_idct8_sse2.skip_prologue
305 SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2.skip_prologue,  128, 8, 0, 0
306 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2.skip_prologue, 128, 8, 0, 0
307
308 cextern x264_sub8x8_dct8_ssse3.skip_prologue
309 SUB_NxN_DCT  x264_sub16x16_dct8_ssse3,  x264_sub8x8_dct8_ssse3.skip_prologue,  128, 8, 0, 0
310
311
312 ;-----------------------------------------------------------------------------
313 ; void add8x8_idct_dc( uint8_t *p_dst, int16_t *dct2x2 )
314 ;-----------------------------------------------------------------------------
315
316 %macro ADD_DC 3
317     movq      mm4, [%3+FDEC_STRIDE*0]
318     movq      mm5, [%3+FDEC_STRIDE*1]
319     movq      mm6, [%3+FDEC_STRIDE*2]
320     paddusb   mm4, %1
321     paddusb   mm5, %1
322     paddusb   mm6, %1
323     paddusb    %1, [%3+FDEC_STRIDE*3]
324     psubusb   mm4, %2
325     psubusb   mm5, %2
326     psubusb   mm6, %2
327     psubusb    %1, %2
328     movq      [%3+FDEC_STRIDE*0], mm4
329     movq      [%3+FDEC_STRIDE*1], mm5
330     movq      [%3+FDEC_STRIDE*2], mm6
331     movq      [%3+FDEC_STRIDE*3], %1
332 %endmacro
333
334 cglobal x264_add8x8_idct_dc_mmx, 2,2
335     movq      mm0, [r1]
336     pxor      mm1, mm1
337     add        r0, FDEC_STRIDE*4
338     paddw     mm0, [pw_32 GLOBAL]
339     psraw     mm0, 6
340     psubw     mm1, mm0
341     packuswb  mm0, mm0
342     packuswb  mm1, mm1
343     punpcklbw mm0, mm0
344     punpcklbw mm1, mm1
345     pshufw    mm2, mm0, 0xFA
346     pshufw    mm3, mm1, 0xFA
347     punpcklbw mm0, mm0
348     punpcklbw mm1, mm1
349     ADD_DC    mm0, mm1, r0-FDEC_STRIDE*4
350     ADD_DC    mm2, mm3, r0
351     RET
352
353 cglobal x264_add8x8_idct_dc_ssse3, 2,2
354     movq      xmm0, [r1]
355     pxor      xmm1, xmm1
356     add         r0, FDEC_STRIDE*4
357     paddw     xmm0, [pw_32 GLOBAL]
358     psraw     xmm0, 6
359     psubw     xmm1, xmm0
360     movdqa    xmm5, [pb_idctdc_unpack GLOBAL]
361     packuswb  xmm0, xmm0
362     packuswb  xmm1, xmm1
363     pshufb    xmm0, xmm5
364     pshufb    xmm1, xmm5
365     movq      xmm2, [r0+FDEC_STRIDE*-4]
366     movq      xmm3, [r0+FDEC_STRIDE*-3]
367     movq      xmm4, [r0+FDEC_STRIDE*-2]
368     movq      xmm5, [r0+FDEC_STRIDE*-1]
369     movhps    xmm2, [r0+FDEC_STRIDE* 0]
370     movhps    xmm3, [r0+FDEC_STRIDE* 1]
371     movhps    xmm4, [r0+FDEC_STRIDE* 2]
372     movhps    xmm5, [r0+FDEC_STRIDE* 3]
373     paddusb   xmm2, xmm0
374     paddusb   xmm3, xmm0
375     paddusb   xmm4, xmm0
376     paddusb   xmm5, xmm0
377     psubusb   xmm2, xmm1
378     psubusb   xmm3, xmm1
379     psubusb   xmm4, xmm1
380     psubusb   xmm5, xmm1
381     movq      [r0+FDEC_STRIDE*-4], xmm2
382     movq      [r0+FDEC_STRIDE*-3], xmm3
383     movq      [r0+FDEC_STRIDE*-2], xmm4
384     movq      [r0+FDEC_STRIDE*-1], xmm5
385     movhps    [r0+FDEC_STRIDE* 0], xmm2
386     movhps    [r0+FDEC_STRIDE* 1], xmm3
387     movhps    [r0+FDEC_STRIDE* 2], xmm4
388     movhps    [r0+FDEC_STRIDE* 3], xmm5
389     RET
390
391 cglobal x264_add16x16_idct_dc_mmx, 2,3
392     mov       r2, 4
393 .loop:
394     movq      mm0, [r1]
395     pxor      mm1, mm1
396     paddw     mm0, [pw_32 GLOBAL]
397     psraw     mm0, 6
398     psubw     mm1, mm0
399     packuswb  mm0, mm0
400     packuswb  mm1, mm1
401     punpcklbw mm0, mm0
402     punpcklbw mm1, mm1
403     pshufw    mm2, mm0, 0xFA
404     pshufw    mm3, mm1, 0xFA
405     punpcklbw mm0, mm0
406     punpcklbw mm1, mm1
407     ADD_DC    mm0, mm1, r0
408     ADD_DC    mm2, mm3, r0+8
409     add       r1, 8
410     add       r0, FDEC_STRIDE*4
411     dec       r2
412     jg .loop
413     REP_RET
414
415 %macro IDCT_DC_STORE 3
416     movdqa    xmm4, [r0+%1+FDEC_STRIDE*0]
417     movdqa    xmm5, [r0+%1+FDEC_STRIDE*1]
418     movdqa    xmm6, [r0+%1+FDEC_STRIDE*2]
419     movdqa    xmm7, [r0+%1+FDEC_STRIDE*3]
420     paddusb   xmm4, %2
421     paddusb   xmm5, %2
422     paddusb   xmm6, %2
423     paddusb   xmm7, %2
424     psubusb   xmm4, %3
425     psubusb   xmm5, %3
426     psubusb   xmm6, %3
427     psubusb   xmm7, %3
428     movdqa    [r0+%1+FDEC_STRIDE*0], xmm4
429     movdqa    [r0+%1+FDEC_STRIDE*1], xmm5
430     movdqa    [r0+%1+FDEC_STRIDE*2], xmm6
431     movdqa    [r0+%1+FDEC_STRIDE*3], xmm7
432 %endmacro
433
434 cglobal x264_add16x16_idct_dc_sse2, 2,2,8
435     call .loop
436     add       r0, FDEC_STRIDE*4
437 %ifdef WIN64
438     call .loop
439     RET
440 %endif
441 .loop:
442     add       r0, FDEC_STRIDE*4
443     movq      xmm0, [r1+0]
444     movq      xmm2, [r1+8]
445     add       r1, 16
446     punpcklwd xmm0, xmm0
447     punpcklwd xmm2, xmm2
448     pxor      xmm1, xmm1
449     pxor      xmm3, xmm3
450     paddw     xmm0, [pw_32 GLOBAL]
451     paddw     xmm2, [pw_32 GLOBAL]
452     psraw     xmm0, 6
453     psraw     xmm2, 6
454     psubw     xmm1, xmm0
455     psubw     xmm3, xmm2
456     packuswb  xmm0, xmm1
457     packuswb  xmm2, xmm3
458     movdqa    xmm1, xmm0
459     movdqa    xmm3, xmm2
460     punpcklbw xmm0, xmm0
461     punpcklbw xmm2, xmm2
462     punpckhbw xmm1, xmm1
463     punpckhbw xmm3, xmm3
464     IDCT_DC_STORE FDEC_STRIDE*-4, xmm0, xmm1
465     IDCT_DC_STORE 0, xmm2, xmm3
466     ret
467
468 cglobal x264_add16x16_idct_dc_ssse3, 2,2,8
469     call .loop
470     add       r0, FDEC_STRIDE*4
471 %ifdef WIN64
472     call .loop
473     RET
474 %endif
475 .loop:
476     add       r0, FDEC_STRIDE*4
477     movdqa    xmm0, [r1]
478     add       r1, 16
479     pxor      xmm1, xmm1
480     paddw     xmm0, [pw_32 GLOBAL]
481     psraw     xmm0, 6
482     psubw     xmm1, xmm0
483     movdqa    xmm5, [ pb_idctdc_unpack GLOBAL]
484     movdqa    xmm6, [pb_idctdc_unpack2 GLOBAL]
485     packuswb  xmm0, xmm0
486     packuswb  xmm1, xmm1
487     movdqa    xmm2, xmm0
488     movdqa    xmm3, xmm1
489     pshufb    xmm0, xmm5
490     pshufb    xmm2, xmm6
491     pshufb    xmm1, xmm5
492     pshufb    xmm3, xmm6
493     IDCT_DC_STORE FDEC_STRIDE*-4, xmm0, xmm1
494     IDCT_DC_STORE 0, xmm2, xmm3
495     ret
496
497 ;-----------------------------------------------------------------------------
498 ; void sub8x8_dct_dc( int16_t dct[2][2], uint8_t *pix1, uint8_t *pix2 )
499 ;-----------------------------------------------------------------------------
500
501 %macro DCTDC_2ROW_MMX 3
502     movq      %1, [r1+FENC_STRIDE*(0+%3)]
503     movq      m1, [r1+FENC_STRIDE*(1+%3)]
504     movq      m2, [r2+FDEC_STRIDE*(0+%3)]
505     movq      m3, [r2+FDEC_STRIDE*(1+%3)]
506     movq      %2, %1
507     punpckldq %1, m1
508     punpckhdq %2, m1
509     movq      m1, m2
510     punpckldq m2, m3
511     punpckhdq m1, m3
512     psadbw    %1, m7
513     psadbw    %2, m7
514     psadbw    m2, m7
515     psadbw    m1, m7
516     psubw     %1, m2
517     psubw     %2, m1
518 %endmacro
519
520 INIT_MMX
521 cglobal x264_sub8x8_dct_dc_mmxext, 3,3
522     pxor      m7, m7
523     call .loop
524     add       r1, FENC_STRIDE*4
525     add       r2, FDEC_STRIDE*4
526     add       r0, 4
527 .loop:
528     DCTDC_2ROW_MMX m0, m4, 0
529     DCTDC_2ROW_MMX m5, m6, 2
530     paddw     m0, m5
531     paddw     m4, m6
532     punpcklwd m0, m4
533     movd    [r0], m0
534     ret
535
536 INIT_XMM
537 %macro DCTDC_2ROW_SSE2 3
538     movq      m0, [r1+FENC_STRIDE*(0+%1)]
539     movq      m1, [r1+FENC_STRIDE*(1+%1)]
540     movq      m2, [r2+FDEC_STRIDE*(0+%1)]
541     movq      m3, [r2+FDEC_STRIDE*(1+%1)]
542     punpckldq m0, m1
543     punpckldq m2, m3
544     psadbw    m0, m7
545     psadbw    m2, m7
546 %if %2
547     paddw     %3, m0
548     paddw     m6, m2
549 %else
550     SWAP      %3, m0
551     SWAP      m6, m2
552 %endif
553 %endmacro
554
555 cglobal x264_sub8x8_dct_dc_sse2, 3,3,8
556     pxor     m7, m7
557     DCTDC_2ROW_SSE2 0, 0, m4
558     DCTDC_2ROW_SSE2 2, 1, m4
559     add      r1, FENC_STRIDE*4
560     add      r2, FDEC_STRIDE*4
561     psubq    m4, m6
562     DCTDC_2ROW_SSE2 0, 0, m5
563     DCTDC_2ROW_SSE2 2, 1, m5
564     psubq    m5, m6
565     packssdw m4, m5
566     packssdw m4, m4
567     movq   [r0], m4
568     RET
569
570 ;-----------------------------------------------------------------------------
571 ; void x264_zigzag_scan_8x8_frame_ssse3( int16_t level[64], int16_t dct[8][8] )
572 ;-----------------------------------------------------------------------------
573 %macro SCAN_8x8 1
574 cglobal x264_zigzag_scan_8x8_frame_%1, 2,2,8
575     movdqa    xmm0, [r1]
576     movdqa    xmm1, [r1+16]
577     movdq2q    mm0, xmm0
578     PALIGNR   xmm1, xmm1, 14, xmm2
579     movdq2q    mm1, xmm1
580
581     movdqa    xmm2, [r1+32]
582     movdqa    xmm3, [r1+48]
583     PALIGNR   xmm2, xmm2, 12, xmm4
584     movdq2q    mm2, xmm2
585     PALIGNR   xmm3, xmm3, 10, xmm4
586     movdq2q    mm3, xmm3
587
588     punpckhwd xmm0, xmm1
589     punpckhwd xmm2, xmm3
590
591     movq       mm4, mm1
592     movq       mm5, mm1
593     movq       mm6, mm2
594     movq       mm7, mm3
595     punpckhwd  mm1, mm0
596     psllq      mm0, 16
597     psrlq      mm3, 16
598     punpckhdq  mm1, mm1
599     punpckhdq  mm2, mm0
600     punpcklwd  mm0, mm4
601     punpckhwd  mm4, mm3
602     punpcklwd  mm4, mm2
603     punpckhdq  mm0, mm2
604     punpcklwd  mm6, mm3
605     punpcklwd  mm5, mm7
606     punpcklwd  mm5, mm6
607
608     movdqa    xmm4, [r1+64]
609     movdqa    xmm5, [r1+80]
610     movdqa    xmm6, [r1+96]
611     movdqa    xmm7, [r1+112]
612
613     movq [r0+2*00], mm0
614     movq [r0+2*04], mm4
615     movd [r0+2*08], mm1
616     movq [r0+2*36], mm5
617     movq [r0+2*46], mm6
618
619     PALIGNR   xmm4, xmm4, 14, xmm3
620     movdq2q    mm4, xmm4
621     PALIGNR   xmm5, xmm5, 12, xmm3
622     movdq2q    mm5, xmm5
623     PALIGNR   xmm6, xmm6, 10, xmm3
624     movdq2q    mm6, xmm6
625 %ifidn %1, ssse3
626     PALIGNR   xmm7, xmm7, 8, xmm3
627     movdq2q    mm7, xmm7
628 %else
629     movhlps   xmm3, xmm7
630     punpcklqdq xmm7, xmm7
631     movdq2q    mm7, xmm3
632 %endif
633
634     punpckhwd xmm4, xmm5
635     punpckhwd xmm6, xmm7
636
637     movq       mm0, mm4
638     movq       mm1, mm5
639     movq       mm3, mm7
640     punpcklwd  mm7, mm6
641     psrlq      mm6, 16
642     punpcklwd  mm4, mm6
643     punpcklwd  mm5, mm4
644     punpckhdq  mm4, mm3
645     punpcklwd  mm3, mm6
646     punpckhwd  mm3, mm4
647     punpckhwd  mm0, mm1
648     punpckldq  mm4, mm0
649     punpckhdq  mm0, mm6
650     pshufw     mm4, mm4, 0x6c
651
652     movq [r0+2*14], mm4
653     movq [r0+2*25], mm0
654     movd [r0+2*54], mm7
655     movq [r0+2*56], mm5
656     movq [r0+2*60], mm3
657
658     movdqa    xmm3, xmm0
659     movdqa    xmm7, xmm4
660     punpckldq xmm0, xmm2
661     punpckldq xmm4, xmm6
662     punpckhdq xmm3, xmm2
663     punpckhdq xmm7, xmm6
664     pshufhw   xmm0, xmm0, 0x1b
665     pshuflw   xmm4, xmm4, 0x1b
666     pshufhw   xmm3, xmm3, 0x1b
667     pshuflw   xmm7, xmm7, 0x1b
668
669     movlps [r0+2*10], xmm0
670     movhps [r0+2*17], xmm0
671     movlps [r0+2*21], xmm3
672     movlps [r0+2*28], xmm4
673     movhps [r0+2*32], xmm3
674     movhps [r0+2*39], xmm4
675     movlps [r0+2*43], xmm7
676     movhps [r0+2*50], xmm7
677
678     RET
679 %endmacro
680
681 INIT_XMM
682 %define PALIGNR PALIGNR_MMX
683 SCAN_8x8 sse2
684 %define PALIGNR PALIGNR_SSSE3
685 SCAN_8x8 ssse3
686
687 ;-----------------------------------------------------------------------------
688 ; void x264_zigzag_scan_8x8_frame_mmxext( int16_t level[64], int16_t dct[8][8] )
689 ;-----------------------------------------------------------------------------
690 cglobal x264_zigzag_scan_8x8_frame_mmxext, 2,2
691     movq       mm0, [r1]
692     movq       mm1, [r1+2*8]
693     movq       mm2, [r1+2*14]
694     movq       mm3, [r1+2*21]
695     movq       mm4, [r1+2*28]
696     movq       mm5, mm0
697     movq       mm6, mm1
698     psrlq      mm0, 16
699     punpckldq  mm1, mm1
700     punpcklwd  mm5, mm6
701     punpckhwd  mm1, mm3
702     punpckhwd  mm6, mm0
703     punpckldq  mm5, mm0
704     movq       mm7, [r1+2*52]
705     movq       mm0, [r1+2*60]
706     punpckhwd  mm1, mm2
707     punpcklwd  mm2, mm4
708     punpckhwd  mm4, mm3
709     punpckldq  mm3, mm3
710     punpckhwd  mm3, mm2
711     movq      [r0], mm5
712     movq  [r0+2*4], mm1
713     movq  [r0+2*8], mm6
714     punpcklwd  mm6, mm0
715     punpcklwd  mm6, mm7
716     movq       mm1, [r1+2*32]
717     movq       mm5, [r1+2*39]
718     movq       mm2, [r1+2*46]
719     movq [r0+2*35], mm3
720     movq [r0+2*47], mm4
721     punpckhwd  mm7, mm0
722     psllq      mm0, 16
723     movq       mm3, mm5
724     punpcklwd  mm5, mm1
725     punpckhwd  mm1, mm2
726     punpckhdq  mm3, mm3
727     movq [r0+2*52], mm6
728     movq [r0+2*13], mm5
729     movq       mm4, [r1+2*11]
730     movq       mm6, [r1+2*25]
731     punpcklwd  mm5, mm7
732     punpcklwd  mm1, mm3
733     punpckhdq  mm0, mm7
734     movq       mm3, [r1+2*4]
735     movq       mm7, [r1+2*18]
736     punpcklwd  mm2, mm5
737     movq [r0+2*25], mm1
738     movq       mm1, mm4
739     movq       mm5, mm6
740     punpcklwd  mm4, mm3
741     punpcklwd  mm6, mm7
742     punpckhwd  mm1, mm3
743     punpckhwd  mm5, mm7
744     movq       mm3, mm6
745     movq       mm7, mm5
746     punpckldq  mm6, mm4
747     punpckldq  mm5, mm1
748     punpckhdq  mm3, mm4
749     punpckhdq  mm7, mm1
750     movq       mm4, [r1+2*35]
751     movq       mm1, [r1+2*49]
752     pshufw     mm6, mm6, 0x1b
753     pshufw     mm5, mm5, 0x1b
754     movq [r0+2*60], mm0
755     movq [r0+2*56], mm2
756     movq       mm0, [r1+2*42]
757     movq       mm2, [r1+2*56]
758     movq [r0+2*17], mm3
759     movq [r0+2*32], mm7
760     movq [r0+2*10], mm6
761     movq [r0+2*21], mm5
762     movq       mm3, mm0
763     movq       mm7, mm2
764     punpcklwd  mm0, mm4
765     punpcklwd  mm2, mm1
766     punpckhwd  mm3, mm4
767     punpckhwd  mm7, mm1
768     movq       mm4, mm2
769     movq       mm1, mm7
770     punpckhdq  mm2, mm0
771     punpckhdq  mm7, mm3
772     punpckldq  mm4, mm0
773     punpckldq  mm1, mm3
774     pshufw     mm2, mm2, 0x1b
775     pshufw     mm7, mm7, 0x1b
776     movq [r0+2*28], mm4
777     movq [r0+2*43], mm1
778     movq [r0+2*39], mm2
779     movq [r0+2*50], mm7
780     RET
781
782 ;-----------------------------------------------------------------------------
783 ; void x264_zigzag_scan_4x4_frame_mmx( int16_t level[16], int16_t dct[4][4] )
784 ;-----------------------------------------------------------------------------
785 cglobal x264_zigzag_scan_4x4_frame_mmx, 2,2
786     movq       mm0, [r1]
787     movq       mm1, [r1+8]
788     movq       mm2, [r1+16]
789     movq       mm3, [r1+24]
790     movq       mm4, mm0
791     movq       mm5, mm1
792     movq       mm6, mm2
793     movq       mm7, mm3
794     psllq      mm3, 16
795     psrlq      mm0, 16
796     punpckldq  mm2, mm2
797     punpckhdq  mm1, mm1
798     punpcklwd  mm4, mm5
799     punpcklwd  mm5, mm3
800     punpckldq  mm4, mm0
801     punpckhwd  mm5, mm2
802     punpckhwd  mm0, mm6
803     punpckhwd  mm6, mm7
804     punpcklwd  mm1, mm0
805     punpckhdq  mm3, mm6
806     movq      [r0], mm4
807     movq    [r0+8], mm5
808     movq   [r0+16], mm1
809     movq   [r0+24], mm3
810     RET
811
812 ;-----------------------------------------------------------------------------
813 ; void x264_zigzag_scan_4x4_frame_ssse3( int16_t level[16], int16_t dct[4][4] )
814 ;-----------------------------------------------------------------------------
815 cglobal x264_zigzag_scan_4x4_frame_ssse3, 2,2
816     movdqa    xmm1, [r1+16]
817     movdqa    xmm0, [r1]
818     pshufb    xmm1, [pb_scan4frameb GLOBAL]
819     pshufb    xmm0, [pb_scan4framea GLOBAL]
820     movdqa    xmm2, xmm1
821     psrldq    xmm1, 6
822     palignr   xmm2, xmm0, 6
823     pslldq    xmm0, 10
824     palignr   xmm1, xmm0, 10
825     movdqa    [r0], xmm2
826     movdqa [r0+16], xmm1
827     RET
828
829 ;-----------------------------------------------------------------------------
830 ; void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] )
831 ;-----------------------------------------------------------------------------
832 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
833 cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
834     pshufw     mm0, [r1+4], 0xd2
835     movq       mm1, [r1+16]
836     movq       mm2, [r1+24]
837     movq    [r0+4], mm0
838     movq   [r0+16], mm1
839     movq   [r0+24], mm2
840     mov        r2d, [r1]
841     mov       [r0], r2d
842     mov        r2d, [r1+12]
843     mov    [r0+12], r2d
844     RET
845
846 ;-----------------------------------------------------------------------------
847 ; void x264_zigzag_scan_8x8_field_mmxext( int16_t level[64], int16_t dct[8][8] )
848 ;-----------------------------------------------------------------------------
849
850 ; Output order:
851 ;  0  1  2  8  9  3  4 10
852 ; 16 11  5  6  7 12 17 24
853 ; 18 13 14 15 19 25 32 26
854 ; 20 21 22 23 27 33 40 34
855 ; 28 29 30 31 35 41 48 42
856 ; 36 37 38 39 43 49 50 44
857 ; 45 46 47 51 56 57 52 53
858 ; 54 55 58 59 60 61 62 63
859
860 cglobal x264_zigzag_scan_8x8_field_mmxext, 2,3
861     movq       mm0, [r1+2*0]        ; 03 02 01 00
862     movq       mm1, [r1+2*4]        ; 07 06 05 04
863     movq       mm2, [r1+2*8]        ; 11 10 09 08
864     pshufw     mm3, mm0, 011111111b ; 03 03 03 03
865     movd        r2, mm2             ; 09 08
866     pshufw     mm2, mm2, 000111001b ; 08 11 10 09
867     punpcklwd  mm3, mm1             ; 05 03 04 03
868     pinsrw     mm0, r2, 3           ; 08 02 01 00
869     movq       mm4, mm2
870     punpcklwd  mm2, mm3             ; 04 10 03 09
871     pshufw     mm2, mm2, 010110100b ; 10 04 03 09
872     movq  [r0+2*0], mm0             ; 08 02 01 00
873     movq  [r0+2*4], mm2             ; 10 04 03 09
874     movq       mm3, [r1+2*12]       ; 15 14 13 12
875     movq       mm5, [r1+2*16]       ; 19 18 17 16
876     punpckldq  mm6, mm5             ; 17 16 XX XX
877     psrlq      mm1, 16              ; XX 07 06 05
878     punpckhwd  mm6, mm4             ; 08 17 11 16
879     punpckldq  mm6, mm1             ; 06 05 11 16
880     movq  [r0+2*8], mm6             ; 06 05 11 16
881     psrlq      mm1, 16              ; XX XX 07 06
882     punpcklwd  mm1, mm5             ; 17 07 16 06
883     movq       mm0, [r1+2*20]       ; 23 22 21 20
884     movq       mm2, [r1+2*24]       ; 27 26 25 24
885     movq       mm6, mm3
886     punpckhdq  mm1, mm1             ; 17 07 17 07
887     punpcklwd  mm6, mm2             ; 25 13 24 12
888     pextrw      r2, mm5, 2
889     movq [r0+2*24], mm0             ; 23 22 21 20
890     punpcklwd  mm1, mm6             ; 24 17 12 07
891     movq [r0+2*12], mm1
892     pinsrw     mm3, r2, 0           ; 15 14 13 18
893     movq [r0+2*16], mm3             ; 15 14 13 18
894     movq       mm7, [r1+2*28]
895     movq       mm0, [r1+2*32]       ; 35 34 33 32
896     psrlq      mm5, 48              ; XX XX XX 19
897     pshufw     mm1, mm2, 011111001b ; 27 27 26 25
898     punpcklwd  mm5, mm0             ; 33 XX 32 19
899     psrlq      mm2, 48              ; XX XX XX 27
900     punpcklwd  mm5, mm1             ; 26 32 25 19
901     movq [r0+2*32], mm7
902     movq [r0+2*20], mm5             ; 26 32 25 19
903     movq       mm7, [r1+2*36]
904     movq       mm1, [r1+2*40]       ; 43 42 41 40
905     pshufw     mm3, mm0, 011111001b ; 35 35 34 33
906     punpcklwd  mm2, mm1             ; 41 XX 40 27
907     movq [r0+2*40], mm7
908     punpcklwd  mm2, mm3             ; 34 40 33 27
909     movq [r0+2*28], mm2
910     movq       mm7, [r1+2*44]       ; 47 46 45 44
911     movq       mm2, [r1+2*48]       ; 51 50 49 48
912     psrlq      mm0, 48              ; XX XX XX 35
913     punpcklwd  mm0, mm2             ; 49 XX 48 35
914     pshufw     mm3, mm1, 011111001b ; 43 43 42 41
915     punpcklwd  mm0, mm3             ; 42 48 41 35
916     movq [r0+2*36], mm0
917     pextrw      r2, mm2, 3          ; 51
918     psrlq      mm1, 48              ; XX XX XX 43
919     punpcklwd  mm1, mm7             ; 45 XX 44 43
920     psrlq      mm2, 16              ; XX 51 50 49
921     punpcklwd  mm1, mm2             ; 50 44 49 43
922     pshufw     mm1, mm1, 010110100b ; 44 50 49 43
923     movq [r0+2*44], mm1
924     psrlq      mm7, 16              ; XX 47 46 45
925     pinsrw     mm7, r2, 3           ; 51 47 46 45
926     movq [r0+2*48], mm7
927     movq       mm0, [r1+2*56]       ; 59 58 57 56
928     movq       mm1, [r1+2*52]       ; 55 54 53 52
929     movq       mm2, mm0
930     movq       mm7, [r1+2*60]
931     punpckldq  mm2, mm1             ; 53 52 57 56
932     punpckhdq  mm1, mm0             ; 59 58 55 54
933     movq [r0+2*52], mm2
934     movq [r0+2*56], mm1
935     movq [r0+2*60], mm7
936     RET
937
938 ;-----------------------------------------------------------------------------
939 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
940 ;-----------------------------------------------------------------------------
941 %macro ZIGZAG_SUB_4x4 2
942 %ifidn %1, ac
943 cglobal x264_zigzag_sub_4x4%1_%2_ssse3, 4,4,8
944 %else
945 cglobal x264_zigzag_sub_4x4%1_%2_ssse3, 3,3,8
946 %endif
947     movd      xmm0, [r1+0*FENC_STRIDE]
948     movd      xmm1, [r1+1*FENC_STRIDE]
949     movd      xmm2, [r1+2*FENC_STRIDE]
950     movd      xmm3, [r1+3*FENC_STRIDE]
951     movd      xmm4, [r2+0*FDEC_STRIDE]
952     movd      xmm5, [r2+1*FDEC_STRIDE]
953     movd      xmm6, [r2+2*FDEC_STRIDE]
954     movd      xmm7, [r2+3*FDEC_STRIDE]
955     movd      [r2+0*FDEC_STRIDE], xmm0
956     movd      [r2+1*FDEC_STRIDE], xmm1
957     movd      [r2+2*FDEC_STRIDE], xmm2
958     movd      [r2+3*FDEC_STRIDE], xmm3
959     punpckldq xmm0, xmm1
960     punpckldq xmm2, xmm3
961     punpckldq xmm4, xmm5
962     punpckldq xmm6, xmm7
963     punpcklqdq xmm0, xmm2
964     punpcklqdq xmm4, xmm6
965 %ifidn %2, frame
966     movdqa    xmm7, [pb_sub4frame GLOBAL]
967 %else
968     movdqa    xmm7, [pb_sub4field GLOBAL]
969 %endif
970     pshufb    xmm0, xmm7
971     pshufb    xmm4, xmm7
972     pxor      xmm6, xmm6
973     movdqa    xmm1, xmm0
974     movdqa    xmm5, xmm4
975     punpcklbw xmm0, xmm6
976     punpckhbw xmm1, xmm6
977     punpcklbw xmm4, xmm6
978     punpckhbw xmm5, xmm6
979     psubw     xmm0, xmm4
980     psubw     xmm1, xmm5
981 %ifidn %1, ac
982     movd       r2d, xmm0
983     pand      xmm0, [pb_subacmask GLOBAL]
984 %endif
985     movdqa    [r0], xmm0
986     pxor      xmm2, xmm2
987     movdqa [r0+16], xmm1
988     por       xmm0, xmm1
989     pcmpeqb   xmm0, xmm2
990     pmovmskb   eax, xmm0
991 %ifidn %1, ac
992     mov       [r3], r2w
993 %endif
994     sub        eax, 0xffff
995     shr        eax, 31
996     RET
997 %endmacro
998
999 ZIGZAG_SUB_4x4   , frame
1000 ZIGZAG_SUB_4x4 ac, frame
1001 ZIGZAG_SUB_4x4   , field
1002 ZIGZAG_SUB_4x4 ac, field
1003
1004 ;-----------------------------------------------------------------------------
1005 ; void x264_zigzag_interleave_8x8_cavlc_mmx( int16_t *dst, int16_t *src, uint8_t *nnz )
1006 ;-----------------------------------------------------------------------------
1007
1008 %macro INTERLEAVE 1
1009     movq   m0, [r1+%1*4+ 0]
1010     movq   m1, [r1+%1*4+ 8]
1011     movq   m2, [r1+%1*4+16]
1012     movq   m3, [r1+%1*4+24]
1013     TRANSPOSE4x4W 0,1,2,3,4
1014     movq   [r0+%1+ 0], m0
1015     movq   [r0+%1+32], m1
1016     movq   [r0+%1+64], m2
1017     movq   [r0+%1+96], m3
1018 %if %1
1019     packsswb m0, m1
1020     por    m6, m2
1021     por    m7, m3
1022     por    m5, m0
1023 %else
1024     packsswb m0, m1
1025     SWAP   m5, m0
1026     SWAP   m6, m2
1027     SWAP   m7, m3
1028 %endif
1029 %endmacro
1030
1031 INIT_MMX
1032 cglobal x264_zigzag_interleave_8x8_cavlc_mmx, 3,3
1033     INTERLEAVE  0
1034     INTERLEAVE  8
1035     INTERLEAVE 16
1036     INTERLEAVE 24
1037     packsswb m6, m7
1038     packsswb m5, m6
1039     packsswb m5, m5
1040     pxor     m0, m0
1041     pcmpeqb  m5, m0
1042     paddb    m5, [pb_1 GLOBAL]
1043     movd    r0d, m5
1044     mov  [r2+0], r0w
1045     shr     r0d, 16
1046     mov  [r2+8], r0w
1047     RET
1048
1049 %macro INTERLEAVE_XMM 1
1050     mova   m0, [r1+%1*4+ 0]
1051     mova   m1, [r1+%1*4+16]
1052     mova   m4, [r1+%1*4+32]
1053     mova   m5, [r1+%1*4+48]
1054     SBUTTERFLY wd, 0, 1, 6
1055     SBUTTERFLY wd, 4, 5, 7
1056     SBUTTERFLY wd, 0, 1, 6
1057     SBUTTERFLY wd, 4, 5, 7
1058     movq   [r0+%1+  0], m0
1059     movhps [r0+%1+ 32], m0
1060     movq   [r0+%1+ 64], m1
1061     movhps [r0+%1+ 96], m1
1062     movq   [r0+%1+  8], m4
1063     movhps [r0+%1+ 40], m4
1064     movq   [r0+%1+ 72], m5
1065     movhps [r0+%1+104], m5
1066 %if %1
1067     por    m2, m0
1068     por    m3, m1
1069     por    m2, m4
1070     por    m3, m5
1071 %else
1072     SWAP 0,2
1073     SWAP 3,1
1074     por    m2, m4
1075     por    m3, m5
1076 %endif
1077 %endmacro
1078
1079 INIT_XMM
1080 cglobal x264_zigzag_interleave_8x8_cavlc_sse2, 3,3,8
1081     INTERLEAVE_XMM  0
1082     INTERLEAVE_XMM 16
1083     packsswb m2, m3
1084     pxor     m5, m5
1085     packsswb m2, m2
1086     packsswb m2, m2
1087     pcmpeqb  m5, m2
1088     paddb    m5, [pb_1 GLOBAL]
1089     movd    r0d, m5
1090     mov  [r2+0], r0w
1091     shr     r0d, 16
1092     mov  [r2+8], r0w
1093     RET
1094