#   memmoveQ6.s


#   Copyright Notice --------------------------------------------------------
#
#   Copyright 2001 by Q-TPS, QTPS@EarthLink.net
#
#   Permission is hereby granted to use or copy this module freely provided 
#   that this copyright notice remains unchanged.
#
#   Q-TPS make no warenty, either expressed or implied, as to this module's
#   reliability, performance, or fitness for use.
#
#   If you make enhancvements to this module please e-mail them back to Q-TPS
#   at QTPS@EarthLink.net
#
#   End Of Copyright Notice -------------------------------------------------


#   Description of File -----------------------------------------------------
#
#   This is an optimized version of the memmove() function.  It attempts to 
#   do double word moves on double word boundries.
#
#   End Of Description of File ----------------------------------------------


#   Change History ----------------------------------------------------------
#
#   Date    Version Who Description of Change
#   ------  ------- --- ---------------------
#   011025  6.01.01 brc written from scratch for QNX Neutrino
#
#   End Of Change History ---------------------------------------------------


#   Included Headers --------------------------------------------------------
#
#   There are no other files included
#
#   End Of Included Headers -------------------------------------------------


#   Function memmove --------------------------------------------------------
#
	.file	"memmoveQ6.s"
	.version    "01.01"
gcc2_compiled.:
.text
	.align 4
.globl memmove
	.type	 memmove,@function


# stack calling convention

memmove:
	    pushl   %ebp
	    movl    %esp,%ebp

	    pushl   %esi	    # save regs
	    pushl   %edi
	    push    %es
	    mov     %ds,%ax	    # ES = DS
	    mov     %ax,%es

	    movl    8(%ebp),%edi    # EDI = to
	    movl    12(%ebp),%esi   # ESI = from
	    movl    16(%ebp),%ecx   # ECX = length
	    pushl   %edi	    #	this must be returned

	    testl   %ecx,%ecx	    # if( length == 0 )
	    jz	    L99 	    #	 get out
	    cmpl    %edi,%esi	    # if( from == to )
	    je	    L99 	    #	 get out
	    ja	    L20 	    # if( to < from )
				    #	 OK to copy forward

	    lea     (%esi,%ecx),%edx# EDX = &from[length]
	    cmpl    %edi,%edx	    # if( to < from[length] )
	    jbe     L20 	    #	 OK to copy forward

# copy backward
	    std 		    # set direction flag down
	    add     %ecx,%edi	    # EDI = &to[length]
	    mov     %edx,%esi	    # ESI = &from[length]
	    dec     %edi	    # adjust EDI
	    dec     %esi	    # adjust ESI

# copy odd trailing bytes first
	    mov     %edi,%eax	    # calculate number of trailing bytes
	    and     $3,%eax
	    cmp     %ecx,%eax
	    jge     L16
	    xchg    %ecx,%eax	    # and number of remaining bytes
	    sub     %ecx,%eax
	rep movsb

# copy double words
	    movl    %eax,%ecx	    # restore length
	    shrl    %ecx	    # length /= 4
	    shrl    %ecx
	    sub     $3,%edi
	    sub     $3,%esi
	rep movsl

# copy leading bytes
	    andl    $3,%eax	    # length = length % 4
	    movl    %eax,%ecx
	    add     $3,%edi
	    add     $3,%esi
L16:	rep movsb

# prepare to exit
	    cld 		    # clear direction flag
	    jmp     L99 	    # prepare to exit - eax must = to


# copy forward
	    .align  4
L20:	    movl    %edi,%eax	    # calculate number of leading odd bytes
	    andl    $3,%eax
	    cmp     %ecx,%eax
	    jge     L26
	    xchg    %eax,%ecx	    # and number of remaining bytes
	    subl    %ecx,%eax

# copy odd leading bytes first
	rep movsb		    # move a leading byte

# copy double words
	    movl    %eax,%ecx	    # restore length
	    shrl    %ecx	    # length /= 4
	    shrl    %ecx
	rep movsl		    # move double words

# copy trailing bytes
	    andl    $3,%eax	    # length = length % 4
	    movl    %eax,%ecx
L26:	rep movsb		    # move extra bytes

# prepare to exit

L99:	    popl    %eax	    # return to
	    pop     %es 	    # restore regs
	    popl    %edi
	    popl    %esi
	    leave
	    ret
#
#   End Of Function memmove -------------------------------------------------


.Lfe1:
	    .size    memmove,.Lfe1-memmove
	    .ident  "Bill Caroselli, Q-TPS, QTPS@EarthLink.net"
