]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
skip intra pred+dct+quant in cases where it's redundant (analyse vs encode)
[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
31 SECTION .text
32
33 %macro LOAD_DIFF_4P 5
34     movd        %1, %4
35     punpcklbw   %1, %3
36     movd        %2, %5
37     punpcklbw   %2, %3
38     psubw       %1, %2
39 %endmacro
40
41 %macro SUMSUB_BA 2
42     paddw   %1, %2
43     paddw   %2, %2
44     psubw   %2, %1
45 %endmacro
46
47 %macro SUMSUB_BADC 4
48     paddw   %1, %2
49     paddw   %3, %4
50     paddw   %2, %2
51     paddw   %4, %4
52     psubw   %2, %1
53     psubw   %4, %3
54 %endmacro
55
56 %macro SUMSUB2_AB 3
57     movq    %3, %1
58     paddw   %1, %1
59     paddw   %1, %2
60     psubw   %3, %2
61     psubw   %3, %2
62 %endmacro
63
64 %macro SUMSUBD2_AB 4
65     movq    %4, %1
66     movq    %3, %2
67     psraw   %2, 1
68     psraw   %4, 1
69     paddw   %1, %2
70     psubw   %4, %3
71 %endmacro
72
73 %macro SBUTTERFLY 5
74     mov%1       %5, %3
75     punpckl%2   %3, %4
76     punpckh%2   %5, %4
77 %endmacro
78
79 ;-----------------------------------------------------------------------------
80 ; input ABCD output ADTC
81 ;-----------------------------------------------------------------------------
82 %macro TRANSPOSE4x4W 5
83     SBUTTERFLY q, wd, %1, %2, %5
84     SBUTTERFLY q, wd, %3, %4, %2
85     SBUTTERFLY q, dq, %1, %3, %4
86     SBUTTERFLY q, dq, %5, %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 ;-----------------------------------------------------------------------------
100 ; void x264_dct4x4dc_mmx( int16_t d[4][4] )
101 ;-----------------------------------------------------------------------------
102 cglobal x264_dct4x4dc_mmx, 1,1,1
103     movq      mm0, [r0+ 0]
104     movq      mm1, [r0+ 8]
105     movq      mm2, [r0+16]
106     movq      mm3, [r0+24]
107
108     SUMSUB_BADC    mm1, mm0, mm3, mm2          ; mm1=s01  mm0=d01  mm3=s23  mm2=d23
109     SUMSUB_BADC    mm3, mm1, mm2, mm0          ; mm3=s01+s23  mm1=s01-s23  mm2=d01+d23  mm0=d01-d23
110
111     TRANSPOSE4x4W  mm3, mm1, mm0, mm2, mm4     ; in: mm3, mm1, mm0, mm2  out: mm3, mm2, mm4, mm0 
112
113     SUMSUB_BADC    mm2, mm3, mm0, mm4          ; mm2=s01  mm3=d01  mm0=s23  mm4=d23
114     SUMSUB_BADC    mm0, mm2, mm4, mm3          ; mm0=s01+s23  mm2=s01-s23  mm4=d01+d23  mm3=d01-d23
115
116     movq      mm6, [pw_1 GLOBAL]
117     paddw     mm0, mm6
118     paddw     mm2, mm6
119     psraw     mm0, 1
120     movq  [r0+ 0], mm0
121     psraw     mm2, 1
122     movq  [r0+ 8], mm2
123     paddw     mm3, mm6
124     paddw     mm4, mm6
125     psraw     mm3, 1
126     movq  [r0+16], mm3
127     psraw     mm4, 1
128     movq  [r0+24], mm4
129     RET
130
131 ;-----------------------------------------------------------------------------
132 ; void x264_idct4x4dc_mmx( int16_t d[4][4] )
133 ;-----------------------------------------------------------------------------
134 cglobal x264_idct4x4dc_mmx, 1,1
135     movq    mm0, [r0+ 0]
136     movq    mm1, [r0+ 8]
137     movq    mm2, [r0+16]
138     movq    mm3, [r0+24]
139
140     SUMSUB_BADC    mm1, mm0, mm3, mm2          ; mm1=s01  mm0=d01  mm3=s23  mm2=d23
141     SUMSUB_BADC    mm3, mm1, mm2, mm0          ; mm3=s01+s23 mm1=s01-s23 mm2=d01+d23 mm0=d01-d23
142
143     TRANSPOSE4x4W  mm3, mm1, mm0, mm2, mm4     ; in: mm3, mm1, mm0, mm2  out: mm3, mm2, mm4, mm0 
144
145     SUMSUB_BADC    mm2, mm3, mm0, mm4          ; mm2=s01  mm3=d01  mm0=s23  mm4=d23
146     SUMSUB_BADC    mm0, mm2, mm4, mm3          ; mm0=s01+s23  mm2=s01-s23  mm4=d01+d23  mm3=d01-d23
147
148     movq    [r0+ 0], mm0
149     movq    [r0+ 8], mm2
150     movq    [r0+16], mm3
151     movq    [r0+24], mm4
152     RET
153
154 ;-----------------------------------------------------------------------------
155 ; void x264_sub4x4_dct_mmx( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
156 ;-----------------------------------------------------------------------------
157 cglobal x264_sub4x4_dct_mmx, 3,3
158 .skip_prologue:
159     pxor mm7, mm7
160
161     ; Load 4 lines
162     LOAD_DIFF_4P   mm0, mm6, mm7, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
163     LOAD_DIFF_4P   mm1, mm6, mm7, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
164     LOAD_DIFF_4P   mm2, mm6, mm7, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
165     LOAD_DIFF_4P   mm3, mm6, mm7, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
166
167     SUMSUB_BADC    mm3, mm0, mm2, mm1          ; mm3=s03  mm0=d03  mm2=s12  mm1=d12
168
169     SUMSUB_BA      mm2, mm3                    ; mm2=s03+s12      mm3=s03-s12
170     SUMSUB2_AB     mm0, mm1, mm4               ; mm0=2.d03+d12    mm4=d03-2.d12
171
172     ; transpose in: mm2, mm0, mm3, mm4, out: mm2, mm4, mm1, mm3
173     TRANSPOSE4x4W  mm2, mm0, mm3, mm4, mm1
174
175     SUMSUB_BADC    mm3, mm2, mm1, mm4          ; mm3=s03  mm2=d03  mm1=s12  mm4=d12
176
177     SUMSUB_BA      mm1, mm3                    ; mm1=s03+s12      mm3=s03-s12
178     SUMSUB2_AB     mm2, mm4, mm0               ; mm2=2.d03+d12    mm0=d03-2.d12
179
180     movq    [r0+ 0], mm1
181     movq    [r0+ 8], mm2
182     movq    [r0+16], mm3
183     movq    [r0+24], mm0
184     RET
185
186 ;-----------------------------------------------------------------------------
187 ; void x264_add4x4_idct_mmx( uint8_t *p_dst, int16_t dct[4][4] )
188 ;-----------------------------------------------------------------------------
189 cglobal x264_add4x4_idct_mmx, 2,2,1
190 .skip_prologue:
191     ; Load dct coeffs
192     movq    mm0, [r1+ 0] ; dct
193     movq    mm1, [r1+ 8]
194     movq    mm2, [r1+16]
195     movq    mm3, [r1+24]
196     
197     SUMSUB_BA      mm2, mm0                        ; mm2=s02  mm0=d02
198     SUMSUBD2_AB    mm1, mm3, mm5, mm4              ; mm1=s13  mm4=d13 ( well 1 + 3>>1 and 1>>1 + 3)
199
200     SUMSUB_BADC    mm1, mm2, mm4, mm0              ; mm1=s02+s13  mm2=s02-s13  mm4=d02+d13  mm0=d02-d13
201
202     ; in: mm1, mm4, mm0, mm2  out: mm1, mm2, mm3, mm0
203     TRANSPOSE4x4W  mm1, mm4, mm0, mm2, mm3
204
205     SUMSUB_BA      mm3, mm1                        ; mm3=s02  mm1=d02
206     SUMSUBD2_AB    mm2, mm0, mm5, mm4              ; mm2=s13  mm4=d13 ( well 1 + 3>>1 and 1>>1 + 3)
207
208     SUMSUB_BADC    mm2, mm3, mm4, mm1              ; mm2=s02+s13  mm3=s02-s13  mm4=d02+d13  mm1=d02-d13
209
210     pxor mm7, mm7
211     movq           mm6, [pw_32 GLOBAL]
212     
213     STORE_DIFF_4P  mm2, mm0, mm6, mm7, [r0+0*FDEC_STRIDE]
214     STORE_DIFF_4P  mm4, mm0, mm6, mm7, [r0+1*FDEC_STRIDE]
215     STORE_DIFF_4P  mm1, mm0, mm6, mm7, [r0+2*FDEC_STRIDE]
216     STORE_DIFF_4P  mm3, mm0, mm6, mm7, [r0+3*FDEC_STRIDE]
217
218     RET
219
220
221
222 ;-----------------------------------------------------------------------------
223 ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
224 ;-----------------------------------------------------------------------------
225 %macro SUB_NxN_DCT 6
226 cglobal %1, 3,3
227 .skip_prologue:
228     call %2
229     add  r0, %3
230     add  r1, %4-%5*FENC_STRIDE
231     add  r2, %4-%5*FDEC_STRIDE
232     call %2
233     add  r0, %3
234     add  r1, %4*FENC_STRIDE-%6
235     add  r2, %4*FDEC_STRIDE-%6
236     call %2
237     add  r0, %3
238     add  r1, %4-%5*FENC_STRIDE
239     add  r2, %4-%5*FDEC_STRIDE
240     jmp  %2
241 %endmacro
242
243 ;-----------------------------------------------------------------------------
244 ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
245 ;-----------------------------------------------------------------------------
246 %macro ADD_NxN_IDCT 6
247 cglobal %1, 2,2,1
248 .skip_prologue:
249     call %2
250     add  r0, %4-%5*FDEC_STRIDE
251     add  r1, %3
252     call %2
253     add  r0, %4*FDEC_STRIDE-%6
254     add  r1, %3
255     call %2
256     add  r0, %4-%5*FDEC_STRIDE
257     add  r1, %3
258     jmp  %2
259 %endmacro
260
261 SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx  %+ .skip_prologue, 32, 4, 0,  4
262 ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx %+ .skip_prologue, 32, 4, 0,  4
263
264 SUB_NxN_DCT  x264_sub16x16_dct_mmx,  x264_sub8x8_dct_mmx  %+ .skip_prologue, 32, 4, 4, 12
265 ADD_NxN_IDCT x264_add16x16_idct_mmx, x264_add8x8_idct_mmx %+ .skip_prologue, 32, 4, 4, 12
266
267 %ifdef ARCH_X86_64
268 cextern x264_sub8x8_dct8_sse2
269 cextern x264_add8x8_idct8_sse2
270 SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2,  128, 8, 0,  8
271 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2, 128, 8, 0,  8
272 %endif
273
274
275 ;-----------------------------------------------------------------------------
276 ; void x264_zigzag_scan_4x4_field_sse2( int level[16], int16_t dct[4][4] )
277 ;-----------------------------------------------------------------------------
278 cglobal x264_zigzag_scan_4x4_field_sse2, 2,2
279     punpcklwd xmm0, [r1]
280     punpckhwd xmm1, [r1]
281     punpcklwd xmm2, [r1+16]
282     punpckhwd xmm3, [r1+16]
283     psrad     xmm0, 16
284     psrad     xmm1, 16
285     psrad     xmm2, 16
286     psrad     xmm3, 16
287     movq   [r0   ], xmm0
288     movdqa [r0+16], xmm1
289     movdqa [r0+32], xmm2
290     movhlps   xmm0, xmm0
291     movdqa [r0+48], xmm3
292     movq   [r0+12], xmm0
293     movd   [r0+ 8], xmm1
294     RET
295