Mercurial > libavcodec.hg
view x86/dsputil_mmx_avg_template.c @ 9003:b595a8a59967 libavcodec
Change the type of pblocks from pointers to short array into
pointers to array of 64 DCTELEM, similarly to other block fields.
This also get rid of some casts and fixes a warning.
author | iive |
---|---|
date | Sun, 22 Feb 2009 09:02:06 +0000 |
parents | 04423b2f6e0b |
children | 36b60aa6bc75 |
line wrap: on
line source
/* * DSP utils : average functions are compiled twice for 3dnow/mmx2 * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * * MMX optimization by Nick Kurshev <nickols_k@mail.ru> * mostly rewritten by Michael Niedermayer <michaelni@gmx.at> * and improved by Zdenek Kabelac <kabi@users.sf.net> * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* XXX: we use explicit registers to avoid a gcc 2.95.2 register asm clobber bug - now it will work with 2.95.2 and also with -fPIC */ static void DEF(put_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { __asm__ volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "movq (%1, %3), %%mm1 \n\t" PAVGB" 1(%1), %%mm0 \n\t" PAVGB" 1(%1, %3), %%mm1 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "add %%"REG_a", %1 \n\t" "add %%"REG_a", %2 \n\t" "movq (%1), %%mm0 \n\t" "movq (%1, %3), %%mm1 \n\t" PAVGB" 1(%1), %%mm0 \n\t" PAVGB" 1(%1, %3), %%mm1 \n\t" "add %%"REG_a", %1 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D"(block) :"r" ((x86_reg)line_size) :"%"REG_a, "memory"); } static void DEF(put_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { __asm__ volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movd (%1), %%mm0 \n\t" "movd (%2), %%mm1 \n\t" "add %4, %1 \n\t" "add $4, %2 \n\t" PAVGB" %%mm1, %%mm0 \n\t" "movd %%mm0, (%3) \n\t" "add %5, %3 \n\t" "decl %0 \n\t" "1: \n\t" "movd (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movd (%1), %%mm1 \n\t" "movd (%2), %%mm2 \n\t" "movd 4(%2), %%mm3 \n\t" "add %4, %1 \n\t" PAVGB" %%mm2, %%mm0 \n\t" PAVGB" %%mm3, %%mm1 \n\t" "movd %%mm0, (%3) \n\t" "add %5, %3 \n\t" "movd %%mm1, (%3) \n\t" "add %5, %3 \n\t" "movd (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movd (%1), %%mm1 \n\t" "movd 8(%2), %%mm2 \n\t" "movd 12(%2), %%mm3 \n\t" "add %4, %1 \n\t" PAVGB" %%mm2, %%mm0 \n\t" PAVGB" %%mm3, %%mm1 \n\t" "movd %%mm0, (%3) \n\t" "add %5, %3 \n\t" "movd %%mm1, (%3) \n\t" "add %5, %3 \n\t" "add $16, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) #endif :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride) :"memory"); } static void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { __asm__ volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" "movq (%2), %%mm1 \n\t" "add %4, %1 \n\t" "add $8, %2 \n\t" PAVGB" %%mm1, %%mm0 \n\t" "movq %%mm0, (%3) \n\t" "add %5, %3 \n\t" "decl %0 \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movq (%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" 8(%2), %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "add %5, %3 \n\t" "movq %%mm1, (%3) \n\t" "add %5, %3 \n\t" "movq (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movq (%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" 16(%2), %%mm0 \n\t" PAVGB" 24(%2), %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "add %5, %3 \n\t" "movq %%mm1, (%3) \n\t" "add %5, %3 \n\t" "add $32, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) #endif :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride) :"memory"); //the following should be used, though better not with gcc ... /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) :"r"(src1Stride), "r"(dstStride) :"memory");*/ } static void DEF(put_no_rnd_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { __asm__ volatile( "pcmpeqb %%mm6, %%mm6 \n\t" "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" "movq (%2), %%mm1 \n\t" "add %4, %1 \n\t" "add $8, %2 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" PAVGB" %%mm1, %%mm0 \n\t" "pxor %%mm6, %%mm0 \n\t" "movq %%mm0, (%3) \n\t" "add %5, %3 \n\t" "decl %0 \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movq (%1), %%mm1 \n\t" "add %4, %1 \n\t" "movq (%2), %%mm2 \n\t" "movq 8(%2), %%mm3 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "pxor %%mm6, %%mm2 \n\t" "pxor %%mm6, %%mm3 \n\t" PAVGB" %%mm2, %%mm0 \n\t" PAVGB" %%mm3, %%mm1 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "add %5, %3 \n\t" "movq %%mm1, (%3) \n\t" "add %5, %3 \n\t" "movq (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movq (%1), %%mm1 \n\t" "add %4, %1 \n\t" "movq 16(%2), %%mm2 \n\t" "movq 24(%2), %%mm3 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "pxor %%mm6, %%mm2 \n\t" "pxor %%mm6, %%mm3 \n\t" PAVGB" %%mm2, %%mm0 \n\t" PAVGB" %%mm3, %%mm1 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "add %5, %3 \n\t" "movq %%mm1, (%3) \n\t" "add %5, %3 \n\t" "add $32, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) #endif :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride) :"memory"); //the following should be used, though better not with gcc ... /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) :"r"(src1Stride), "r"(dstStride) :"memory");*/ } static void DEF(avg_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { __asm__ volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movd (%1), %%mm0 \n\t" "movd (%2), %%mm1 \n\t" "add %4, %1 \n\t" "add $4, %2 \n\t" PAVGB" %%mm1, %%mm0 \n\t" PAVGB" (%3), %%mm0 \n\t" "movd %%mm0, (%3) \n\t" "add %5, %3 \n\t" "decl %0 \n\t" "1: \n\t" "movd (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movd (%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" 4(%2), %%mm1 \n\t" PAVGB" (%3), %%mm0 \n\t" "movd %%mm0, (%3) \n\t" "add %5, %3 \n\t" PAVGB" (%3), %%mm1 \n\t" "movd %%mm1, (%3) \n\t" "add %5, %3 \n\t" "movd (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movd (%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" 8(%2), %%mm0 \n\t" PAVGB" 12(%2), %%mm1 \n\t" PAVGB" (%3), %%mm0 \n\t" "movd %%mm0, (%3) \n\t" "add %5, %3 \n\t" PAVGB" (%3), %%mm1 \n\t" "movd %%mm1, (%3) \n\t" "add %5, %3 \n\t" "add $16, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) #endif :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride) :"memory"); } static void DEF(avg_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { __asm__ volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" "movq (%2), %%mm1 \n\t" "add %4, %1 \n\t" "add $8, %2 \n\t" PAVGB" %%mm1, %%mm0 \n\t" PAVGB" (%3), %%mm0 \n\t" "movq %%mm0, (%3) \n\t" "add %5, %3 \n\t" "decl %0 \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movq (%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" 8(%2), %%mm1 \n\t" PAVGB" (%3), %%mm0 \n\t" "movq %%mm0, (%3) \n\t" "add %5, %3 \n\t" PAVGB" (%3), %%mm1 \n\t" "movq %%mm1, (%3) \n\t" "add %5, %3 \n\t" "movq (%1), %%mm0 \n\t" "add %4, %1 \n\t" "movq (%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" 16(%2), %%mm0 \n\t" PAVGB" 24(%2), %%mm1 \n\t" PAVGB" (%3), %%mm0 \n\t" "movq %%mm0, (%3) \n\t" "add %5, %3 \n\t" PAVGB" (%3), %%mm1 \n\t" "movq %%mm1, (%3) \n\t" "add %5, %3 \n\t" "add $32, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) #endif :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride) :"memory"); //the following should be used, though better not with gcc ... /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) :"r"(src1Stride), "r"(dstStride) :"memory");*/ } static void DEF(put_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { __asm__ volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "movq (%1, %3), %%mm1 \n\t" "movq 8(%1), %%mm2 \n\t" "movq 8(%1, %3), %%mm3 \n\t" PAVGB" 1(%1), %%mm0 \n\t" PAVGB" 1(%1, %3), %%mm1 \n\t" PAVGB" 9(%1), %%mm2 \n\t" PAVGB" 9(%1, %3), %%mm3 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "movq %%mm2, 8(%2) \n\t" "movq %%mm3, 8(%2, %3) \n\t" "add %%"REG_a", %1 \n\t" "add %%"REG_a", %2 \n\t" "movq (%1), %%mm0 \n\t" "movq (%1, %3), %%mm1 \n\t" "movq 8(%1), %%mm2 \n\t" "movq 8(%1, %3), %%mm3 \n\t" PAVGB" 1(%1), %%mm0 \n\t" PAVGB" 1(%1, %3), %%mm1 \n\t" PAVGB" 9(%1), %%mm2 \n\t" PAVGB" 9(%1, %3), %%mm3 \n\t" "add %%"REG_a", %1 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "movq %%mm2, 8(%2) \n\t" "movq %%mm3, 8(%2, %3) \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D"(block) :"r" ((x86_reg)line_size) :"%"REG_a, "memory"); } static void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { __asm__ volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm1 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" 8(%2), %%mm1 \n\t" "add %4, %1 \n\t" "add $16, %2 \n\t" "movq %%mm0, (%3) \n\t" "movq %%mm1, 8(%3) \n\t" "add %5, %3 \n\t" "decl %0 \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" 8(%2), %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "movq %%mm1, 8(%3) \n\t" "add %5, %3 \n\t" "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" 16(%2), %%mm0 \n\t" PAVGB" 24(%2), %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "movq %%mm1, 8(%3) \n\t" "add %5, %3 \n\t" "add $32, %2 \n\t" "subl $2, %0 \n\t" "jnz 1b \n\t" #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) #endif :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride) :"memory"); //the following should be used, though better not with gcc ... /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) :"r"(src1Stride), "r"(dstStride) :"memory");*/ } static void DEF(avg_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { __asm__ volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm1 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" 8(%2), %%mm1 \n\t" "add %4, %1 \n\t" "add $16, %2 \n\t" PAVGB" (%3), %%mm0 \n\t" PAVGB" 8(%3), %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "movq %%mm1, 8(%3) \n\t" "add %5, %3 \n\t" "decl %0 \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" 8(%2), %%mm1 \n\t" PAVGB" (%3), %%mm0 \n\t" PAVGB" 8(%3), %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "movq %%mm1, 8(%3) \n\t" "add %5, %3 \n\t" "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm1 \n\t" "add %4, %1 \n\t" PAVGB" 16(%2), %%mm0 \n\t" PAVGB" 24(%2), %%mm1 \n\t" PAVGB" (%3), %%mm0 \n\t" PAVGB" 8(%3), %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "movq %%mm1, 8(%3) \n\t" "add %5, %3 \n\t" "add $32, %2 \n\t" "subl $2, %0 \n\t" "jnz 1b \n\t" #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) #endif :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride) :"memory"); //the following should be used, though better not with gcc ... /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) :"r"(src1Stride), "r"(dstStride) :"memory");*/ } static void DEF(put_no_rnd_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { __asm__ volatile( "pcmpeqb %%mm6, %%mm6 \n\t" "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm1 \n\t" "movq (%2), %%mm2 \n\t" "movq 8(%2), %%mm3 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "pxor %%mm6, %%mm2 \n\t" "pxor %%mm6, %%mm3 \n\t" PAVGB" %%mm2, %%mm0 \n\t" PAVGB" %%mm3, %%mm1 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "add %4, %1 \n\t" "add $16, %2 \n\t" "movq %%mm0, (%3) \n\t" "movq %%mm1, 8(%3) \n\t" "add %5, %3 \n\t" "decl %0 \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm1 \n\t" "add %4, %1 \n\t" "movq (%2), %%mm2 \n\t" "movq 8(%2), %%mm3 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "pxor %%mm6, %%mm2 \n\t" "pxor %%mm6, %%mm3 \n\t" PAVGB" %%mm2, %%mm0 \n\t" PAVGB" %%mm3, %%mm1 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "movq %%mm1, 8(%3) \n\t" "add %5, %3 \n\t" "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm1 \n\t" "add %4, %1 \n\t" "movq 16(%2), %%mm2 \n\t" "movq 24(%2), %%mm3 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "pxor %%mm6, %%mm2 \n\t" "pxor %%mm6, %%mm3 \n\t" PAVGB" %%mm2, %%mm0 \n\t" PAVGB" %%mm3, %%mm1 \n\t" "pxor %%mm6, %%mm0 \n\t" "pxor %%mm6, %%mm1 \n\t" "movq %%mm0, (%3) \n\t" "movq %%mm1, 8(%3) \n\t" "add %5, %3 \n\t" "add $32, %2 \n\t" "subl $2, %0 \n\t" "jnz 1b \n\t" #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) #endif :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride) :"memory"); //the following should be used, though better not with gcc ... /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) :"r"(src1Stride), "r"(dstStride) :"memory");*/ } /* GL: this function does incorrect rounding if overflow */ static void DEF(put_no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BONE(mm6); __asm__ volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "movq (%1, %3), %%mm2 \n\t" "movq 1(%1), %%mm1 \n\t" "movq 1(%1, %3), %%mm3 \n\t" "add %%"REG_a", %1 \n\t" "psubusb %%mm6, %%mm0 \n\t" "psubusb %%mm6, %%mm2 \n\t" PAVGB" %%mm1, %%mm0 \n\t" PAVGB" %%mm3, %%mm2 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm2, (%2, %3) \n\t" "movq (%1), %%mm0 \n\t" "movq 1(%1), %%mm1 \n\t" "movq (%1, %3), %%mm2 \n\t" "movq 1(%1, %3), %%mm3 \n\t" "add %%"REG_a", %2 \n\t" "add %%"REG_a", %1 \n\t" "psubusb %%mm6, %%mm0 \n\t" "psubusb %%mm6, %%mm2 \n\t" PAVGB" %%mm1, %%mm0 \n\t" PAVGB" %%mm3, %%mm2 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm2, (%2, %3) \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D"(block) :"r" ((x86_reg)line_size) :"%"REG_a, "memory"); } static void DEF(put_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { __asm__ volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" "sub %3, %2 \n\t" "1: \n\t" "movq (%1, %3), %%mm1 \n\t" "movq (%1, %%"REG_a"), %%mm2 \n\t" "add %%"REG_a", %1 \n\t" PAVGB" %%mm1, %%mm0 \n\t" PAVGB" %%mm2, %%mm1 \n\t" "movq %%mm0, (%2, %3) \n\t" "movq %%mm1, (%2, %%"REG_a") \n\t" "movq (%1, %3), %%mm1 \n\t" "movq (%1, %%"REG_a"), %%mm0 \n\t" "add %%"REG_a", %2 \n\t" "add %%"REG_a", %1 \n\t" PAVGB" %%mm1, %%mm2 \n\t" PAVGB" %%mm0, %%mm1 \n\t" "movq %%mm2, (%2, %3) \n\t" "movq %%mm1, (%2, %%"REG_a") \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D" (block) :"r" ((x86_reg)line_size) :"%"REG_a, "memory"); } /* GL: this function does incorrect rounding if overflow */ static void DEF(put_no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BONE(mm6); __asm__ volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" "sub %3, %2 \n\t" "1: \n\t" "movq (%1, %3), %%mm1 \n\t" "movq (%1, %%"REG_a"), %%mm2 \n\t" "add %%"REG_a", %1 \n\t" "psubusb %%mm6, %%mm1 \n\t" PAVGB" %%mm1, %%mm0 \n\t" PAVGB" %%mm2, %%mm1 \n\t" "movq %%mm0, (%2, %3) \n\t" "movq %%mm1, (%2, %%"REG_a") \n\t" "movq (%1, %3), %%mm1 \n\t" "movq (%1, %%"REG_a"), %%mm0 \n\t" "add %%"REG_a", %2 \n\t" "add %%"REG_a", %1 \n\t" "psubusb %%mm6, %%mm1 \n\t" PAVGB" %%mm1, %%mm2 \n\t" PAVGB" %%mm0, %%mm1 \n\t" "movq %%mm2, (%2, %3) \n\t" "movq %%mm1, (%2, %%"REG_a") \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D" (block) :"r" ((x86_reg)line_size) :"%"REG_a, "memory"); } static void DEF(avg_pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { __asm__ volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%2), %%mm0 \n\t" "movq (%2, %3), %%mm1 \n\t" PAVGB" (%1), %%mm0 \n\t" PAVGB" (%1, %3), %%mm1 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "add %%"REG_a", %1 \n\t" "add %%"REG_a", %2 \n\t" "movq (%2), %%mm0 \n\t" "movq (%2, %3), %%mm1 \n\t" PAVGB" (%1), %%mm0 \n\t" PAVGB" (%1, %3), %%mm1 \n\t" "add %%"REG_a", %1 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D"(block) :"r" ((x86_reg)line_size) :"%"REG_a, "memory"); } static void DEF(avg_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { __asm__ volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" "movq (%1, %3), %%mm2 \n\t" PAVGB" 1(%1), %%mm0 \n\t" PAVGB" 1(%1, %3), %%mm2 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" (%2, %3), %%mm2 \n\t" "add %%"REG_a", %1 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm2, (%2, %3) \n\t" "movq (%1), %%mm0 \n\t" "movq (%1, %3), %%mm2 \n\t" PAVGB" 1(%1), %%mm0 \n\t" PAVGB" 1(%1, %3), %%mm2 \n\t" "add %%"REG_a", %2 \n\t" "add %%"REG_a", %1 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" (%2, %3), %%mm2 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm2, (%2, %3) \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D"(block) :"r" ((x86_reg)line_size) :"%"REG_a, "memory"); } static void DEF(avg_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { __asm__ volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" "sub %3, %2 \n\t" "1: \n\t" "movq (%1, %3), %%mm1 \n\t" "movq (%1, %%"REG_a"), %%mm2 \n\t" "add %%"REG_a", %1 \n\t" PAVGB" %%mm1, %%mm0 \n\t" PAVGB" %%mm2, %%mm1 \n\t" "movq (%2, %3), %%mm3 \n\t" "movq (%2, %%"REG_a"), %%mm4 \n\t" PAVGB" %%mm3, %%mm0 \n\t" PAVGB" %%mm4, %%mm1 \n\t" "movq %%mm0, (%2, %3) \n\t" "movq %%mm1, (%2, %%"REG_a") \n\t" "movq (%1, %3), %%mm1 \n\t" "movq (%1, %%"REG_a"), %%mm0 \n\t" PAVGB" %%mm1, %%mm2 \n\t" PAVGB" %%mm0, %%mm1 \n\t" "add %%"REG_a", %2 \n\t" "add %%"REG_a", %1 \n\t" "movq (%2, %3), %%mm3 \n\t" "movq (%2, %%"REG_a"), %%mm4 \n\t" PAVGB" %%mm3, %%mm2 \n\t" PAVGB" %%mm4, %%mm1 \n\t" "movq %%mm2, (%2, %3) \n\t" "movq %%mm1, (%2, %%"REG_a") \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D"(block) :"r" ((x86_reg)line_size) :"%"REG_a, "memory"); } /* Note this is not correctly rounded, but this function is only * used for B-frames so it does not matter. */ static void DEF(avg_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BONE(mm6); __asm__ volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" PAVGB" 1(%1), %%mm0 \n\t" ASMALIGN(3) "1: \n\t" "movq (%1, %%"REG_a"), %%mm2 \n\t" "movq (%1, %3), %%mm1 \n\t" "psubusb %%mm6, %%mm2 \n\t" PAVGB" 1(%1, %3), %%mm1 \n\t" PAVGB" 1(%1, %%"REG_a"), %%mm2 \n\t" "add %%"REG_a", %1 \n\t" PAVGB" %%mm1, %%mm0 \n\t" PAVGB" %%mm2, %%mm1 \n\t" PAVGB" (%2), %%mm0 \n\t" PAVGB" (%2, %3), %%mm1 \n\t" "movq %%mm0, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "movq (%1, %3), %%mm1 \n\t" "movq (%1, %%"REG_a"), %%mm0 \n\t" PAVGB" 1(%1, %3), %%mm1 \n\t" PAVGB" 1(%1, %%"REG_a"), %%mm0 \n\t" "add %%"REG_a", %2 \n\t" "add %%"REG_a", %1 \n\t" PAVGB" %%mm1, %%mm2 \n\t" PAVGB" %%mm0, %%mm1 \n\t" PAVGB" (%2), %%mm2 \n\t" PAVGB" (%2, %3), %%mm1 \n\t" "movq %%mm2, (%2) \n\t" "movq %%mm1, (%2, %3) \n\t" "add %%"REG_a", %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" :"+g"(h), "+S"(pixels), "+D"(block) :"r" ((x86_reg)line_size) :"%"REG_a, "memory"); } static void DEF(avg_pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { do { __asm__ volatile( "movd (%1), %%mm0 \n\t" "movd (%1, %2), %%mm1 \n\t" "movd (%1, %2, 2), %%mm2 \n\t" "movd (%1, %3), %%mm3 \n\t" PAVGB" (%0), %%mm0 \n\t" PAVGB" (%0, %2), %%mm1 \n\t" PAVGB" (%0, %2, 2), %%mm2 \n\t" PAVGB" (%0, %3), %%mm3 \n\t" "movd %%mm0, (%1) \n\t" "movd %%mm1, (%1, %2) \n\t" "movd %%mm2, (%1, %2, 2) \n\t" "movd %%mm3, (%1, %3) \n\t" ::"S"(pixels), "D"(block), "r" ((x86_reg)line_size), "r"((x86_reg)3L*line_size) :"memory"); block += 4*line_size; pixels += 4*line_size; h -= 4; } while(h > 0); } //FIXME the following could be optimized too ... static void DEF(put_no_rnd_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ DEF(put_no_rnd_pixels8_x2)(block , pixels , line_size, h); DEF(put_no_rnd_pixels8_x2)(block+8, pixels+8, line_size, h); } static void DEF(put_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ DEF(put_pixels8_y2)(block , pixels , line_size, h); DEF(put_pixels8_y2)(block+8, pixels+8, line_size, h); } static void DEF(put_no_rnd_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ DEF(put_no_rnd_pixels8_y2)(block , pixels , line_size, h); DEF(put_no_rnd_pixels8_y2)(block+8, pixels+8, line_size, h); } static void DEF(avg_pixels16)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ DEF(avg_pixels8)(block , pixels , line_size, h); DEF(avg_pixels8)(block+8, pixels+8, line_size, h); } static void DEF(avg_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ DEF(avg_pixels8_x2)(block , pixels , line_size, h); DEF(avg_pixels8_x2)(block+8, pixels+8, line_size, h); } static void DEF(avg_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ DEF(avg_pixels8_y2)(block , pixels , line_size, h); DEF(avg_pixels8_y2)(block+8, pixels+8, line_size, h); } static void DEF(avg_pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ DEF(avg_pixels8_xy2)(block , pixels , line_size, h); DEF(avg_pixels8_xy2)(block+8, pixels+8, line_size, h); } #define QPEL_2TAP_L3(OPNAME) \ static void DEF(OPNAME ## 2tap_qpel16_l3)(uint8_t *dst, uint8_t *src, int stride, int h, int off1, int off2){\ __asm__ volatile(\ "1: \n\t"\ "movq (%1,%2), %%mm0 \n\t"\ "movq 8(%1,%2), %%mm1 \n\t"\ PAVGB" (%1,%3), %%mm0 \n\t"\ PAVGB" 8(%1,%3), %%mm1 \n\t"\ PAVGB" (%1), %%mm0 \n\t"\ PAVGB" 8(%1), %%mm1 \n\t"\ STORE_OP( (%1,%4),%%mm0)\ STORE_OP(8(%1,%4),%%mm1)\ "movq %%mm0, (%1,%4) \n\t"\ "movq %%mm1, 8(%1,%4) \n\t"\ "add %5, %1 \n\t"\ "decl %0 \n\t"\ "jnz 1b \n\t"\ :"+g"(h), "+r"(src)\ :"r"((x86_reg)off1), "r"((x86_reg)off2),\ "r"((x86_reg)(dst-src)), "r"((x86_reg)stride)\ :"memory"\ );\ }\ static void DEF(OPNAME ## 2tap_qpel8_l3)(uint8_t *dst, uint8_t *src, int stride, int h, int off1, int off2){\ __asm__ volatile(\ "1: \n\t"\ "movq (%1,%2), %%mm0 \n\t"\ PAVGB" (%1,%3), %%mm0 \n\t"\ PAVGB" (%1), %%mm0 \n\t"\ STORE_OP((%1,%4),%%mm0)\ "movq %%mm0, (%1,%4) \n\t"\ "add %5, %1 \n\t"\ "decl %0 \n\t"\ "jnz 1b \n\t"\ :"+g"(h), "+r"(src)\ :"r"((x86_reg)off1), "r"((x86_reg)off2),\ "r"((x86_reg)(dst-src)), "r"((x86_reg)stride)\ :"memory"\ );\ } #define STORE_OP(a,b) PAVGB" "#a","#b" \n\t" QPEL_2TAP_L3(avg_) #undef STORE_OP #define STORE_OP(a,b) QPEL_2TAP_L3(put_) #undef STORE_OP #undef QPEL_2TAP_L3