]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/h264_idct_10bit.asm
2x faster h264_idct_add8_10.
[ffmpeg] / libavcodec / x86 / h264_idct_10bit.asm
1 ;*****************************************************************************
2 ;* MMX/SSE2/AVX-optimized 10-bit H.264 iDCT code
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2011 x264 project
5 ;*
6 ;* Authors: Daniel Kang <daniel.d.kang@gmail.com>
7 ;*
8 ;* This file is part of Libav.
9 ;*
10 ;* Libav is free software; you can redistribute it and/or
11 ;* modify it under the terms of the GNU Lesser General Public
12 ;* License as published by the Free Software Foundation; either
13 ;* version 2.1 of the License, or (at your option) any later version.
14 ;*
15 ;* Libav 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 GNU
18 ;* Lesser General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU Lesser General Public
21 ;* License along with Libav; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ;******************************************************************************
24
25 %include "x86inc.asm"
26 %include "x86util.asm"
27
28 SECTION_RODATA
29
30 pw_pixel_max: times 8 dw ((1 << 10)-1)
31 pd_32:        times 4 dd 32
32 scan8_mem: db 4+1*8, 5+1*8, 4+2*8, 5+2*8
33            db 6+1*8, 7+1*8, 6+2*8, 7+2*8
34            db 4+3*8, 5+3*8, 4+4*8, 5+4*8
35            db 6+3*8, 7+3*8, 6+4*8, 7+4*8
36            db 1+1*8, 2+1*8
37            db 1+2*8, 2+2*8
38            db 1+4*8, 2+4*8
39            db 1+5*8, 2+5*8
40
41 %ifdef PIC
42 %define scan8 r11
43 %else
44 %define scan8 scan8_mem
45 %endif
46
47 SECTION .text
48
49 ;-----------------------------------------------------------------------------
50 ; void h264_idct_add(pixel *dst, dctcoef *block, int stride)
51 ;-----------------------------------------------------------------------------
52 %macro STORE_DIFFx2 6
53     psrad       %1, 6
54     psrad       %2, 6
55     packssdw    %1, %2
56     movq        %3, [%5]
57     movhps      %3, [%5+%6]
58     paddsw      %1, %3
59     CLIPW       %1, %4, [pw_pixel_max]
60     movq      [%5], %1
61     movhps [%5+%6], %1
62 %endmacro
63
64 %macro STORE_DIFF16 5
65     psrad       %1, 6
66     psrad       %2, 6
67     packssdw    %1, %2
68     paddsw      %1, [%5]
69     CLIPW       %1, %3, %4
70     mova      [%5], %1
71 %endmacro
72
73 ;dst, in, stride
74 %macro IDCT4_ADD_10 3
75     mova  m0, [%2+ 0]
76     mova  m1, [%2+16]
77     mova  m2, [%2+32]
78     mova  m3, [%2+48]
79     IDCT4_1D d,0,1,2,3,4,5
80     TRANSPOSE4x4D 0,1,2,3,4
81     paddd m0, [pd_32]
82     IDCT4_1D d,0,1,2,3,4,5
83     pxor  m5, m5
84     STORE_DIFFx2 m0, m1, m4, m5, %1, %3
85     lea   %1, [%1+%3*2]
86     STORE_DIFFx2 m2, m3, m4, m5, %1, %3
87 %endmacro
88
89 %macro IDCT_ADD_10 1
90 cglobal h264_idct_add_10_%1, 3,3
91     IDCT4_ADD_10 r0, r1, r2
92     RET
93 %endmacro
94
95 INIT_XMM
96 IDCT_ADD_10 sse2
97 %ifdef HAVE_AVX
98 INIT_AVX
99 IDCT_ADD_10 avx
100 %endif
101
102 ;-----------------------------------------------------------------------------
103 ; h264_idct_add16(pixel *dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
104 ;-----------------------------------------------------------------------------
105 ;;;;;;; NO FATE SAMPLES TRIGGER THIS
106 %macro ADD4x4IDCT 1
107 add4x4_idct_%1:
108     add   r5, r0
109     mova  m0, [r2+ 0]
110     mova  m1, [r2+16]
111     mova  m2, [r2+32]
112     mova  m3, [r2+48]
113     IDCT4_1D d,0,1,2,3,4,5
114     TRANSPOSE4x4D 0,1,2,3,4
115     paddd m0, [pd_32]
116     IDCT4_1D d,0,1,2,3,4,5
117     pxor  m5, m5
118     STORE_DIFFx2 m0, m1, m4, m5, r5, r3
119     lea   r5, [r5+r3*2]
120     STORE_DIFFx2 m2, m3, m4, m5, r5, r3
121     ret
122 %endmacro
123
124 INIT_XMM
125 ALIGN 16
126 ADD4x4IDCT sse2
127 %ifdef HAVE_AVX
128 INIT_AVX
129 ALIGN 16
130 ADD4x4IDCT avx
131 %endif
132
133 %macro ADD16_OP 3
134     cmp          byte [r4+%3], 0
135     jz .skipblock%2
136     mov         r5d, dword [r1+%2*4]
137     call add4x4_idct_%1
138 .skipblock%2:
139 %if %2<15
140     add          r2, 64
141 %endif
142 %endmacro
143
144 %macro IDCT_ADD16_10 1
145 cglobal h264_idct_add16_10_%1, 5,6
146     ADD16_OP %1, 0, 4+1*8
147     ADD16_OP %1, 1, 5+1*8
148     ADD16_OP %1, 2, 4+2*8
149     ADD16_OP %1, 3, 5+2*8
150     ADD16_OP %1, 4, 6+1*8
151     ADD16_OP %1, 5, 7+1*8
152     ADD16_OP %1, 6, 6+2*8
153     ADD16_OP %1, 7, 7+2*8
154     ADD16_OP %1, 8, 4+3*8
155     ADD16_OP %1, 9, 5+3*8
156     ADD16_OP %1, 10, 4+4*8
157     ADD16_OP %1, 11, 5+4*8
158     ADD16_OP %1, 12, 6+3*8
159     ADD16_OP %1, 13, 7+3*8
160     ADD16_OP %1, 14, 6+4*8
161     ADD16_OP %1, 15, 7+4*8
162     RET
163 %endmacro
164
165 INIT_XMM
166 IDCT_ADD16_10 sse2
167 %ifdef HAVE_AVX
168 INIT_AVX
169 IDCT_ADD16_10 avx
170 %endif
171
172 ;-----------------------------------------------------------------------------
173 ; void h264_idct_dc_add(pixel *dst, dctcoef *block, int stride)
174 ;-----------------------------------------------------------------------------
175 %macro IDCT_DC_ADD_OP_10 3
176     pxor      m5, m5
177 %if avx_enabled
178     paddw     m1, m0, [%1+0   ]
179     paddw     m2, m0, [%1+%2  ]
180     paddw     m3, m0, [%1+%2*2]
181     paddw     m4, m0, [%1+%3  ]
182 %else
183     mova      m1, [%1+0   ]
184     mova      m2, [%1+%2  ]
185     mova      m3, [%1+%2*2]
186     mova      m4, [%1+%3  ]
187     paddw     m1, m0
188     paddw     m2, m0
189     paddw     m3, m0
190     paddw     m4, m0
191 %endif
192     CLIPW     m1, m5, m6
193     CLIPW     m2, m5, m6
194     CLIPW     m3, m5, m6
195     CLIPW     m4, m5, m6
196     mova [%1+0   ], m1
197     mova [%1+%2  ], m2
198     mova [%1+%2*2], m3
199     mova [%1+%3  ], m4
200 %endmacro
201
202 INIT_MMX
203 cglobal h264_idct_dc_add_10_mmx2,3,3
204     movd      m0, dword [r1]
205     paddd     m0, [pd_32]
206     psrad     m0, 6
207     lea       r1, [r2*3]
208     pshufw    m0, m0, 0
209     mova      m6, [pw_pixel_max]
210     IDCT_DC_ADD_OP_10 r0, r2, r1
211     RET
212
213 ;-----------------------------------------------------------------------------
214 ; void h264_idct8_dc_add(pixel *dst, dctcoef *block, int stride)
215 ;-----------------------------------------------------------------------------
216 %macro IDCT8_DC_ADD 1
217 cglobal h264_idct8_dc_add_10_%1,3,3,7
218     mov      r1d, dword [r1]
219     add       r1, 32
220     sar       r1, 6
221     movd      m0, r1d
222     lea       r1, [r2*3]
223     SPLATW    m0, m0, 0
224     mova      m6, [pw_pixel_max]
225     IDCT_DC_ADD_OP_10 r0, r2, r1
226     lea       r0, [r0+r2*4]
227     IDCT_DC_ADD_OP_10 r0, r2, r1
228     RET
229 %endmacro
230
231 INIT_XMM
232 IDCT8_DC_ADD sse2
233 %ifdef HAVE_AVX
234 INIT_AVX
235 IDCT8_DC_ADD avx
236 %endif
237
238 ;-----------------------------------------------------------------------------
239 ; h264_idct_add16intra(pixel *dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
240 ;-----------------------------------------------------------------------------
241 %macro AC 2
242 .ac%2
243     mov  r5d, dword [r1+(%2+0)*4]
244     call add4x4_idct_%1
245     mov  r5d, dword [r1+(%2+1)*4]
246     add  r2, 64
247     call add4x4_idct_%1
248     add  r2, 64
249     jmp .skipadd%2
250 %endmacro
251
252 %assign last_block 16
253 %macro ADD16_OP_INTRA 3
254     cmp         word [r4+%3], 0
255     jnz .ac%2
256     mov         r5d, dword [r2+ 0]
257     or          r5d, dword [r2+64]
258     jz .skipblock%2
259     mov         r5d, dword [r1+(%2+0)*4]
260     call idct_dc_add_%1
261 .skipblock%2:
262 %if %2<last_block-2
263     add          r2, 128
264 %endif
265 .skipadd%2:
266 %endmacro
267
268 %macro IDCT_ADD16INTRA_10 1
269 idct_dc_add_%1:
270     add       r5, r0
271     movq      m0, [r2+ 0]
272     movhps    m0, [r2+64]
273     paddd     m0, [pd_32]
274     psrad     m0, 6
275     pshufhw   m0, m0, 0
276     pshuflw   m0, m0, 0
277     lea       r6, [r3*3]
278     mova      m6, [pw_pixel_max]
279     IDCT_DC_ADD_OP_10 r5, r3, r6
280     ret
281
282 cglobal h264_idct_add16intra_10_%1,5,7,8
283     ADD16_OP_INTRA %1, 0, 4+1*8
284     ADD16_OP_INTRA %1, 2, 4+2*8
285     ADD16_OP_INTRA %1, 4, 6+1*8
286     ADD16_OP_INTRA %1, 6, 6+2*8
287     ADD16_OP_INTRA %1, 8, 4+3*8
288     ADD16_OP_INTRA %1, 10, 4+4*8
289     ADD16_OP_INTRA %1, 12, 6+3*8
290     ADD16_OP_INTRA %1, 14, 6+4*8
291     RET
292 %assign i 14
293 %rep 8
294     AC %1, i
295 %assign i i-2
296 %endrep
297 %endmacro
298
299 INIT_XMM
300 IDCT_ADD16INTRA_10 sse2
301 %ifdef HAVE_AVX
302 INIT_AVX
303 IDCT_ADD16INTRA_10 avx
304 %endif
305
306 %assign last_block 24
307 ;-----------------------------------------------------------------------------
308 ; h264_idct_add8(pixel **dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
309 ;-----------------------------------------------------------------------------
310 %macro IDCT_ADD8 1
311 cglobal h264_idct_add8_10_%1,5,7
312 %ifdef ARCH_X86_64
313     mov r10, r0
314 %endif
315     add r2, 1024
316     mov r0, [r0]
317     ADD16_OP_INTRA %1, 16, 1+1*8
318     ADD16_OP_INTRA %1, 18, 1+2*8
319 %ifdef ARCH_X86_64
320     mov r0, [r10+gprsize]
321 %else
322     mov r0, r0m
323     mov r0, [r0+gprsize]
324 %endif
325     ADD16_OP_INTRA %1, 20, 1+4*8
326     ADD16_OP_INTRA %1, 22, 1+5*8
327     REP_RET
328     AC %1, 16
329     AC %1, 18
330     AC %1, 20
331     AC %1, 22
332
333 %endmacro ; IDCT_ADD8
334
335 INIT_XMM
336 IDCT_ADD8 sse2
337 %ifdef HAVE_AVX
338 INIT_AVX
339 IDCT_ADD8 avx
340 %endif
341
342 ;-----------------------------------------------------------------------------
343 ; void h264_idct8_add(pixel *dst, dctcoef *block, int stride)
344 ;-----------------------------------------------------------------------------
345 %macro IDCT8_1D 2
346     SWAP         0, 1
347     psrad        m4, m5, 1
348     psrad        m1, m0, 1
349     paddd        m4, m5
350     paddd        m1, m0
351     paddd        m4, m7
352     paddd        m1, m5
353     psubd        m4, m0
354     paddd        m1, m3
355
356     psubd        m0, m3
357     psubd        m5, m3
358     paddd        m0, m7
359     psubd        m5, m7
360     psrad        m3, 1
361     psrad        m7, 1
362     psubd        m0, m3
363     psubd        m5, m7
364
365     SWAP         1, 7
366     psrad        m1, m7, 2
367     psrad        m3, m4, 2
368     paddd        m3, m0
369     psrad        m0, 2
370     paddd        m1, m5
371     psrad        m5, 2
372     psubd        m0, m4
373     psubd        m7, m5
374
375     SWAP         5, 6
376     psrad        m4, m2, 1
377     psrad        m6, m5, 1
378     psubd        m4, m5
379     paddd        m6, m2
380
381     mova         m2, %1
382     mova         m5, %2
383     SUMSUB_BA    d, 5, 2
384     SUMSUB_BA    d, 6, 5
385     SUMSUB_BA    d, 4, 2
386     SUMSUB_BA    d, 7, 6
387     SUMSUB_BA    d, 0, 4
388     SUMSUB_BA    d, 3, 2
389     SUMSUB_BA    d, 1, 5
390     SWAP         7, 6, 4, 5, 2, 3, 1, 0 ; 70315246 -> 01234567
391 %endmacro
392
393 %macro IDCT8_1D_FULL 1
394     mova         m7, [%1+112*2]
395     mova         m6, [%1+ 96*2]
396     mova         m5, [%1+ 80*2]
397     mova         m3, [%1+ 48*2]
398     mova         m2, [%1+ 32*2]
399     mova         m1, [%1+ 16*2]
400     IDCT8_1D   [%1], [%1+ 64*2]
401 %endmacro
402
403 ; %1=int16_t *block, %2=int16_t *dstblock
404 %macro IDCT8_ADD_SSE_START 2
405     IDCT8_1D_FULL %1
406 %ifdef ARCH_X86_64
407     TRANSPOSE4x4D  0,1,2,3,8
408     mova    [%2    ], m0
409     TRANSPOSE4x4D  4,5,6,7,8
410     mova    [%2+8*2], m4
411 %else
412     mova         [%1], m7
413     TRANSPOSE4x4D   0,1,2,3,7
414     mova           m7, [%1]
415     mova    [%2     ], m0
416     mova    [%2+16*2], m1
417     mova    [%2+32*2], m2
418     mova    [%2+48*2], m3
419     TRANSPOSE4x4D   4,5,6,7,3
420     mova    [%2+ 8*2], m4
421     mova    [%2+24*2], m5
422     mova    [%2+40*2], m6
423     mova    [%2+56*2], m7
424 %endif
425 %endmacro
426
427 ; %1=uint8_t *dst, %2=int16_t *block, %3=int stride
428 %macro IDCT8_ADD_SSE_END 3
429     IDCT8_1D_FULL %2
430     mova  [%2     ], m6
431     mova  [%2+16*2], m7
432
433     pxor         m7, m7
434     STORE_DIFFx2 m0, m1, m6, m7, %1, %3
435     lea          %1, [%1+%3*2]
436     STORE_DIFFx2 m2, m3, m6, m7, %1, %3
437     mova         m0, [%2     ]
438     mova         m1, [%2+16*2]
439     lea          %1, [%1+%3*2]
440     STORE_DIFFx2 m4, m5, m6, m7, %1, %3
441     lea          %1, [%1+%3*2]
442     STORE_DIFFx2 m0, m1, m6, m7, %1, %3
443 %endmacro
444
445 %macro IDCT8_ADD 1
446 cglobal h264_idct8_add_10_%1, 3,4,16
447 %ifndef UNIX64
448     %assign pad 16-gprsize-(stack_offset&15)
449     sub  rsp, pad
450     call h264_idct8_add1_10_%1
451     add  rsp, pad
452     RET
453 %endif
454
455 ALIGN 16
456 ; TODO: does not need to use stack
457 h264_idct8_add1_10_%1:
458 %assign pad 256+16-gprsize
459     sub          rsp, pad
460     add   dword [r1], 32
461
462 %ifdef ARCH_X86_64
463     IDCT8_ADD_SSE_START r1, rsp
464     SWAP 1,  9
465     SWAP 2, 10
466     SWAP 3, 11
467     SWAP 5, 13
468     SWAP 6, 14
469     SWAP 7, 15
470     IDCT8_ADD_SSE_START r1+16, rsp+128
471     PERMUTE 1,9, 2,10, 3,11, 5,1, 6,2, 7,3, 9,13, 10,14, 11,15, 13,5, 14,6, 15,7
472     IDCT8_1D [rsp], [rsp+128]
473     SWAP 0,  8
474     SWAP 1,  9
475     SWAP 2, 10
476     SWAP 3, 11
477     SWAP 4, 12
478     SWAP 5, 13
479     SWAP 6, 14
480     SWAP 7, 15
481     IDCT8_1D [rsp+16], [rsp+144]
482     psrad         m8, 6
483     psrad         m0, 6
484     packssdw      m8, m0
485     paddsw        m8, [r0]
486     pxor          m0, m0
487     CLIPW         m8, m0, [pw_pixel_max]
488     mova        [r0], m8
489     mova          m8, [pw_pixel_max]
490     STORE_DIFF16  m9, m1, m0, m8, r0+r2
491     lea           r0, [r0+r2*2]
492     STORE_DIFF16 m10, m2, m0, m8, r0
493     STORE_DIFF16 m11, m3, m0, m8, r0+r2
494     lea           r0, [r0+r2*2]
495     STORE_DIFF16 m12, m4, m0, m8, r0
496     STORE_DIFF16 m13, m5, m0, m8, r0+r2
497     lea           r0, [r0+r2*2]
498     STORE_DIFF16 m14, m6, m0, m8, r0
499     STORE_DIFF16 m15, m7, m0, m8, r0+r2
500 %else
501     IDCT8_ADD_SSE_START r1,    rsp
502     IDCT8_ADD_SSE_START r1+16, rsp+128
503     lea           r3, [r0+8]
504     IDCT8_ADD_SSE_END r0, rsp,    r2
505     IDCT8_ADD_SSE_END r3, rsp+16, r2
506 %endif ; ARCH_X86_64
507
508     add          rsp, pad
509     ret
510 %endmacro
511
512 INIT_XMM
513 IDCT8_ADD sse2
514 %ifdef HAVE_AVX
515 INIT_AVX
516 IDCT8_ADD avx
517 %endif
518
519 ;-----------------------------------------------------------------------------
520 ; h264_idct8_add4(pixel **dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
521 ;-----------------------------------------------------------------------------
522 ;;;;;;; NO FATE SAMPLES TRIGGER THIS
523 %macro IDCT8_ADD4_OP 3
524     cmp       byte [r4+%3], 0
525     jz .skipblock%2
526     mov      r0d, dword [r6+%2*4]
527     add       r0, r5
528     call h264_idct8_add1_10_%1
529 .skipblock%2:
530 %if %2<12
531     add       r1, 256
532 %endif
533 %endmacro
534
535 %macro IDCT8_ADD4 1
536 cglobal h264_idct8_add4_10_%1, 0,7,16
537     %assign pad 16-gprsize-(stack_offset&15)
538     SUB      rsp, pad
539     mov       r5, r0mp
540     mov       r6, r1mp
541     mov       r1, r2mp
542     mov      r2d, r3m
543     movifnidn r4, r4mp
544     IDCT8_ADD4_OP %1,  0, 4+1*8
545     IDCT8_ADD4_OP %1,  4, 6+1*8
546     IDCT8_ADD4_OP %1,  8, 4+3*8
547     IDCT8_ADD4_OP %1, 12, 6+3*8
548     ADD       rsp, pad
549     RET
550 %endmacro ; IDCT8_ADD4
551
552 INIT_XMM
553 IDCT8_ADD4 sse2
554 %ifdef HAVE_AVX
555 INIT_AVX
556 IDCT8_ADD4 avx
557 %endif