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