]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
Update file headers throughout x264
[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: Laurent Aimar <fenrir@via.ecp.fr>
7 ;*          Loren Merritt <lorenm@u.washington.edu>
8 ;*          Min Chen <chenm001.163.com>
9 ;*
10 ;* This program is free software; you can redistribute it and/or modify
11 ;* it under the terms of the GNU General Public License as published by
12 ;* the Free Software Foundation; either version 2 of the License, or
13 ;* (at your option) any later version.
14 ;*
15 ;* This program is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;* GNU General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU General Public License
21 ;* along with this program; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23 ;*****************************************************************************
24
25 %include "x86inc.asm"
26
27 SECTION_RODATA
28 pw_1:  times 8 dw 1
29 pw_32: times 8 dw 32
30 pb_zigzag4: db 0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15
31
32 SECTION .text
33
34 %macro LOAD_DIFF_4P 5
35     movh        %1, %4
36     punpcklbw   %1, %3
37     movh        %2, %5
38     punpcklbw   %2, %3
39     psubw       %1, %2
40 %endmacro
41
42 %macro SUMSUB_BA 2
43     paddw   %1, %2
44     paddw   %2, %2
45     psubw   %2, %1
46 %endmacro
47
48 %macro SUMSUB_BADC 4
49     paddw   %1, %2
50     paddw   %3, %4
51     paddw   %2, %2
52     paddw   %4, %4
53     psubw   %2, %1
54     psubw   %4, %3
55 %endmacro
56
57 %macro SUMSUB2_AB 3
58     mova    %3, %1
59     paddw   %1, %1
60     paddw   %1, %2
61     psubw   %3, %2
62     psubw   %3, %2
63 %endmacro
64
65 %macro SUMSUBD2_AB 4
66     mova    %4, %1
67     mova    %3, %2
68     psraw   %2, 1
69     psraw   %4, 1
70     paddw   %1, %2
71     psubw   %4, %3
72 %endmacro
73
74 %macro SBUTTERFLY 4
75     mova       m%4, m%2
76     punpckl%1  m%2, m%3
77     punpckh%1  m%4, m%3
78     SWAP %3, %4
79 %endmacro
80
81 %macro TRANSPOSE4x4W 5
82     SBUTTERFLY wd, %1, %2, %5
83     SBUTTERFLY wd, %3, %4, %5
84     SBUTTERFLY dq, %1, %3, %5
85     SBUTTERFLY dq, %2, %4, %5
86     SWAP %2, %3
87 %endmacro
88
89 %macro TRANSPOSE2x4x4W 5
90     SBUTTERFLY wd, %1, %2, %5
91     SBUTTERFLY wd, %3, %4, %5
92     SBUTTERFLY dq, %1, %3, %5
93     SBUTTERFLY dq, %2, %4, %5
94     SBUTTERFLY qdq, %1, %2, %5
95     SBUTTERFLY qdq, %3, %4, %5
96 %endmacro
97
98 %macro STORE_DIFF_4P 4
99     psraw       %1, 6
100     movh        %2, %4
101     punpcklbw   %2, %3
102     paddsw      %1, %2
103     packuswb    %1, %1
104     movh        %4, %1
105 %endmacro
106
107 %macro HADAMARD4_1D 4
108     SUMSUB_BADC m%2, m%1, m%4, m%3
109     SUMSUB_BADC m%4, m%2, m%3, m%1
110     SWAP %1, %4, %3
111 %endmacro
112
113 ;-----------------------------------------------------------------------------
114 ; void x264_dct4x4dc_mmx( int16_t d[4][4] )
115 ;-----------------------------------------------------------------------------
116 cglobal x264_dct4x4dc_mmx, 1,1,1
117     movq   m0, [r0+ 0]
118     movq   m1, [r0+ 8]
119     movq   m2, [r0+16]
120     movq   m3, [r0+24]
121     HADAMARD4_1D  0,1,2,3
122     TRANSPOSE4x4W 0,1,2,3,4
123     HADAMARD4_1D  0,1,2,3
124     movq   m6, [pw_1 GLOBAL]
125     paddw  m0, m6
126     paddw  m1, m6
127     paddw  m2, m6
128     paddw  m3, m6
129     psraw  m0, 1
130     psraw  m1, 1
131     psraw  m2, 1
132     psraw  m3, 1
133     movq  [r0+0], m0
134     movq  [r0+8], m1
135     movq [r0+16], m2
136     movq [r0+24], m3
137     RET
138
139 ;-----------------------------------------------------------------------------
140 ; void x264_idct4x4dc_mmx( int16_t d[4][4] )
141 ;-----------------------------------------------------------------------------
142 cglobal x264_idct4x4dc_mmx, 1,1
143     movq  m0, [r0+ 0]
144     movq  m1, [r0+ 8]
145     movq  m2, [r0+16]
146     movq  m3, [r0+24]
147     HADAMARD4_1D  0,1,2,3
148     TRANSPOSE4x4W 0,1,2,3,4
149     HADAMARD4_1D  0,1,2,3
150     movq  [r0+ 0], m0
151     movq  [r0+ 8], m1
152     movq  [r0+16], m2
153     movq  [r0+24], m3
154     RET
155
156 %macro DCT4_1D 5
157     SUMSUB_BADC m%4, m%1, m%3, m%2
158     SUMSUB_BA   m%3, m%4
159     SUMSUB2_AB  m%1, m%2, m%5
160     SWAP %1, %3, %4, %5, %2
161 %endmacro
162
163 %macro IDCT4_1D 6
164     SUMSUB_BA   m%3, m%1
165     SUMSUBD2_AB m%2, m%4, m%6, m%5
166     SUMSUB_BADC m%2, m%3, m%5, m%1
167     SWAP %1, %2, %5, %4, %3
168 %endmacro
169
170 ;-----------------------------------------------------------------------------
171 ; void x264_sub4x4_dct_mmx( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
172 ;-----------------------------------------------------------------------------
173 cglobal x264_sub4x4_dct_mmx, 3,3
174 .skip_prologue:
175 %macro SUB_DCT4 1
176     LOAD_DIFF_4P  m0, m6, m7, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
177     LOAD_DIFF_4P  m1, m6, m7, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
178     LOAD_DIFF_4P  m2, m6, m7, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
179     LOAD_DIFF_4P  m3, m6, m7, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
180     DCT4_1D 0,1,2,3,4
181     TRANSPOSE%1 0,1,2,3,4
182     DCT4_1D 0,1,2,3,4
183     movq  [r0+ 0], m0
184     movq  [r0+ 8], m1
185     movq  [r0+16], m2
186     movq  [r0+24], m3
187 %endmacro
188     SUB_DCT4 4x4W
189     RET
190
191 ;-----------------------------------------------------------------------------
192 ; void x264_add4x4_idct_mmx( uint8_t *p_dst, int16_t dct[4][4] )
193 ;-----------------------------------------------------------------------------
194 cglobal x264_add4x4_idct_mmx, 2,2,1
195 .skip_prologue:
196     movq  m0, [r1+ 0]
197     movq  m1, [r1+ 8]
198     movq  m2, [r1+16]
199     movq  m3, [r1+24]
200 %macro ADD_IDCT4 1
201     IDCT4_1D 0,1,2,3,4,5
202     TRANSPOSE%1 0,1,2,3,4
203     paddw m0, [pw_32 GLOBAL]
204     IDCT4_1D 0,1,2,3,4,5
205     pxor  m7, m7
206     STORE_DIFF_4P  m0, m4, m7, [r0+0*FDEC_STRIDE]
207     STORE_DIFF_4P  m1, m4, m7, [r0+1*FDEC_STRIDE]
208     STORE_DIFF_4P  m2, m4, m7, [r0+2*FDEC_STRIDE]
209     STORE_DIFF_4P  m3, m4, m7, [r0+3*FDEC_STRIDE]
210 %endmacro
211     ADD_IDCT4 4x4W
212     RET
213
214 INIT_XMM
215
216 cglobal x264_sub8x8_dct_sse2, 3,3
217 .skip_prologue:
218     call .8x4
219     add  r0, 64
220     add  r1, 4*FENC_STRIDE
221     add  r2, 4*FDEC_STRIDE
222 .8x4:
223     SUB_DCT4 2x4x4W
224     movhps [r0+32], m0
225     movhps [r0+40], m1
226     movhps [r0+48], m2
227     movhps [r0+56], m3
228     ret
229
230 cglobal x264_add8x8_idct_sse2, 2,2,1
231 .skip_prologue:
232     call .8x4
233     add  r1, 64
234     add  r0, 4*FDEC_STRIDE
235 .8x4:
236     movq   m0, [r1+ 0]
237     movq   m1, [r1+ 8]
238     movq   m2, [r1+16]
239     movq   m3, [r1+24]
240     movhps m0, [r1+32]
241     movhps m1, [r1+40]
242     movhps m2, [r1+48]
243     movhps m3, [r1+56]
244     ADD_IDCT4 2x4x4W
245     ret
246
247 ;-----------------------------------------------------------------------------
248 ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
249 ;-----------------------------------------------------------------------------
250 %macro SUB_NxN_DCT 6
251 cglobal %1, 3,3
252 .skip_prologue:
253     call %2
254     add  r0, %3
255     add  r1, %4-%5-%6*FENC_STRIDE
256     add  r2, %4-%5-%6*FDEC_STRIDE
257     call %2
258     add  r0, %3
259     add  r1, (%4-%6)*FENC_STRIDE-%5-%4
260     add  r2, (%4-%6)*FDEC_STRIDE-%5-%4
261     call %2
262     add  r0, %3
263     add  r1, %4-%5-%6*FENC_STRIDE
264     add  r2, %4-%5-%6*FDEC_STRIDE
265     jmp  %2
266 %endmacro
267
268 ;-----------------------------------------------------------------------------
269 ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
270 ;-----------------------------------------------------------------------------
271 %macro ADD_NxN_IDCT 6
272 cglobal %1, 2,2,1
273 .skip_prologue:
274     call %2
275     add  r0, %4-%5-%6*FDEC_STRIDE
276     add  r1, %3
277     call %2
278     add  r0, (%4-%6)*FDEC_STRIDE-%5-%4
279     add  r1, %3
280     call %2
281     add  r0, %4-%5-%6*FDEC_STRIDE
282     add  r1, %3
283     jmp  %2
284 %endmacro
285
286 %ifndef ARCH_X86_64
287 SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx  %+ .skip_prologue, 32, 4, 0, 0
288 ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx %+ .skip_prologue, 32, 4, 0, 0
289 SUB_NxN_DCT  x264_sub16x16_dct_mmx,  x264_sub8x8_dct_mmx  %+ .skip_prologue, 32, 8, 4, 4
290 ADD_NxN_IDCT x264_add16x16_idct_mmx, x264_add8x8_idct_mmx %+ .skip_prologue, 32, 8, 4, 4
291
292 cextern x264_sub8x8_dct8_mmx.skip_prologue
293 cextern x264_add8x8_idct8_mmx.skip_prologue
294 SUB_NxN_DCT  x264_sub16x16_dct8_mmx,  x264_sub8x8_dct8_mmx  %+ .skip_prologue, 128, 8, 0, 0
295 ADD_NxN_IDCT x264_add16x16_idct8_mmx, x264_add8x8_idct8_mmx %+ .skip_prologue, 128, 8, 0, 0
296 %define x264_sub8x8_dct8_sse2 x264_sub8x8_dct8_sse2.skip_prologue
297 %define x264_add8x8_idct8_sse2 x264_add8x8_idct8_sse2.skip_prologue
298 %endif
299
300 SUB_NxN_DCT  x264_sub16x16_dct_sse2,  x264_sub8x8_dct_sse2  %+ .skip_prologue, 64, 8, 0, 4
301 ADD_NxN_IDCT x264_add16x16_idct_sse2, x264_add8x8_idct_sse2 %+ .skip_prologue, 64, 8, 0, 4
302
303 cextern x264_sub8x8_dct8_sse2
304 cextern x264_add8x8_idct8_sse2
305 SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2,  128, 8, 0, 0
306 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2, 128, 8, 0, 0
307
308
309
310 ;-----------------------------------------------------------------------------
311 ; void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] )
312 ;-----------------------------------------------------------------------------
313 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
314 cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
315     pshufw     mm0, [r1+4], 0xd2
316     movq       mm1, [r1+16]
317     movq       mm2, [r1+24]
318     movq    [r0+4], mm0
319     movq   [r0+16], mm1
320     movq   [r0+24], mm2
321     mov        r2d, [r1]
322     mov       [r0], r2d
323     mov        r2d, [r1+12]
324     mov    [r0+12], r2d
325     RET
326
327 ;-----------------------------------------------------------------------------
328 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
329 ;-----------------------------------------------------------------------------
330 cglobal x264_zigzag_sub_4x4_frame_ssse3, 3,3
331     movd      xmm0, [r1+0*FENC_STRIDE]
332     movd      xmm1, [r1+1*FENC_STRIDE]
333     movd      xmm2, [r1+2*FENC_STRIDE]
334     movd      xmm3, [r1+3*FENC_STRIDE]
335     movd      xmm4, [r2+0*FDEC_STRIDE]
336     movd      xmm5, [r2+1*FDEC_STRIDE]
337     movd      xmm6, [r2+2*FDEC_STRIDE]
338     movd      xmm7, [r2+3*FDEC_STRIDE]
339     movd      [r2+0*FDEC_STRIDE], xmm0
340     movd      [r2+1*FDEC_STRIDE], xmm1
341     movd      [r2+2*FDEC_STRIDE], xmm2
342     movd      [r2+3*FDEC_STRIDE], xmm3
343     picgetgot r1
344     punpckldq xmm0, xmm1
345     punpckldq xmm2, xmm3
346     punpckldq xmm4, xmm5
347     punpckldq xmm6, xmm7
348     movlhps   xmm0, xmm2
349     movlhps   xmm4, xmm6
350     movdqa    xmm7, [pb_zigzag4 GLOBAL]
351     pshufb    xmm0, xmm7
352     pshufb    xmm4, xmm7
353     pxor      xmm6, xmm6
354     movdqa    xmm1, xmm0
355     movdqa    xmm5, xmm4
356     punpcklbw xmm0, xmm6
357     punpckhbw xmm1, xmm6
358     punpcklbw xmm4, xmm6
359     punpckhbw xmm5, xmm6
360     psubw     xmm0, xmm4
361     psubw     xmm1, xmm5
362     movdqa    [r0], xmm0
363     movdqa [r0+16], xmm1
364     RET