]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/h264_idct.asm
Merge commit 'ed9b2a5178d7a7c5a95694da3a808af327f36aff'
[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 cglobal h264_idct_add8_422_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
701 ; dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
702     movsxdifnidn r3, r3d
703 %ifdef PIC
704     lea     picregq, [scan8_mem]
705 %endif
706 %if ARCH_X86_64
707     mov       dst2q, r0
708 %endif
709
710     mov          r5, 16  ; i
711     add          r2, 512 ; i * 16 * sizeof(dctcoef) ; #define dctcoef int16_t
712
713     call         h264_idct_add8_mmx_plane
714     add r5, 4
715     call         h264_idct_add8_mmx_plane
716
717 %if ARCH_X86_64
718     add       dst2q, gprsize ; dest[1]
719 %else
720     add        r0mp, gprsize
721 %endif
722
723     add r5, 4   ; set to 32
724     add r2, 256 ; set to i * 16 * sizeof(dctcoef)
725
726     call         h264_idct_add8_mmx_plane
727     add r5, 4
728     call         h264_idct_add8_mmx_plane
729
730     RET
731
732 h264_idct_add8_mmxext_plane:
733     movsxdifnidn r3, r3d
734 .nextblock:
735     movzx        r6, byte [scan8+r5]
736     movzx        r6, byte [r4+r6]
737     test         r6, r6
738     jz .try_dc
739 %if ARCH_X86_64
740     mov         r0d, dword [r1+r5*4]
741     add          r0, [dst2q]
742 %else
743     mov          r0, r1m ; XXX r1m here is actually r0m of the calling func
744     mov          r0, [r0]
745     add          r0, dword [r1+r5*4]
746 %endif
747     IDCT4_ADD    r0, r2, r3
748     inc          r5
749     add          r2, 32
750     test         r5, 3
751     jnz .nextblock
752     rep ret
753 .try_dc:
754     movsx        r6, word [r2]
755     test         r6, r6
756     jz .skipblock
757     mov   word [r2], 0
758     DC_ADD_MMXEXT_INIT r6, r3
759 %if ARCH_X86_64
760     mov         r0d, dword [r1+r5*4]
761     add          r0, [dst2q]
762 %else
763     mov          r0, r1m ; XXX r1m here is actually r0m of the calling func
764     mov          r0, [r0]
765     add          r0, dword [r1+r5*4]
766 %endif
767     DC_ADD_MMXEXT_OP movh, r0, r3, r6
768 .skipblock:
769     inc          r5
770     add          r2, 32
771     test         r5, 3
772     jnz .nextblock
773     rep ret
774
775 INIT_MMX mmxext
776 ; void ff_h264_idct_add8_8_mmxext(uint8_t **dest, const int *block_offset,
777 ;                                 int16_t *block, int stride,
778 ;                                 const uint8_t nnzc[6 * 8])
779 cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
780     movsxdifnidn r3, r3d
781     mov          r5, 16
782     add          r2, 512
783 %if ARCH_X86_64
784     mov       dst2q, r0
785 %endif
786 %ifdef PIC
787     lea     picregq, [scan8_mem]
788 %endif
789     call h264_idct_add8_mmxext_plane
790     mov          r5, 32
791     add          r2, 384
792 %if ARCH_X86_64
793     add       dst2q, gprsize
794 %else
795     add        r0mp, gprsize
796 %endif
797     call h264_idct_add8_mmxext_plane
798     RET
799
800 ; r0 = uint8_t *dst, r2 = int16_t *block, r3 = int stride, r6=clobbered
801 h264_idct_dc_add8_mmxext:
802     movsxdifnidn r3, r3d
803     movd         m0, [r2   ]          ;  0 0 X D
804     mov word [r2+ 0], 0
805     punpcklwd    m0, [r2+32]          ;  x X d D
806     mov word [r2+32], 0
807     paddsw       m0, [pw_32]
808     psraw        m0, 6
809     punpcklwd    m0, m0               ;  d d D D
810     pxor         m1, m1               ;  0 0 0 0
811     psubw        m1, m0               ; -d-d-D-D
812     packuswb     m0, m1               ; -d-d-D-D d d D D
813     pshufw       m1, m0, 0xFA         ; -d-d-d-d-D-D-D-D
814     punpcklwd    m0, m0               ;  d d d d D D D D
815     lea          r6, [r3*3]
816     DC_ADD_MMXEXT_OP movq, r0, r3, r6
817     ret
818
819 ALIGN 16
820 INIT_XMM sse2
821 ; r0 = uint8_t *dst (clobbered), r2 = int16_t *block, r3 = int stride
822 h264_add8x4_idct_sse2:
823     movsxdifnidn r3, r3d
824     movq   m0, [r2+ 0]
825     movq   m1, [r2+ 8]
826     movq   m2, [r2+16]
827     movq   m3, [r2+24]
828     movhps m0, [r2+32]
829     movhps m1, [r2+40]
830     movhps m2, [r2+48]
831     movhps m3, [r2+56]
832     IDCT4_1D w,0,1,2,3,4,5
833     TRANSPOSE2x4x4W 0,1,2,3,4
834     paddw m0, [pw_32]
835     IDCT4_1D w,0,1,2,3,4,5
836     pxor  m7, m7
837     mova [r2+ 0], m7
838     mova [r2+16], m7
839     mova [r2+32], m7
840     mova [r2+48], m7
841     STORE_DIFFx2 m0, m1, m4, m5, m7, 6, r0, r3
842     lea   r0, [r0+r3*2]
843     STORE_DIFFx2 m2, m3, m4, m5, m7, 6, r0, r3
844     ret
845
846 %macro add16_sse2_cycle 2
847     movzx       r0, word [r4+%2]
848     test        r0, r0
849     jz .cycle%1end
850     mov        r0d, dword [r1+%1*8]
851 %if ARCH_X86_64
852     add         r0, r5
853 %else
854     add         r0, r0m
855 %endif
856     call        h264_add8x4_idct_sse2
857 .cycle%1end:
858 %if %1 < 7
859     add         r2, 64
860 %endif
861 %endmacro
862
863 ; void ff_h264_idct_add16_8_sse2(uint8_t *dst, const int *block_offset,
864 ;                                int16_t *block, int stride,
865 ;                                const uint8_t nnzc[6 * 8])
866 cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8
867     movsxdifnidn r3, r3d
868 %if ARCH_X86_64
869     mov         r5, r0
870 %endif
871     ; unrolling of the loop leads to an average performance gain of
872     ; 20-25%
873     add16_sse2_cycle 0, 0xc
874     add16_sse2_cycle 1, 0x14
875     add16_sse2_cycle 2, 0xe
876     add16_sse2_cycle 3, 0x16
877     add16_sse2_cycle 4, 0x1c
878     add16_sse2_cycle 5, 0x24
879     add16_sse2_cycle 6, 0x1e
880     add16_sse2_cycle 7, 0x26
881     RET
882
883 %macro add16intra_sse2_cycle 2
884     movzx       r0, word [r4+%2]
885     test        r0, r0
886     jz .try%1dc
887     mov        r0d, dword [r1+%1*8]
888 %if ARCH_X86_64
889     add         r0, r7
890 %else
891     add         r0, r0m
892 %endif
893     call        h264_add8x4_idct_sse2
894     jmp .cycle%1end
895 .try%1dc:
896     movsx       r0, word [r2   ]
897     or         r0w, word [r2+32]
898     jz .cycle%1end
899     mov        r0d, dword [r1+%1*8]
900 %if ARCH_X86_64
901     add         r0, r7
902 %else
903     add         r0, r0m
904 %endif
905     call        h264_idct_dc_add8_mmxext
906 .cycle%1end:
907 %if %1 < 7
908     add         r2, 64
909 %endif
910 %endmacro
911
912 ; void ff_h264_idct_add16intra_8_sse2(uint8_t *dst, const int *block_offset,
913 ;                                     int16_t *block, int stride,
914 ;                                     const uint8_t nnzc[6 * 8])
915 cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8
916     movsxdifnidn r3, r3d
917 %if ARCH_X86_64
918     mov         r7, r0
919 %endif
920     add16intra_sse2_cycle 0, 0xc
921     add16intra_sse2_cycle 1, 0x14
922     add16intra_sse2_cycle 2, 0xe
923     add16intra_sse2_cycle 3, 0x16
924     add16intra_sse2_cycle 4, 0x1c
925     add16intra_sse2_cycle 5, 0x24
926     add16intra_sse2_cycle 6, 0x1e
927     add16intra_sse2_cycle 7, 0x26
928     RET
929
930 %macro add8_sse2_cycle 2
931     movzx       r0, word [r4+%2]
932     test        r0, r0
933     jz .try%1dc
934 %if ARCH_X86_64
935     mov        r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
936     add         r0, [r7]
937 %else
938     mov         r0, r0m
939     mov         r0, [r0]
940     add         r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
941 %endif
942     call        h264_add8x4_idct_sse2
943     jmp .cycle%1end
944 .try%1dc:
945     movsx       r0, word [r2   ]
946     or         r0w, word [r2+32]
947     jz .cycle%1end
948 %if ARCH_X86_64
949     mov        r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
950     add         r0, [r7]
951 %else
952     mov         r0, r0m
953     mov         r0, [r0]
954     add         r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
955 %endif
956     call        h264_idct_dc_add8_mmxext
957 .cycle%1end:
958 %if %1 == 1
959     add         r2, 384+64
960 %elif %1 < 3
961     add         r2, 64
962 %endif
963 %endmacro
964
965 ; void ff_h264_idct_add8_8_sse2(uint8_t **dest, const int *block_offset,
966 ;                               int16_t *block, int stride,
967 ;                               const uint8_t nnzc[6 * 8])
968 cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8
969     movsxdifnidn r3, r3d
970     add          r2, 512
971 %if ARCH_X86_64
972     mov          r7, r0
973 %endif
974     add8_sse2_cycle 0, 0x34
975     add8_sse2_cycle 1, 0x3c
976 %if ARCH_X86_64
977     add          r7, gprsize
978 %else
979     add        r0mp, gprsize
980 %endif
981     add8_sse2_cycle 2, 0x5c
982     add8_sse2_cycle 3, 0x64
983     RET
984
985 ;void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul)
986
987 %macro WALSH4_1D 5
988     SUMSUB_BADC w, %4, %3, %2, %1, %5
989     SUMSUB_BADC w, %4, %2, %3, %1, %5
990     SWAP %1, %4, %3
991 %endmacro
992
993 %macro DEQUANT_MMX 3
994     mova        m7, [pw_1]
995     mova        m4, %1
996     punpcklwd   %1, m7
997     punpckhwd   m4, m7
998     mova        m5, %2
999     punpcklwd   %2, m7
1000     punpckhwd   m5, m7
1001     movd        m7, t3d
1002     punpckldq   m7, m7
1003     pmaddwd     %1, m7
1004     pmaddwd     %2, m7
1005     pmaddwd     m4, m7
1006     pmaddwd     m5, m7
1007     psrad       %1, %3
1008     psrad       %2, %3
1009     psrad       m4, %3
1010     psrad       m5, %3
1011     packssdw    %1, m4
1012     packssdw    %2, m5
1013 %endmacro
1014
1015 %macro STORE_WORDS 5-9
1016 %if cpuflag(sse)
1017     movd  t0d, %1
1018     psrldq  %1, 4
1019     movd  t1d, %1
1020     psrldq  %1, 4
1021     mov [t2+%2*32], t0w
1022     mov [t2+%4*32], t1w
1023     shr   t0d, 16
1024     shr   t1d, 16
1025     mov [t2+%3*32], t0w
1026     mov [t2+%5*32], t1w
1027     movd  t0d, %1
1028     psrldq  %1, 4
1029     movd  t1d, %1
1030     mov [t2+%6*32], t0w
1031     mov [t2+%8*32], t1w
1032     shr   t0d, 16
1033     shr   t1d, 16
1034     mov [t2+%7*32], t0w
1035     mov [t2+%9*32], t1w
1036 %else
1037     movd  t0d, %1
1038     psrlq  %1, 32
1039     movd  t1d, %1
1040     mov [t2+%2*32], t0w
1041     mov [t2+%4*32], t1w
1042     shr   t0d, 16
1043     shr   t1d, 16
1044     mov [t2+%3*32], t0w
1045     mov [t2+%5*32], t1w
1046 %endif
1047 %endmacro
1048
1049 %macro DEQUANT_STORE 1
1050 %if cpuflag(sse2)
1051     movd      xmm4, t3d
1052     movq      xmm5, [pw_1]
1053     pshufd    xmm4, xmm4, 0
1054     movq2dq   xmm0, m0
1055     movq2dq   xmm1, m1
1056     movq2dq   xmm2, m2
1057     movq2dq   xmm3, m3
1058     punpcklwd xmm0, xmm5
1059     punpcklwd xmm1, xmm5
1060     punpcklwd xmm2, xmm5
1061     punpcklwd xmm3, xmm5
1062     pmaddwd   xmm0, xmm4
1063     pmaddwd   xmm1, xmm4
1064     pmaddwd   xmm2, xmm4
1065     pmaddwd   xmm3, xmm4
1066     psrad     xmm0, %1
1067     psrad     xmm1, %1
1068     psrad     xmm2, %1
1069     psrad     xmm3, %1
1070     packssdw  xmm0, xmm1
1071     packssdw  xmm2, xmm3
1072     STORE_WORDS xmm0,  0,  1,  4,  5,  2,  3,  6,  7
1073     STORE_WORDS xmm2,  8,  9, 12, 13, 10, 11, 14, 15
1074 %else
1075     DEQUANT_MMX m0, m1, %1
1076     STORE_WORDS m0,  0,  1,  4,  5
1077     STORE_WORDS m1,  2,  3,  6,  7
1078
1079     DEQUANT_MMX m2, m3, %1
1080     STORE_WORDS m2,  8,  9, 12, 13
1081     STORE_WORDS m3, 10, 11, 14, 15
1082 %endif
1083 %endmacro
1084
1085 %macro IDCT_DC_DEQUANT 1
1086 cglobal h264_luma_dc_dequant_idct, 3, 4, %1
1087     ; manually spill XMM registers for Win64 because
1088     ; the code here is initialized with INIT_MMX
1089     WIN64_SPILL_XMM %1
1090     movq        m3, [r1+24]
1091     movq        m2, [r1+16]
1092     movq        m1, [r1+ 8]
1093     movq        m0, [r1+ 0]
1094     WALSH4_1D    0,1,2,3,4
1095     TRANSPOSE4x4W 0,1,2,3,4
1096     WALSH4_1D    0,1,2,3,4
1097
1098 ; shift, tmp, output, qmul
1099 %if WIN64
1100     DECLARE_REG_TMP 0,3,1,2
1101     ; we can't avoid this, because r0 is the shift register (ecx) on win64
1102     xchg        r0, t2
1103 %elif ARCH_X86_64
1104     DECLARE_REG_TMP 3,1,0,2
1105 %else
1106     DECLARE_REG_TMP 1,3,0,2
1107 %endif
1108
1109     cmp        t3d, 32767
1110     jg .big_qmul
1111     add        t3d, 128 << 16
1112     DEQUANT_STORE 8
1113     RET
1114 .big_qmul:
1115     bsr        t0d, t3d
1116     add        t3d, 128 << 16
1117     mov        t1d, 7
1118     cmp        t0d, t1d
1119     cmovg      t0d, t1d
1120     inc        t1d
1121     shr        t3d, t0b
1122     sub        t1d, t0d
1123 %if cpuflag(sse2)
1124     movd      xmm6, t1d
1125     DEQUANT_STORE xmm6
1126 %else
1127     movd        m6, t1d
1128     DEQUANT_STORE m6
1129 %endif
1130     RET
1131 %endmacro
1132
1133 INIT_MMX mmx
1134 IDCT_DC_DEQUANT 0
1135 INIT_MMX sse2
1136 IDCT_DC_DEQUANT 7