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