x86: h264_idct: Remove incorrect comment
[ffmpeg.git] / 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_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_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_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_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_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 cglobal h264_idct_dc_add_8, 2, 3, 0
330     movsx        r2, word [r1]
331     mov  dword [r1], 0
332     mov          r1, r2m
333     DC_ADD_MMXEXT_INIT r2, r1
334     DC_ADD_MMXEXT_OP movh, r0, r1, r2
335     RET
336
337 ; ff_h264_idct8_dc_add_mmxext(uint8_t *dst, int16_t *block, int stride)
338 cglobal h264_idct8_dc_add_8, 2, 3, 0
339     movsx        r2, word [r1]
340     mov  dword [r1], 0
341     mov          r1, r2m
342     DC_ADD_MMXEXT_INIT r2, r1
343     DC_ADD_MMXEXT_OP mova, r0, r1, r2
344     lea          r0, [r0+r1*4]
345     DC_ADD_MMXEXT_OP mova, r0, r1, r2
346     RET
347 %endif
348
349 INIT_MMX mmx
350 ; ff_h264_idct_add16_mmx(uint8_t *dst, const int *block_offset,
351 ;             int16_t *block, int stride, const uint8_t nnzc[6*8])
352 cglobal h264_idct_add16_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
353     xor          r5, r5
354 %ifdef PIC
355     lea     picregq, [scan8_mem]
356 %endif
357 .nextblock:
358     movzx        r6, byte [scan8+r5]
359     movzx        r6, byte [r4+r6]
360     test         r6, r6
361     jz .skipblock
362     mov         r6d, dword [r1+r5*4]
363     lea          r6, [r0+r6]
364     IDCT4_ADD    r6, r2, r3
365 .skipblock:
366     inc          r5
367     add          r2, 32
368     cmp          r5, 16
369     jl .nextblock
370     REP_RET
371
372 ; ff_h264_idct8_add4_mmx(uint8_t *dst, const int *block_offset,
373 ;                        int16_t *block, int stride, const uint8_t nnzc[6*8])
374 cglobal h264_idct8_add4_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
375     %assign pad 128+4-(stack_offset&7)
376     SUB         rsp, pad
377
378     xor          r5, r5
379 %ifdef PIC
380     lea     picregq, [scan8_mem]
381 %endif
382 .nextblock:
383     movzx        r6, byte [scan8+r5]
384     movzx        r6, byte [r4+r6]
385     test         r6, r6
386     jz .skipblock
387     mov         r6d, dword [r1+r5*4]
388     add          r6, r0
389     add   word [r2], 32
390     IDCT8_ADD_MMX_START r2  , rsp
391     IDCT8_ADD_MMX_START r2+8, rsp+64
392     IDCT8_ADD_MMX_END   r6  , rsp,   r3, r2
393     mov         r6d, dword [r1+r5*4]
394     lea          r6, [r0+r6+4]
395     IDCT8_ADD_MMX_END   r6  , rsp+8, r3
396 .skipblock:
397     add          r5, 4
398     add          r2, 128
399     cmp          r5, 16
400     jl .nextblock
401     ADD         rsp, pad
402     RET
403
404 INIT_MMX mmxext
405 ; ff_h264_idct_add16_mmxext(uint8_t *dst, const int *block_offset,
406 ;                           int16_t *block, int stride, const uint8_t nnzc[6*8])
407 cglobal h264_idct_add16_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
408     xor          r5, r5
409 %ifdef PIC
410     lea     picregq, [scan8_mem]
411 %endif
412 .nextblock:
413     movzx        r6, byte [scan8+r5]
414     movzx        r6, byte [r4+r6]
415     test         r6, r6
416     jz .skipblock
417     cmp          r6, 1
418     jnz .no_dc
419     movsx        r6, word [r2]
420     test         r6, r6
421     jz .no_dc
422     mov   word [r2], 0
423     DC_ADD_MMXEXT_INIT r6, r3
424 %if ARCH_X86_64 == 0
425 %define dst2q r1
426 %define dst2d r1d
427 %endif
428     mov       dst2d, dword [r1+r5*4]
429     lea       dst2q, [r0+dst2q]
430     DC_ADD_MMXEXT_OP movh, dst2q, r3, r6
431 %if ARCH_X86_64 == 0
432     mov          r1, r1m
433 %endif
434     inc          r5
435     add          r2, 32
436     cmp          r5, 16
437     jl .nextblock
438     REP_RET
439 .no_dc:
440     mov         r6d, dword [r1+r5*4]
441     add          r6, r0
442     IDCT4_ADD    r6, r2, r3
443 .skipblock:
444     inc          r5
445     add          r2, 32
446     cmp          r5, 16
447     jl .nextblock
448     REP_RET
449
450 INIT_MMX mmx
451 ; ff_h264_idct_add16intra_mmx(uint8_t *dst, const int *block_offset,
452 ;                             int16_t *block, int stride, const uint8_t nnzc[6*8])
453 cglobal h264_idct_add16intra_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
454     xor          r5, r5
455 %ifdef PIC
456     lea     picregq, [scan8_mem]
457 %endif
458 .nextblock:
459     movzx        r6, byte [scan8+r5]
460     movzx        r6, byte [r4+r6]
461     or          r6w, word [r2]
462     test         r6, r6
463     jz .skipblock
464     mov         r6d, dword [r1+r5*4]
465     add          r6, r0
466     IDCT4_ADD    r6, r2, r3
467 .skipblock:
468     inc          r5
469     add          r2, 32
470     cmp          r5, 16
471     jl .nextblock
472     REP_RET
473
474 INIT_MMX mmxext
475 ; ff_h264_idct_add16intra_mmxext(uint8_t *dst, const int *block_offset,
476 ;                                int16_t *block, int stride,
477 ;                                const uint8_t nnzc[6*8])
478 cglobal h264_idct_add16intra_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
479     xor          r5, r5
480 %ifdef PIC
481     lea     picregq, [scan8_mem]
482 %endif
483 .nextblock:
484     movzx        r6, byte [scan8+r5]
485     movzx        r6, byte [r4+r6]
486     test         r6, r6
487     jz .try_dc
488     mov         r6d, dword [r1+r5*4]
489     lea          r6, [r0+r6]
490     IDCT4_ADD    r6, r2, r3
491     inc          r5
492     add          r2, 32
493     cmp          r5, 16
494     jl .nextblock
495     REP_RET
496 .try_dc:
497     movsx        r6, word [r2]
498     test         r6, r6
499     jz .skipblock
500     mov   word [r2], 0
501     DC_ADD_MMXEXT_INIT r6, r3
502 %if ARCH_X86_64 == 0
503 %define dst2q r1
504 %define dst2d r1d
505 %endif
506     mov       dst2d, dword [r1+r5*4]
507     add       dst2q, r0
508     DC_ADD_MMXEXT_OP movh, dst2q, r3, r6
509 %if ARCH_X86_64 == 0
510     mov          r1, r1m
511 %endif
512 .skipblock:
513     inc          r5
514     add          r2, 32
515     cmp          r5, 16
516     jl .nextblock
517     REP_RET
518
519 ; ff_h264_idct8_add4_mmxext(uint8_t *dst, const int *block_offset,
520 ;                           int16_t *block, int stride,
521 ;                           const uint8_t nnzc[6*8])
522 cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
523     %assign pad 128+4-(stack_offset&7)
524     SUB         rsp, pad
525
526     xor          r5, r5
527 %ifdef PIC
528     lea     picregq, [scan8_mem]
529 %endif
530 .nextblock:
531     movzx        r6, byte [scan8+r5]
532     movzx        r6, byte [r4+r6]
533     test         r6, r6
534     jz .skipblock
535     cmp          r6, 1
536     jnz .no_dc
537     movsx        r6, word [r2]
538     test         r6, r6
539     jz .no_dc
540     mov   word [r2], 0
541     DC_ADD_MMXEXT_INIT r6, r3
542 %if ARCH_X86_64 == 0
543 %define dst2q r1
544 %define dst2d r1d
545 %endif
546     mov       dst2d, dword [r1+r5*4]
547     lea       dst2q, [r0+dst2q]
548     DC_ADD_MMXEXT_OP mova, dst2q, r3, r6
549     lea       dst2q, [dst2q+r3*4]
550     DC_ADD_MMXEXT_OP mova, dst2q, r3, r6
551 %if ARCH_X86_64 == 0
552     mov          r1, r1m
553 %endif
554     add          r5, 4
555     add          r2, 128
556     cmp          r5, 16
557     jl .nextblock
558
559     ADD         rsp, pad
560     RET
561 .no_dc:
562     mov         r6d, dword [r1+r5*4]
563     add          r6, r0
564     add   word [r2], 32
565     IDCT8_ADD_MMX_START r2  , rsp
566     IDCT8_ADD_MMX_START r2+8, rsp+64
567     IDCT8_ADD_MMX_END   r6  , rsp,   r3, r2
568     mov         r6d, dword [r1+r5*4]
569     lea          r6, [r0+r6+4]
570     IDCT8_ADD_MMX_END   r6  , rsp+8, r3
571 .skipblock:
572     add          r5, 4
573     add          r2, 128
574     cmp          r5, 16
575     jl .nextblock
576
577     ADD         rsp, pad
578     RET
579
580 INIT_XMM sse2
581 ; ff_h264_idct8_add4_sse2(uint8_t *dst, const int *block_offset,
582 ;                         int16_t *block, int stride, const uint8_t nnzc[6*8])
583 cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
584     xor          r5, r5
585 %ifdef PIC
586     lea     picregq, [scan8_mem]
587 %endif
588 .nextblock:
589     movzx        r6, byte [scan8+r5]
590     movzx        r6, byte [r4+r6]
591     test         r6, r6
592     jz .skipblock
593     cmp          r6, 1
594     jnz .no_dc
595     movsx        r6, word [r2]
596     test         r6, r6
597     jz .no_dc
598 INIT_MMX cpuname
599     mov   word [r2], 0
600     DC_ADD_MMXEXT_INIT r6, r3
601 %if ARCH_X86_64 == 0
602 %define dst2q r1
603 %define dst2d r1d
604 %endif
605     mov       dst2d, dword [r1+r5*4]
606     add       dst2q, r0
607     DC_ADD_MMXEXT_OP mova, dst2q, r3, r6
608     lea       dst2q, [dst2q+r3*4]
609     DC_ADD_MMXEXT_OP mova, dst2q, r3, r6
610 %if ARCH_X86_64 == 0
611     mov          r1, r1m
612 %endif
613     add          r5, 4
614     add          r2, 128
615     cmp          r5, 16
616     jl .nextblock
617     REP_RET
618 .no_dc:
619 INIT_XMM cpuname
620     mov       dst2d, dword [r1+r5*4]
621     add       dst2q, r0
622     IDCT8_ADD_SSE dst2q, r2, r3, r6
623 %if ARCH_X86_64 == 0
624     mov          r1, r1m
625 %endif
626 .skipblock:
627     add          r5, 4
628     add          r2, 128
629     cmp          r5, 16
630     jl .nextblock
631     REP_RET
632
633 INIT_MMX mmx
634 h264_idct_add8_mmx_plane:
635 .nextblock:
636     movzx        r6, byte [scan8+r5]
637     movzx        r6, byte [r4+r6]
638     or          r6w, word [r2]
639     test         r6, r6
640     jz .skipblock
641 %if ARCH_X86_64
642     mov         r0d, dword [r1+r5*4]
643     add          r0, [dst2q]
644 %else
645     mov          r0, r1m ; XXX r1m here is actually r0m of the calling func
646     mov          r0, [r0]
647     add          r0, dword [r1+r5*4]
648 %endif
649     IDCT4_ADD    r0, r2, r3
650 .skipblock:
651     inc          r5
652     add          r2, 32
653     test         r5, 3
654     jnz .nextblock
655     rep ret
656
657 ; ff_h264_idct_add8_mmx(uint8_t **dest, const int *block_offset,
658 ;                       int16_t *block, int stride, const uint8_t nnzc[6*8])
659 cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
660     mov          r5, 16
661     add          r2, 512
662 %ifdef PIC
663     lea     picregq, [scan8_mem]
664 %endif
665 %if ARCH_X86_64
666     mov       dst2q, r0
667 %endif
668     call         h264_idct_add8_mmx_plane
669     mov          r5, 32
670     add          r2, 384
671 %if ARCH_X86_64
672     add       dst2q, gprsize
673 %else
674     add        r0mp, gprsize
675 %endif
676     call         h264_idct_add8_mmx_plane
677     RET
678
679 h264_idct_add8_mmxext_plane:
680 .nextblock:
681     movzx        r6, byte [scan8+r5]
682     movzx        r6, byte [r4+r6]
683     test         r6, r6
684     jz .try_dc
685 %if ARCH_X86_64
686     mov         r0d, dword [r1+r5*4]
687     add          r0, [dst2q]
688 %else
689     mov          r0, r1m ; XXX r1m here is actually r0m of the calling func
690     mov          r0, [r0]
691     add          r0, dword [r1+r5*4]
692 %endif
693     IDCT4_ADD    r0, r2, r3
694     inc          r5
695     add          r2, 32
696     test         r5, 3
697     jnz .nextblock
698     rep ret
699 .try_dc:
700     movsx        r6, word [r2]
701     test         r6, r6
702     jz .skipblock
703     mov   word [r2], 0
704     DC_ADD_MMXEXT_INIT r6, r3
705 %if ARCH_X86_64
706     mov         r0d, dword [r1+r5*4]
707     add          r0, [dst2q]
708 %else
709     mov          r0, r1m ; XXX r1m here is actually r0m of the calling func
710     mov          r0, [r0]
711     add          r0, dword [r1+r5*4]
712 %endif
713     DC_ADD_MMXEXT_OP movh, r0, r3, r6
714 .skipblock:
715     inc          r5
716     add          r2, 32
717     test         r5, 3
718     jnz .nextblock
719     rep ret
720
721 INIT_MMX mmxext
722 ; ff_h264_idct_add8_mmxext(uint8_t **dest, const int *block_offset,
723 ;                          int16_t *block, int stride, const uint8_t nnzc[6*8])
724 cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
725     mov          r5, 16
726     add          r2, 512
727 %if ARCH_X86_64
728     mov       dst2q, r0
729 %endif
730 %ifdef PIC
731     lea     picregq, [scan8_mem]
732 %endif
733     call h264_idct_add8_mmxext_plane
734     mov          r5, 32
735     add          r2, 384
736 %if ARCH_X86_64
737     add       dst2q, gprsize
738 %else
739     add        r0mp, gprsize
740 %endif
741     call h264_idct_add8_mmxext_plane
742     RET
743
744 ; r0 = uint8_t *dst, r2 = int16_t *block, r3 = int stride, r6=clobbered
745 h264_idct_dc_add8_mmxext:
746     movd         m0, [r2   ]          ;  0 0 X D
747     mov word [r2+ 0], 0
748     punpcklwd    m0, [r2+32]          ;  x X d D
749     mov word [r2+32], 0
750     paddsw       m0, [pw_32]
751     psraw        m0, 6
752     punpcklwd    m0, m0               ;  d d D D
753     pxor         m1, m1               ;  0 0 0 0
754     psubw        m1, m0               ; -d-d-D-D
755     packuswb     m0, m1               ; -d-d-D-D d d D D
756     pshufw       m1, m0, 0xFA         ; -d-d-d-d-D-D-D-D
757     punpcklwd    m0, m0               ;  d d d d D D D D
758     lea          r6, [r3*3]
759     DC_ADD_MMXEXT_OP movq, r0, r3, r6
760     ret
761
762 ALIGN 16
763 INIT_XMM sse2
764 ; r0 = uint8_t *dst (clobbered), r2 = int16_t *block, r3 = int stride
765 h264_add8x4_idct_sse2:
766     movq   m0, [r2+ 0]
767     movq   m1, [r2+ 8]
768     movq   m2, [r2+16]
769     movq   m3, [r2+24]
770     movhps m0, [r2+32]
771     movhps m1, [r2+40]
772     movhps m2, [r2+48]
773     movhps m3, [r2+56]
774     IDCT4_1D w,0,1,2,3,4,5
775     TRANSPOSE2x4x4W 0,1,2,3,4
776     paddw m0, [pw_32]
777     IDCT4_1D w,0,1,2,3,4,5
778     pxor  m7, m7
779     mova [r2+ 0], m7
780     mova [r2+16], m7
781     mova [r2+32], m7
782     mova [r2+48], m7
783     STORE_DIFFx2 m0, m1, m4, m5, m7, 6, r0, r3
784     lea   r0, [r0+r3*2]
785     STORE_DIFFx2 m2, m3, m4, m5, m7, 6, r0, r3
786     ret
787
788 %macro add16_sse2_cycle 2
789     movzx       r0, word [r4+%2]
790     test        r0, r0
791     jz .cycle%1end
792     mov        r0d, dword [r1+%1*8]
793 %if ARCH_X86_64
794     add         r0, r5
795 %else
796     add         r0, r0m
797 %endif
798     call        h264_add8x4_idct_sse2
799 .cycle%1end:
800 %if %1 < 7
801     add         r2, 64
802 %endif
803 %endmacro
804
805 ; ff_h264_idct_add16_sse2(uint8_t *dst, const int *block_offset,
806 ;                         int16_t *block, int stride, const uint8_t nnzc[6*8])
807 cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8
808 %if ARCH_X86_64
809     mov         r5, r0
810 %endif
811     ; unrolling of the loop leads to an average performance gain of
812     ; 20-25%
813     add16_sse2_cycle 0, 0xc
814     add16_sse2_cycle 1, 0x14
815     add16_sse2_cycle 2, 0xe
816     add16_sse2_cycle 3, 0x16
817     add16_sse2_cycle 4, 0x1c
818     add16_sse2_cycle 5, 0x24
819     add16_sse2_cycle 6, 0x1e
820     add16_sse2_cycle 7, 0x26
821     RET
822
823 %macro add16intra_sse2_cycle 2
824     movzx       r0, word [r4+%2]
825     test        r0, r0
826     jz .try%1dc
827     mov        r0d, dword [r1+%1*8]
828 %if ARCH_X86_64
829     add         r0, r7
830 %else
831     add         r0, r0m
832 %endif
833     call        h264_add8x4_idct_sse2
834     jmp .cycle%1end
835 .try%1dc:
836     movsx       r0, word [r2   ]
837     or         r0w, word [r2+32]
838     jz .cycle%1end
839     mov        r0d, dword [r1+%1*8]
840 %if ARCH_X86_64
841     add         r0, r7
842 %else
843     add         r0, r0m
844 %endif
845     call        h264_idct_dc_add8_mmxext
846 .cycle%1end:
847 %if %1 < 7
848     add         r2, 64
849 %endif
850 %endmacro
851
852 ; ff_h264_idct_add16intra_sse2(uint8_t *dst, const int *block_offset,
853 ;                              int16_t *block, int stride, const uint8_t nnzc[6*8])
854 cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8
855 %if ARCH_X86_64
856     mov         r7, r0
857 %endif
858     add16intra_sse2_cycle 0, 0xc
859     add16intra_sse2_cycle 1, 0x14
860     add16intra_sse2_cycle 2, 0xe
861     add16intra_sse2_cycle 3, 0x16
862     add16intra_sse2_cycle 4, 0x1c
863     add16intra_sse2_cycle 5, 0x24
864     add16intra_sse2_cycle 6, 0x1e
865     add16intra_sse2_cycle 7, 0x26
866     RET
867
868 %macro add8_sse2_cycle 2
869     movzx       r0, word [r4+%2]
870     test        r0, r0
871     jz .try%1dc
872 %if ARCH_X86_64
873     mov        r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
874     add         r0, [r7]
875 %else
876     mov         r0, r0m
877     mov         r0, [r0]
878     add         r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
879 %endif
880     call        h264_add8x4_idct_sse2
881     jmp .cycle%1end
882 .try%1dc:
883     movsx       r0, word [r2   ]
884     or         r0w, word [r2+32]
885     jz .cycle%1end
886 %if ARCH_X86_64
887     mov        r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
888     add         r0, [r7]
889 %else
890     mov         r0, r0m
891     mov         r0, [r0]
892     add         r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
893 %endif
894     call        h264_idct_dc_add8_mmxext
895 .cycle%1end:
896 %if %1 == 1
897     add         r2, 384+64
898 %elif %1 < 3
899     add         r2, 64
900 %endif
901 %endmacro
902
903 ; ff_h264_idct_add8_sse2(uint8_t **dest, const int *block_offset,
904 ;                        int16_t *block, int stride, const uint8_t nnzc[6*8])
905 cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8
906     add          r2, 512
907 %if ARCH_X86_64
908     mov          r7, r0
909 %endif
910     add8_sse2_cycle 0, 0x34
911     add8_sse2_cycle 1, 0x3c
912 %if ARCH_X86_64
913     add          r7, gprsize
914 %else
915     add        r0mp, gprsize
916 %endif
917     add8_sse2_cycle 2, 0x5c
918     add8_sse2_cycle 3, 0x64
919     RET
920
921 ;void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul)
922
923 %macro WALSH4_1D 5
924     SUMSUB_BADC w, %4, %3, %2, %1, %5
925     SUMSUB_BADC w, %4, %2, %3, %1, %5
926     SWAP %1, %4, %3
927 %endmacro
928
929 %macro DEQUANT_MMX 3
930     mova        m7, [pw_1]
931     mova        m4, %1
932     punpcklwd   %1, m7
933     punpckhwd   m4, m7
934     mova        m5, %2
935     punpcklwd   %2, m7
936     punpckhwd   m5, m7
937     movd        m7, t3d
938     punpckldq   m7, m7
939     pmaddwd     %1, m7
940     pmaddwd     %2, m7
941     pmaddwd     m4, m7
942     pmaddwd     m5, m7
943     psrad       %1, %3
944     psrad       %2, %3
945     psrad       m4, %3
946     psrad       m5, %3
947     packssdw    %1, m4
948     packssdw    %2, m5
949 %endmacro
950
951 %macro STORE_WORDS 5-9
952 %if cpuflag(sse)
953     movd  t0d, %1
954     psrldq  %1, 4
955     movd  t1d, %1
956     psrldq  %1, 4
957     mov [t2+%2*32], t0w
958     mov [t2+%4*32], t1w
959     shr   t0d, 16
960     shr   t1d, 16
961     mov [t2+%3*32], t0w
962     mov [t2+%5*32], t1w
963     movd  t0d, %1
964     psrldq  %1, 4
965     movd  t1d, %1
966     mov [t2+%6*32], t0w
967     mov [t2+%8*32], t1w
968     shr   t0d, 16
969     shr   t1d, 16
970     mov [t2+%7*32], t0w
971     mov [t2+%9*32], t1w
972 %else
973     movd  t0d, %1
974     psrlq  %1, 32
975     movd  t1d, %1
976     mov [t2+%2*32], t0w
977     mov [t2+%4*32], t1w
978     shr   t0d, 16
979     shr   t1d, 16
980     mov [t2+%3*32], t0w
981     mov [t2+%5*32], t1w
982 %endif
983 %endmacro
984
985 %macro DEQUANT_STORE 1
986 %if cpuflag(sse2)
987     movd      xmm4, t3d
988     movq      xmm5, [pw_1]
989     pshufd    xmm4, xmm4, 0
990     movq2dq   xmm0, m0
991     movq2dq   xmm1, m1
992     movq2dq   xmm2, m2
993     movq2dq   xmm3, m3
994     punpcklwd xmm0, xmm5
995     punpcklwd xmm1, xmm5
996     punpcklwd xmm2, xmm5
997     punpcklwd xmm3, xmm5
998     pmaddwd   xmm0, xmm4
999     pmaddwd   xmm1, xmm4
1000     pmaddwd   xmm2, xmm4
1001     pmaddwd   xmm3, xmm4
1002     psrad     xmm0, %1
1003     psrad     xmm1, %1
1004     psrad     xmm2, %1
1005     psrad     xmm3, %1
1006     packssdw  xmm0, xmm1
1007     packssdw  xmm2, xmm3
1008     STORE_WORDS xmm0,  0,  1,  4,  5,  2,  3,  6,  7
1009     STORE_WORDS xmm2,  8,  9, 12, 13, 10, 11, 14, 15
1010 %else
1011     DEQUANT_MMX m0, m1, %1
1012     STORE_WORDS m0,  0,  1,  4,  5
1013     STORE_WORDS m1,  2,  3,  6,  7
1014
1015     DEQUANT_MMX m2, m3, %1
1016     STORE_WORDS m2,  8,  9, 12, 13
1017     STORE_WORDS m3, 10, 11, 14, 15
1018 %endif
1019 %endmacro
1020
1021 %macro IDCT_DC_DEQUANT 1
1022 cglobal h264_luma_dc_dequant_idct, 3, 4, %1
1023     ; manually spill XMM registers for Win64 because
1024     ; the code here is initialized with INIT_MMX
1025     WIN64_SPILL_XMM %1
1026     movq        m3, [r1+24]
1027     movq        m2, [r1+16]
1028     movq        m1, [r1+ 8]
1029     movq        m0, [r1+ 0]
1030     WALSH4_1D    0,1,2,3,4
1031     TRANSPOSE4x4W 0,1,2,3,4
1032     WALSH4_1D    0,1,2,3,4
1033
1034 ; shift, tmp, output, qmul
1035 %if WIN64
1036     DECLARE_REG_TMP 0,3,1,2
1037     ; we can't avoid this, because r0 is the shift register (ecx) on win64
1038     xchg        r0, t2
1039 %elif ARCH_X86_64
1040     DECLARE_REG_TMP 3,1,0,2
1041 %else
1042     DECLARE_REG_TMP 1,3,0,2
1043 %endif
1044
1045     cmp        t3d, 32767
1046     jg .big_qmul
1047     add        t3d, 128 << 16
1048     DEQUANT_STORE 8
1049     RET
1050 .big_qmul:
1051     bsr        t0d, t3d
1052     add        t3d, 128 << 16
1053     mov        t1d, 7
1054     cmp        t0d, t1d
1055     cmovg      t0d, t1d
1056     inc        t1d
1057     shr        t3d, t0b
1058     sub        t1d, t0d
1059 %if cpuflag(sse2)
1060     movd      xmm6, t1d
1061     DEQUANT_STORE xmm6
1062 %else
1063     movd        m6, t1d
1064     DEQUANT_STORE m6
1065 %endif
1066     RET
1067 %endmacro
1068
1069 INIT_MMX mmx
1070 IDCT_DC_DEQUANT 0
1071 INIT_MMX sse2
1072 IDCT_DC_DEQUANT 7