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