]> git.sesse.net Git - x264/blob - common/x86/dct-32.asm
remove x264_mc_clip1.
[x264] / common / x86 / dct-32.asm
1 ;*****************************************************************************
2 ;* dct-32.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2008 x264 project
5 ;*
6 ;* Authors: Laurent Aimar <fenrir@via.ecp.fr> (initial version)
7 ;*          Min Chen <chenm001.163.com> (converted to nasm)
8 ;*          Christian Heine <sennindemokrit@gmx.net> (dct8/idct8 functions)
9 ;*          Loren Merritt <lorenm@u.washington.edu> (misc)
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24 ;*****************************************************************************
25
26 %include "x86inc.asm"
27
28 SECTION_RODATA
29
30 pw_32: times 8 dw 32
31
32 SECTION .text
33
34 %macro SUMSUB_BA 2
35     paddw   %1, %2
36     paddw   %2, %2
37     psubw   %2, %1
38 %endmacro
39
40 %macro SUMSUB_BADC 4
41     paddw   %1, %2
42     paddw   %3, %4
43     paddw   %2, %2
44     paddw   %4, %4
45     psubw   %2, %1
46     psubw   %4, %3
47 %endmacro
48
49 %macro SBUTTERFLY 5
50     mov%1     %5, %3
51     punpckl%2 %3, %4
52     punpckh%2 %5, %4
53 %endmacro
54
55 ; input ABCD output ADTC
56 %macro TRANSPOSE4x4W 5
57     SBUTTERFLY q, wd, %1, %2, %5
58     SBUTTERFLY q, wd, %3, %4, %2
59     SBUTTERFLY q, dq, %1, %3, %4
60     SBUTTERFLY q, dq, %5, %2, %3
61 %endmacro
62
63 ; input 2x8 unsigned bytes (%5,%6), zero (%7) output: difference (%1,%2)
64 %macro LOAD_DIFF_8P 7
65     movq       %1, %5
66     movq       %2, %1
67     punpcklbw  %1, %7
68     punpckhbw  %2, %7
69     movq       %3, %6
70     movq       %4, %3
71     punpcklbw  %3, %7
72     punpckhbw  %4, %7
73     psubw      %1, %3
74     psubw      %2, %4
75 %endmacro
76  
77 %macro LOADSUMSUB 4     ; returns %1=%3+%4, %2=%3-%4
78     movq       %2, %3
79     movq       %1, %4
80     SUMSUB_BA  %1, %2
81 %endmacro
82
83 %macro STORE_DIFF_8P 4
84     psraw      %1, 6
85     movq       %3, %2
86     punpcklbw  %3, %4
87     paddsw     %1, %3
88     packuswb   %1, %1
89     movq       %2, %1
90 %endmacro
91
92
93 ;-----------------------------------------------------------------------------
94 ; void x264_pixel_sub_8x8_mmx( int16_t *diff, uint8_t *pix1, uint8_t *pix2 );
95 ;-----------------------------------------------------------------------------
96 ALIGN 16
97 x264_pixel_sub_8x8_mmx:
98     pxor mm7, mm7
99     %assign i 0
100     %rep  8
101     LOAD_DIFF_8P mm0, mm1, mm2, mm3, [r1], [r2], mm7
102     movq  [r0+i], mm0
103     movq  [r0+i+8], mm1
104     add   r1, FENC_STRIDE
105     add   r2, FDEC_STRIDE
106     %assign i i+16
107     %endrep
108     ret
109
110 ;-----------------------------------------------------------------------------
111 ; void x264_ydct8_mmx( int16_t dest[8][8] );
112 ;-----------------------------------------------------------------------------
113 ALIGN 16
114 x264_ydct8_mmx:
115     ;-------------------------------------------------------------------------
116     ; vertical dct ( compute 4 columns at a time -> 2 loops )
117     ;-------------------------------------------------------------------------
118     %assign i 0
119     %rep 2
120     
121     LOADSUMSUB  mm2, mm3, [r0+i+0*16], [r0+i+7*16] ; mm2 = s07, mm3 = d07
122     LOADSUMSUB  mm1, mm5, [r0+i+1*16], [r0+i+6*16] ; mm1 = s16, mm5 = d16
123     LOADSUMSUB  mm0, mm6, [r0+i+2*16], [r0+i+5*16] ; mm0 = s25, mm6 = d25
124     LOADSUMSUB  mm4, mm7, [r0+i+3*16], [r0+i+4*16] ; mm4 = s34, mm7 = d34
125
126     SUMSUB_BA   mm4, mm2        ; mm4 = a0, mm2 = a2
127     SUMSUB_BA   mm0, mm1        ; mm0 = a1, mm1 = a3
128     SUMSUB_BA   mm0, mm4        ; mm0 = dst0, mm1 = dst4
129
130     movq    [r0+i+0*16], mm0
131     movq    [r0+i+4*16], mm4
132
133     movq    mm0, mm1         ; a3
134     psraw   mm0, 1           ; a3>>1
135     paddw   mm0, mm2         ; a2 + (a3>>1)
136     psraw   mm2, 1           ; a2>>1
137     psubw   mm2, mm1         ; (a2>>1) - a3
138
139     movq    [r0+i+2*16], mm0
140     movq    [r0+i+6*16], mm2
141
142     movq    mm0, mm6
143     psraw   mm0, 1
144     paddw   mm0, mm6         ; d25+(d25>>1)
145     movq    mm1, mm3
146     psubw   mm1, mm7         ; a5 = d07-d34-(d25+(d25>>1))
147     psubw   mm1, mm0
148
149     movq    mm0, mm5
150     psraw   mm0, 1
151     paddw   mm0, mm5         ; d16+(d16>>1)
152     movq    mm2, mm3
153     paddw   mm2, mm7         ; a6 = d07+d34-(d16+(d16>>1))
154     psubw   mm2, mm0
155
156     movq    mm0, mm3
157     psraw   mm0, 1
158     paddw   mm0, mm3         ; d07+(d07>>1)
159     paddw   mm0, mm5
160     paddw   mm0, mm6         ; a4 = d16+d25+(d07+(d07>>1))
161
162     movq    mm3, mm7
163     psraw   mm3, 1
164     paddw   mm3, mm7         ; d34+(d34>>1)
165     paddw   mm3, mm5
166     psubw   mm3, mm6         ; a7 = d16-d25+(d34+(d34>>1))
167
168     movq    mm7, mm3
169     psraw   mm7, 2
170     paddw   mm7, mm0         ; a4 + (a7>>2)
171
172     movq    mm6, mm2
173     psraw   mm6, 2
174     paddw   mm6, mm1         ; a5 + (a6>>2)
175
176     psraw   mm0, 2
177     psraw   mm1, 2
178     psubw   mm0, mm3         ; (a4>>2) - a7
179     psubw   mm2, mm1         ; a6 - (a5>>2)
180
181     movq    [r0+i+1*16], mm7
182     movq    [r0+i+3*16], mm6
183     movq    [r0+i+5*16], mm2
184     movq    [r0+i+7*16], mm0
185
186     %assign i i+8
187     %endrep
188     ret
189
190 ;-----------------------------------------------------------------------------
191 ; void x264_yidct8_mmx( int16_t dest[8][8] );
192 ;-----------------------------------------------------------------------------
193 ALIGN 16
194 x264_yidct8_mmx:
195     ;-------------------------------------------------------------------------
196     ; vertical idct ( compute 4 columns at a time -> 2 loops )
197     ;-------------------------------------------------------------------------
198     %assign i 0
199     %rep 2
200
201     movq        mm1, [r0+i+1*16]        ; mm1 = d1
202     movq        mm3, [r0+i+3*16]        ; mm3 = d3
203     movq        mm5, [r0+i+5*16]        ; mm5 = d5
204     movq        mm7, [r0+i+7*16]        ; mm7 = d7
205
206     movq        mm4, mm7
207     psraw       mm4, 1
208     movq        mm0, mm5
209     psubw       mm0, mm7
210     psubw       mm0, mm4
211     psubw       mm0, mm3                ; mm0 = e1
212
213     movq        mm6, mm3
214     psraw       mm6, 1
215     movq        mm2, mm7
216     psubw       mm2, mm6
217     psubw       mm2, mm3
218     paddw       mm2, mm1                ; mm2 = e3
219
220     movq        mm4, mm5
221     psraw       mm4, 1
222     paddw       mm4, mm5
223     paddw       mm4, mm7
224     psubw       mm4, mm1                ; mm4 = e5
225
226     movq        mm6, mm1
227     psraw       mm6, 1
228     paddw       mm6, mm1
229     paddw       mm6, mm5
230     paddw       mm6, mm3                ; mm6 = e7
231
232     movq        mm1, mm0
233     movq        mm3, mm4
234     movq        mm5, mm2
235     movq        mm7, mm6
236     psraw       mm6, 2
237     psraw       mm3, 2
238     psraw       mm5, 2
239     psraw       mm0, 2
240     paddw       mm1, mm6                ; mm1 = f1
241     paddw       mm3, mm2                ; mm3 = f3
242     psubw       mm5, mm4                ; mm5 = f5
243     psubw       mm7, mm0                ; mm7 = f7
244
245     movq        mm2, [r0+i+2*16]        ; mm2 = d2
246     movq        mm6, [r0+i+6*16]        ; mm6 = d6
247     movq        mm4, mm2
248     movq        mm0, mm6
249     psraw       mm4, 1
250     psraw       mm6, 1
251     psubw       mm4, mm0                ; mm4 = a4
252     paddw       mm6, mm2                ; mm6 = a6
253
254     movq        mm2, [r0+i+0*16]        ; mm2 = d0
255     movq        mm0, [r0+i+4*16]        ; mm0 = d4
256     SUMSUB_BA   mm0, mm2                ; mm0 = a0, mm2 = a2
257
258     SUMSUB_BADC mm6, mm0, mm4, mm2      ; mm6 = f0, mm0 = f6
259                                         ; mm4 = f2, mm2 = f4
260
261     SUMSUB_BADC mm7, mm6, mm5, mm4      ; mm7 = g0, mm6 = g7
262                                         ; mm5 = g1, mm4 = g6
263     SUMSUB_BADC mm3, mm2, mm1, mm0      ; mm3 = g2, mm2 = g5
264                                         ; mm1 = g3, mm0 = g4
265
266     movq        [r0+i+0*16], mm7
267     movq        [r0+i+1*16], mm5
268     movq        [r0+i+2*16], mm3
269     movq        [r0+i+3*16], mm1
270     movq        [r0+i+4*16], mm0
271     movq        [r0+i+5*16], mm2
272     movq        [r0+i+6*16], mm4
273     movq        [r0+i+7*16], mm6
274
275     %assign i i+8
276     %endrep
277     ret
278
279 ;-----------------------------------------------------------------------------
280 ; void x264_pixel_add_8x8_mmx( uint8_t *dst, int16_t src[8][8] );
281 ;-----------------------------------------------------------------------------
282 ALIGN 16
283 x264_pixel_add_8x8_mmx:
284     pxor mm7, mm7
285     %assign i 0
286     %rep 8
287     movq        mm0, [r0]
288     movq        mm2, [r1+i]
289     movq        mm3, [r1+i+8]
290     movq        mm1, mm0
291     psraw       mm2, 6
292     psraw       mm3, 6
293     punpcklbw   mm0, mm7
294     punpckhbw   mm1, mm7
295     paddw       mm0, mm2
296     paddw       mm1, mm3
297     packuswb    mm0, mm1
298     movq       [r0], mm0
299     add          r0, FDEC_STRIDE
300     %assign i i+16
301     %endrep
302     ret
303
304 ;-----------------------------------------------------------------------------
305 ; void x264_transpose_8x8_mmx( int16_t src[8][8] );
306 ;-----------------------------------------------------------------------------
307 ALIGN 16
308 x264_transpose_8x8_mmx:
309     movq  mm0, [r0    ]
310     movq  mm1, [r0+ 16]
311     movq  mm2, [r0+ 32]
312     movq  mm3, [r0+ 48]
313     TRANSPOSE4x4W  mm0, mm1, mm2, mm3, mm4
314     movq  [r0    ], mm0
315     movq  [r0+ 16], mm3
316     movq  [r0+ 32], mm4
317     movq  [r0+ 48], mm2
318
319     movq  mm0, [r0+ 72]
320     movq  mm1, [r0+ 88]
321     movq  mm2, [r0+104]
322     movq  mm3, [r0+120]
323     TRANSPOSE4x4W  mm0, mm1, mm2, mm3, mm4
324     movq  [r0+ 72], mm0
325     movq  [r0+ 88], mm3
326     movq  [r0+104], mm4
327     movq  [r0+120], mm2
328
329     movq  mm0, [r0+  8]
330     movq  mm1, [r0+ 24]
331     movq  mm2, [r0+ 40]
332     movq  mm3, [r0+ 56]
333     TRANSPOSE4x4W  mm0, mm1, mm2, mm3, mm4
334     movq  mm1, [r0+ 64]
335     movq  mm5, [r0+ 80]
336     movq  mm6, [r0+ 96]
337     movq  mm7, [r0+112]
338
339     movq  [r0+ 64], mm0
340     movq  [r0+ 80], mm3
341     movq  [r0+ 96], mm4
342     movq  [r0+112], mm2
343     TRANSPOSE4x4W  mm1, mm5, mm6, mm7, mm4
344     movq  [r0+  8], mm1
345     movq  [r0+ 24], mm7
346     movq  [r0+ 40], mm4
347     movq  [r0+ 56], mm6
348     ret
349
350 ;-----------------------------------------------------------------------------
351 ; void x264_sub8x8_dct8_mmx( int16_t dct[8][8], uint8_t *pix1, uint8_t *pix2 )
352 ;-----------------------------------------------------------------------------
353 cglobal x264_sub8x8_dct8_mmx, 3,3
354     call x264_pixel_sub_8x8_mmx
355     call x264_ydct8_mmx
356     call x264_transpose_8x8_mmx
357     jmp  x264_ydct8_mmx
358
359 ;-----------------------------------------------------------------------------
360 ; void x264_add8x8_idct8_mmx( uint8_t *dst, int16_t dct[8][8] )
361 ;-----------------------------------------------------------------------------
362 cglobal x264_add8x8_idct8_mmx, 0,1
363     mov  r0, r1m
364     add  word [r0], 32
365     call x264_yidct8_mmx
366     call x264_transpose_8x8_mmx
367     call x264_yidct8_mmx
368     mov  r1, r0
369     mov  r0, r0m
370     jmp  x264_pixel_add_8x8_mmx
371
372 %macro IDCT8_1D 8
373     movdqa     %1, %3
374     movdqa     %5, %7
375     psraw      %3, 1
376     psraw      %7, 1
377     psubw      %3, %5
378     paddw      %7, %1
379     movdqa     %5, %2
380     psraw      %5, 1
381     paddw      %5, %2
382     paddw      %5, %4
383     paddw      %5, %6
384     movdqa     %1, %6
385     psraw      %1, 1
386     paddw      %1, %6
387     paddw      %1, %8
388     psubw      %1, %2
389     psubw      %2, %4
390     psubw      %6, %4
391     paddw      %2, %8
392     psubw      %6, %8
393     psraw      %4, 1
394     psraw      %8, 1
395     psubw      %2, %4
396     psubw      %6, %8
397     movdqa     %4, %5
398     movdqa     %8, %1
399     psraw      %4, 2
400     psraw      %8, 2
401     paddw      %4, %6
402     paddw      %8, %2
403     psraw      %6, 2
404     psraw      %2, 2
405     psubw      %5, %6
406     psubw      %2, %1
407     movdqa     %1, [eax+0x00]
408     movdqa     %6, [eax+0x40]
409     SUMSUB_BA  %6, %1
410     SUMSUB_BA  %7, %6
411     SUMSUB_BA  %3, %1
412     SUMSUB_BA  %5, %7
413     SUMSUB_BA  %2, %3
414     SUMSUB_BA  %8, %1
415     SUMSUB_BA  %4, %6
416 %endmacro
417
418 %macro TRANSPOSE8 9
419     movdqa [%9], %8
420     SBUTTERFLY dqa, wd, %1, %2, %8
421     movdqa [%9+16], %8
422     movdqa %8, [%9]
423     SBUTTERFLY dqa, wd, %3, %4, %2
424     SBUTTERFLY dqa, wd, %5, %6, %4
425     SBUTTERFLY dqa, wd, %7, %8, %6
426     SBUTTERFLY dqa, dq, %1, %3, %8
427     movdqa [%9], %8
428     movdqa %8, [16+%9]
429     SBUTTERFLY dqa, dq, %8, %2, %3
430     SBUTTERFLY dqa, dq, %5, %7, %2
431     SBUTTERFLY dqa, dq, %4, %6, %7
432     SBUTTERFLY dqa, qdq, %1, %5, %6
433     SBUTTERFLY dqa, qdq, %8, %4, %5
434     movdqa [%9+16], %8
435     movdqa %8, [%9]
436     SBUTTERFLY dqa, qdq, %8, %2, %4
437     SBUTTERFLY dqa, qdq, %3, %7, %2
438     movdqa %7, [%9+16]
439 %endmacro
440
441 ;-----------------------------------------------------------------------------
442 ; void x264_add8x8_idct8_sse2( uint8_t *p_dst, int16_t dct[8][8] )
443 ;-----------------------------------------------------------------------------
444 cglobal x264_add8x8_idct8_sse2
445     mov ecx, [esp+4]
446     mov eax, [esp+8]
447     movdqa     xmm1, [eax+0x10]
448     movdqa     xmm2, [eax+0x20]
449     movdqa     xmm3, [eax+0x30]
450     movdqa     xmm5, [eax+0x50]
451     movdqa     xmm6, [eax+0x60]
452     movdqa     xmm7, [eax+0x70]
453     IDCT8_1D   xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
454     TRANSPOSE8 xmm4, xmm1, xmm7, xmm3, xmm5, xmm0, xmm2, xmm6, eax
455     picgetgot  edx
456     paddw      xmm4, [pw_32 GLOBAL]
457     movdqa     [eax+0x00], xmm4
458     movdqa     [eax+0x40], xmm2
459     IDCT8_1D   xmm4, xmm0, xmm6, xmm3, xmm2, xmm5, xmm7, xmm1
460     movdqa     [eax+0x60], xmm6
461     movdqa     [eax+0x70], xmm7
462     pxor       xmm7, xmm7
463     STORE_DIFF_8P xmm2, [ecx+FDEC_STRIDE*0], xmm6, xmm7
464     STORE_DIFF_8P xmm0, [ecx+FDEC_STRIDE*1], xmm6, xmm7
465     STORE_DIFF_8P xmm1, [ecx+FDEC_STRIDE*2], xmm6, xmm7
466     STORE_DIFF_8P xmm3, [ecx+FDEC_STRIDE*3], xmm6, xmm7
467     STORE_DIFF_8P xmm5, [ecx+FDEC_STRIDE*4], xmm6, xmm7
468     STORE_DIFF_8P xmm4, [ecx+FDEC_STRIDE*5], xmm6, xmm7
469     movdqa     xmm0, [eax+0x60]
470     movdqa     xmm1, [eax+0x70]
471     STORE_DIFF_8P xmm0, [ecx+FDEC_STRIDE*6], xmm6, xmm7
472     STORE_DIFF_8P xmm1, [ecx+FDEC_STRIDE*7], xmm6, xmm7
473     ret
474
475 ;-----------------------------------------------------------------------------
476 ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
477 ;-----------------------------------------------------------------------------
478 %macro SUB_NxN_DCT 4
479 cglobal %1
480     mov  edx, [esp+12]
481     mov  ecx, [esp+ 8]
482     mov  eax, [esp+ 4]
483     add  edx, %4
484     add  ecx, %4
485     add  eax, %3
486     push edx
487     push ecx
488     push eax
489     call %2
490     add  dword [esp+0], %3
491     add  dword [esp+4], %4*FENC_STRIDE-%4
492     add  dword [esp+8], %4*FDEC_STRIDE-%4
493     call %2
494     add  dword [esp+0], %3
495     add  dword [esp+4], %4
496     add  dword [esp+8], %4
497     call %2
498     add  esp, 12
499     jmp  %2
500 %endmacro
501
502 ;-----------------------------------------------------------------------------
503 ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
504 ;-----------------------------------------------------------------------------
505 %macro ADD_NxN_IDCT 4
506 cglobal %1
507     mov  ecx, [esp+8]
508     mov  eax, [esp+4]
509     add  ecx, %3
510     add  eax, %4
511     push ecx
512     push eax
513     call %2
514     add  dword [esp+0], %4*FDEC_STRIDE-%4
515     add  dword [esp+4], %3
516     call %2
517     add  dword [esp+0], %4
518     add  dword [esp+4], %3
519     call %2
520     add  esp, 8
521     jmp  %2
522 %endmacro
523
524 SUB_NxN_DCT  x264_sub16x16_dct8_mmx,  x264_sub8x8_dct8_mmx,  128, 8
525 ADD_NxN_IDCT x264_add16x16_idct8_mmx, x264_add8x8_idct8_mmx, 128, 8
526
527 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2, 128, 8
528
529 ;-----------------------------------------------------------------------------
530 ; void x264_zigzag_scan_4x4_field_mmx( int level[16], int16_t dct[4][4] )
531 ;-----------------------------------------------------------------------------
532 cglobal x264_zigzag_scan_4x4_field_mmx
533     mov       edx, [esp+8]
534     mov       ecx, [esp+4]
535     punpcklwd mm0, [edx]
536     punpckhwd mm1, [edx]
537     punpcklwd mm2, [edx+8]
538     punpckhwd mm3, [edx+8]
539     punpcklwd mm4, [edx+16]
540     punpckhwd mm5, [edx+16]
541     punpcklwd mm6, [edx+24]
542     punpckhwd mm7, [edx+24]
543     psrad     mm0, 16
544     psrad     mm1, 16
545     psrad     mm2, 16
546     psrad     mm3, 16
547     psrad     mm4, 16
548     psrad     mm5, 16
549     psrad     mm6, 16
550     psrad     mm7, 16
551     movq      [ecx   ], mm0
552     movq      [ecx+16], mm2
553     movq      [ecx+24], mm3
554     movq      [ecx+32], mm4
555     movq      [ecx+40], mm5
556     movq      [ecx+48], mm6
557     movq      [ecx+56], mm7
558     movq      [ecx+12], mm1
559     movd      [ecx+ 8], mm2
560     ret