]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
Fix regression in r922
[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 %include "x86util.asm"
27
28 SECTION_RODATA
29 pw_1:  times 8 dw 1
30 pw_32: times 8 dw 32
31 pb_zigzag4: db 0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15
32
33 SECTION .text
34
35 %macro SBUTTERFLY 4
36     mova       m%4, m%2
37     punpckl%1  m%2, m%3
38     punpckh%1  m%4, m%3
39     SWAP %3, %4
40 %endmacro
41
42 %macro TRANSPOSE4x4W 5
43     SBUTTERFLY wd, %1, %2, %5
44     SBUTTERFLY wd, %3, %4, %5
45     SBUTTERFLY dq, %1, %3, %5
46     SBUTTERFLY dq, %2, %4, %5
47     SWAP %2, %3
48 %endmacro
49
50 %macro TRANSPOSE2x4x4W 5
51     SBUTTERFLY wd, %1, %2, %5
52     SBUTTERFLY wd, %3, %4, %5
53     SBUTTERFLY dq, %1, %3, %5
54     SBUTTERFLY dq, %2, %4, %5
55     SBUTTERFLY qdq, %1, %2, %5
56     SBUTTERFLY qdq, %3, %4, %5
57 %endmacro
58
59 %macro HADAMARD4_1D 4
60     SUMSUB_BADC m%2, m%1, m%4, m%3
61     SUMSUB_BADC m%4, m%2, m%3, m%1
62     SWAP %1, %4, %3
63 %endmacro
64
65 ;-----------------------------------------------------------------------------
66 ; void x264_dct4x4dc_mmx( int16_t d[4][4] )
67 ;-----------------------------------------------------------------------------
68 cglobal x264_dct4x4dc_mmx, 1,1,1
69     movq   m0, [r0+ 0]
70     movq   m1, [r0+ 8]
71     movq   m2, [r0+16]
72     movq   m3, [r0+24]
73     HADAMARD4_1D  0,1,2,3
74     TRANSPOSE4x4W 0,1,2,3,4
75     HADAMARD4_1D  0,1,2,3
76     movq   m6, [pw_1 GLOBAL]
77     paddw  m0, m6
78     paddw  m1, m6
79     paddw  m2, m6
80     paddw  m3, m6
81     psraw  m0, 1
82     psraw  m1, 1
83     psraw  m2, 1
84     psraw  m3, 1
85     movq  [r0+0], m0
86     movq  [r0+8], m1
87     movq [r0+16], m2
88     movq [r0+24], m3
89     RET
90
91 ;-----------------------------------------------------------------------------
92 ; void x264_idct4x4dc_mmx( int16_t d[4][4] )
93 ;-----------------------------------------------------------------------------
94 cglobal x264_idct4x4dc_mmx, 1,1
95     movq  m0, [r0+ 0]
96     movq  m1, [r0+ 8]
97     movq  m2, [r0+16]
98     movq  m3, [r0+24]
99     HADAMARD4_1D  0,1,2,3
100     TRANSPOSE4x4W 0,1,2,3,4
101     HADAMARD4_1D  0,1,2,3
102     movq  [r0+ 0], m0
103     movq  [r0+ 8], m1
104     movq  [r0+16], m2
105     movq  [r0+24], m3
106     RET
107
108 %macro DCT4_1D 5
109     SUMSUB_BADC m%4, m%1, m%3, m%2
110     SUMSUB_BA   m%3, m%4
111     SUMSUB2_AB  m%1, m%2, m%5
112     SWAP %1, %3, %4, %5, %2
113 %endmacro
114
115 %macro IDCT4_1D 6
116     SUMSUB_BA   m%3, m%1
117     SUMSUBD2_AB m%2, m%4, m%6, m%5
118     SUMSUB_BADC m%2, m%3, m%5, m%1
119     SWAP %1, %2, %5, %4, %3
120 %endmacro
121
122 ;-----------------------------------------------------------------------------
123 ; void x264_sub4x4_dct_mmx( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
124 ;-----------------------------------------------------------------------------
125 cglobal x264_sub4x4_dct_mmx, 3,3
126 .skip_prologue:
127 %macro SUB_DCT4 1
128     LOAD_DIFF  m0, m6, m7, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
129     LOAD_DIFF  m1, m6, m7, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
130     LOAD_DIFF  m2, m6, m7, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
131     LOAD_DIFF  m3, m6, m7, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
132     DCT4_1D 0,1,2,3,4
133     TRANSPOSE%1 0,1,2,3,4
134     DCT4_1D 0,1,2,3,4
135     movq  [r0+ 0], m0
136     movq  [r0+ 8], m1
137     movq  [r0+16], m2
138     movq  [r0+24], m3
139 %endmacro
140     SUB_DCT4 4x4W
141     RET
142
143 ;-----------------------------------------------------------------------------
144 ; void x264_add4x4_idct_mmx( uint8_t *p_dst, int16_t dct[4][4] )
145 ;-----------------------------------------------------------------------------
146 cglobal x264_add4x4_idct_mmx, 2,2,1
147 .skip_prologue:
148     movq  m0, [r1+ 0]
149     movq  m1, [r1+ 8]
150     movq  m2, [r1+16]
151     movq  m3, [r1+24]
152 %macro ADD_IDCT4 1
153     IDCT4_1D 0,1,2,3,4,5
154     TRANSPOSE%1 0,1,2,3,4
155     paddw m0, [pw_32 GLOBAL]
156     IDCT4_1D 0,1,2,3,4,5
157     pxor  m7, m7
158     STORE_DIFF  m0, m4, m7, [r0+0*FDEC_STRIDE]
159     STORE_DIFF  m1, m4, m7, [r0+1*FDEC_STRIDE]
160     STORE_DIFF  m2, m4, m7, [r0+2*FDEC_STRIDE]
161     STORE_DIFF  m3, m4, m7, [r0+3*FDEC_STRIDE]
162 %endmacro
163     ADD_IDCT4 4x4W
164     RET
165
166 INIT_XMM
167
168 cglobal x264_sub8x8_dct_sse2, 3,3
169 .skip_prologue:
170     call .8x4
171     add  r0, 64
172     add  r1, 4*FENC_STRIDE
173     add  r2, 4*FDEC_STRIDE
174 .8x4:
175     SUB_DCT4 2x4x4W
176     movhps [r0+32], m0
177     movhps [r0+40], m1
178     movhps [r0+48], m2
179     movhps [r0+56], m3
180     ret
181
182 cglobal x264_add8x8_idct_sse2, 2,2,1
183 .skip_prologue:
184     call .8x4
185     add  r1, 64
186     add  r0, 4*FDEC_STRIDE
187 .8x4:
188     movq   m0, [r1+ 0]
189     movq   m1, [r1+ 8]
190     movq   m2, [r1+16]
191     movq   m3, [r1+24]
192     movhps m0, [r1+32]
193     movhps m1, [r1+40]
194     movhps m2, [r1+48]
195     movhps m3, [r1+56]
196     ADD_IDCT4 2x4x4W
197     ret
198
199 ;-----------------------------------------------------------------------------
200 ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
201 ;-----------------------------------------------------------------------------
202 %macro SUB_NxN_DCT 6
203 cglobal %1, 3,3
204 .skip_prologue:
205     call %2
206     add  r0, %3
207     add  r1, %4-%5-%6*FENC_STRIDE
208     add  r2, %4-%5-%6*FDEC_STRIDE
209     call %2
210     add  r0, %3
211     add  r1, (%4-%6)*FENC_STRIDE-%5-%4
212     add  r2, (%4-%6)*FDEC_STRIDE-%5-%4
213     call %2
214     add  r0, %3
215     add  r1, %4-%5-%6*FENC_STRIDE
216     add  r2, %4-%5-%6*FDEC_STRIDE
217     jmp  %2
218 %endmacro
219
220 ;-----------------------------------------------------------------------------
221 ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
222 ;-----------------------------------------------------------------------------
223 %macro ADD_NxN_IDCT 6
224 cglobal %1, 2,2,1
225 .skip_prologue:
226     call %2
227     add  r0, %4-%5-%6*FDEC_STRIDE
228     add  r1, %3
229     call %2
230     add  r0, (%4-%6)*FDEC_STRIDE-%5-%4
231     add  r1, %3
232     call %2
233     add  r0, %4-%5-%6*FDEC_STRIDE
234     add  r1, %3
235     jmp  %2
236 %endmacro
237
238 %ifndef ARCH_X86_64
239 SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx  %+ .skip_prologue, 32, 4, 0, 0
240 ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx %+ .skip_prologue, 32, 4, 0, 0
241 SUB_NxN_DCT  x264_sub16x16_dct_mmx,  x264_sub8x8_dct_mmx  %+ .skip_prologue, 32, 8, 4, 4
242 ADD_NxN_IDCT x264_add16x16_idct_mmx, x264_add8x8_idct_mmx %+ .skip_prologue, 32, 8, 4, 4
243
244 cextern x264_sub8x8_dct8_mmx.skip_prologue
245 cextern x264_add8x8_idct8_mmx.skip_prologue
246 SUB_NxN_DCT  x264_sub16x16_dct8_mmx,  x264_sub8x8_dct8_mmx  %+ .skip_prologue, 128, 8, 0, 0
247 ADD_NxN_IDCT x264_add16x16_idct8_mmx, x264_add8x8_idct8_mmx %+ .skip_prologue, 128, 8, 0, 0
248 %define x264_sub8x8_dct8_sse2 x264_sub8x8_dct8_sse2.skip_prologue
249 %define x264_add8x8_idct8_sse2 x264_add8x8_idct8_sse2.skip_prologue
250 %endif
251
252 SUB_NxN_DCT  x264_sub16x16_dct_sse2,  x264_sub8x8_dct_sse2  %+ .skip_prologue, 64, 8, 0, 4
253 ADD_NxN_IDCT x264_add16x16_idct_sse2, x264_add8x8_idct_sse2 %+ .skip_prologue, 64, 8, 0, 4
254
255 cextern x264_sub8x8_dct8_sse2
256 cextern x264_add8x8_idct8_sse2
257 SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2,  128, 8, 0, 0
258 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2, 128, 8, 0, 0
259
260
261
262 ;-----------------------------------------------------------------------------
263 ; void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] )
264 ;-----------------------------------------------------------------------------
265 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
266 cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
267     pshufw     mm0, [r1+4], 0xd2
268     movq       mm1, [r1+16]
269     movq       mm2, [r1+24]
270     movq    [r0+4], mm0
271     movq   [r0+16], mm1
272     movq   [r0+24], mm2
273     mov        r2d, [r1]
274     mov       [r0], r2d
275     mov        r2d, [r1+12]
276     mov    [r0+12], r2d
277     RET
278
279 ;-----------------------------------------------------------------------------
280 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
281 ;-----------------------------------------------------------------------------
282 cglobal x264_zigzag_sub_4x4_frame_ssse3, 3,3
283     movd      xmm0, [r1+0*FENC_STRIDE]
284     movd      xmm1, [r1+1*FENC_STRIDE]
285     movd      xmm2, [r1+2*FENC_STRIDE]
286     movd      xmm3, [r1+3*FENC_STRIDE]
287     movd      xmm4, [r2+0*FDEC_STRIDE]
288     movd      xmm5, [r2+1*FDEC_STRIDE]
289     movd      xmm6, [r2+2*FDEC_STRIDE]
290     movd      xmm7, [r2+3*FDEC_STRIDE]
291     movd      [r2+0*FDEC_STRIDE], xmm0
292     movd      [r2+1*FDEC_STRIDE], xmm1
293     movd      [r2+2*FDEC_STRIDE], xmm2
294     movd      [r2+3*FDEC_STRIDE], xmm3
295     picgetgot r1
296     punpckldq xmm0, xmm1
297     punpckldq xmm2, xmm3
298     punpckldq xmm4, xmm5
299     punpckldq xmm6, xmm7
300     movlhps   xmm0, xmm2
301     movlhps   xmm4, xmm6
302     movdqa    xmm7, [pb_zigzag4 GLOBAL]
303     pshufb    xmm0, xmm7
304     pshufb    xmm4, xmm7
305     pxor      xmm6, xmm6
306     movdqa    xmm1, xmm0
307     movdqa    xmm5, xmm4
308     punpcklbw xmm0, xmm6
309     punpckhbw xmm1, xmm6
310     punpcklbw xmm4, xmm6
311     punpckhbw xmm5, xmm6
312     psubw     xmm0, xmm4
313     psubw     xmm1, xmm5
314     movdqa    [r0], xmm0
315     movdqa [r0+16], xmm1
316     RET