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