Merge commit 'edd1f833fa145eb9c5026877c699ebe6efca00a0'
[ffmpeg.git] / 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 pw_pixel_max: times 8 dw ((1 << 10)-1)
30 pd_32:        times 4 dd 32
31
32 SECTION .text
33
34 ;-----------------------------------------------------------------------------
35 ; void h264_idct_add(pixel *dst, int16_t *block, int stride)
36 ;-----------------------------------------------------------------------------
37 %macro STORE_DIFFx2 6
38     psrad       %1, 6
39     psrad       %2, 6
40     packssdw    %1, %2
41     movq        %3, [%5]
42     movhps      %3, [%5+%6]
43     paddsw      %1, %3
44     CLIPW       %1, %4, [pw_pixel_max]
45     movq      [%5], %1
46     movhps [%5+%6], %1
47 %endmacro
48
49 %macro STORE_DIFF16 5
50     psrad       %1, 6
51     psrad       %2, 6
52     packssdw    %1, %2
53     paddsw      %1, [%5]
54     CLIPW       %1, %3, %4
55     mova      [%5], %1
56 %endmacro
57
58 ;dst, in, stride
59 %macro IDCT4_ADD_10 3
60     mova  m0, [%2+ 0]
61     mova  m1, [%2+16]
62     mova  m2, [%2+32]
63     mova  m3, [%2+48]
64     IDCT4_1D d,0,1,2,3,4,5
65     TRANSPOSE4x4D 0,1,2,3,4
66     paddd m0, [pd_32]
67     IDCT4_1D d,0,1,2,3,4,5
68     pxor  m5, m5
69     mova [%2+ 0], m5
70     mova [%2+16], m5
71     mova [%2+32], m5
72     mova [%2+48], m5
73     STORE_DIFFx2 m0, m1, m4, m5, %1, %3
74     lea   %1, [%1+%3*2]
75     STORE_DIFFx2 m2, m3, m4, m5, %1, %3
76 %endmacro
77
78 %macro IDCT_ADD_10 0
79 cglobal h264_idct_add_10, 3,3
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 ; h264_idct_add16(pixel *dst, const int *block_offset, int16_t *block,
93 ;                 int stride, 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 h264_idct_dc_add(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 h264_idct8_dc_add(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 ; h264_idct_add16intra(pixel *dst, const int *block_offset, int16_t *block,
235 ;                      int stride, const uint8_t nnzc[6*8])
236 ;-----------------------------------------------------------------------------
237 %macro AC 1
238 .ac%1:
239     mov  r5d, [r1+(%1+0)*4]
240     call add4x4_idct %+ SUFFIX
241     mov  r5d, [r1+(%1+1)*4]
242     add  r2, 64
243     call add4x4_idct %+ SUFFIX
244     add  r2, 64
245     jmp .skipadd%1
246 %endmacro
247
248 %assign last_block 16
249 %macro ADD16_OP_INTRA 2
250     cmp      word [r4+%2], 0
251     jnz .ac%1
252     mov      r5d, [r2+ 0]
253     or       r5d, [r2+64]
254     jz .skipblock%1
255     mov      r5d, [r1+(%1+0)*4]
256     call idct_dc_add %+ SUFFIX
257 .skipblock%1:
258 %if %1<last_block-2
259     add       r2, 128
260 %endif
261 .skipadd%1:
262 %endmacro
263
264 %macro IDCT_ADD16INTRA_10 0
265 idct_dc_add %+ SUFFIX:
266     add       r5, r0
267     movq      m0, [r2+ 0]
268     movhps    m0, [r2+64]
269     mov dword [r2+ 0], 0
270     mov dword [r2+64], 0
271     paddd     m0, [pd_32]
272     psrad     m0, 6
273     pshufhw   m0, m0, 0
274     pshuflw   m0, m0, 0
275     lea       r6, [r3*3]
276     mova      m6, [pw_pixel_max]
277     IDCT_DC_ADD_OP_10 r5, r3, r6
278     ret
279
280 cglobal h264_idct_add16intra_10,5,7,8
281     ADD16_OP_INTRA 0, 4+1*8
282     ADD16_OP_INTRA 2, 4+2*8
283     ADD16_OP_INTRA 4, 6+1*8
284     ADD16_OP_INTRA 6, 6+2*8
285     ADD16_OP_INTRA 8, 4+3*8
286     ADD16_OP_INTRA 10, 4+4*8
287     ADD16_OP_INTRA 12, 6+3*8
288     ADD16_OP_INTRA 14, 6+4*8
289     REP_RET
290     AC 8
291     AC 10
292     AC 12
293     AC 14
294     AC 0
295     AC 2
296     AC 4
297     AC 6
298 %endmacro
299
300 INIT_XMM sse2
301 IDCT_ADD16INTRA_10
302 %if HAVE_AVX_EXTERNAL
303 INIT_XMM avx
304 IDCT_ADD16INTRA_10
305 %endif
306
307 %assign last_block 36
308 ;-----------------------------------------------------------------------------
309 ; h264_idct_add8(pixel **dst, const int *block_offset, int16_t *block,
310 ;                int stride, const uint8_t nnzc[6*8])
311 ;-----------------------------------------------------------------------------
312 %macro IDCT_ADD8 0
313 cglobal h264_idct_add8_10,5,8,7
314 %if ARCH_X86_64
315     mov      r7, r0
316 %endif
317     add      r2, 1024
318     mov      r0, [r0]
319     ADD16_OP_INTRA 16, 4+ 6*8
320     ADD16_OP_INTRA 18, 4+ 7*8
321     add      r2, 1024-128*2
322 %if ARCH_X86_64
323     mov      r0, [r7+gprsize]
324 %else
325     mov      r0, r0m
326     mov      r0, [r0+gprsize]
327 %endif
328     ADD16_OP_INTRA 32, 4+11*8
329     ADD16_OP_INTRA 34, 4+12*8
330     REP_RET
331     AC 16
332     AC 18
333     AC 32
334     AC 34
335
336 %endmacro ; IDCT_ADD8
337
338 INIT_XMM sse2
339 IDCT_ADD8
340 %if HAVE_AVX_EXTERNAL
341 INIT_XMM avx
342 IDCT_ADD8
343 %endif
344
345 ;-----------------------------------------------------------------------------
346 ; void h264_idct8_add(pixel *dst, int16_t *block, int stride)
347 ;-----------------------------------------------------------------------------
348 %macro IDCT8_1D 2
349     SWAP      0, 1
350     psrad     m4, m5, 1
351     psrad     m1, m0, 1
352     paddd     m4, m5
353     paddd     m1, m0
354     paddd     m4, m7
355     paddd     m1, m5
356     psubd     m4, m0
357     paddd     m1, m3
358
359     psubd     m0, m3
360     psubd     m5, m3
361     paddd     m0, m7
362     psubd     m5, m7
363     psrad     m3, 1
364     psrad     m7, 1
365     psubd     m0, m3
366     psubd     m5, m7
367
368     SWAP      1, 7
369     psrad     m1, m7, 2
370     psrad     m3, m4, 2
371     paddd     m3, m0
372     psrad     m0, 2
373     paddd     m1, m5
374     psrad     m5, 2
375     psubd     m0, m4
376     psubd     m7, m5
377
378     SWAP      5, 6
379     psrad     m4, m2, 1
380     psrad     m6, m5, 1
381     psubd     m4, m5
382     paddd     m6, m2
383
384     mova      m2, %1
385     mova      m5, %2
386     SUMSUB_BA d, 5, 2
387     SUMSUB_BA d, 6, 5
388     SUMSUB_BA d, 4, 2
389     SUMSUB_BA d, 7, 6
390     SUMSUB_BA d, 0, 4
391     SUMSUB_BA d, 3, 2
392     SUMSUB_BA d, 1, 5
393     SWAP      7, 6, 4, 5, 2, 3, 1, 0 ; 70315246 -> 01234567
394 %endmacro
395
396 %macro IDCT8_1D_FULL 1
397     mova         m7, [%1+112*2]
398     mova         m6, [%1+ 96*2]
399     mova         m5, [%1+ 80*2]
400     mova         m3, [%1+ 48*2]
401     mova         m2, [%1+ 32*2]
402     mova         m1, [%1+ 16*2]
403     IDCT8_1D   [%1], [%1+ 64*2]
404 %endmacro
405
406 ; %1=int16_t *block, %2=int16_t *dstblock
407 %macro IDCT8_ADD_SSE_START 2
408     IDCT8_1D_FULL %1
409 %if ARCH_X86_64
410     TRANSPOSE4x4D  0,1,2,3,8
411     mova    [%2    ], m0
412     TRANSPOSE4x4D  4,5,6,7,8
413     mova    [%2+8*2], m4
414 %else
415     mova         [%1], m7
416     TRANSPOSE4x4D   0,1,2,3,7
417     mova           m7, [%1]
418     mova    [%2     ], m0
419     mova    [%2+16*2], m1
420     mova    [%2+32*2], m2
421     mova    [%2+48*2], m3
422     TRANSPOSE4x4D   4,5,6,7,3
423     mova    [%2+ 8*2], m4
424     mova    [%2+24*2], m5
425     mova    [%2+40*2], m6
426     mova    [%2+56*2], m7
427 %endif
428 %endmacro
429
430 ; %1=uint8_t *dst, %2=int16_t *block, %3=int stride
431 %macro IDCT8_ADD_SSE_END 3
432     IDCT8_1D_FULL %2
433     mova  [%2     ], m6
434     mova  [%2+16*2], m7
435
436     pxor         m7, m7
437     STORE_DIFFx2 m0, m1, m6, m7, %1, %3
438     lea          %1, [%1+%3*2]
439     STORE_DIFFx2 m2, m3, m6, m7, %1, %3
440     mova         m0, [%2     ]
441     mova         m1, [%2+16*2]
442     lea          %1, [%1+%3*2]
443     STORE_DIFFx2 m4, m5, m6, m7, %1, %3
444     lea          %1, [%1+%3*2]
445     STORE_DIFFx2 m0, m1, m6, m7, %1, %3
446 %endmacro
447
448 %macro IDCT8_ADD 0
449 cglobal h264_idct8_add_10, 3,4,16
450 %if UNIX64 == 0
451     %assign pad 16-gprsize-(stack_offset&15)
452     sub  rsp, pad
453     call h264_idct8_add1_10 %+ SUFFIX
454     add  rsp, pad
455     RET
456 %endif
457
458 ALIGN 16
459 ; TODO: does not need to use stack
460 h264_idct8_add1_10 %+ SUFFIX:
461 %assign pad 256+16-gprsize
462     sub          rsp, pad
463     add   dword [r1], 32
464
465 %if ARCH_X86_64
466     IDCT8_ADD_SSE_START r1, rsp
467     SWAP 1,  9
468     SWAP 2, 10
469     SWAP 3, 11
470     SWAP 5, 13
471     SWAP 6, 14
472     SWAP 7, 15
473     IDCT8_ADD_SSE_START r1+16, rsp+128
474     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
475     IDCT8_1D [rsp], [rsp+128]
476     SWAP 0,  8
477     SWAP 1,  9
478     SWAP 2, 10
479     SWAP 3, 11
480     SWAP 4, 12
481     SWAP 5, 13
482     SWAP 6, 14
483     SWAP 7, 15
484     IDCT8_1D [rsp+16], [rsp+144]
485     psrad         m8, 6
486     psrad         m0, 6
487     packssdw      m8, m0
488     paddsw        m8, [r0]
489     pxor          m0, m0
490     mova    [r1+  0], m0
491     mova    [r1+ 16], m0
492     mova    [r1+ 32], m0
493     mova    [r1+ 48], m0
494     mova    [r1+ 64], m0
495     mova    [r1+ 80], m0
496     mova    [r1+ 96], m0
497     mova    [r1+112], m0
498     mova    [r1+128], m0
499     mova    [r1+144], m0
500     mova    [r1+160], m0
501     mova    [r1+176], m0
502     mova    [r1+192], m0
503     mova    [r1+208], m0
504     mova    [r1+224], m0
505     mova    [r1+240], m0
506     CLIPW         m8, m0, [pw_pixel_max]
507     mova        [r0], m8
508     mova          m8, [pw_pixel_max]
509     STORE_DIFF16  m9, m1, m0, m8, r0+r2
510     lea           r0, [r0+r2*2]
511     STORE_DIFF16 m10, m2, m0, m8, r0
512     STORE_DIFF16 m11, m3, m0, m8, r0+r2
513     lea           r0, [r0+r2*2]
514     STORE_DIFF16 m12, m4, m0, m8, r0
515     STORE_DIFF16 m13, m5, m0, m8, r0+r2
516     lea           r0, [r0+r2*2]
517     STORE_DIFF16 m14, m6, m0, m8, r0
518     STORE_DIFF16 m15, m7, m0, m8, r0+r2
519 %else
520     IDCT8_ADD_SSE_START r1,    rsp
521     IDCT8_ADD_SSE_START r1+16, rsp+128
522     lea           r3, [r0+8]
523     IDCT8_ADD_SSE_END r0, rsp,    r2
524     IDCT8_ADD_SSE_END r3, rsp+16, r2
525     mova    [r1+  0], m7
526     mova    [r1+ 16], m7
527     mova    [r1+ 32], m7
528     mova    [r1+ 48], m7
529     mova    [r1+ 64], m7
530     mova    [r1+ 80], m7
531     mova    [r1+ 96], m7
532     mova    [r1+112], m7
533     mova    [r1+128], m7
534     mova    [r1+144], m7
535     mova    [r1+160], m7
536     mova    [r1+176], m7
537     mova    [r1+192], m7
538     mova    [r1+208], m7
539     mova    [r1+224], m7
540     mova    [r1+240], m7
541 %endif ; ARCH_X86_64
542
543     add          rsp, pad
544     ret
545 %endmacro
546
547 INIT_XMM sse2
548 IDCT8_ADD
549 %if HAVE_AVX_EXTERNAL
550 INIT_XMM avx
551 IDCT8_ADD
552 %endif
553
554 ;-----------------------------------------------------------------------------
555 ; h264_idct8_add4(pixel **dst, const int *block_offset, int16_t *block,
556 ;                 int stride, const uint8_t nnzc[6*8])
557 ;-----------------------------------------------------------------------------
558 ;;;;;;; NO FATE SAMPLES TRIGGER THIS
559 %macro IDCT8_ADD4_OP 2
560     cmp       byte [r4+%2], 0
561     jz .skipblock%1
562     mov      r0d, [r6+%1*4]
563     add       r0, r5
564     call h264_idct8_add1_10 %+ SUFFIX
565 .skipblock%1:
566 %if %1<12
567     add       r1, 256
568 %endif
569 %endmacro
570
571 %macro IDCT8_ADD4 0
572 cglobal h264_idct8_add4_10, 0,7,16
573     %assign pad 16-gprsize-(stack_offset&15)
574     SUB      rsp, pad
575     mov       r5, r0mp
576     mov       r6, r1mp
577     mov       r1, r2mp
578     mov      r2d, r3m
579     movifnidn r4, r4mp
580     IDCT8_ADD4_OP  0, 4+1*8
581     IDCT8_ADD4_OP  4, 6+1*8
582     IDCT8_ADD4_OP  8, 4+3*8
583     IDCT8_ADD4_OP 12, 6+3*8
584     ADD       rsp, pad
585     RET
586 %endmacro ; IDCT8_ADD4
587
588 INIT_XMM sse2
589 IDCT8_ADD4
590 %if HAVE_AVX_EXTERNAL
591 INIT_XMM avx
592 IDCT8_ADD4
593 %endif