]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
77baddaabd01dea9d3c25b13c1bf960f9b4d9a98
[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 ;*          Min Chen <chenm001.163.com>
8 ;*          Loren Merritt <lorenm@u.washington.edu>
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., 59 Temple Place - Suite 330, 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 SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx  %+ .skip_prologue, 32, 4, 0, 0
287 ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx %+ .skip_prologue, 32, 4, 0, 0
288
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 SUB_NxN_DCT  x264_sub16x16_dct_sse2,  x264_sub8x8_dct_sse2  %+ .skip_prologue, 64, 8, 0, 4
293 ADD_NxN_IDCT x264_add16x16_idct_sse2, x264_add8x8_idct_sse2 %+ .skip_prologue, 64, 8, 0, 4
294
295 %ifndef ARCH_X86_64
296 cextern x264_sub8x8_dct8_mmx.skip_prologue
297 cextern x264_add8x8_idct8_mmx.skip_prologue
298 SUB_NxN_DCT  x264_sub16x16_dct8_mmx,  x264_sub8x8_dct8_mmx  %+ .skip_prologue, 128, 8, 0, 0
299 ADD_NxN_IDCT x264_add16x16_idct8_mmx, x264_add8x8_idct8_mmx %+ .skip_prologue, 128, 8, 0, 0
300 %define x264_sub8x8_dct8_sse2 x264_sub8x8_dct8_sse2.skip_prologue
301 %define x264_add8x8_idct8_sse2 x264_add8x8_idct8_sse2.skip_prologue
302 %endif
303
304 cextern x264_sub8x8_dct8_sse2
305 cextern x264_add8x8_idct8_sse2
306 SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2,  128, 8, 0, 0
307 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2, 128, 8, 0, 0
308
309
310
311 ;-----------------------------------------------------------------------------
312 ; void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] )
313 ;-----------------------------------------------------------------------------
314 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
315 cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
316     pshufw     mm0, [r1+4], 0xd2
317     movq       mm1, [r1+16]
318     movq       mm2, [r1+24]
319     movq    [r0+4], mm0
320     movq   [r0+16], mm1
321     movq   [r0+24], mm2
322     mov        r2d, [r1]
323     mov       [r0], r2d
324     mov        r2d, [r1+12]
325     mov    [r0+12], r2d
326     RET
327
328 ;-----------------------------------------------------------------------------
329 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
330 ;-----------------------------------------------------------------------------
331 cglobal x264_zigzag_sub_4x4_frame_ssse3, 3,3
332     movd      xmm0, [r1+0*FENC_STRIDE]
333     movd      xmm1, [r1+1*FENC_STRIDE]
334     movd      xmm2, [r1+2*FENC_STRIDE]
335     movd      xmm3, [r1+3*FENC_STRIDE]
336     movd      xmm4, [r2+0*FDEC_STRIDE]
337     movd      xmm5, [r2+1*FDEC_STRIDE]
338     movd      xmm6, [r2+2*FDEC_STRIDE]
339     movd      xmm7, [r2+3*FDEC_STRIDE]
340     movd      [r2+0*FDEC_STRIDE], xmm0
341     movd      [r2+1*FDEC_STRIDE], xmm1
342     movd      [r2+2*FDEC_STRIDE], xmm2
343     movd      [r2+3*FDEC_STRIDE], xmm3
344     picgetgot r1
345     punpckldq xmm0, xmm1
346     punpckldq xmm2, xmm3
347     punpckldq xmm4, xmm5
348     punpckldq xmm6, xmm7
349     movlhps   xmm0, xmm2
350     movlhps   xmm4, xmm6
351     movdqa    xmm7, [pb_zigzag4 GLOBAL]
352     pshufb    xmm0, xmm7
353     pshufb    xmm4, xmm7
354     pxor      xmm6, xmm6
355     movdqa    xmm1, xmm0
356     movdqa    xmm5, xmm4
357     punpcklbw xmm0, xmm6
358     punpckhbw xmm1, xmm6
359     punpcklbw xmm4, xmm6
360     punpckhbw xmm5, xmm6
361     psubw     xmm0, xmm4
362     psubw     xmm1, xmm5
363     movdqa    [r0], xmm0
364     movdqa [r0+16], xmm1
365     RET