]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/h264_idct_10bit.asm
3f7cf4cefc9706216ed54d9609e10c6e7d864ef4
[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 scan8_mem: db 4+1*8, 5+1*8, 4+2*8, 5+2*8
33            db 6+1*8, 7+1*8, 6+2*8, 7+2*8
34            db 4+3*8, 5+3*8, 4+4*8, 5+4*8
35            db 6+3*8, 7+3*8, 6+4*8, 7+4*8
36            db 1+1*8, 2+1*8
37            db 1+2*8, 2+2*8
38            db 1+4*8, 2+4*8
39            db 1+5*8, 2+5*8
40
41 %ifdef PIC
42 %define scan8 r11
43 %else
44 %define scan8 scan8_mem
45 %endif
46
47 SECTION .text
48
49 ;-----------------------------------------------------------------------------
50 ; void h264_idct_add(pixel *dst, dctcoef *block, int stride)
51 ;-----------------------------------------------------------------------------
52 %macro STORE_DIFFx2 6
53     psrad       %1, 6
54     psrad       %2, 6
55     packssdw    %1, %2
56     movq        %3, [%5]
57     movhps      %3, [%5+%6]
58     paddsw      %1, %3
59     CLIPW       %1, %4, [pw_pixel_max]
60     movq      [%5], %1
61     movhps [%5+%6], %1
62 %endmacro
63
64 %macro STORE_DIFF16 5
65     psrad       %1, 6
66     psrad       %2, 6
67     packssdw    %1, %2
68     paddsw      %1, [%5]
69     CLIPW       %1, %3, %4
70     mova      [%5], %1
71 %endmacro
72
73 ;dst, in, stride
74 %macro IDCT4_ADD_10 3
75     mova  m0, [%2+ 0]
76     mova  m1, [%2+16]
77     mova  m2, [%2+32]
78     mova  m3, [%2+48]
79     IDCT4_1D d,0,1,2,3,4,5
80     TRANSPOSE4x4D 0,1,2,3,4
81     paddd m0, [pd_32]
82     IDCT4_1D d,0,1,2,3,4,5
83     pxor  m5, m5
84     STORE_DIFFx2 m0, m1, m4, m5, %1, %3
85     lea   %1, [%1+%3*2]
86     STORE_DIFFx2 m2, m3, m4, m5, %1, %3
87 %endmacro
88
89 %macro IDCT_ADD_10 1
90 cglobal h264_idct_add_10_%1, 3,3
91     IDCT4_ADD_10 r0, r1, r2
92     RET
93 %endmacro
94
95 INIT_XMM
96 IDCT_ADD_10 sse2
97 %ifdef HAVE_AVX
98 INIT_AVX
99 IDCT_ADD_10 avx
100 %endif
101
102 ;-----------------------------------------------------------------------------
103 ; h264_idct_add16(pixel *dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
104 ;-----------------------------------------------------------------------------
105 ;;;;;;; NO FATE SAMPLES TRIGGER THIS
106 %macro ADD4x4IDCT 1
107 add4x4_idct_%1:
108     add   r5, r0
109     mova  m0, [r2+ 0]
110     mova  m1, [r2+16]
111     mova  m2, [r2+32]
112     mova  m3, [r2+48]
113     IDCT4_1D d,0,1,2,3,4,5
114     TRANSPOSE4x4D 0,1,2,3,4
115     paddd m0, [pd_32]
116     IDCT4_1D d,0,1,2,3,4,5
117     pxor  m5, m5
118     STORE_DIFFx2 m0, m1, m4, m5, r5, r3
119     lea   r5, [r5+r3*2]
120     STORE_DIFFx2 m2, m3, m4, m5, r5, r3
121     ret
122 %endmacro
123
124 INIT_XMM
125 ALIGN 16
126 ADD4x4IDCT sse2
127 %ifdef HAVE_AVX
128 INIT_AVX
129 ALIGN 16
130 ADD4x4IDCT avx
131 %endif
132
133 %macro ADD16_OP 3
134     cmp          byte [r4+%3], 0
135     jz .skipblock%2
136     mov         r5d, [r1+%2*4]
137     call add4x4_idct_%1
138 .skipblock%2:
139 %if %2<15
140     add          r2, 64
141 %endif
142 %endmacro
143
144 %macro IDCT_ADD16_10 1
145 cglobal h264_idct_add16_10_%1, 5,6
146     ADD16_OP %1, 0, 4+1*8
147     ADD16_OP %1, 1, 5+1*8
148     ADD16_OP %1, 2, 4+2*8
149     ADD16_OP %1, 3, 5+2*8
150     ADD16_OP %1, 4, 6+1*8
151     ADD16_OP %1, 5, 7+1*8
152     ADD16_OP %1, 6, 6+2*8
153     ADD16_OP %1, 7, 7+2*8
154     ADD16_OP %1, 8, 4+3*8
155     ADD16_OP %1, 9, 5+3*8
156     ADD16_OP %1, 10, 4+4*8
157     ADD16_OP %1, 11, 5+4*8
158     ADD16_OP %1, 12, 6+3*8
159     ADD16_OP %1, 13, 7+3*8
160     ADD16_OP %1, 14, 6+4*8
161     ADD16_OP %1, 15, 7+4*8
162     REP_RET
163 %endmacro
164
165 INIT_XMM
166 IDCT_ADD16_10 sse2
167 %ifdef HAVE_AVX
168 INIT_AVX
169 IDCT_ADD16_10 avx
170 %endif
171
172 ;-----------------------------------------------------------------------------
173 ; void h264_idct_dc_add(pixel *dst, dctcoef *block, int stride)
174 ;-----------------------------------------------------------------------------
175 %macro IDCT_DC_ADD_OP_10 3
176     pxor      m5, m5
177 %if avx_enabled
178     paddw     m1, m0, [%1+0   ]
179     paddw     m2, m0, [%1+%2  ]
180     paddw     m3, m0, [%1+%2*2]
181     paddw     m4, m0, [%1+%3  ]
182 %else
183     mova      m1, [%1+0   ]
184     mova      m2, [%1+%2  ]
185     mova      m3, [%1+%2*2]
186     mova      m4, [%1+%3  ]
187     paddw     m1, m0
188     paddw     m2, m0
189     paddw     m3, m0
190     paddw     m4, m0
191 %endif
192     CLIPW     m1, m5, m6
193     CLIPW     m2, m5, m6
194     CLIPW     m3, m5, m6
195     CLIPW     m4, m5, m6
196     mova [%1+0   ], m1
197     mova [%1+%2  ], m2
198     mova [%1+%2*2], m3
199     mova [%1+%3  ], m4
200 %endmacro
201
202 INIT_MMX
203 cglobal h264_idct_dc_add_10_mmx2,3,3
204     movd      m0, [r1]
205     paddd     m0, [pd_32]
206     psrad     m0, 6
207     lea       r1, [r2*3]
208     pshufw    m0, m0, 0
209     mova      m6, [pw_pixel_max]
210     IDCT_DC_ADD_OP_10 r0, r2, r1
211     RET
212
213 ;-----------------------------------------------------------------------------
214 ; void h264_idct8_dc_add(pixel *dst, dctcoef *block, int stride)
215 ;-----------------------------------------------------------------------------
216 %macro IDCT8_DC_ADD 1
217 cglobal h264_idct8_dc_add_10_%1,3,3,7
218     mov      r1d, [r1]
219     add       r1, 32
220     sar       r1, 6
221     movd      m0, r1d
222     lea       r1, [r2*3]
223     SPLATW    m0, m0, 0
224     mova      m6, [pw_pixel_max]
225     IDCT_DC_ADD_OP_10 r0, r2, r1
226     lea       r0, [r0+r2*4]
227     IDCT_DC_ADD_OP_10 r0, r2, r1
228     RET
229 %endmacro
230
231 INIT_XMM
232 IDCT8_DC_ADD sse2
233 %ifdef HAVE_AVX
234 INIT_AVX
235 IDCT8_DC_ADD avx
236 %endif
237
238 ;-----------------------------------------------------------------------------
239 ; h264_idct_add16intra(pixel *dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
240 ;-----------------------------------------------------------------------------
241 %macro AC 2
242 .ac%2
243     mov  r5d, [r1+(%2+0)*4]
244     call add4x4_idct_%1
245     mov  r5d, [r1+(%2+1)*4]
246     add  r2, 64
247     call add4x4_idct_%1
248     add  r2, 64
249     jmp .skipadd%2
250 %endmacro
251
252 %assign last_block 16
253 %macro ADD16_OP_INTRA 3
254     cmp      word [r4+%3], 0
255     jnz .ac%2
256     mov      r5d, [r2+ 0]
257     or       r5d, [r2+64]
258     jz .skipblock%2
259     mov      r5d, [r1+(%2+0)*4]
260     call idct_dc_add_%1
261 .skipblock%2:
262 %if %2<last_block-2
263     add       r2, 128
264 %endif
265 .skipadd%2:
266 %endmacro
267
268 %macro IDCT_ADD16INTRA_10 1
269 idct_dc_add_%1:
270     add       r5, r0
271     movq      m0, [r2+ 0]
272     movhps    m0, [r2+64]
273     paddd     m0, [pd_32]
274     psrad     m0, 6
275     pshufhw   m0, m0, 0
276     pshuflw   m0, m0, 0
277     lea       r6, [r3*3]
278     mova      m6, [pw_pixel_max]
279     IDCT_DC_ADD_OP_10 r5, r3, r6
280     ret
281
282 cglobal h264_idct_add16intra_10_%1,5,7,8
283     ADD16_OP_INTRA %1, 0, 4+1*8
284     ADD16_OP_INTRA %1, 2, 4+2*8
285     ADD16_OP_INTRA %1, 4, 6+1*8
286     ADD16_OP_INTRA %1, 6, 6+2*8
287     ADD16_OP_INTRA %1, 8, 4+3*8
288     ADD16_OP_INTRA %1, 10, 4+4*8
289     ADD16_OP_INTRA %1, 12, 6+3*8
290     ADD16_OP_INTRA %1, 14, 6+4*8
291     REP_RET
292     AC %1, 8
293     AC %1, 10
294     AC %1, 12
295     AC %1, 14
296     AC %1, 0
297     AC %1, 2
298     AC %1, 4
299     AC %1, 6
300 %endmacro
301
302 INIT_XMM
303 IDCT_ADD16INTRA_10 sse2
304 %ifdef HAVE_AVX
305 INIT_AVX
306 IDCT_ADD16INTRA_10 avx
307 %endif
308
309 %assign last_block 24
310 ;-----------------------------------------------------------------------------
311 ; h264_idct_add8(pixel **dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
312 ;-----------------------------------------------------------------------------
313 %macro IDCT_ADD8 1
314 cglobal h264_idct_add8_10_%1,5,7
315 %ifdef ARCH_X86_64
316     mov r10, r0
317 %endif
318     add      r2, 1024
319     mov      r0, [r0]
320     ADD16_OP_INTRA %1, 16, 1+1*8
321     ADD16_OP_INTRA %1, 18, 1+2*8
322 %ifdef ARCH_X86_64
323     mov      r0, [r10+gprsize]
324 %else
325     mov      r0, r0m
326     mov      r0, [r0+gprsize]
327 %endif
328     ADD16_OP_INTRA %1, 20, 1+4*8
329     ADD16_OP_INTRA %1, 22, 1+5*8
330     REP_RET
331     AC %1, 16
332     AC %1, 18
333     AC %1, 20
334     AC %1, 22
335
336 %endmacro ; IDCT_ADD8
337
338 INIT_XMM
339 IDCT_ADD8 sse2
340 %ifdef HAVE_AVX
341 INIT_AVX
342 IDCT_ADD8 avx
343 %endif
344
345 ;-----------------------------------------------------------------------------
346 ; void h264_idct8_add(pixel *dst, dctcoef *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 %ifdef 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 1
449 cglobal h264_idct8_add_10_%1, 3,4,16
450 %ifndef UNIX64
451     %assign pad 16-gprsize-(stack_offset&15)
452     sub  rsp, pad
453     call h264_idct8_add1_10_%1
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_%1:
461 %assign pad 256+16-gprsize
462     sub          rsp, pad
463     add   dword [r1], 32
464
465 %ifdef 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     CLIPW         m8, m0, [pw_pixel_max]
491     mova        [r0], m8
492     mova          m8, [pw_pixel_max]
493     STORE_DIFF16  m9, m1, m0, m8, r0+r2
494     lea           r0, [r0+r2*2]
495     STORE_DIFF16 m10, m2, m0, m8, r0
496     STORE_DIFF16 m11, m3, m0, m8, r0+r2
497     lea           r0, [r0+r2*2]
498     STORE_DIFF16 m12, m4, m0, m8, r0
499     STORE_DIFF16 m13, m5, m0, m8, r0+r2
500     lea           r0, [r0+r2*2]
501     STORE_DIFF16 m14, m6, m0, m8, r0
502     STORE_DIFF16 m15, m7, m0, m8, r0+r2
503 %else
504     IDCT8_ADD_SSE_START r1,    rsp
505     IDCT8_ADD_SSE_START r1+16, rsp+128
506     lea           r3, [r0+8]
507     IDCT8_ADD_SSE_END r0, rsp,    r2
508     IDCT8_ADD_SSE_END r3, rsp+16, r2
509 %endif ; ARCH_X86_64
510
511     add          rsp, pad
512     ret
513 %endmacro
514
515 INIT_XMM
516 IDCT8_ADD sse2
517 %ifdef HAVE_AVX
518 INIT_AVX
519 IDCT8_ADD avx
520 %endif
521
522 ;-----------------------------------------------------------------------------
523 ; h264_idct8_add4(pixel **dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
524 ;-----------------------------------------------------------------------------
525 ;;;;;;; NO FATE SAMPLES TRIGGER THIS
526 %macro IDCT8_ADD4_OP 3
527     cmp       byte [r4+%3], 0
528     jz .skipblock%2
529     mov      r0d, [r6+%2*4]
530     add       r0, r5
531     call h264_idct8_add1_10_%1
532 .skipblock%2:
533 %if %2<12
534     add       r1, 256
535 %endif
536 %endmacro
537
538 %macro IDCT8_ADD4 1
539 cglobal h264_idct8_add4_10_%1, 0,7,16
540     %assign pad 16-gprsize-(stack_offset&15)
541     SUB      rsp, pad
542     mov       r5, r0mp
543     mov       r6, r1mp
544     mov       r1, r2mp
545     mov      r2d, r3m
546     movifnidn r4, r4mp
547     IDCT8_ADD4_OP %1,  0, 4+1*8
548     IDCT8_ADD4_OP %1,  4, 6+1*8
549     IDCT8_ADD4_OP %1,  8, 4+3*8
550     IDCT8_ADD4_OP %1, 12, 6+3*8
551     ADD       rsp, pad
552     RET
553 %endmacro ; IDCT8_ADD4
554
555 INIT_XMM
556 IDCT8_ADD4 sse2
557 %ifdef HAVE_AVX
558 INIT_AVX
559 IDCT8_ADD4 avx
560 %endif