/* asm_stuff.S */

	.text

#if CPU_NUMBER >= 4
#define BSWAP(r)	bswap %e##r##x
#else
#define BSWAP(r)	roll $16,%e##r##x
#endif

	.lcomm	count,1

	.align	2
#define OFFSET	4
	.globl	_zero_8x8
_zero_8x8:
	pushl	%ebx
	movl	OFFSET+4(%esp),%ecx
	movl	OFFSET+8(%esp),%edx
	xorl	%eax,%eax
	leal	(%edx,%edx),%ebx
	movl	%eax,(%ecx)
	movl	%eax,4(%ecx)
	movl	%eax,(%ecx,%edx)
	movl	%eax,4(%ecx,%edx)
	addl	%ebx,%ecx
	movl	%eax,(%ecx)
	movl	%eax,4(%ecx)
	movl	%eax,(%ecx,%edx)
	movl	%eax,4(%ecx,%edx)
	addl	%ebx,%ecx
	movl	%eax,(%ecx)
	movl	%eax,4(%ecx)
	movl	%eax,(%ecx,%edx)
	movl	%eax,4(%ecx,%edx)
	addl	%ebx,%ecx
	movl	%eax,(%ecx)
	movl	%eax,4(%ecx)
	movl	%eax,(%ecx,%edx)
	movl	%eax,4(%ecx,%edx)
	popl	%ebx
	ret
#undef OFFSET


	.align	2
#define OFFSET	16
	.globl	_copy_crop_8x8
_copy_crop_8x8:
	pushl	%esi
	pushl	%edi
	pushl	%ebp
	pushl	%ebx
	movl	OFFSET+4(%esp),%edi
	movl	OFFSET+8(%esp),%esi
	movl	OFFSET+12(%esp),%ecx
	movl	_crop_table,%ebx
	movl	$8,%ebp
	movl	%ebx,%edx

	.align	2
loop1:
	movl	(%esi),%eax
	BSWAP(a)
	movb	%al,%bl
	movb	%ah,%dl
	movb	(%ebx),%al
	movb	(%edx),%ah
	BSWAP(a)
	movb	%al,%bl
	movb	%ah,%dl
	movb	(%ebx),%al
	movb	(%edx),%ah
	movl	%eax,(%edi)

	movl	4(%esi),%eax
	BSWAP(a)
	movb	%al,%bl
	movb	%ah,%dl
	movb	(%ebx),%al
	movb	(%edx),%ah
	BSWAP(a)
	movb	%al,%bl
	movb	%ah,%dl
	movb	(%ebx),%al
	movb	(%edx),%ah
	movl	%eax,4(%edi)

	addl	$16,%esi
	addl	%ecx,%edi
	decl	%ebp
	jnz	loop1

	popl	%ebx
	popl	%ebp
	popl	%edi
	popl	%esi
	ret
#undef OFFSET


	.align	2
#define OFFSET	8
	.globl	_copy_8x8
_copy_8x8:
	pushl	%esi
	pushl	%edi
	movl	OFFSET+4(%esp),%edi
	movl	OFFSET+8(%esp),%esi
	movl	OFFSET+12(%esp),%edx

	movl	(%esi),%eax
	movl	4(%esi),%ecx
	movl	%eax,(%edi)
	movl	%ecx,4(%edi)

	movl	(%esi,%edx),%eax
	movl	4(%esi,%edx),%ecx
	movl	%eax,(%edi,%edx)
	movl	%ecx,4(%edi,%edx)

	leal	(%esi,%edx,2),%esi
	leal	(%edi,%edx,2),%edi

	movl	(%esi),%eax
	movl	4(%esi),%ecx
	movl	%eax,(%edi)
	movl	%ecx,4(%edi)

	movl	(%esi,%edx),%eax
	movl	4(%esi,%edx),%ecx
	movl	%eax,(%edi,%edx)
	movl	%ecx,4(%edi,%edx)

	leal	(%esi,%edx,2),%esi
	leal	(%edi,%edx,2),%edi

	movl	(%esi),%eax
	movl	4(%esi),%ecx
	movl	%eax,(%edi)
	movl	%ecx,4(%edi)

	movl	(%esi,%edx),%eax
	movl	4(%esi,%edx),%ecx
	movl	%eax,(%edi,%edx)
	movl	%ecx,4(%edi,%edx)

	leal	(%esi,%edx,2),%esi
	leal	(%edi,%edx,2),%edi

	movl	(%esi),%eax
	movl	4(%esi),%ecx
	movl	%eax,(%edi)
	movl	%ecx,4(%edi)

	movl	(%esi,%edx),%eax
	movl	4(%esi,%edx),%ecx
	movl	%eax,(%edi,%edx)
	movl	%ecx,4(%edi,%edx)

	popl	%edi
	popl	%esi
	ret
#undef OFFSET


	.align	2
#define OFFSET	12
	.globl	_copy_16x16
_copy_16x16:
	pushl	%esi
	pushl	%edi
	pushl	%ebx
	movl	OFFSET+4(%esp),%edi
	movl	OFFSET+8(%esp),%esi
	movl	OFFSET+12(%esp),%ecx
	movl	$8,%ebx
	.align	2

loop3:
	movl	(%esi),%eax
	movl	4(%esi),%edx
	movl	%eax,(%edi)
	movl	%edx,4(%edi)
	movl	8(%esi),%eax
	movl	12(%esi),%edx
	movl	%eax,8(%edi)
	movl	%edx,12(%edi)

	movl	(%esi,%ecx),%eax
	movl	4(%esi,%ecx),%edx
	movl	%eax,(%edi,%ecx)
	movl	%edx,4(%edi,%ecx)
	movl	8(%esi,%ecx),%eax
	movl	12(%esi,%ecx),%edx
	movl	%eax,8(%edi,%ecx)
	movl	%edx,12(%edi,%ecx)

	leal	(%esi,%ecx,2),%esi
	leal	(%edi,%ecx,2),%edi

	decl	%ebx
	jnz	loop3

	popl	%ebx
	popl	%edi
	popl	%esi
	ret
#undef OFFSET


	.align	2
#define OFFSET	16
	.globl	_average_16x16
_average_16x16:
	pushl	%esi
	pushl	%edi
	pushl	%ebx
	pushl	%ebp
	movl	OFFSET+4(%esp),%edi
	movl	OFFSET+8(%esp),%esi
	movl	OFFSET+12(%esp),%ebp
	movl	OFFSET+16(%esp),%ecx
	movb	$8,count
	movl	$0x3f3f3f3f,%ebx
	.align	2

loop4:
	movl	(%esi),%eax
	movl	4(%esi),%edx
	addl	(%ebp),%eax
	addl	4(%ebp),%edx
	shrl	%eax
	shrl	%edx
	andl	%ebx,%eax
	andl	%ebx,%edx
	movl	%eax,(%edi)
	movl	%edx,4(%edi)
	movl	8(%esi),%eax
	movl	12(%esi),%edx
	addl	8(%ebp),%eax
	addl	12(%ebp),%edx
	shrl	%eax
	shrl	%edx
	andl	%ebx,%eax
	andl	%ebx,%edx
	movl	%eax,8(%edi)
	movl	%edx,12(%edi)

	movl	(%esi,%ecx),%eax
	movl	4(%esi,%ecx),%edx
	addl	(%ebp,%ecx),%eax
	addl	4(%ebp,%ecx),%edx
	shrl	%eax
	shrl	%edx
	andl	%ebx,%eax
	andl	%ebx,%edx
	movl	%eax,(%edi,%ecx)
	movl	%edx,4(%edi,%ecx)
	movl	8(%esi,%ecx),%eax
	movl	12(%esi,%ecx),%edx
	addl	8(%ebp,%ecx),%eax
	addl	12(%ebp,%ecx),%edx
	shrl	%eax
	shrl	%edx
	andl	%ebx,%eax
	andl	%ebx,%edx
	movl	%eax,8(%edi,%ecx)
	movl	%edx,12(%edi,%ecx)

	leal	(%esi,%ecx,2),%esi
	leal	(%ebp,%ecx,2),%ebp
	leal	(%edi,%ecx,2),%edi

	decb	count
	jnz	loop4

	popl	%ebp
	popl	%ebx
	popl	%edi
	popl	%esi
	ret
#undef OFFSET


	.align	2
#define OFFSET	16
	.globl	_average_8x8
_average_8x8:
	pushl	%esi
	pushl	%edi
	pushl	%ebx
	pushl	%ebp
	movl	OFFSET+4(%esp),%edi
	movl	OFFSET+8(%esp),%esi
	movl	OFFSET+12(%esp),%ebp
	movl	OFFSET+16(%esp),%ecx
	movb	$4,count
	movl	$0x3f3f3f3f,%ebx

	.align	2

loop5:
	movl	(%esi),%eax
	movl	4(%esi),%edx
	addl	(%ebp),%eax
	addl	4(%ebp),%edx
	shrl	%eax
	shrl	%edx
	andl	%ebx,%eax
	andl	%ebx,%edx
	movl	%eax,(%edi)
	movl	%edx,4(%edi)

	movl	(%esi,%ecx),%eax
	movl	4(%esi,%ecx),%edx
	addl	(%ebp,%ecx),%eax
	addl	4(%ebp,%ecx),%edx
	shrl	%eax
	shrl	%edx
	andl	%ebx,%eax
	andl	%ebx,%edx
	movl	%eax,(%edi,%ecx)
	movl	%edx,4(%edi,%ecx)

	leal	(%esi,%ecx,2),%esi
	leal	(%ebp,%ecx,2),%ebp
	leal	(%edi,%ecx,2),%edi

	decb	count
	jnz	loop5

	popl	%ebp
	popl	%ebx
	popl	%edi
	popl	%esi
	ret
#undef OFFSET


	.align	2
#define OFFSET	16
	.globl	_add_crop_8x8
_add_crop_8x8:
	pushl	%esi
	pushl	%edi
	pushl	%ebp
	pushl	%ebx
	movl	OFFSET+4(%esp),%edi
	movl	OFFSET+8(%esp),%ebp
	movl	OFFSET+12(%esp),%esi
	movl	OFFSET+16(%esp),%edx
	movl	_crop_table,%ecx
	movl	$8,count
	movl	%ecx,%ebx

	.align	2
loop6:
	movl	(%ebp),%eax
	addl	(%esi),%eax
	BSWAP(a)
	movb	%al,%cl
	movb	%ah,%bl
	movb	(%ecx),%al
	movb	(%ebx),%ah
	BSWAP(a)
	movb	%al,%cl
	movb	%ah,%bl
	movb	(%ecx),%al
	movb	(%ebx),%ah
	movl	%eax,(%edi)

	movl	4(%ebp),%eax
	addl	4(%esi),%eax
	BSWAP(a)
	movb	%al,%cl
	movb	%ah,%bl
	movb	(%ecx),%al
	movb	(%ebx),%ah
	BSWAP(a)
	movb	%al,%cl
	movb	%ah,%bl
	movb	(%ecx),%al
	movb	(%ebx),%ah
	movl	%eax,4(%edi)

	addl	$16,%esi
	addl	%edx,%ebp
	addl	%edx,%edi
	decl	count
	jnz	loop6

	popl	%ebx
	popl	%ebp
	popl	%edi
	popl	%esi
	ret
#undef OFFSET


	.align	2
#define OFFSET	16
	.globl	_add_average_crop_8x8
_add_average_crop_8x8:
	pushl	%esi
	pushl	%edi
	pushl	%ebp
	pushl	%ebx
	movl	OFFSET+4(%esp),%edi
	movl	OFFSET+8(%esp),%ebp
	movl	OFFSET+12(%esp),%ebx
	movl	OFFSET+16(%esp),%esi
	movl	OFFSET+20(%esp),%ecx
	movl	_crop_table,%edx
	movl	$8,count

	.align	2
loop7:
	movl	(%ebp),%eax
	addl	(%ebx),%eax
	shrl	%eax
	andl	$0x3f3f3f3f,%eax
	addl	(%esi),%eax
	BSWAP(a)
	movb	%al,%dl
	movb	(%edx),%al
	movb	%ah,%dl
	movb	(%edx),%ah
	BSWAP(a)
	movb	%al,%dl
	movb	(%edx),%al
	movb	%ah,%dl
	movb	(%edx),%ah
	movl	%eax,(%edi)

	movl	4(%ebp),%eax
	addl	4(%ebx),%eax
	shrl	%eax
	andl	$0x3f3f3f3f,%eax
	addl	4(%esi),%eax
	BSWAP(a)
	movb	%al,%dl
	movb	(%edx),%al
	movb	%ah,%dl
	movb	(%edx),%ah
	BSWAP(a)
	movb	%al,%dl
	movb	(%edx),%al
	movb	%ah,%dl
	movb	(%edx),%ah
	movl	%eax,4(%edi)

	addl	$16,%esi
	addl	%ecx,%ebp
	addl	%ecx,%ebx
	addl	%ecx,%edi

	decl	count
	jnz	loop7

	popl	%ebx
	popl	%ebp
	popl	%edi
	popl	%esi
	ret
#undef OFFSET


	.align	2
#define OFFSET	8
	.globl	_copy_memory
_copy_memory:
	pushl	%esi
	pushl	%edi
	cld
	movl	OFFSET+12(%esp),%ecx
	movl	OFFSET+4(%esp),%edi
	orl	%ecx,%ecx
	movl	OFFSET+8(%esp),%esi
	jz	done1
loop10:
	test	$3,%edi
	jz	no1
	movsb
	decl	%ecx
	jz	done1
	jmp	loop10
no1:
	movl	%ecx,%edx
	shrl	$2,%ecx
	rep
	movsl
	andl	$3,%edx
	rep
	movsb
done1:
	popl	%edi
	popl	%esi
	ret
#undef OFFSET
