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