]> git.sesse.net Git - x264/blob - common/x86/dct-a.asm
rearrange cabac struct to reduce code size
[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 5
75     mov%1       %5, %3
76     punpckl%2   %3, %4
77     punpckh%2   %5, %4
78 %endmacro
79
80 ;-----------------------------------------------------------------------------
81 ; input ABCD output ADTC
82 ;-----------------------------------------------------------------------------
83 %macro TRANSPOSE4x4W 5
84     SBUTTERFLY q, wd, %1, %2, %5
85     SBUTTERFLY q, wd, %3, %4, %2
86     SBUTTERFLY q, dq, %1, %3, %4
87     SBUTTERFLY q, dq, %5, %2, %3
88 %endmacro
89
90 %macro STORE_DIFF_4P 5
91     paddw       %1, %3
92     psraw       %1, 6
93     movd        %2, %5
94     punpcklbw   %2, %4
95     paddsw      %1, %2
96     packuswb    %1, %1
97     movd        %5, %1
98 %endmacro
99
100 ;-----------------------------------------------------------------------------
101 ; void x264_dct4x4dc_mmx( int16_t d[4][4] )
102 ;-----------------------------------------------------------------------------
103 cglobal x264_dct4x4dc_mmx, 1,1,1
104     movq      mm0, [r0+ 0]
105     movq      mm1, [r0+ 8]
106     movq      mm2, [r0+16]
107     movq      mm3, [r0+24]
108
109     SUMSUB_BADC    mm1, mm0, mm3, mm2          ; mm1=s01  mm0=d01  mm3=s23  mm2=d23
110     SUMSUB_BADC    mm3, mm1, mm2, mm0          ; mm3=s01+s23  mm1=s01-s23  mm2=d01+d23  mm0=d01-d23
111
112     TRANSPOSE4x4W  mm3, mm1, mm0, mm2, mm4     ; in: mm3, mm1, mm0, mm2  out: mm3, mm2, mm4, mm0 
113
114     SUMSUB_BADC    mm2, mm3, mm0, mm4          ; mm2=s01  mm3=d01  mm0=s23  mm4=d23
115     SUMSUB_BADC    mm0, mm2, mm4, mm3          ; mm0=s01+s23  mm2=s01-s23  mm4=d01+d23  mm3=d01-d23
116
117     movq      mm6, [pw_1 GLOBAL]
118     paddw     mm0, mm6
119     paddw     mm2, mm6
120     psraw     mm0, 1
121     movq  [r0+ 0], mm0
122     psraw     mm2, 1
123     movq  [r0+ 8], mm2
124     paddw     mm3, mm6
125     paddw     mm4, mm6
126     psraw     mm3, 1
127     movq  [r0+16], mm3
128     psraw     mm4, 1
129     movq  [r0+24], mm4
130     RET
131
132 ;-----------------------------------------------------------------------------
133 ; void x264_idct4x4dc_mmx( int16_t d[4][4] )
134 ;-----------------------------------------------------------------------------
135 cglobal x264_idct4x4dc_mmx, 1,1
136     movq    mm0, [r0+ 0]
137     movq    mm1, [r0+ 8]
138     movq    mm2, [r0+16]
139     movq    mm3, [r0+24]
140
141     SUMSUB_BADC    mm1, mm0, mm3, mm2          ; mm1=s01  mm0=d01  mm3=s23  mm2=d23
142     SUMSUB_BADC    mm3, mm1, mm2, mm0          ; mm3=s01+s23 mm1=s01-s23 mm2=d01+d23 mm0=d01-d23
143
144     TRANSPOSE4x4W  mm3, mm1, mm0, mm2, mm4     ; in: mm3, mm1, mm0, mm2  out: mm3, mm2, mm4, mm0 
145
146     SUMSUB_BADC    mm2, mm3, mm0, mm4          ; mm2=s01  mm3=d01  mm0=s23  mm4=d23
147     SUMSUB_BADC    mm0, mm2, mm4, mm3          ; mm0=s01+s23  mm2=s01-s23  mm4=d01+d23  mm3=d01-d23
148
149     movq    [r0+ 0], mm0
150     movq    [r0+ 8], mm2
151     movq    [r0+16], mm3
152     movq    [r0+24], mm4
153     RET
154
155 ;-----------------------------------------------------------------------------
156 ; void x264_sub4x4_dct_mmx( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
157 ;-----------------------------------------------------------------------------
158 cglobal x264_sub4x4_dct_mmx, 3,3
159 .skip_prologue:
160     pxor mm7, mm7
161
162     ; Load 4 lines
163     LOAD_DIFF_4P   mm0, mm6, mm7, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
164     LOAD_DIFF_4P   mm1, mm6, mm7, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
165     LOAD_DIFF_4P   mm2, mm6, mm7, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
166     LOAD_DIFF_4P   mm3, mm6, mm7, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
167
168     SUMSUB_BADC    mm3, mm0, mm2, mm1          ; mm3=s03  mm0=d03  mm2=s12  mm1=d12
169
170     SUMSUB_BA      mm2, mm3                    ; mm2=s03+s12      mm3=s03-s12
171     SUMSUB2_AB     mm0, mm1, mm4               ; mm0=2.d03+d12    mm4=d03-2.d12
172
173     ; transpose in: mm2, mm0, mm3, mm4, out: mm2, mm4, mm1, mm3
174     TRANSPOSE4x4W  mm2, mm0, mm3, mm4, mm1
175
176     SUMSUB_BADC    mm3, mm2, mm1, mm4          ; mm3=s03  mm2=d03  mm1=s12  mm4=d12
177
178     SUMSUB_BA      mm1, mm3                    ; mm1=s03+s12      mm3=s03-s12
179     SUMSUB2_AB     mm2, mm4, mm0               ; mm2=2.d03+d12    mm0=d03-2.d12
180
181     movq    [r0+ 0], mm1
182     movq    [r0+ 8], mm2
183     movq    [r0+16], mm3
184     movq    [r0+24], mm0
185     RET
186
187 ;-----------------------------------------------------------------------------
188 ; void x264_add4x4_idct_mmx( uint8_t *p_dst, int16_t dct[4][4] )
189 ;-----------------------------------------------------------------------------
190 cglobal x264_add4x4_idct_mmx, 2,2,1
191 .skip_prologue:
192     ; Load dct coeffs
193     movq    mm0, [r1+ 0] ; dct
194     movq    mm1, [r1+ 8]
195     movq    mm2, [r1+16]
196     movq    mm3, [r1+24]
197     
198     SUMSUB_BA      mm2, mm0                        ; mm2=s02  mm0=d02
199     SUMSUBD2_AB    mm1, mm3, mm5, mm4              ; mm1=s13  mm4=d13 ( well 1 + 3>>1 and 1>>1 + 3)
200
201     SUMSUB_BADC    mm1, mm2, mm4, mm0              ; mm1=s02+s13  mm2=s02-s13  mm4=d02+d13  mm0=d02-d13
202
203     ; in: mm1, mm4, mm0, mm2  out: mm1, mm2, mm3, mm0
204     TRANSPOSE4x4W  mm1, mm4, mm0, mm2, mm3
205
206     SUMSUB_BA      mm3, mm1                        ; mm3=s02  mm1=d02
207     SUMSUBD2_AB    mm2, mm0, mm5, mm4              ; mm2=s13  mm4=d13 ( well 1 + 3>>1 and 1>>1 + 3)
208
209     SUMSUB_BADC    mm2, mm3, mm4, mm1              ; mm2=s02+s13  mm3=s02-s13  mm4=d02+d13  mm1=d02-d13
210
211     pxor mm7, mm7
212     movq           mm6, [pw_32 GLOBAL]
213     
214     STORE_DIFF_4P  mm2, mm0, mm6, mm7, [r0+0*FDEC_STRIDE]
215     STORE_DIFF_4P  mm4, mm0, mm6, mm7, [r0+1*FDEC_STRIDE]
216     STORE_DIFF_4P  mm1, mm0, mm6, mm7, [r0+2*FDEC_STRIDE]
217     STORE_DIFF_4P  mm3, mm0, mm6, mm7, [r0+3*FDEC_STRIDE]
218
219     RET
220
221
222
223 ;-----------------------------------------------------------------------------
224 ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
225 ;-----------------------------------------------------------------------------
226 %macro SUB_NxN_DCT 6
227 cglobal %1, 3,3
228 .skip_prologue:
229     call %2
230     add  r0, %3
231     add  r1, %4-%5*FENC_STRIDE
232     add  r2, %4-%5*FDEC_STRIDE
233     call %2
234     add  r0, %3
235     add  r1, %4*FENC_STRIDE-%6
236     add  r2, %4*FDEC_STRIDE-%6
237     call %2
238     add  r0, %3
239     add  r1, %4-%5*FENC_STRIDE
240     add  r2, %4-%5*FDEC_STRIDE
241     jmp  %2
242 %endmacro
243
244 ;-----------------------------------------------------------------------------
245 ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
246 ;-----------------------------------------------------------------------------
247 %macro ADD_NxN_IDCT 6
248 cglobal %1, 2,2,1
249 .skip_prologue:
250     call %2
251     add  r0, %4-%5*FDEC_STRIDE
252     add  r1, %3
253     call %2
254     add  r0, %4*FDEC_STRIDE-%6
255     add  r1, %3
256     call %2
257     add  r0, %4-%5*FDEC_STRIDE
258     add  r1, %3
259     jmp  %2
260 %endmacro
261
262 SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx  %+ .skip_prologue, 32, 4, 0,  4
263 ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx %+ .skip_prologue, 32, 4, 0,  4
264
265 SUB_NxN_DCT  x264_sub16x16_dct_mmx,  x264_sub8x8_dct_mmx  %+ .skip_prologue, 32, 4, 4, 12
266 ADD_NxN_IDCT x264_add16x16_idct_mmx, x264_add8x8_idct_mmx %+ .skip_prologue, 32, 4, 4, 12
267
268 %ifdef ARCH_X86_64
269 cextern x264_sub8x8_dct8_sse2
270 cextern x264_add8x8_idct8_sse2
271 SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2,  128, 8, 0,  8
272 ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2, 128, 8, 0,  8
273 %endif
274
275
276
277 ;-----------------------------------------------------------------------------
278 ; void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] )
279 ;-----------------------------------------------------------------------------
280 ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
281 cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
282     pshufw     mm0, [r1+4], 0xd2
283     movq       mm1, [r1+16]
284     movq       mm2, [r1+24]
285     movq    [r0+4], mm0
286     movq   [r0+16], mm1
287     movq   [r0+24], mm2
288     mov        r2d, [r1]
289     mov       [r0], r2d
290     mov        r2d, [r1+12]
291     mov    [r0+12], r2d
292     RET
293
294 %ifdef HAVE_SSE3
295 ;-----------------------------------------------------------------------------
296 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
297 ;-----------------------------------------------------------------------------
298 cglobal x264_zigzag_sub_4x4_frame_ssse3, 3,3
299     movd      xmm0, [r1+0*FENC_STRIDE]
300     movd      xmm1, [r1+1*FENC_STRIDE]
301     movd      xmm2, [r1+2*FENC_STRIDE]
302     movd      xmm3, [r1+3*FENC_STRIDE]
303     movd      xmm4, [r2+0*FDEC_STRIDE]
304     movd      xmm5, [r2+1*FDEC_STRIDE]
305     movd      xmm6, [r2+2*FDEC_STRIDE]
306     movd      xmm7, [r2+3*FDEC_STRIDE]
307     movd      [r2+0*FDEC_STRIDE], xmm0
308     movd      [r2+1*FDEC_STRIDE], xmm1
309     movd      [r2+2*FDEC_STRIDE], xmm2
310     movd      [r2+3*FDEC_STRIDE], xmm3
311     picgetgot r1
312     punpckldq xmm0, xmm1
313     punpckldq xmm2, xmm3
314     punpckldq xmm4, xmm5
315     punpckldq xmm6, xmm7
316     movlhps   xmm0, xmm2
317     movlhps   xmm4, xmm6
318     movdqa    xmm7, [pb_zigzag4 GLOBAL]
319     pshufb    xmm0, xmm7
320     pshufb    xmm4, xmm7
321     pxor      xmm6, xmm6
322     movdqa    xmm1, xmm0
323     movdqa    xmm5, xmm4
324     punpcklbw xmm0, xmm6
325     punpckhbw xmm1, xmm6
326     punpcklbw xmm4, xmm6
327     punpckhbw xmm5, xmm6
328     psubw     xmm0, xmm4
329     psubw     xmm1, xmm5
330     movdqa    [r0], xmm0
331     movdqa [r0+16], xmm1
332     RET
333 %endif