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