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