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