]> git.sesse.net Git - x264/blob - common/x86/dct-32.asm
Faster 8x8dct+CAVLC interleave
[x264] / common / x86 / dct-32.asm
1 ;*****************************************************************************
2 ;* dct-32.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2008 x264 project
5 ;*
6 ;* Authors: Laurent Aimar <fenrir@via.ecp.fr> (initial version)
7 ;*          Loren Merritt <lorenm@u.washington.edu> (misc)
8 ;*          Min Chen <chenm001.163.com> (converted to nasm)
9 ;*          Christian Heine <sennindemokrit@gmx.net> (dct8/idct8 functions)
10 ;*
11 ;* This program is free software; you can redistribute it and/or modify
12 ;* it under the terms of the GNU General Public License as published by
13 ;* the Free Software Foundation; either version 2 of the License, or
14 ;* (at your option) any later version.
15 ;*
16 ;* This program is distributed in the hope that it will be useful,
17 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;* GNU General Public License for more details.
20 ;*
21 ;* You should have received a copy of the GNU General Public License
22 ;* along with this program; if not, write to the Free Software
23 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
24 ;*****************************************************************************
25
26 %include "x86inc.asm"
27 %include "x86util.asm"
28
29 SECTION_RODATA
30
31 pw_32: times 8 dw 32
32
33 SECTION .text
34
35 ; in: m0..m7
36 ; out: 0,4,6 in mem, rest in regs
37 %macro DCT8_1D 9
38     SUMSUB_BA  m%8, m%1      ; %8 = s07, %1 = d07
39     SUMSUB_BA  m%7, m%2      ; %7 = s16, %2 = d16
40     SUMSUB_BA  m%6, m%3      ; %6 = s25, %3 = d25
41     SUMSUB_BA  m%5, m%4      ; %5 = s34, %4 = d34
42     SUMSUB_BA  m%5, m%8      ; %5 = a0,  %8 = a2
43     SUMSUB_BA  m%6, m%7      ; %6 = a1,  %7 = a3
44     SUMSUB_BA  m%6, m%5      ; %6 = dst0, %5 = dst4
45     mova    [%9+0x00], m%6
46     mova    [%9+0x40], m%5
47     mova    m%6, m%7         ; a3
48     psraw   m%6, 1           ; a3>>1
49     paddw   m%6, m%8         ; a2 + (a3>>1)
50     psraw   m%8, 1           ; a2>>1
51     psubw   m%8, m%7         ; (a2>>1) - a3
52     mova    [%9+0x60], m%8
53     mova    m%5, m%3
54     psraw   m%5, 1
55     paddw   m%5, m%3         ; d25+(d25>>1)
56     mova    m%7, m%1
57     psubw   m%7, m%4         ; a5 = d07-d34-(d25+(d25>>1))
58     psubw   m%7, m%5
59     mova    m%5, m%2
60     psraw   m%5, 1
61     paddw   m%5, m%2         ; d16+(d16>>1)
62     mova    m%8, m%1
63     paddw   m%8, m%4
64     psubw   m%8, m%5         ; a6 = d07+d34-(d16+(d16>>1))
65     mova    m%5, m%1
66     psraw   m%5, 1
67     paddw   m%5, m%1         ; d07+(d07>>1)
68     paddw   m%5, m%2
69     paddw   m%5, m%3         ; a4 = d16+d25+(d07+(d07>>1))
70     mova    m%1, m%4
71     psraw   m%1, 1
72     paddw   m%1, m%4         ; d34+(d34>>1)
73     paddw   m%1, m%2
74     psubw   m%1, m%3         ; a7 = d16-d25+(d34+(d34>>1))
75     mova    m%4, m%1
76     psraw   m%4, 2
77     paddw   m%4, m%5         ; a4 + (a7>>2)
78     mova    m%3, m%8
79     psraw   m%3, 2
80     paddw   m%3, m%7         ; a5 + (a6>>2)
81     psraw   m%5, 2
82     psraw   m%7, 2
83     psubw   m%5, m%1         ; (a4>>2) - a7
84     psubw   m%8, m%7         ; a6 - (a5>>2)
85     SWAP %2, %4, %3, %6, %8, %5
86 %endmacro
87
88 ; in: 0,4 in mem, rest in regs
89 ; out: m0..m7
90 %macro IDCT8_1D 9
91     mova      m%1, m%3
92     mova      m%5, m%7
93     psraw     m%3, 1
94     psraw     m%7, 1
95     psubw     m%3, m%5
96     paddw     m%7, m%1
97     mova      m%5, m%2
98     psraw     m%5, 1
99     paddw     m%5, m%2
100     paddw     m%5, m%4
101     paddw     m%5, m%6
102     mova      m%1, m%6
103     psraw     m%1, 1
104     paddw     m%1, m%6
105     paddw     m%1, m%8
106     psubw     m%1, m%2
107     psubw     m%2, m%4
108     psubw     m%6, m%4
109     paddw     m%2, m%8
110     psubw     m%6, m%8
111     psraw     m%4, 1
112     psraw     m%8, 1
113     psubw     m%2, m%4
114     psubw     m%6, m%8
115     mova      m%4, m%5
116     mova      m%8, m%1
117     psraw     m%4, 2
118     psraw     m%8, 2
119     paddw     m%4, m%6
120     paddw     m%8, m%2
121     psraw     m%6, 2
122     psraw     m%2, 2
123     psubw     m%5, m%6
124     psubw     m%2, m%1
125     mova      m%1, [%9+0x00]
126     mova      m%6, [%9+0x40]
127     SUMSUB_BA m%6, m%1
128     SUMSUB_BA m%7, m%6
129     SUMSUB_BA m%3, m%1
130     SUMSUB_BA m%5, m%7
131     SUMSUB_BA m%2, m%3
132     SUMSUB_BA m%8, m%1
133     SUMSUB_BA m%4, m%6
134     SWAP %1, %5, %6
135     SWAP %3, %8, %7
136 %endmacro
137
138 INIT_MMX
139 ALIGN 16
140 load_diff_4x8_mmx:
141     LOAD_DIFF m0, m7, none, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
142     LOAD_DIFF m1, m7, none, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
143     LOAD_DIFF m2, m7, none, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
144     LOAD_DIFF m3, m7, none, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
145     LOAD_DIFF m4, m7, none, [r1+4*FENC_STRIDE], [r2+4*FDEC_STRIDE]
146     LOAD_DIFF m5, m7, none, [r1+5*FENC_STRIDE], [r2+5*FDEC_STRIDE]
147     movq  [r0], m0
148     LOAD_DIFF m6, m7, none, [r1+6*FENC_STRIDE], [r2+6*FDEC_STRIDE]
149     LOAD_DIFF m7, m0, none, [r1+7*FENC_STRIDE], [r2+7*FDEC_STRIDE]
150     movq  m0, [r0]
151     ret
152
153 INIT_MMX
154 ALIGN 16
155 dct8_mmx:
156     DCT8_1D 0,1,2,3,4,5,6,7,r0
157     SAVE_MM_PERMUTATION dct8_mmx
158     ret
159
160 %macro SPILL_SHUFFLE 3-* ; ptr, list of regs, list of memory offsets
161     %xdefine %%base %1
162     %rep %0/2
163     %xdefine %%tmp m%2
164     %rotate %0/2
165     mova [%%base + %2*16], %%tmp
166     %rotate 1-%0/2
167     %endrep
168 %endmacro
169
170 %macro UNSPILL_SHUFFLE 3-*
171     %xdefine %%base %1
172     %rep %0/2
173     %xdefine %%tmp m%2
174     %rotate %0/2
175     mova %%tmp, [%%base + %2*16]
176     %rotate 1-%0/2
177     %endrep
178 %endmacro
179
180 %macro SPILL 2+ ; assume offsets are the same as reg numbers
181     SPILL_SHUFFLE %1, %2, %2
182 %endmacro
183
184 %macro UNSPILL 2+
185     UNSPILL_SHUFFLE %1, %2, %2
186 %endmacro
187
188 ;-----------------------------------------------------------------------------
189 ; void x264_sub8x8_dct8_mmx( int16_t dct[8][8], uint8_t *pix1, uint8_t *pix2 )
190 ;-----------------------------------------------------------------------------
191 cglobal x264_sub8x8_dct8_mmx, 3,3
192 global x264_sub8x8_dct8_mmx %+ .skip_prologue
193 .skip_prologue:
194     INIT_MMX
195     call load_diff_4x8_mmx
196     call dct8_mmx
197     UNSPILL r0, 0
198     TRANSPOSE4x4W 0,1,2,3,4
199     SPILL r0, 0,1,2,3
200     UNSPILL r0, 4,6
201     TRANSPOSE4x4W 4,5,6,7,0
202     SPILL r0, 4,5,6,7
203     INIT_MMX
204     add   r1, 4
205     add   r2, 4
206     add   r0, 8
207     call load_diff_4x8_mmx
208     sub   r1, 4
209     sub   r2, 4
210     call dct8_mmx
211     sub   r0, 8
212     UNSPILL r0+8, 4,6
213     TRANSPOSE4x4W 4,5,6,7,0
214     SPILL r0+8, 4,5,6,7
215     UNSPILL r0+8, 0
216     TRANSPOSE4x4W 0,1,2,3,5
217     UNSPILL r0, 4,5,6,7
218     SPILL_SHUFFLE r0, 0,1,2,3, 4,5,6,7
219     movq  mm4, m6 ; depends on the permutation to not produce conflicts
220     movq  mm0, m4
221     movq  mm1, m5
222     movq  mm2, mm4
223     movq  mm3, m7
224     INIT_MMX
225     UNSPILL r0+8, 4,5,6,7
226     add   r0, 8
227     call dct8_mmx
228     sub   r0, 8
229     SPILL r0+8, 1,2,3,5,7
230     INIT_MMX
231     UNSPILL r0, 0,1,2,3,4,5,6,7
232     call dct8_mmx
233     SPILL r0, 1,2,3,5,7
234     ret
235
236 INIT_MMX
237 ALIGN 16
238 idct8_mmx:
239     IDCT8_1D 0,1,2,3,4,5,6,7,r1
240     SAVE_MM_PERMUTATION idct8_mmx
241     ret
242
243 %macro ADD_STORE_ROW 3
244     movq  m1, [r0+%1*FDEC_STRIDE]
245     movq  m2, m1
246     punpcklbw m1, m0
247     punpckhbw m2, m0
248     paddw m1, %2
249     paddw m2, %3
250     packuswb m1, m2
251     movq  [r0+%1*FDEC_STRIDE], m1
252 %endmacro
253
254 ;-----------------------------------------------------------------------------
255 ; void x264_add8x8_idct8_mmx( uint8_t *dst, int16_t dct[8][8] )
256 ;-----------------------------------------------------------------------------
257 cglobal x264_add8x8_idct8_mmx, 2,2
258 global x264_add8x8_idct8_mmx %+ .skip_prologue
259 .skip_prologue:
260     INIT_MMX
261     add word [r1], 32
262     UNSPILL r1, 1,2,3,5,6,7
263     call idct8_mmx
264     SPILL r1, 7
265     TRANSPOSE4x4W 0,1,2,3,7
266     SPILL r1, 0,1,2,3
267     UNSPILL r1, 7
268     TRANSPOSE4x4W 4,5,6,7,0
269     SPILL r1, 4,5,6,7
270     INIT_MMX
271     UNSPILL r1+8, 1,2,3,5,6,7
272     add r1, 8
273     call idct8_mmx
274     sub r1, 8
275     SPILL r1+8, 7
276     TRANSPOSE4x4W 0,1,2,3,7
277     SPILL r1+8, 0,1,2,3
278     UNSPILL r1+8, 7
279     TRANSPOSE4x4W 4,5,6,7,0
280     SPILL r1+8, 4,5,6,7
281     INIT_MMX
282     movq  m3, [r1+0x08]
283     movq  m0, [r1+0x40]
284     movq  [r1+0x40], m3
285     movq  [r1+0x08], m0
286     ; memory layout at this time:
287     ; A0------ A1------
288     ; B0------ F0------
289     ; C0------ G0------
290     ; D0------ H0------
291     ; E0------ E1------
292     ; B1------ F1------
293     ; C1------ G1------
294     ; D1------ H1------
295     UNSPILL_SHUFFLE r1, 1,2,3, 5,6,7
296     UNSPILL r1+8, 5,6,7
297     add r1, 8
298     call idct8_mmx
299     sub r1, 8
300     psraw m0, 6
301     psraw m1, 6
302     psraw m2, 6
303     psraw m3, 6
304     psraw m4, 6
305     psraw m5, 6
306     psraw m6, 6
307     psraw m7, 6
308     movq  [r1+0x08], m0 ; mm4
309     movq  [r1+0x48], m4 ; mm5
310     movq  [r1+0x58], m5 ; mm0
311     movq  [r1+0x68], m6 ; mm2
312     movq  [r1+0x78], m7 ; mm6
313     movq  mm5, [r1+0x18]
314     movq  mm6, [r1+0x28]
315     movq  [r1+0x18], m1 ; mm1
316     movq  [r1+0x28], m2 ; mm7
317     movq  mm7, [r1+0x38]
318     movq  [r1+0x38], m3 ; mm3
319     movq  mm1, [r1+0x10]
320     movq  mm2, [r1+0x20]
321     movq  mm3, [r1+0x30]
322     call idct8_mmx
323     psraw m0, 6
324     psraw m1, 6
325     psraw m2, 6
326     psraw m3, 6
327     psraw m4, 6
328     psraw m5, 6
329     psraw m6, 6
330     psraw m7, 6
331     SPILL r1, 0,1,2
332     pxor  m0, m0
333     ADD_STORE_ROW 0, [r1+0x00], [r1+0x08]
334     ADD_STORE_ROW 1, [r1+0x10], [r1+0x18]
335     ADD_STORE_ROW 2, [r1+0x20], [r1+0x28]
336     ADD_STORE_ROW 3, m3, [r1+0x38]
337     ADD_STORE_ROW 4, m4, [r1+0x48]
338     ADD_STORE_ROW 5, m5, [r1+0x58]
339     ADD_STORE_ROW 6, m6, [r1+0x68]
340     ADD_STORE_ROW 7, m7, [r1+0x78]
341     ret
342
343
344
345 INIT_XMM
346
347 ;-----------------------------------------------------------------------------
348 ; void x264_sub8x8_dct8_sse2( int16_t dct[8][8], uint8_t *pix1, uint8_t *pix2 )
349 ;-----------------------------------------------------------------------------
350 cglobal x264_sub8x8_dct8_sse2, 3,3
351 global x264_sub8x8_dct8_sse2 %+ .skip_prologue
352 .skip_prologue:
353     LOAD_DIFF m0, m7, none, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
354     LOAD_DIFF m1, m7, none, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
355     LOAD_DIFF m2, m7, none, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
356     LOAD_DIFF m3, m7, none, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
357     LOAD_DIFF m4, m7, none, [r1+4*FENC_STRIDE], [r2+4*FDEC_STRIDE]
358     LOAD_DIFF m5, m7, none, [r1+5*FENC_STRIDE], [r2+5*FDEC_STRIDE]
359     SPILL r0, 0
360     LOAD_DIFF m6, m7, none, [r1+6*FENC_STRIDE], [r2+6*FDEC_STRIDE]
361     LOAD_DIFF m7, m0, none, [r1+7*FENC_STRIDE], [r2+7*FDEC_STRIDE]
362     UNSPILL r0, 0
363     DCT8_1D 0,1,2,3,4,5,6,7,r0
364     UNSPILL r0, 0,4
365     TRANSPOSE8x8W 0,1,2,3,4,5,6,7,[r0+0x60],[r0+0x40],1
366     UNSPILL r0, 4
367     DCT8_1D 0,1,2,3,4,5,6,7,r0
368     SPILL r0, 1,2,3,5,7
369     ret
370
371 ;-----------------------------------------------------------------------------
372 ; void x264_add8x8_idct8_sse2( uint8_t *p_dst, int16_t dct[8][8] )
373 ;-----------------------------------------------------------------------------
374 cglobal x264_add8x8_idct8_sse2, 2,2
375 global x264_add8x8_idct8_sse2 %+ .skip_prologue
376 .skip_prologue:
377     UNSPILL r1, 1,2,3,5,6,7
378     IDCT8_1D   0,1,2,3,4,5,6,7,r1
379     SPILL r1, 6
380     TRANSPOSE8x8W 0,1,2,3,4,5,6,7,[r1+0x60],[r1+0x40],1
381     paddw      m0, [pw_32 GLOBAL]
382     SPILL r1, 0
383     IDCT8_1D   0,1,2,3,4,5,6,7,r1
384     SPILL r1, 6,7
385     pxor       m7, m7
386     STORE_DIFF m0, m6, m7, [r0+FDEC_STRIDE*0]
387     STORE_DIFF m1, m6, m7, [r0+FDEC_STRIDE*1]
388     STORE_DIFF m2, m6, m7, [r0+FDEC_STRIDE*2]
389     STORE_DIFF m3, m6, m7, [r0+FDEC_STRIDE*3]
390     STORE_DIFF m4, m6, m7, [r0+FDEC_STRIDE*4]
391     STORE_DIFF m5, m6, m7, [r0+FDEC_STRIDE*5]
392     UNSPILL_SHUFFLE r1, 0,1, 6,7
393     STORE_DIFF m0, m6, m7, [r0+FDEC_STRIDE*6]
394     STORE_DIFF m1, m6, m7, [r0+FDEC_STRIDE*7]
395     ret
396