[XviD-devel] inlined SAD

Michael Militzer xvid-devel@xvid.org
Tue, 3 Sep 2002 16:31:00 +0200


This is a multi-part message in MIME format.

------=_NextPart_000_0059_01C25367.49945530
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Hi,

> for a speed test sysKin and I wanted to inline as many functions as
> possible, but this isn't possible for NASM code :-(.
> Does any of you have inline assembler versions of sad16_mmx
> and/or sad16_xmm in exactly the version as it's in nasm sources? gcc or
> VC++ doesn't matter.

yes, I have inlined versions of all assembler functions (VC++ inlined), but
not the latest versions. However it doesn't make a difference for sad
because there weren't important changes for months...

Also it's sufficient to compare inlined and non-inline - btw: I did
something like that earlier already and didn't notice any good improvement
from inlining, but maybe times have changed in the meantime ;-) So I'll be
interested in hearing your results...

bye
Michael

------=_NextPart_000_0059_01C25367.49945530
Content-Type: application/octet-stream;
	name="sad_mmx_asm.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="sad_mmx_asm.c"

///**********************************************************************=
****
// *
// *	XVID MPEG-4 VIDEO CODEC
// *	mmx/xmm sum of absolute difference
// *
// *	This program is an implementation of a part of one or more MPEG-4
// *	Video tools as specified in ISO/IEC 14496-2 standard.  Those =
intending
// *	to use this software module in hardware or software products are
// *	advised that its use may infringe existing patents or copyrights, =
and
// *	any such use would be at such party's own risk.  The original
// *	developer of this software module and his/her company, and =
subsequent
// *	editors and their companies, will have no liability for use of this
// *	software or modifications or derivatives thereof.
// *
// *	This program is free software// you can redistribute it and/or =
modify
// *	it under the terms of the GNU General Public License as published =
by
// *	the Free Software Foundation// either version 2 of the License, or
// *	(at your option) any later version.
// *
// *	This program 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 General Public License for more details.
// *
// *	You should have received a copy of the GNU General Public License
// *	along with this program// if not, write to the Free Software
// *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// *
// =
*************************************************************************=
/

///**********************************************************************=
****
// *
// *	History:
// *
// * 17.11.2001  bugfix and small improvement for dev16_xmm,
// *             removed terminate early in sad16_xmm=20
// *	12.11.2001	inital version// (c)2001 peter ross =
<pross@cs.rmit.edu.au>
// *
// =
*************************************************************************=
/

#include "../../portab.h"

int16_t xmm_one[4] =3D {1, 1, 1, 1};

//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
//
uint32_t sad16_mmx(const uint8_t * const cur,
					const uint8_t * const ref,
					const uint32_t stride,
					const uint32_t best_sad)
//
// (early termination ignore// slows this down)
//
//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
{
	__asm {
		mov esi, ref	// ref
		mov edi, cur	// cur
		mov ecx, [stride]	// stride
		mov	edx, 16
	=09
		pxor mm6, mm6			// mm6 =3D sum =3D 0
		pxor mm7, mm7			// mm7 =3D 0
sad_loop:
		movq mm0, [esi]	// ref
		movq mm1, [edi]	// cur

		movq mm2, [esi+8]	// ref2
		movq mm3, [edi+8]	// cur2

		movq mm4, mm0=20
		movq mm5, mm2

		psubusb mm0, mm1
		psubusb mm2, mm3
	=09
		psubusb mm1, mm4
		psubusb mm3, mm5

		por mm0, mm1			// mm0 =3D |ref - cur|
		por mm2, mm3			// mm2 =3D |ref2 - cur2|

		movq mm1,mm0
		movq mm3,mm2

		punpcklbw mm0,mm7
		punpcklbw mm2,mm7

		punpckhbw mm1,mm7
		punpckhbw mm3,mm7

		paddusw mm0,mm1
		paddusw mm2,mm3
	=09
		paddusw mm6,mm0		// sum +=3D mm01
		paddusw mm6,mm2		// sum +=3D mm23

		add	esi, ecx
		add	edi, ecx
		dec	edx
		jnz	sad_loop

		pmaddwd mm6, [xmm_one]	// merge sum
		movq mm7, mm6
		psrlq mm7, 32=20
		paddd mm6, mm7
		movd eax, mm6
	}
}


//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
//

uint32_t sad16_xmm(const uint8_t * const cur,
					const uint8_t * const ref,
					const uint32_t stride,
					const uint32_t best_sad)

// experimental!
//
//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
{
	__asm {
		mov esi, ref		// ref
		mov edi, cur		// cur

		mov ecx, [stride]	// stride

		mov edx, ecx
		shl edx, 1
//		mov	edx, 16
	=09
		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]
	=09
		pxor mm6, mm6			// mm6 =3D sum =3D 0
		pxor mm5, mm5
//.loop
		movq mm0, [esi]			// ref
		movq mm1, [esi + 8]		// ref2
	=09
		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi+8]		// mm0 =3D |ref2 - cur2|

		prefetchnta [esi + 2*ecx]
		prefetchnta [edi + 2*ecx]

		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1

		movq mm2, [esi + ecx]
		movq mm3, [esi + ecx + 8]

		psadbw mm2, [edi + ecx]		// mm0 =3D |ref2 - cur2|
		psadbw mm3, [edi + ecx + 8]	// mm0 =3D |ref2 - cur2|

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		paddw mm6,mm2			// sum +=3D mm01
		paddw mm5,mm3

		movq mm0, [esi]			// ref
		movq mm1, [esi + 8]		// ref2
	=09
		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi+8]		// mm0 =3D |ref2 - cur2|

		prefetchnta [esi + 2*ecx]
		prefetchnta [edi + 2*ecx]

		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1

		movq mm2, [esi + ecx]
		movq mm3, [esi + ecx + 8]

		psadbw mm2, [edi + ecx]		// mm0 =3D |ref2 - cur2|
		psadbw mm3, [edi + ecx + 8]	// mm0 =3D |ref2 - cur2|

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		paddw mm6,mm2			// sum +=3D mm01
		paddw mm5,mm3

		movq mm0, [esi]			// ref
		movq mm1, [esi + 8]		// ref2
	=09
		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi+8]		// mm0 =3D |ref2 - cur2|

		prefetchnta [esi + 2*ecx]
		prefetchnta [edi + 2*ecx]

		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1

		movq mm2, [esi + ecx]
		movq mm3, [esi + ecx + 8]

		psadbw mm2, [edi + ecx]		// mm0 =3D |ref2 - cur2|
		psadbw mm3, [edi + ecx + 8]	// mm0 =3D |ref2 - cur2|

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		paddw mm6,mm2			// sum +=3D mm01
		paddw mm5,mm3

		movq mm0, [esi]			// ref
		movq mm1, [esi + 8]		// ref2
	=09
		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi+8]		// mm0 =3D |ref2 - cur2|

		prefetchnta [esi + 2*ecx]
		prefetchnta [edi + 2*ecx]

		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1

		movq mm2, [esi + ecx]
		movq mm3, [esi + ecx + 8]

		psadbw mm2, [edi + ecx]		// mm0 =3D |ref2 - cur2|
		psadbw mm3, [edi + ecx + 8]	// mm0 =3D |ref2 - cur2|

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		paddw mm6,mm2			// sum +=3D mm01
		paddw mm5,mm3

		movq mm0, [esi]			// ref
		movq mm1, [esi + 8]		// ref2
	=09
		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi+8]		// mm0 =3D |ref2 - cur2|

		prefetchnta [esi + 2*ecx]
		prefetchnta [edi + 2*ecx]

		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1

		movq mm2, [esi + ecx]
		movq mm3, [esi + ecx + 8]

		psadbw mm2, [edi + ecx]		// mm0 =3D |ref2 - cur2|
		psadbw mm3, [edi + ecx + 8]	// mm0 =3D |ref2 - cur2|

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		paddw mm6,mm2			// sum +=3D mm01
		paddw mm5,mm3

		movq mm0, [esi]			// ref
		movq mm1, [esi + 8]		// ref2
	=09
		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi+8]		// mm0 =3D |ref2 - cur2|

		prefetchnta [esi + 2*ecx]
		prefetchnta [edi + 2*ecx]

		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1

		movq mm2, [esi + ecx]
		movq mm3, [esi + ecx + 8]

		psadbw mm2, [edi + ecx]		// mm0 =3D |ref2 - cur2|
		psadbw mm3, [edi + ecx + 8]	// mm0 =3D |ref2 - cur2|

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		paddw mm6,mm2			// sum +=3D mm01
		paddw mm5,mm3

		movq mm0, [esi]			// ref
		movq mm1, [esi + 8]		// ref2
	=09
		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi+8]		// mm0 =3D |ref2 - cur2|

		prefetchnta [esi + 2*ecx]
		prefetchnta [edi + 2*ecx]

		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1

		movq mm2, [esi + ecx]
		movq mm3, [esi + ecx + 8]

		psadbw mm2, [edi + ecx]		// mm0 =3D |ref2 - cur2|
		psadbw mm3, [edi + ecx + 8]	// mm0 =3D |ref2 - cur2|

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		paddw mm6,mm2			// sum +=3D mm01
		paddw mm5,mm3

		movq mm0, [esi]			// ref
		movq mm1, [esi + 8]		// ref2
	=09
		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi+8]		// mm0 =3D |ref2 - cur2|

		prefetchnta [esi + 2*ecx]
		prefetchnta [edi + 2*ecx]

		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1

		movq mm2, [esi + ecx]
		movq mm3, [esi + ecx + 8]

		psadbw mm2, [edi + ecx]		// mm0 =3D |ref2 - cur2|
		psadbw mm3, [edi + ecx + 8]	// mm0 =3D |ref2 - cur2|

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		paddw mm6,mm2			// sum +=3D mm01
		paddw mm5,mm3

		paddw mm6, mm5
		movd eax, mm6

	}
}

//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
//
uint32_t sad8_mmx(const uint8_t * const cur,
					const uint8_t * const ref,
					const uint32_t stride)//
//
//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
{
	__asm {
		mov 	esi, ref	// ref
		mov 	edi, cur	// cur
		mov 	ecx, [stride]	// stride
		mov	eax, 4
	=09
		pxor mm6, mm6			// mm6 =3D sum =3D 0
		pxor mm7, mm7			// mm7 =3D 0
sad_loop:
		movq mm0, [esi]	// ref
		movq mm1, [edi]	// cur

		movq mm2, [esi+ecx]	// ref2
		movq mm3, [edi+ecx]	// cur2

		movq mm4, mm0=20
		movq mm5, mm2

		psubusb mm0, mm1
		psubusb mm2, mm3
	=09
		psubusb mm1, mm4
		psubusb mm3, mm5

		por mm0, mm1			// mm0 =3D |ref - cur|
		por mm2, mm3			// mm2 =3D |ref2 - cur2|

		movq mm1,mm0
		movq mm3,mm2

		punpcklbw mm0,mm7
		punpcklbw mm2,mm7

		punpckhbw mm1,mm7
		punpckhbw mm3,mm7

		paddusw mm0,mm1
		paddusw mm2,mm3
	=09
		paddusw mm6,mm0		// sum +=3D mm01
		paddusw mm6,mm2		// sum +=3D mm23

		add	esi, ecx
		add	edi, ecx
		add	esi, ecx
		add	edi, ecx
		dec	eax
		jnz	sad_loop

		pmaddwd mm6, [xmm_one]	// merge sum
		movq mm7, mm6
		psrlq mm7, 32=20
		paddd mm6, mm7
		movd eax, mm6
	}
}




//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
//
uint32_t sad8_xmm(const uint8_t * const cur,
					const uint8_t * const ref,
					const uint32_t stride)//
//
// experimental!
//
//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
{
	__asm {
		mov 	esi, ref	// ref
		mov 	edi, cur	// cur
		mov 	ecx, [stride]	// stride

		mov     edx, ecx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		shl     edx, 1

//		mov	eax, 4
	=09
		pxor mm6, mm6			// mm6 =3D sum =3D 0
		pxor mm5, mm5
//.loop
		movq mm0, [esi]			// ref
		movq mm1, [esi + ecx]	// ref2

		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi + ecx]	// mm0 =3D |ref2 - cur2|
	=09
		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1			// sum +=3D mm23

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		movq mm0, [esi]			// ref
		movq mm1, [esi + ecx]	// ref2

		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi + ecx]	// mm0 =3D |ref2 - cur2|
	=09
		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1			// sum +=3D mm23

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		movq mm0, [esi]			// ref
		movq mm1, [esi + ecx]	// ref2

		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi + ecx]	// mm0 =3D |ref2 - cur2|
	=09
		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1			// sum +=3D mm23

		add	esi, edx
		add	edi, edx

		prefetchnta [esi + ecx]
		prefetchnta [edi + ecx]

		movq mm0, [esi]			// ref
		movq mm1, [esi + ecx]	// ref2

		psadbw mm0, [edi]		// mm0 =3D |ref - cur|
		psadbw mm1, [edi + ecx]	// mm0 =3D |ref2 - cur2|
	=09
		paddw mm6,mm0			// sum +=3D mm01
		paddw mm5,mm1			// sum +=3D mm23

		add	esi, edx
		add	edi, edx

		paddw mm6, mm5

		movd eax, mm6
	}
}


//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
//
uint32_t dev16_mmx(const uint8_t * const cur,
				const uint32_t stride)//
//
//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
{
	__asm {
		pxor mm4, mm4			// mm23 =3D sum =3D 0
		pxor mm5, mm5

		mov 	esi, cur	// cur
		mov 	ecx, [stride]	// stride
		mov     edi, esi

		mov	eax, 16
		pxor mm7, mm7			// mm7 =3D 0
sad_loop1:
		movq mm0, [esi]
		movq mm2, [esi + 8]

		movq mm1, mm0
		movq mm3, mm2

		punpcklbw mm0, mm7
		punpcklbw mm2, mm7

		punpckhbw mm1, mm7	=09
		punpckhbw mm3, mm7	=09

		paddw mm0, mm1
		paddw mm2, mm3

		paddw mm4, mm0
		paddw mm5, mm2

		add	esi, ecx
		dec	eax
		jnz	sad_loop1

		paddusw	mm4, mm5
		pmaddwd mm4, [xmm_one]	// merge sum
		movq mm5, mm4
		psrlq mm5, 32=20
		paddd mm4, mm5

		psllq mm4, 32			// blank upper dword
		psrlq mm4, 32 + 8		// mm4 /=3D (16*16)

		punpckldq mm4, mm4	=09
		packssdw mm4, mm4		// mm4 =3D mean

		pxor mm6, mm6			// mm6 =3D dev =3D 0
		mov	eax, 16
sad_loop2:
		movq mm0, [edi]
		movq mm2, [edi + 8]

		movq mm1, mm0
		movq mm3, mm2

		punpcklbw mm0, mm7
		punpcklbw mm2, mm7

		punpckhbw mm1, mm7		// mm01 =3D cur
		punpckhbw mm3, mm7		// mm23 =3D cur2

		movq mm5, mm4			//
		psubusw mm5, mm0		//
		psubusw mm0, mm4		//
		por mm0, mm5			//
		movq mm5, mm4			//
		psubusw mm5, mm1		//
		psubusw mm1, mm4		//
		por mm1, mm5			// mm01 =3D |mm01 - mm4|


		movq mm5, mm4			//
		psubusw mm5, mm2		//
		psubusw mm2, mm4		//
		por mm2, mm5			//

		movq mm5, mm4			//
		psubusw mm5, mm3		//
		psubusw mm3, mm4		//
		por mm3, mm5			// mm23 =3D |mm23 - mm4|

		paddw mm0, mm1
		paddw mm2, mm3

		paddw mm6, mm0
		paddw mm6, mm2			// dev +=3D mm01 + mm23

		add	edi, ecx
		dec	eax
		jnz	sad_loop2

		pmaddwd mm6, [xmm_one]	// merge dev
		movq mm7, mm6
		psrlq mm7, 32=20
		paddd mm6, mm7
		movd eax, mm6
	}
}


//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
//
uint32_t dev16_xmm(const uint8_t * const cur,
					const uint32_t stride)//
//
// experimental!
//
//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
{
	__asm {
		pxor mm4, mm4			// mm23 =3D sum =3D 0

		mov 	esi, cur	// cur
		mov 	ecx, [stride]	// stride
		mov     edi, esi

//		mov	eax, 16
		pxor mm7, mm7			// mm7 =3D 0
//.loop1
		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7			// abs(cur0 - 0) + abs(cur1 - 0) + ... + abs(cur7 - =
0) -> mm0
		psadbw mm2, mm7			// abs(cur8 - 0) + abs(cur9 - 0) + ... + abs(cur15 - =
0) -> mm2

		paddw mm4,mm0			// mean +=3D mm0
		paddw mm4,mm2			// mean +=3D mm2

		add	esi, ecx
//		dec	eax
//		jnz	.loop1

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		add	esi, ecx

		movq mm0, [esi]
		movq mm2, [esi + 8]

		psadbw mm0, mm7
		psadbw mm2, mm7

		paddw mm4,mm0
		paddw mm4,mm2

		movq mm5, mm4
		psllq mm5, 32=20
		paddd mm4, mm5

		psrld mm4, 8
		packssdw mm4, mm4
		packuswb mm4, mm4

		pxor mm6, mm6			// mm6 =3D dev =3D 0
//		mov	eax, 16
//.loop2
		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4			// mm0 =3D |cur - mean|
		psadbw mm2, mm4			// mm0 =3D |cur2 - mean|
=09
		paddw mm6,mm0			// dev +=3D mm01
		paddw mm6,mm2			// dev +=3D mm23

		add	edi, ecx
//		dec	eax
//		jnz	.loop2

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		add	edi, ecx

		movq mm0, [edi]
		movq mm2, [edi + 8]

		psadbw mm0, mm4
		psadbw mm2, mm4
=09
		paddw mm6,mm0
		paddw mm6,mm2

		movq mm7, mm6
		psllq mm7, 32=20
		paddd mm6, mm7
		movd eax, mm6
	}
}

------=_NextPart_000_0059_01C25367.49945530--