]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/h264_idct.asm
Merge commit '17c99b6158f2c6720af74e81ee727ee50d2e7e96'
[ffmpeg] / libavcodec / x86 / h264_idct.asm
1 ;*****************************************************************************
2 ;* MMX/SSE2-optimized H.264 iDCT
3 ;*****************************************************************************
4 ;* Copyright (C) 2004-2005 Michael Niedermayer, Loren Merritt
5 ;* Copyright (C) 2003-2008 x264 project
6 ;*
7 ;* Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 ;*          Loren Merritt <lorenm@u.washington.edu>
9 ;*          Holger Lubitz <hal@duncan.ol.sub.de>
10 ;*          Min Chen <chenm001.163.com>
11 ;*
12 ;* This file is part of FFmpeg.
13 ;*
14 ;* FFmpeg is free software; you can redistribute it and/or
15 ;* modify it under the terms of the GNU Lesser General Public
16 ;* License as published by the Free Software Foundation; either
17 ;* version 2.1 of the License, or (at your option) any later version.
18 ;*
19 ;* FFmpeg is distributed in the hope that it will be useful,
20 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22 ;* Lesser General Public License for more details.
23 ;*
24 ;* You should have received a copy of the GNU Lesser General Public
25 ;* License along with FFmpeg; if not, write to the Free Software
26 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 ;*****************************************************************************
28
29 %include "libavutil/x86/x86util.asm"
30
31 SECTION_RODATA
32
33 scan8_mem: db  4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8
34            db  6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8
35            db  4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8
36            db  6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8
37            db  4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8
38            db  6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8
39            db  4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8
40            db  6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8
41            db  4+11*8, 5+11*8, 4+12*8, 5+12*8
42            db  6+11*8, 7+11*8, 6+12*8, 7+12*8
43            db  4+13*8, 5+13*8, 4+14*8, 5+14*8
44            db  6+13*8, 7+13*8, 6+14*8, 7+14*8
45 %ifdef PIC
46 %define npicregs 1
47 %define scan8 picregq
48 %else
49 %define npicregs 0
50 %define scan8 scan8_mem
51 %endif
52
53 cextern pw_32
54 cextern pw_1
55
56 SECTION .text
57
58 ; %1=uint8_t *dst, %2=int16_t *block, %3=int stride
59 %macro IDCT4_ADD 3
60     ; Load dct coeffs
61     movq         m0, [%2]
62     movq         m1, [%2+8]
63     movq         m2, [%2+16]
64     movq         m3, [%2+24]
65
66     IDCT4_1D      w, 0, 1, 2, 3, 4, 5
67     mova         m6, [pw_32]
68     TRANSPOSE4x4W 0, 1, 2, 3, 4
69     paddw        m0, m6
70     IDCT4_1D      w, 0, 1, 2, 3, 4, 5
71     pxor         m7, m7
72     movq    [%2+ 0], m7
73     movq    [%2+ 8], m7
74     movq    [%2+16], m7
75     movq    [%2+24], m7
76
77     STORE_DIFFx2 m0, m1, m4, m5, m7, 6, %1, %3
78     lea          %1, [%1+%3*2]
79     STORE_DIFFx2 m2, m3, m4, m5, m7, 6, %1, %3
80 %endmacro
81
82 INIT_MMX mmx
83 ; void ff_h264_idct_add_8_mmx(uint8_t *dst, int16_t *block, int stride)
84 cglobal h264_idct_add_8, 3, 3, 0
85     movsxdifnidn r2, r2d
86     IDCT4_ADD    r0, r1, r2
87     RET
88
89 %macro IDCT8_1D 2
90     mova         m0, m1
91     psraw        m1, 1
92     mova         m4, m5
93     psraw        m4, 1
94     paddw        m4, m5
95     paddw        m1, m0
96     paddw        m4, m7
97     paddw        m1, m5
98     psubw        m4, m0
99     paddw        m1, m3
100
101     psubw        m0, m3
102     psubw        m5, m3
103     psraw        m3, 1
104     paddw        m0, m7
105     psubw        m5, m7
106     psraw        m7, 1
107     psubw        m0, m3
108     psubw        m5, m7
109
110     mova         m7, m1
111     psraw        m1, 2
112     mova         m3, m4
113     psraw        m3, 2
114     paddw        m3, m0
115     psraw        m0, 2
116     paddw        m1, m5
117     psraw        m5, 2
118     psubw        m0, m4
119     psubw        m7, m5
120
121     mova         m5, m6
122     psraw        m6, 1
123     mova         m4, m2
124     psraw        m4, 1
125     paddw        m6, m2
126     psubw        m4, m5
127
128     mova         m2, %1
129     mova         m5, %2
130     SUMSUB_BA    w, 5, 2
131     SUMSUB_BA    w, 6, 5
132     SUMSUB_BA    w, 4, 2
133     SUMSUB_BA    w, 7, 6
134     SUMSUB_BA    w, 0, 4
135     SUMSUB_BA    w, 3, 2
136     SUMSUB_BA    w, 1, 5
137     SWAP         7, 6, 4, 5, 2, 3, 1, 0 ; 70315246 -> 01234567
138 %endmacro
139
140 %macro IDCT8_1D_FULL 1
141     mova         m7, [%1+112]
142     mova         m6, [%1+ 96]
143     mova         m5, [%1+ 80]
144     mova         m3, [%1+ 48]
145     mova         m2, [%1+ 32]
146     mova         m1, [%1+ 16]
147     IDCT8_1D   [%1], [%1+ 64]
148 %endmacro
149
150 ; %1=int16_t *block, %2=int16_t *dstblock
151 %macro IDCT8_ADD_MMX_START 2
152     IDCT8_1D_FULL %1
153     mova       [%1], m7
154     TRANSPOSE4x4W 0, 1, 2, 3, 7
155     mova         m7, [%1]
156     mova    [%2   ], m0
157     mova    [%2+16], m1
158     mova    [%2+32], m2
159     mova    [%2+48], m3
160     TRANSPOSE4x4W 4, 5, 6, 7, 3
161     mova    [%2+ 8], m4
162     mova    [%2+24], m5
163     mova    [%2+40], m6
164     mova    [%2+56], m7
165 %endmacro
166
167 ; %1=uint8_t *dst, %2=int16_t *block, %3=int stride
168 %macro IDCT8_ADD_MMX_END 3-4
169     IDCT8_1D_FULL %2
170     mova    [%2   ], m5
171     mova    [%2+16], m6
172     mova    [%2+32], m7
173
174     pxor         m7, m7
175 %if %0 == 4
176     movq   [%4+  0], m7
177     movq   [%4+  8], m7
178     movq   [%4+ 16], m7
179     movq   [%4+ 24], m7
180     movq   [%4+ 32], m7
181     movq   [%4+ 40], m7
182     movq   [%4+ 48], m7
183     movq   [%4+ 56], m7
184     movq   [%4+ 64], m7
185     movq   [%4+ 72], m7
186     movq   [%4+ 80], m7
187     movq   [%4+ 88], m7
188     movq   [%4+ 96], m7
189     movq   [%4+104], m7
190     movq   [%4+112], m7
191     movq   [%4+120], m7
192 %endif
193     STORE_DIFFx2 m0, m1, m5, m6, m7, 6, %1, %3
194     lea          %1, [%1+%3*2]
195     STORE_DIFFx2 m2, m3, m5, m6, m7, 6, %1, %3
196     mova         m0, [%2   ]
197     mova         m1, [%2+16]
198     mova         m2, [%2+32]
199     lea          %1, [%1+%3*2]
200     STORE_DIFFx2 m4, m0, m5, m6, m7, 6, %1, %3
201     lea          %1, [%1+%3*2]
202     STORE_DIFFx2 m1, m2, m5, m6, m7, 6, %1, %3
203 %endmacro
204
205 INIT_MMX mmx
206 ; void ff_h264_idct8_add_8_mmx(uint8_t *dst, int16_t *block, int stride)
207 cglobal h264_idct8_add_8, 3, 4, 0
208     movsxdifnidn r2, r2d
209     %assign pad 128+4-(stack_offset&7)
210     SUB         rsp, pad
211
212     add   word [r1], 32
213     IDCT8_ADD_MMX_START r1  , rsp
214     IDCT8_ADD_MMX_START r1+8, rsp+64
215     lea          r3, [r0+4]
216     IDCT8_ADD_MMX_END   r0  , rsp,   r2, r1
217     IDCT8_ADD_MMX_END   r3  , rsp+8, r2
218
219     ADD         rsp, pad
220     RET
221
222 ; %1=uint8_t *dst, %2=int16_t *block, %3=int stride
223 %macro IDCT8_ADD_SSE 4
224     IDCT8_1D_FULL %2
225 %if ARCH_X86_64
226     TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8
227 %else
228     TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [%2], [%2+16]
229 %endif
230     paddw        m0, [pw_32]
231
232 %if ARCH_X86_64 == 0
233     mova    [%2   ], m0
234     mova    [%2+16], m4
235     IDCT8_1D   [%2], [%2+ 16]
236     mova    [%2   ], m6
237     mova    [%2+16], m7
238 %else
239     SWAP          0, 8
240     SWAP          4, 9
241     IDCT8_1D     m8, m9
242     SWAP          6, 8
243     SWAP          7, 9
244 %endif
245
246     pxor         m7, m7
247     lea          %4, [%3*3]
248     STORE_DIFF   m0, m6, m7, [%1     ]
249     STORE_DIFF   m1, m6, m7, [%1+%3  ]
250     STORE_DIFF   m2, m6, m7, [%1+%3*2]
251     STORE_DIFF   m3, m6, m7, [%1+%4  ]
252 %if ARCH_X86_64 == 0
253     mova         m0, [%2   ]
254     mova         m1, [%2+16]
255 %else
256     SWAP          0, 8
257     SWAP          1, 9
258 %endif
259     mova   [%2+  0], m7
260     mova   [%2+ 16], m7
261     mova   [%2+ 32], m7
262     mova   [%2+ 48], m7
263     mova   [%2+ 64], m7
264     mova   [%2+ 80], m7
265     mova   [%2+ 96], m7
266     mova   [%2+112], m7
267     lea          %1, [%1+%3*4]
268     STORE_DIFF   m4, m6, m7, [%1     ]
269     STORE_DIFF   m5, m6, m7, [%1+%3  ]
270     STORE_DIFF   m0, m6, m7, [%1+%3*2]
271     STORE_DIFF   m1, m6, m7, [%1+%4  ]
272 %endmacro
273
274 INIT_XMM sse2
275 ; void ff_h264_idct8_add_8_sse2(uint8_t *dst, int16_t *block, int stride)
276 cglobal h264_idct8_add_8, 3, 4, 10
277     movsxdifnidn  r2, r2d
278     IDCT8_ADD_SSE r0, r1, r2, r3
279     RET
280
281 %macro DC_ADD_MMXEXT_INIT 2
282     add          %1, 32
283     sar          %1, 6
284     movd         m0, %1d
285     lea          %1, [%2*3]
286     pshufw       m0, m0, 0
287     pxor         m1, m1
288     psubw        m1, m0
289     packuswb     m0, m0
290     packuswb     m1, m1
291 %endmacro
292
293 %macro DC_ADD_MMXEXT_OP 4
294     %1           m2, [%2     ]
295     %1           m3, [%2+%3  ]
296     %1           m4, [%2+%3*2]
297     %1           m5, [%2+%4  ]
298     paddusb      m2, m0
299     paddusb      m3, m0
300     paddusb      m4, m0
301     paddusb      m5, m0
302     psubusb      m2, m1
303     psubusb      m3, m1
304     psubusb      m4, m1
305     psubusb      m5, m1
306     %1    [%2     ], m2
307     %1    [%2+%3  ], m3
308     %1    [%2+%3*2], m4
309     %1    [%2+%4  ], m5
310 %endmacro
311
312 INIT_MMX mmxext
313 ; void ff_h264_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
314 %if ARCH_X86_64
315 cglobal h264_idct_dc_add_8, 3, 4, 0
316     movsxd       r2, r2d
317     movsx        r3, word [r1]
318     mov  dword [r1], 0
319     DC_ADD_MMXEXT_INIT r3, r2
320     DC_ADD_MMXEXT_OP movh, r0, r2, r3
321     RET
322
323 ; void ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
324 cglobal h264_idct8_dc_add_8, 3, 4, 0
325     movsxd       r2, r2d
326     movsx        r3, word [r1]
327     mov  dword [r1], 0
328     DC_ADD_MMXEXT_INIT r3, r2
329     DC_ADD_MMXEXT_OP mova, r0, r2, r3
330     lea          r0, [r0+r2*4]
331     DC_ADD_MMXEXT_OP mova, r0, r2, r3
332     RET
333 %else
334 ; void ff_h264_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
335 cglobal h264_idct_dc_add_8, 2, 3, 0
336     movsx        r2, word [r1]
337     mov  dword [r1], 0
338     mov          r1, r2m
339     DC_ADD_MMXEXT_INIT r2, r1
340     DC_ADD_MMXEXT_OP movh, r0, r1, r2
341     RET
342
343 ; void ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
344 cglobal h264_idct8_dc_add_8, 2, 3, 0
345     movsx        r2, word [r1]
346     mov  dword [r1], 0
347     mov          r1, r2m
348     DC_ADD_MMXEXT_INIT r2, r1
349     DC_ADD_MMXEXT_OP mova, r0, r1, r2
350     lea          r0, [r0+r1*4]
351     DC_ADD_MMXEXT_OP mova, r0, r1, r2
352     RET
353 %endif
354
355 INIT_MMX mmx
356 ; void ff_h264_idct_add16_8_mmx(uint8_t *dst, const int *block_offset,
357 ;                               int16_t *block, int stride,
358 ;                               const uint8_t nnzc[6 * 8])
359 cglobal h264_idct_add16_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
360     movsxdifnidn r3, r3d
361     xor          r5, r5
362 %ifdef PIC
363     lea     picregq, [scan8_mem]
364 %endif
365 .nextblock:
366     movzx        r6, byte [scan8+r5]
367     movzx        r6, byte [r4+r6]
368     test         r6, r6
369     jz .skipblock
370     mov         r6d, dword [r1+r5*4]
371     lea          r6, [r0+r6]
372     IDCT4_ADD    r6, r2, r3
373 .skipblock:
374     inc          r5
375     add          r2, 32
376     cmp          r5, 16
377     jl .nextblock
378     REP_RET
379
380 ; void ff_h264_idct8_add4_8_mmx(uint8_t *dst, const int *block_offset,
381 ;                               int16_t *block, int stride,
382 ;                               const uint8_t nnzc[6 * 8])
383 cglobal h264_idct8_add4_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
384     movsxdifnidn r3, r3d
385     %assign pad 128+4-(stack_offset&7)
386     SUB         rsp, pad
387
388     xor          r5, r5
389 %ifdef PIC
390     lea     picregq, [scan8_mem]
391 %endif
392 .nextblock:
393     movzx        r6, byte [scan8+r5]
394     movzx        r6, byte [r4+r6]
395     test         r6, r6
396     jz .skipblock
397     mov         r6d, dword [r1+r5*4]
398     add          r6, r0
399     add   word [r2], 32
400     IDCT8_ADD_MMX_START r2  , rsp
401     IDCT8_ADD_MMX_START r2+8, rsp+64
402     IDCT8_ADD_MMX_END   r6  , rsp,   r3, r2
403     mov         r6d, dword [r1+r5*4]
404     lea          r6, [r0+r6+4]
405     IDCT8_ADD_MMX_END   r6  , rsp+8, r3
406 .skipblock:
407     add          r5, 4
408     add          r2, 128
409     cmp          r5, 16
410     jl .nextblock
411     ADD         rsp, pad
412     RET
413
414 INIT_MMX mmxext
415 ; void ff_h264_idct_add16_8_mmxext(uint8_t *dst, const int *block_offset,
416 ;                                  int16_t *block, int stride,
417 ;                                  const uint8_t nnzc[6 * 8])
418 cglobal h264_idct_add16_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
419     movsxdifnidn r3, r3d
420     xor          r5, r5
421 %ifdef PIC
422     lea     picregq, [scan8_mem]
423 %endif
424 .nextblock:
425     movzx        r6, byte [scan8+r5]
426     movzx        r6, byte [r4+r6]
427     test         r6, r6
428     jz .skipblock
429     cmp          r6, 1
430     jnz .no_dc
431     movsx        r6, word [r2]
432     test         r6, r6
433     jz .no_dc
434     mov   word [r2], 0
435     DC_ADD_MMXEXT_INIT r6, r3
436 %if ARCH_X86_64 == 0
437 %define dst2q r1
438 %define dst2d r1d
439 %endif
440     mov       dst2d, dword [r1+r5*4]
441     lea       dst2q, [r0+dst2q]
442     DC_ADD_MMXEXT_OP movh, dst2q, r3, r6
443 %if ARCH_X86_64 == 0
444     mov          r1, r1m
445 %endif
446     inc          r5
447     add          r2, 32
448     cmp          r5, 16
449     jl .nextblock
450     REP_RET
451 .no_dc:
452     mov         r6d, dword [r1+r5*4]
453     add          r6, r0
454     IDCT4_ADD    r6, r2, r3
455 .skipblock:
456     inc          r5
457     add          r2, 32
458     cmp          r5, 16
459     jl .nextblock
460     REP_RET
461
462 INIT_MMX mmx
463 ; void ff_h264_idct_add16intra_8_mmx(uint8_t *dst, const int *block_offset,
464 ;                                    int16_t *block, int stride,
465 ;                                    const uint8_t nnzc[6 * 8])
466 cglobal h264_idct_add16intra_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
467     movsxdifnidn r3, r3d
468     xor          r5, r5
469 %ifdef PIC
470     lea     picregq, [scan8_mem]
471 %endif
472 .nextblock:
473     movzx        r6, byte [scan8+r5]
474     movzx        r6, byte [r4+r6]
475     or          r6w, word [r2]
476     test         r6, r6
477     jz .skipblock
478     mov         r6d, dword [r1+r5*4]
479     add          r6, r0
480     IDCT4_ADD    r6, r2, r3
481 .skipblock:
482     inc          r5
483     add          r2, 32
484     cmp          r5, 16
485     jl .nextblock
486     REP_RET
487
488 INIT_MMX mmxext
489 ; void ff_h264_idct_add16intra_8_mmxext(uint8_t *dst, const int *block_offset,
490 ;                                       int16_t *block, int stride,
491 ;                                       const uint8_t nnzc[6 * 8])
492 cglobal h264_idct_add16intra_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
493     movsxdifnidn r3, r3d
494     xor          r5, r5
495 %ifdef PIC
496     lea     picregq, [scan8_mem]
497 %endif
498 .nextblock:
499     movzx        r6, byte [scan8+r5]
500     movzx        r6, byte [r4+r6]
501     test         r6, r6
502     jz .try_dc
503     mov         r6d, dword [r1+r5*4]
504     lea          r6, [r0+r6]
505     IDCT4_ADD    r6, r2, r3
506     inc          r5
507     add          r2, 32
508     cmp          r5, 16
509     jl .nextblock
510     REP_RET
511 .try_dc:
512     movsx        r6, word [r2]
513     test         r6, r6
514     jz .skipblock
515     mov   word [r2], 0
516     DC_ADD_MMXEXT_INIT r6, r3
517 %if ARCH_X86_64 == 0
518 %define dst2q r1
519 %define dst2d r1d
520 %endif
521     mov       dst2d, dword [r1+r5*4]
522     add       dst2q, r0
523     DC_ADD_MMXEXT_OP movh, dst2q, r3, r6
524 %if ARCH_X86_64 == 0
525     mov          r1, r1m
526 %endif
527 .skipblock:
528     inc          r5
529     add          r2, 32
530     cmp          r5, 16
531     jl .nextblock
532     REP_RET
533
534 ; void ff_h264_idct8_add4_8_mmxext(uint8_t *dst, const int *block_offset,
535 ;                                  int16_t *block, int stride,
536 ;                                  const uint8_t nnzc[6 * 8])
537 cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
538     movsxdifnidn r3, r3d
539     %assign pad 128+4-(stack_offset&7)
540     SUB         rsp, pad
541
542     xor          r5, r5
543 %ifdef PIC
544     lea     picregq, [scan8_mem]
545 %endif
546 .nextblock:
547     movzx        r6, byte [scan8+r5]
548     movzx        r6, byte [r4+r6]
549     test         r6, r6
550     jz .skipblock
551     cmp          r6, 1
552     jnz .no_dc
553     movsx        r6, word [r2]
554     test         r6, r6
555     jz .no_dc
556     mov   word [r2], 0
557     DC_ADD_MMXEXT_INIT r6, r3
558 %if ARCH_X86_64 == 0
559 %define dst2q r1
560 %define dst2d r1d
561 %endif
562     mov       dst2d, dword [r1+r5*4]
563     lea       dst2q, [r0+dst2q]
564     DC_ADD_MMXEXT_OP mova, dst2q, r3, r6
565     lea       dst2q, [dst2q+r3*4]
566     DC_ADD_MMXEXT_OP mova, dst2q, r3, r6
567 %if ARCH_X86_64 == 0
568     mov          r1, r1m
569 %endif
570     add          r5, 4
571     add          r2, 128
572     cmp          r5, 16
573     jl .nextblock
574
575     ADD         rsp, pad
576     RET
577 .no_dc:
578     mov         r6d, dword [r1+r5*4]
579     add          r6, r0
580     add   word [r2], 32
581     IDCT8_ADD_MMX_START r2  , rsp
582     IDCT8_ADD_MMX_START r2+8, rsp+64
583     IDCT8_ADD_MMX_END   r6  , rsp,   r3, r2
584     mov         r6d, dword [r1+r5*4]
585     lea          r6, [r0+r6+4]
586     IDCT8_ADD_MMX_END   r6  , rsp+8, r3
587 .skipblock:
588     add          r5, 4
589     add          r2, 128
590     cmp          r5, 16
591     jl .nextblock
592
593     ADD         rsp, pad
594     RET
595
596 INIT_XMM sse2
597 ; void ff_h264_idct8_add4_8_sse2(uint8_t *dst, const int *block_offset,
598 ;                                int16_t *block, int stride,
599 ;                                const uint8_t nnzc[6 * 8])
600 cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
601     movsxdifnidn r3, r3d
602     xor          r5, r5
603 %ifdef PIC
604     lea     picregq, [scan8_mem]
605 %endif
606 .nextblock:
607     movzx        r6, byte [scan8+r5]
608     movzx        r6, byte [r4+r6]
609     test         r6, r6
610     jz .skipblock
611     cmp          r6, 1
612     jnz .no_dc
613     movsx        r6, word [r2]
614     test         r6, r6
615     jz .no_dc
616 INIT_MMX cpuname
617     mov   word [r2], 0
618     DC_ADD_MMXEXT_INIT r6, r3
619 %if ARCH_X86_64 == 0
620 %define dst2q r1
621 %define dst2d r1d
622 %endif
623     mov       dst2d, dword [r1+r5*4]
624     add       dst2q, r0
625     DC_ADD_MMXEXT_OP mova, dst2q, r3, r6
626     lea       dst2q, [dst2q+r3*4]
627     DC_ADD_MMXEXT_OP mova, dst2q, r3, r6
628 %if ARCH_X86_64 == 0
629     mov          r1, r1m
630 %endif
631     add          r5, 4
632     add          r2, 128
633     cmp          r5, 16
634     jl .nextblock
635     REP_RET
636 .no_dc:
637 INIT_XMM cpuname
638     mov       dst2d, dword [r1+r5*4]
639     add       dst2q, r0
640     IDCT8_ADD_SSE dst2q, r2, r3, r6
641 %if ARCH_X86_64 == 0
642     mov          r1, r1m
643 %endif
644 .skipblock:
645     add          r5, 4
646     add          r2, 128
647     cmp          r5, 16
648     jl .nextblock
649     REP_RET
650
651 INIT_MMX mmx
652 h264_idct_add8_mmx_plane:
653     movsxdifnidn r3, r3d
654 .nextblock:
655     movzx        r6, byte [scan8+r5]
656     movzx        r6, byte [r4+r6]
657     or          r6w, word [r2]
658     test         r6, r6
659     jz .skipblock
660 %if ARCH_X86_64
661     mov         r0d, dword [r1+r5*4]
662     add          r0, [dst2q]
663 %else
664     mov          r0, r1m ; XXX r1m here is actually r0m of the calling func
665     mov          r0, [r0]
666     add          r0, dword [r1+r5*4]
667 %endif
668     IDCT4_ADD    r0, r2, r3
669 .skipblock:
670     inc          r5
671     add          r2, 32
672     test         r5, 3
673     jnz .nextblock
674     rep ret
675
676 ; void ff_h264_idct_add8_8_mmx(uint8_t **dest, const int *block_offset,
677 ;                              int16_t *block, int stride,
678 ;                              const uint8_t nnzc[6 * 8])
679 cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
680     movsxdifnidn r3, r3d
681     mov          r5, 16
682     add          r2, 512
683 %ifdef PIC
684     lea     picregq, [scan8_mem]
685 %endif
686 %if ARCH_X86_64
687     mov       dst2q, r0
688 %endif
689     call         h264_idct_add8_mmx_plane
690     mov          r5, 32
691     add          r2, 384
692 %if ARCH_X86_64
693     add       dst2q, gprsize
694 %else
695     add        r0mp, gprsize
696 %endif
697     call         h264_idct_add8_mmx_plane
698     RET
699
700 h264_idct_add8_mmxext_plane:
701     movsxdifnidn r3, r3d
702 .nextblock:
703     movzx        r6, byte [scan8+r5]
704     movzx        r6, byte [r4+r6]
705     test         r6, r6
706     jz .try_dc
707 %if ARCH_X86_64
708     mov         r0d, dword [r1+r5*4]
709     add          r0, [dst2q]
710 %else
711     mov          r0, r1m ; XXX r1m here is actually r0m of the calling func
712     mov          r0, [r0]
713     add          r0, dword [r1+r5*4]
714 %endif
715     IDCT4_ADD    r0, r2, r3
716     inc          r5
717     add          r2, 32
718     test         r5, 3
719     jnz .nextblock
720     rep ret
721 .try_dc:
722     movsx        r6, word [r2]
723     test         r6, r6
724     jz .skipblock
725     mov   word [r2], 0
726     DC_ADD_MMXEXT_INIT r6, r3
727 %if ARCH_X86_64
728     mov         r0d, dword [r1+r5*4]
729     add          r0, [dst2q]
730 %else
731     mov          r0, r1m ; XXX r1m here is actually r0m of the calling func
732     mov          r0, [r0]
733     add          r0, dword [r1+r5*4]
734 %endif
735     DC_ADD_MMXEXT_OP movh, r0, r3, r6
736 .skipblock:
737     inc          r5
738     add          r2, 32
739     test         r5, 3
740     jnz .nextblock
741     rep ret
742
743 INIT_MMX mmxext
744 ; void ff_h264_idct_add8_8_mmxext(uint8_t **dest, const int *block_offset,
745 ;                                 int16_t *block, int stride,
746 ;                                 const uint8_t nnzc[6 * 8])
747 cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
748     movsxdifnidn r3, r3d
749     mov          r5, 16
750     add          r2, 512
751 %if ARCH_X86_64
752     mov       dst2q, r0
753 %endif
754 %ifdef PIC
755     lea     picregq, [scan8_mem]
756 %endif
757     call h264_idct_add8_mmxext_plane
758     mov          r5, 32
759     add          r2, 384
760 %if ARCH_X86_64
761     add       dst2q, gprsize
762 %else
763     add        r0mp, gprsize
764 %endif
765     call h264_idct_add8_mmxext_plane
766     RET
767
768 ; r0 = uint8_t *dst, r2 = int16_t *block, r3 = int stride, r6=clobbered
769 h264_idct_dc_add8_mmxext:
770     movsxdifnidn r3, r3d
771     movd         m0, [r2   ]          ;  0 0 X D
772     mov word [r2+ 0], 0
773     punpcklwd    m0, [r2+32]          ;  x X d D
774     mov word [r2+32], 0
775     paddsw       m0, [pw_32]
776     psraw        m0, 6
777     punpcklwd    m0, m0               ;  d d D D
778     pxor         m1, m1               ;  0 0 0 0
779     psubw        m1, m0               ; -d-d-D-D
780     packuswb     m0, m1               ; -d-d-D-D d d D D
781     pshufw       m1, m0, 0xFA         ; -d-d-d-d-D-D-D-D
782     punpcklwd    m0, m0               ;  d d d d D D D D
783     lea          r6, [r3*3]
784     DC_ADD_MMXEXT_OP movq, r0, r3, r6
785     ret
786
787 ALIGN 16
788 INIT_XMM sse2
789 ; r0 = uint8_t *dst (clobbered), r2 = int16_t *block, r3 = int stride
790 h264_add8x4_idct_sse2:
791     movsxdifnidn r3, r3d
792     movq   m0, [r2+ 0]
793     movq   m1, [r2+ 8]
794     movq   m2, [r2+16]
795     movq   m3, [r2+24]
796     movhps m0, [r2+32]
797     movhps m1, [r2+40]
798     movhps m2, [r2+48]
799     movhps m3, [r2+56]
800     IDCT4_1D w,0,1,2,3,4,5
801     TRANSPOSE2x4x4W 0,1,2,3,4
802     paddw m0, [pw_32]
803     IDCT4_1D w,0,1,2,3,4,5
804     pxor  m7, m7
805     mova [r2+ 0], m7
806     mova [r2+16], m7
807     mova [r2+32], m7
808     mova [r2+48], m7
809     STORE_DIFFx2 m0, m1, m4, m5, m7, 6, r0, r3
810     lea   r0, [r0+r3*2]
811     STORE_DIFFx2 m2, m3, m4, m5, m7, 6, r0, r3
812     ret
813
814 %macro add16_sse2_cycle 2
815     movzx       r0, word [r4+%2]
816     test        r0, r0
817     jz .cycle%1end
818     mov        r0d, dword [r1+%1*8]
819 %if ARCH_X86_64
820     add         r0, r5
821 %else
822     add         r0, r0m
823 %endif
824     call        h264_add8x4_idct_sse2
825 .cycle%1end:
826 %if %1 < 7
827     add         r2, 64
828 %endif
829 %endmacro
830
831 ; void ff_h264_idct_add16_8_sse2(uint8_t *dst, const int *block_offset,
832 ;                                int16_t *block, int stride,
833 ;                                const uint8_t nnzc[6 * 8])
834 cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8
835     movsxdifnidn r3, r3d
836 %if ARCH_X86_64
837     mov         r5, r0
838 %endif
839     ; unrolling of the loop leads to an average performance gain of
840     ; 20-25%
841     add16_sse2_cycle 0, 0xc
842     add16_sse2_cycle 1, 0x14
843     add16_sse2_cycle 2, 0xe
844     add16_sse2_cycle 3, 0x16
845     add16_sse2_cycle 4, 0x1c
846     add16_sse2_cycle 5, 0x24
847     add16_sse2_cycle 6, 0x1e
848     add16_sse2_cycle 7, 0x26
849     RET
850
851 %macro add16intra_sse2_cycle 2
852     movzx       r0, word [r4+%2]
853     test        r0, r0
854     jz .try%1dc
855     mov        r0d, dword [r1+%1*8]
856 %if ARCH_X86_64
857     add         r0, r7
858 %else
859     add         r0, r0m
860 %endif
861     call        h264_add8x4_idct_sse2
862     jmp .cycle%1end
863 .try%1dc:
864     movsx       r0, word [r2   ]
865     or         r0w, word [r2+32]
866     jz .cycle%1end
867     mov        r0d, dword [r1+%1*8]
868 %if ARCH_X86_64
869     add         r0, r7
870 %else
871     add         r0, r0m
872 %endif
873     call        h264_idct_dc_add8_mmxext
874 .cycle%1end:
875 %if %1 < 7
876     add         r2, 64
877 %endif
878 %endmacro
879
880 ; void ff_h264_idct_add16intra_8_sse2(uint8_t *dst, const int *block_offset,
881 ;                                     int16_t *block, int stride,
882 ;                                     const uint8_t nnzc[6 * 8])
883 cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8
884     movsxdifnidn r3, r3d
885 %if ARCH_X86_64
886     mov         r7, r0
887 %endif
888     add16intra_sse2_cycle 0, 0xc
889     add16intra_sse2_cycle 1, 0x14
890     add16intra_sse2_cycle 2, 0xe
891     add16intra_sse2_cycle 3, 0x16
892     add16intra_sse2_cycle 4, 0x1c
893     add16intra_sse2_cycle 5, 0x24
894     add16intra_sse2_cycle 6, 0x1e
895     add16intra_sse2_cycle 7, 0x26
896     RET
897
898 %macro add8_sse2_cycle 2
899     movzx       r0, word [r4+%2]
900     test        r0, r0
901     jz .try%1dc
902 %if ARCH_X86_64
903     mov        r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
904     add         r0, [r7]
905 %else
906     mov         r0, r0m
907     mov         r0, [r0]
908     add         r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
909 %endif
910     call        h264_add8x4_idct_sse2
911     jmp .cycle%1end
912 .try%1dc:
913     movsx       r0, word [r2   ]
914     or         r0w, word [r2+32]
915     jz .cycle%1end
916 %if ARCH_X86_64
917     mov        r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
918     add         r0, [r7]
919 %else
920     mov         r0, r0m
921     mov         r0, [r0]
922     add         r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
923 %endif
924     call        h264_idct_dc_add8_mmxext
925 .cycle%1end:
926 %if %1 == 1
927     add         r2, 384+64
928 %elif %1 < 3
929     add         r2, 64
930 %endif
931 %endmacro
932
933 ; void ff_h264_idct_add8_8_sse2(uint8_t **dest, const int *block_offset,
934 ;                               int16_t *block, int stride,
935 ;                               const uint8_t nnzc[6 * 8])
936 cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8
937     movsxdifnidn r3, r3d
938     add          r2, 512
939 %if ARCH_X86_64
940     mov          r7, r0
941 %endif
942     add8_sse2_cycle 0, 0x34
943     add8_sse2_cycle 1, 0x3c
944 %if ARCH_X86_64
945     add          r7, gprsize
946 %else
947     add        r0mp, gprsize
948 %endif
949     add8_sse2_cycle 2, 0x5c
950     add8_sse2_cycle 3, 0x64
951     RET
952
953 ;void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul)
954
955 %macro WALSH4_1D 5
956     SUMSUB_BADC w, %4, %3, %2, %1, %5
957     SUMSUB_BADC w, %4, %2, %3, %1, %5
958     SWAP %1, %4, %3
959 %endmacro
960
961 %macro DEQUANT_MMX 3
962     mova        m7, [pw_1]
963     mova        m4, %1
964     punpcklwd   %1, m7
965     punpckhwd   m4, m7
966     mova        m5, %2
967     punpcklwd   %2, m7
968     punpckhwd   m5, m7
969     movd        m7, t3d
970     punpckldq   m7, m7
971     pmaddwd     %1, m7
972     pmaddwd     %2, m7
973     pmaddwd     m4, m7
974     pmaddwd     m5, m7
975     psrad       %1, %3
976     psrad       %2, %3
977     psrad       m4, %3
978     psrad       m5, %3
979     packssdw    %1, m4
980     packssdw    %2, m5
981 %endmacro
982
983 %macro STORE_WORDS 5-9
984 %if cpuflag(sse)
985     movd  t0d, %1
986     psrldq  %1, 4
987     movd  t1d, %1
988     psrldq  %1, 4
989     mov [t2+%2*32], t0w
990     mov [t2+%4*32], t1w
991     shr   t0d, 16
992     shr   t1d, 16
993     mov [t2+%3*32], t0w
994     mov [t2+%5*32], t1w
995     movd  t0d, %1
996     psrldq  %1, 4
997     movd  t1d, %1
998     mov [t2+%6*32], t0w
999     mov [t2+%8*32], t1w
1000     shr   t0d, 16
1001     shr   t1d, 16
1002     mov [t2+%7*32], t0w
1003     mov [t2+%9*32], t1w
1004 %else
1005     movd  t0d, %1
1006     psrlq  %1, 32
1007     movd  t1d, %1
1008     mov [t2+%2*32], t0w
1009     mov [t2+%4*32], t1w
1010     shr   t0d, 16
1011     shr   t1d, 16
1012     mov [t2+%3*32], t0w
1013     mov [t2+%5*32], t1w
1014 %endif
1015 %endmacro
1016
1017 %macro DEQUANT_STORE 1
1018 %if cpuflag(sse2)
1019     movd      xmm4, t3d
1020     movq      xmm5, [pw_1]
1021     pshufd    xmm4, xmm4, 0
1022     movq2dq   xmm0, m0
1023     movq2dq   xmm1, m1
1024     movq2dq   xmm2, m2
1025     movq2dq   xmm3, m3
1026     punpcklwd xmm0, xmm5
1027     punpcklwd xmm1, xmm5
1028     punpcklwd xmm2, xmm5
1029     punpcklwd xmm3, xmm5
1030     pmaddwd   xmm0, xmm4
1031     pmaddwd   xmm1, xmm4
1032     pmaddwd   xmm2, xmm4
1033     pmaddwd   xmm3, xmm4
1034     psrad     xmm0, %1
1035     psrad     xmm1, %1
1036     psrad     xmm2, %1
1037     psrad     xmm3, %1
1038     packssdw  xmm0, xmm1
1039     packssdw  xmm2, xmm3
1040     STORE_WORDS xmm0,  0,  1,  4,  5,  2,  3,  6,  7
1041     STORE_WORDS xmm2,  8,  9, 12, 13, 10, 11, 14, 15
1042 %else
1043     DEQUANT_MMX m0, m1, %1
1044     STORE_WORDS m0,  0,  1,  4,  5
1045     STORE_WORDS m1,  2,  3,  6,  7
1046
1047     DEQUANT_MMX m2, m3, %1
1048     STORE_WORDS m2,  8,  9, 12, 13
1049     STORE_WORDS m3, 10, 11, 14, 15
1050 %endif
1051 %endmacro
1052
1053 %macro IDCT_DC_DEQUANT 1
1054 cglobal h264_luma_dc_dequant_idct, 3, 4, %1
1055     ; manually spill XMM registers for Win64 because
1056     ; the code here is initialized with INIT_MMX
1057     WIN64_SPILL_XMM %1
1058     movq        m3, [r1+24]
1059     movq        m2, [r1+16]
1060     movq        m1, [r1+ 8]
1061     movq        m0, [r1+ 0]
1062     WALSH4_1D    0,1,2,3,4
1063     TRANSPOSE4x4W 0,1,2,3,4
1064     WALSH4_1D    0,1,2,3,4
1065
1066 ; shift, tmp, output, qmul
1067 %if WIN64
1068     DECLARE_REG_TMP 0,3,1,2
1069     ; we can't avoid this, because r0 is the shift register (ecx) on win64
1070     xchg        r0, t2
1071 %elif ARCH_X86_64
1072     DECLARE_REG_TMP 3,1,0,2
1073 %else
1074     DECLARE_REG_TMP 1,3,0,2
1075 %endif
1076
1077     cmp        t3d, 32767
1078     jg .big_qmul
1079     add        t3d, 128 << 16
1080     DEQUANT_STORE 8
1081     RET
1082 .big_qmul:
1083     bsr        t0d, t3d
1084     add        t3d, 128 << 16
1085     mov        t1d, 7
1086     cmp        t0d, t1d
1087     cmovg      t0d, t1d
1088     inc        t1d
1089     shr        t3d, t0b
1090     sub        t1d, t0d
1091 %if cpuflag(sse2)
1092     movd      xmm6, t1d
1093     DEQUANT_STORE xmm6
1094 %else
1095     movd        m6, t1d
1096     DEQUANT_STORE m6
1097 %endif
1098     RET
1099 %endmacro
1100
1101 INIT_MMX mmx
1102 IDCT_DC_DEQUANT 0
1103 INIT_MMX sse2
1104 IDCT_DC_DEQUANT 7