/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/

.globl mymemcpy_beos

.align 4
mymemcpy_beos:

	subl	$16,%esp
	movl	%edi,12(%esp)
	movl	%esi,8(%esp)
	movl	%ebx,4(%esp)

	movl	20(%esp), %edi	/* dst */
	movl	24(%esp), %esi	/* src */
	movl	28(%esp), %edx	/* len */

	cld
	
	movl	%edi,%ecx
	neg		%ecx
	andl	$0xf, %ecx
	cmpl	%ecx, %edx
	ja		10f
	movl	%edx, %ecx
10:
	movl	%ecx, %eax
	rep; movsb

	subl	%eax, %edx
	jz		70f
	
20:
	/* grab max of 4K */
	movl	%edx,%ebx
	cmpl	$0x1000,%ebx
	jb 		30f
	movl 	$0x1000,%ebx
	
30:
	subl	%ebx,%edx

	/* Src Cache warming code */
	movl	%esi,(%esp)
	movl	%ebx,%ecx
40:
#if 1
	movb	(%esi),%al
	.byte 0x0f				/* prefetchnta (%esi, 20) */
	.byte 0x18
	.byte 0x46
	.byte 0x20
#endif
	
	addl 	$32,%esi
	subl	$32,%ecx
	jnbe	40b
	movl	(%esp),%esi

	movl	%ebx,%ecx
	shr		$4,%ecx

50:
	jecxz	60f
	.byte 0x0f				/* movups	xmm0, (%esi) */
	.byte 0x10
	.byte 0x06
	addl	$16,%esi

	.byte 0x0f				/* movntps	(%esi), xmm0 */
	.byte 0x2b
	.byte 0x07
	addl	$16,%edi

	nop
	nop
	nop

	nop
	nop
	nop

	decl	%ecx
	jmp		50b

60:
	andl	%edx,%edx
	jnz		20b

	movl	%ebx,%ecx
	andl	$0xf, %ecx
	jz		70f

	rep; movsb

70:
	movl	20(%esp),%eax	/* dst */
	movl	12(%esp),%edi
	movl	8(%esp),%esi
	movl	4(%esp),%ebx
	addl	$16,%esp
	ret

