]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
5c3a83369f925bfd257e8a10f6700da6d4fadbd7
[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     movd        %1, %4
36     punpcklbw   %1, %3
37     movd        %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     movq    %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     movq    %4, %1
67     movq    %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 STORE_DIFF_4P 5
90     paddw       %1, %3
91     psraw       %1, 6
92     movd        %2, %5
93     punpcklbw   %2, %4
94     paddsw      %1, %2
95     packuswb    %1, %1
96     movd        %5, %1
97 %endmacro
98
99 %macro HADAMARD4_1D 4
100     SUMSUB_BADC m%2, m%1, m%4, m%3
101     SUMSUB_BADC m%4, m%2, m%3, m%1
102     SWAP %1, %4, %3
103 %endmacro
104
105 ;-----------------------------------------------------------------------------
106 ; void x264_dct4x4dc_mmx( int16_t d[4][4] )
107 ;-----------------------------------------------------------------------------
108 cglobal x264_dct4x4dc_mmx, 1,1,1
109     movq   m0, [r0+ 0]
110     movq   m1, [r0+ 8]
111     movq   m2, [r0+16]
112     movq   m3, [r0+24]
113     HADAMARD4_1D  0,1,2,3
114     TRANSPOSE4x4W 0,1,2,3,4
115     HADAMARD4_1D  0,1,2,3
116     movq   m6, [pw_1 GLOBAL]
117     paddw  m0, m6
118     paddw  m1, m6
119     paddw  m2, m6
120     paddw  m3, m6
121     psraw  m0, 1
122     psraw  m1, 1
123     psraw  m2, 1
124     psraw  m3, 1
125     movq  [r0+0], m0
126     movq  [r0+8], m1
127     movq [r0+16], m2
128     movq [r0+24], m3
129     RET
130
131 ;-----------------------------------------------------------------------------
132 ; void x264_idct4x4dc_mmx( int16_t d[4][4] )
133 ;-----------------------------------------------------------------------------
134 cglobal x264_idct4x4dc_mmx, 1,1
135     movq  m0, [r0+ 0]
136     movq  m1, [r0+ 8]
137     movq  m2, [r0+16]
138     movq  m3, [r0+24]
139     HADAMARD4_1D  0,1,2,3
140     TRANSPOSE4x4W 0,1,2,3,4
141     HADAMARD4_1D  0,1,2,3
142     movq  [r0+ 0], m0
143     movq  [r0+ 8], m1
144     movq  [r0+16], m2
145     movq  [r0+24], m3
146     RET
147
148 %macro DCT4_1D 5
149     SUMSUB_BADC m%4, m%1, m%3, m%2
150     SUMSUB_BA   m%3, m%4
151     SUMSUB2_AB  m%1, m%2, m%5
152     SWAP %1, %3, %4, %5, %2
153 %endmacro
154
155 %macro IDCT4_1D 6
156     SUMSUB_BA   m%3, m%1
157     SUMSUBD2_AB m%2, m%4, m%6, m%5
158     SUMSUB_BADC m%2, m%3, m%5, m%1
159     SWAP %1, %2, %5, %4, %3
160 %endmacro
161
162 ;-----------------------------------------------------------------------------
163 ; void x264_sub4x4_dct_mmx( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
164 ;-----------------------------------------------------------------------------
165 cglobal x264_sub4x4_dct_mmx, 3,3
166 .skip_prologue:
167     LOAD_DIFF_4P  m0, m6, m7, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
168     LOAD_DIFF_4P  m1, m6, m7, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
169     LOAD_DIFF_4P  m2, m6, m7, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
170     LOAD_DIFF_4P  m3, m6, m7, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
171     DCT4_1D 0,1,2,3,4
172     TRANSPOSE4x4W 0,1,2,3,4
173     DCT4_1D 0,1,2,3,4
174     movq  [r0+ 0], m0
175     movq  [r0+ 8], m1
176     movq  [r0+16], m2
177     movq  [r0+24], m3
178     RET
179
180 ;-----------------------------------------------------------------------------
181 ; void x264_add4x4_idct_mmx( uint8_t *p_dst, int16_t dct[4][4] )
182 ;-----------------------------------------------------------------------------
183 cglobal x264_add4x4_idct_mmx, 2,2,1
184 .skip_prologue:
185     movq  m0, [r1+ 0]
186     movq  m1, [r1+ 8]
187     movq  m2, [r1+16]
188     movq  m3, [r1+24]
189     IDCT4_1D 0,1,2,3,4,5
190     TRANSPOSE4x4W 0,1,2,3,4
191     IDCT4_1D 0,1,2,3,4,5
192     pxor  m7, m7
193     movq  m6, [pw_32 GLOBAL]
194     STORE_DIFF_4P  m0, m4, m6, m7, [r0+0*FDEC_STRIDE]
195     STORE_DIFF_4P  m1, m4, m6, m7, [r0+1*FDEC_STRIDE]
196     STORE_DIFF_4P  m2, m4, m6, m7, [r0+2*FDEC_STRIDE]
197     STORE_DIFF_4P  m3, m4, m6, m7, [r0+3*FDEC_STRIDE]
198     RET
199
200
201
202 ;-----------------------------------------------------------------------------
203 ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
204 ;-----------------------------------------------------------------------------
205 %macro SUB_NxN_DCT 6
206 cglobal %1, 3,3
207 .skip_prologue:
208     call %2
209     add  r0, %3
210     add  r1, %4-%5*FENC_STRIDE
211     add  r2, %4-%5*FDEC_STRIDE
212     call %2
213     add  r0, %3
214     add  r1, %4*FENC_STRIDE-%6
215     add  r2, %4*FDEC_STRIDE-%6
216     call %2
217     add  r0, %3
218     add  r1, %4-%5*FENC_STRIDE
219     add  r2, %4-%5*FDEC_STRIDE
220     jmp  %2
221 %endmacro
222
223 ;-----------------------------------------------------------------------------
224 ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
225 ;-----------------------------------------------------------------------------
226 %macro ADD_NxN_IDCT 6
227 cglobal %1, 2,2,1
228 .skip_prologue:
229     call %2
230     add  r0, %4-%5*FDEC_STRIDE
231     add  r1, %3
232     call %2
233     add  r0, %4*FDEC_STRIDE-%6
234     add  r1, %3
235     call %2
236     add  r0, %4-%5*FDEC_STRIDE
237     add  r1, %3
238     jmp  %2
239 %endmacro
240
241 SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx  %+ .skip_prologue, 32, 4, 0,  4
242 ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx %+ .skip_prologue, 32, 4, 0,  4
243
244 SUB_NxN_DCT  x264_sub16x16_dct_mmx,  x264_sub8x8_dct_mmx  %+ .skip_prologue, 32, 4, 4, 12
245 ADD_NxN_IDCT x264_add16x16_idct_mmx, x264_add8x8_idct_mmx %+ .skip_prologue, 32, 4, 4, 12
246
247 %ifndef ARCH_X86_64
248 cextern x264_sub8x8_dct8_mmx.skip_prologue
249 cextern x264_add8x8_idct8_mmx.skip_prologue
250 SUB_NxN_DCT  x264_sub16x16_dct8_mmx,  x264_sub8x8_dct8_mmx  %+ .skip_prologue, 128, 8, 0,  8
251 ADD_NxN_IDCT x264_add16x16_idct8_mmx, x264_add8x8_idct8_mmx %+ .skip_prologue, 128, 8, 0,  8
252 %define x264_sub8x8_dct8_sse2 x264_sub8x8_dct8_sse2.skip_prologue
253 %define x264_add8x8_idct8_sse2 x264_add8x8_idct8_sse2.skip_prologue
254 %endif
255
256 cextern x264_sub8x8_dct8_sse2
257 cextern x264_add8x8_idct8_sse2
258 SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2,  128, 8, 0,  8
259 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2, 128, 8, 0,  8
260
261
262
263 ;-----------------------------------------------------------------------------
264 ; void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] )
265 ;-----------------------------------------------------------------------------
266 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
267 cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
268     pshufw     mm0, [r1+4], 0xd2
269     movq       mm1, [r1+16]
270     movq       mm2, [r1+24]
271     movq    [r0+4], mm0
272     movq   [r0+16], mm1
273     movq   [r0+24], mm2
274     mov        r2d, [r1]
275     mov       [r0], r2d
276     mov        r2d, [r1+12]
277     mov    [r0+12], r2d
278     RET
279
280 %ifdef HAVE_SSE3
281 ;-----------------------------------------------------------------------------
282 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
283 ;-----------------------------------------------------------------------------
284 cglobal x264_zigzag_sub_4x4_frame_ssse3, 3,3
285     movd      xmm0, [r1+0*FENC_STRIDE]
286     movd      xmm1, [r1+1*FENC_STRIDE]
287     movd      xmm2, [r1+2*FENC_STRIDE]
288     movd      xmm3, [r1+3*FENC_STRIDE]
289     movd      xmm4, [r2+0*FDEC_STRIDE]
290     movd      xmm5, [r2+1*FDEC_STRIDE]
291     movd      xmm6, [r2+2*FDEC_STRIDE]
292     movd      xmm7, [r2+3*FDEC_STRIDE]
293     movd      [r2+0*FDEC_STRIDE], xmm0
294     movd      [r2+1*FDEC_STRIDE], xmm1
295     movd      [r2+2*FDEC_STRIDE], xmm2
296     movd      [r2+3*FDEC_STRIDE], xmm3
297     picgetgot r1
298     punpckldq xmm0, xmm1
299     punpckldq xmm2, xmm3
300     punpckldq xmm4, xmm5
301     punpckldq xmm6, xmm7
302     movlhps   xmm0, xmm2
303     movlhps   xmm4, xmm6
304     movdqa    xmm7, [pb_zigzag4 GLOBAL]
305     pshufb    xmm0, xmm7
306     pshufb    xmm4, xmm7
307     pxor      xmm6, xmm6
308     movdqa    xmm1, xmm0
309     movdqa    xmm5, xmm4
310     punpcklbw xmm0, xmm6
311     punpckhbw xmm1, xmm6
312     punpcklbw xmm4, xmm6
313     punpckhbw xmm5, xmm6
314     psubw     xmm0, xmm4
315     psubw     xmm1, xmm5
316     movdqa    [r0], xmm0
317     movdqa [r0+16], xmm1
318     RET
319 %endif