]> git.sesse.net Git - x264/blob - common/x86/dct-32.asm
Update file headers throughout x264
[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
28 SECTION_RODATA
29
30 pw_32: times 8 dw 32
31
32 SECTION .text
33
34 %macro SUMSUB_BA 2
35     paddw   %1, %2
36     paddw   %2, %2
37     psubw   %2, %1
38 %endmacro
39
40 %macro SBUTTERFLY 4
41     mova       m%4, m%2
42     punpckl%1  m%2, m%3
43     punpckh%1  m%4, m%3
44     SWAP %3, %4
45 %endmacro
46
47 %macro TRANSPOSE4x4W 5
48     SBUTTERFLY wd, %1, %2, %5
49     SBUTTERFLY wd, %3, %4, %5
50     SBUTTERFLY dq, %1, %3, %5
51     SBUTTERFLY dq, %2, %4, %5
52     SWAP %2, %3
53 %endmacro
54
55 %macro LOAD_DIFF_8P 4
56     movh       %1, %3
57     movh       %2, %4
58     punpcklbw  %1, %2
59     punpcklbw  %2, %2
60     psubw      %1, %2
61 %endmacro
62
63 %macro STORE_DIFF_8P 4
64     psraw      %1, 6
65     movh       %3, %2
66     punpcklbw  %3, %4
67     paddsw     %1, %3
68     packuswb   %1, %1
69     movh       %2, %1
70 %endmacro
71
72 ; in: m0..m7
73 ; out: 0,4,6 in mem, rest in regs
74 %macro DCT8_1D 9
75     SUMSUB_BA  m%8, m%1      ; %8 = s07, %1 = d07
76     SUMSUB_BA  m%7, m%2      ; %7 = s16, %2 = d16
77     SUMSUB_BA  m%6, m%3      ; %6 = s25, %3 = d25
78     SUMSUB_BA  m%5, m%4      ; %5 = s34, %4 = d34
79     SUMSUB_BA  m%5, m%8      ; %5 = a0,  %8 = a2
80     SUMSUB_BA  m%6, m%7      ; %6 = a1,  %7 = a3
81     SUMSUB_BA  m%6, m%5      ; %6 = dst0, %5 = dst4
82     mova    [%9+0x00], m%6
83     mova    [%9+0x40], m%5
84     mova    m%6, m%7         ; a3
85     psraw   m%6, 1           ; a3>>1
86     paddw   m%6, m%8         ; a2 + (a3>>1)
87     psraw   m%8, 1           ; a2>>1
88     psubw   m%8, m%7         ; (a2>>1) - a3
89     mova    [%9+0x60], m%8
90     mova    m%5, m%3
91     psraw   m%5, 1
92     paddw   m%5, m%3         ; d25+(d25>>1)
93     mova    m%7, m%1
94     psubw   m%7, m%4         ; a5 = d07-d34-(d25+(d25>>1))
95     psubw   m%7, m%5
96     mova    m%5, m%2
97     psraw   m%5, 1
98     paddw   m%5, m%2         ; d16+(d16>>1)
99     mova    m%8, m%1
100     paddw   m%8, m%4
101     psubw   m%8, m%5         ; a6 = d07+d34-(d16+(d16>>1))
102     mova    m%5, m%1
103     psraw   m%5, 1
104     paddw   m%5, m%1         ; d07+(d07>>1)
105     paddw   m%5, m%2
106     paddw   m%5, m%3         ; a4 = d16+d25+(d07+(d07>>1))
107     mova    m%1, m%4
108     psraw   m%1, 1
109     paddw   m%1, m%4         ; d34+(d34>>1)
110     paddw   m%1, m%2
111     psubw   m%1, m%3         ; a7 = d16-d25+(d34+(d34>>1))
112     mova    m%4, m%1
113     psraw   m%4, 2
114     paddw   m%4, m%5         ; a4 + (a7>>2)
115     mova    m%3, m%8
116     psraw   m%3, 2
117     paddw   m%3, m%7         ; a5 + (a6>>2)
118     psraw   m%5, 2
119     psraw   m%7, 2
120     psubw   m%5, m%1         ; (a4>>2) - a7
121     psubw   m%8, m%7         ; a6 - (a5>>2)
122     SWAP %2, %4, %3, %6, %8, %5
123 %endmacro
124
125 ; in: 0,4 in mem, rest in regs
126 ; out: m0..m7
127 %macro IDCT8_1D 9
128     mova      m%1, m%3
129     mova      m%5, m%7
130     psraw     m%3, 1
131     psraw     m%7, 1
132     psubw     m%3, m%5
133     paddw     m%7, m%1
134     mova      m%5, m%2
135     psraw     m%5, 1
136     paddw     m%5, m%2
137     paddw     m%5, m%4
138     paddw     m%5, m%6
139     mova      m%1, m%6
140     psraw     m%1, 1
141     paddw     m%1, m%6
142     paddw     m%1, m%8
143     psubw     m%1, m%2
144     psubw     m%2, m%4
145     psubw     m%6, m%4
146     paddw     m%2, m%8
147     psubw     m%6, m%8
148     psraw     m%4, 1
149     psraw     m%8, 1
150     psubw     m%2, m%4
151     psubw     m%6, m%8
152     mova      m%4, m%5
153     mova      m%8, m%1
154     psraw     m%4, 2
155     psraw     m%8, 2
156     paddw     m%4, m%6
157     paddw     m%8, m%2
158     psraw     m%6, 2
159     psraw     m%2, 2
160     psubw     m%5, m%6
161     psubw     m%2, m%1
162     mova      m%1, [%9+0x00]
163     mova      m%6, [%9+0x40]
164     SUMSUB_BA m%6, m%1
165     SUMSUB_BA m%7, m%6
166     SUMSUB_BA m%3, m%1
167     SUMSUB_BA m%5, m%7
168     SUMSUB_BA m%2, m%3
169     SUMSUB_BA m%8, m%1
170     SUMSUB_BA m%4, m%6
171     SWAP %1, %5, %6
172     SWAP %3, %8, %7
173 %endmacro
174
175 INIT_MMX
176 ALIGN 16
177 load_diff_4x8_mmx:
178     LOAD_DIFF_8P m0, m7, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
179     LOAD_DIFF_8P m1, m7, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
180     LOAD_DIFF_8P m2, m7, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
181     LOAD_DIFF_8P m3, m7, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
182     LOAD_DIFF_8P m4, m7, [r1+4*FENC_STRIDE], [r2+4*FDEC_STRIDE]
183     LOAD_DIFF_8P m5, m7, [r1+5*FENC_STRIDE], [r2+5*FDEC_STRIDE]
184     movq  [r0], m0
185     LOAD_DIFF_8P m6, m7, [r1+6*FENC_STRIDE], [r2+6*FDEC_STRIDE]
186     LOAD_DIFF_8P m7, m0, [r1+7*FENC_STRIDE], [r2+7*FDEC_STRIDE]
187     movq  m0, [r0]
188     ret
189
190 INIT_MMX
191 ALIGN 16
192 dct8_mmx:
193     DCT8_1D 0,1,2,3,4,5,6,7,r0
194     SAVE_MM_PERMUTATION dct8_mmx
195     ret
196
197 %macro SPILL_SHUFFLE 3-* ; ptr, list of regs, list of memory offsets
198     %xdefine %%base %1
199     %rep %0/2
200     %xdefine %%tmp m%2
201     %rotate %0/2
202     mova [%%base + %2*16], %%tmp
203     %rotate 1-%0/2
204     %endrep
205 %endmacro
206
207 %macro UNSPILL_SHUFFLE 3-*
208     %xdefine %%base %1
209     %rep %0/2
210     %xdefine %%tmp m%2
211     %rotate %0/2
212     mova %%tmp, [%%base + %2*16]
213     %rotate 1-%0/2
214     %endrep
215 %endmacro
216
217 %macro SPILL 2+ ; assume offsets are the same as reg numbers
218     SPILL_SHUFFLE %1, %2, %2
219 %endmacro
220
221 %macro UNSPILL 2+
222     UNSPILL_SHUFFLE %1, %2, %2
223 %endmacro
224
225 ;-----------------------------------------------------------------------------
226 ; void x264_sub8x8_dct8_mmx( int16_t dct[8][8], uint8_t *pix1, uint8_t *pix2 )
227 ;-----------------------------------------------------------------------------
228 cglobal x264_sub8x8_dct8_mmx, 3,3
229 global x264_sub8x8_dct8_mmx %+ .skip_prologue
230 .skip_prologue:
231     INIT_MMX
232     call load_diff_4x8_mmx
233     call dct8_mmx
234     UNSPILL r0, 0
235     TRANSPOSE4x4W 0,1,2,3,4
236     SPILL r0, 0,1,2,3
237     UNSPILL r0, 4,6
238     TRANSPOSE4x4W 4,5,6,7,0
239     SPILL r0, 4,5,6,7
240     INIT_MMX
241     add   r1, 4
242     add   r2, 4
243     add   r0, 8
244     call load_diff_4x8_mmx
245     sub   r1, 4
246     sub   r2, 4
247     call dct8_mmx
248     sub   r0, 8
249     UNSPILL r0+8, 4,6
250     TRANSPOSE4x4W 4,5,6,7,0
251     SPILL r0+8, 4,5,6,7
252     UNSPILL r0+8, 0
253     TRANSPOSE4x4W 0,1,2,3,5
254     UNSPILL r0, 4,5,6,7
255     SPILL_SHUFFLE r0, 0,1,2,3, 4,5,6,7
256     movq  mm4, m6 ; depends on the permutation to not produce conflicts
257     movq  mm0, m4
258     movq  mm1, m5
259     movq  mm2, mm4
260     movq  mm3, m7
261     INIT_MMX
262     UNSPILL r0+8, 4,5,6,7
263     add   r0, 8
264     call dct8_mmx
265     sub   r0, 8
266     SPILL r0+8, 1,2,3,5,7
267     INIT_MMX
268     UNSPILL r0, 0,1,2,3,4,5,6,7
269     call dct8_mmx
270     SPILL r0, 1,2,3,5,7
271     ret
272
273 INIT_MMX
274 ALIGN 16
275 idct8_mmx:
276     IDCT8_1D 0,1,2,3,4,5,6,7,r1
277     SAVE_MM_PERMUTATION idct8_mmx
278     ret
279
280 %macro ADD_STORE_ROW 3
281     movq  m1, [r0+%1*FDEC_STRIDE]
282     movq  m2, m1
283     punpcklbw m1, m0
284     punpckhbw m2, m0
285     paddw m1, %2
286     paddw m2, %3
287     packuswb m1, m2
288     movq  [r0+%1*FDEC_STRIDE], m1
289 %endmacro
290
291 ;-----------------------------------------------------------------------------
292 ; void x264_add8x8_idct8_mmx( uint8_t *dst, int16_t dct[8][8] )
293 ;-----------------------------------------------------------------------------
294 cglobal x264_add8x8_idct8_mmx, 2,2
295 global x264_add8x8_idct8_mmx %+ .skip_prologue
296 .skip_prologue:
297     INIT_MMX
298     add word [r1], 32
299     UNSPILL r1, 1,2,3,5,6,7
300     call idct8_mmx
301     SPILL r1, 7
302     TRANSPOSE4x4W 0,1,2,3,7
303     SPILL r1, 0,1,2,3
304     UNSPILL r1, 7
305     TRANSPOSE4x4W 4,5,6,7,0
306     SPILL r1, 4,5,6,7
307     INIT_MMX
308     UNSPILL r1+8, 1,2,3,5,6,7
309     add r1, 8
310     call idct8_mmx
311     sub r1, 8
312     SPILL r1+8, 7
313     TRANSPOSE4x4W 0,1,2,3,7
314     SPILL r1+8, 0,1,2,3
315     UNSPILL r1+8, 7
316     TRANSPOSE4x4W 4,5,6,7,0
317     SPILL r1+8, 4,5,6,7
318     INIT_MMX
319     movq  m3, [r1+0x08]
320     movq  m0, [r1+0x40]
321     movq  [r1+0x40], m3
322     movq  [r1+0x08], m0
323     ; memory layout at this time:
324     ; A0------ A1------
325     ; B0------ F0------
326     ; C0------ G0------
327     ; D0------ H0------
328     ; E0------ E1------
329     ; B1------ F1------
330     ; C1------ G1------
331     ; D1------ H1------
332     UNSPILL_SHUFFLE r1, 1,2,3, 5,6,7
333     UNSPILL r1+8, 5,6,7
334     add r1, 8
335     call idct8_mmx
336     sub r1, 8
337     psraw m0, 6
338     psraw m1, 6
339     psraw m2, 6
340     psraw m3, 6
341     psraw m4, 6
342     psraw m5, 6
343     psraw m6, 6
344     psraw m7, 6
345     movq  [r1+0x08], m0 ; mm4
346     movq  [r1+0x48], m4 ; mm5
347     movq  [r1+0x58], m5 ; mm0
348     movq  [r1+0x68], m6 ; mm2
349     movq  [r1+0x78], m7 ; mm6
350     movq  mm5, [r1+0x18]
351     movq  mm6, [r1+0x28]
352     movq  [r1+0x18], m1 ; mm1
353     movq  [r1+0x28], m2 ; mm7
354     movq  mm7, [r1+0x38]
355     movq  [r1+0x38], m3 ; mm3
356     movq  mm1, [r1+0x10]
357     movq  mm2, [r1+0x20]
358     movq  mm3, [r1+0x30]
359     call idct8_mmx
360     psraw m0, 6
361     psraw m1, 6
362     psraw m2, 6
363     psraw m3, 6
364     psraw m4, 6
365     psraw m5, 6
366     psraw m6, 6
367     psraw m7, 6
368     SPILL r1, 0,1,2
369     pxor  m0, m0
370     ADD_STORE_ROW 0, [r1+0x00], [r1+0x08]
371     ADD_STORE_ROW 1, [r1+0x10], [r1+0x18]
372     ADD_STORE_ROW 2, [r1+0x20], [r1+0x28]
373     ADD_STORE_ROW 3, m3, [r1+0x38]
374     ADD_STORE_ROW 4, m4, [r1+0x48]
375     ADD_STORE_ROW 5, m5, [r1+0x58]
376     ADD_STORE_ROW 6, m6, [r1+0x68]
377     ADD_STORE_ROW 7, m7, [r1+0x78]
378     ret
379
380
381
382 INIT_XMM
383
384 ; in: m0..m7, except m6 which is in [%9+0x60]
385 ; out: m0..m7, except m4 which is in [%9+0x40]
386 %macro TRANSPOSE8x8W 9
387     SBUTTERFLY wd, %1, %2, %7
388     movdqa [%9+16], m%2
389     movdqa m%7, [%9+0x60]
390     SBUTTERFLY wd, %3, %4, %2
391     SBUTTERFLY wd, %5, %6, %2
392     SBUTTERFLY wd, %7, %8, %2
393     SBUTTERFLY dq, %1, %3, %2
394     movdqa [%9], m%3
395     movdqa m%2, [%9+16]
396     SBUTTERFLY dq, %2, %4, %3
397     SBUTTERFLY dq, %5, %7, %3
398     SBUTTERFLY dq, %6, %8, %3
399     SBUTTERFLY qdq, %1, %5, %3
400     SBUTTERFLY qdq, %2, %6, %3
401     movdqa [%9+0x40], m%2
402     movdqa m%3, [%9]
403     SBUTTERFLY qdq, %3, %7, %2
404     SBUTTERFLY qdq, %4, %8, %2
405     SWAP %2, %5
406     SWAP %4, %7
407 %endmacro
408
409 ;-----------------------------------------------------------------------------
410 ; void x264_sub8x8_dct8_sse2( int16_t dct[8][8], uint8_t *pix1, uint8_t *pix2 )
411 ;-----------------------------------------------------------------------------
412 cglobal x264_sub8x8_dct8_sse2, 3,3
413 global x264_sub8x8_dct8_sse2 %+ .skip_prologue
414 .skip_prologue:
415     LOAD_DIFF_8P m0, m7, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
416     LOAD_DIFF_8P m1, m7, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
417     LOAD_DIFF_8P m2, m7, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
418     LOAD_DIFF_8P m3, m7, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
419     LOAD_DIFF_8P m4, m7, [r1+4*FENC_STRIDE], [r2+4*FDEC_STRIDE]
420     LOAD_DIFF_8P m5, m7, [r1+5*FENC_STRIDE], [r2+5*FDEC_STRIDE]
421     SPILL r0, 0
422     LOAD_DIFF_8P m6, m7, [r1+6*FENC_STRIDE], [r2+6*FDEC_STRIDE]
423     LOAD_DIFF_8P m7, m0, [r1+7*FENC_STRIDE], [r2+7*FDEC_STRIDE]
424     UNSPILL r0, 0
425     DCT8_1D 0,1,2,3,4,5,6,7,r0
426     UNSPILL r0, 0,4
427     TRANSPOSE8x8W 0,1,2,3,4,5,6,7,r0
428     UNSPILL r0, 4
429     DCT8_1D 0,1,2,3,4,5,6,7,r0
430     SPILL r0, 1,2,3,5,7
431     ret
432
433 ;-----------------------------------------------------------------------------
434 ; void x264_add8x8_idct8_sse2( uint8_t *p_dst, int16_t dct[8][8] )
435 ;-----------------------------------------------------------------------------
436 cglobal x264_add8x8_idct8_sse2, 2,2
437 global x264_add8x8_idct8_sse2 %+ .skip_prologue
438 .skip_prologue:
439     UNSPILL r1, 1,2,3,5,6,7
440     IDCT8_1D   0,1,2,3,4,5,6,7,r1
441     SPILL r1, 6
442     TRANSPOSE8x8W 0,1,2,3,4,5,6,7,r1
443     picgetgot  edx
444     paddw      m0, [pw_32 GLOBAL]
445     SPILL r1, 0
446     IDCT8_1D   0,1,2,3,4,5,6,7,r1
447     SPILL r1, 6,7
448     pxor       m7, m7
449     STORE_DIFF_8P m0, [r0+FDEC_STRIDE*0], m6, m7
450     STORE_DIFF_8P m1, [r0+FDEC_STRIDE*1], m6, m7
451     STORE_DIFF_8P m2, [r0+FDEC_STRIDE*2], m6, m7
452     STORE_DIFF_8P m3, [r0+FDEC_STRIDE*3], m6, m7
453     STORE_DIFF_8P m4, [r0+FDEC_STRIDE*4], m6, m7
454     STORE_DIFF_8P m5, [r0+FDEC_STRIDE*5], m6, m7
455     UNSPILL_SHUFFLE r1, 0,1, 6,7
456     STORE_DIFF_8P m0, [r0+FDEC_STRIDE*6], m6, m7
457     STORE_DIFF_8P m1, [r0+FDEC_STRIDE*7], m6, m7
458     ret
459