forked from KolibriOS/kolibrios
Clib string & memory functions
git-svn-id: svn://kolibrios.org@553 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
213
programs/develop/open watcom/trunk/clib/string/cmp386.asm
Normal file
213
programs/develop/open watcom/trunk/clib/string/cmp386.asm
Normal file
@@ -0,0 +1,213 @@
|
||||
;*****************************************************************************
|
||||
;*
|
||||
;* Open Watcom Project
|
||||
;*
|
||||
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
|
||||
;*
|
||||
;* ========================================================================
|
||||
;*
|
||||
;* This file contains Original Code and/or Modifications of Original
|
||||
;* Code as defined in and that are subject to the Sybase Open Watcom
|
||||
;* Public License version 1.0 (the 'License'). You may not use this file
|
||||
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
|
||||
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
|
||||
;* provided with the Original Code and Modifications, and is also
|
||||
;* available at www.sybase.com/developer/opensource.
|
||||
;*
|
||||
;* The Original Code and all software distributed under the License are
|
||||
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
|
||||
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
|
||||
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
|
||||
;* NON-INFRINGEMENT. Please see the License for the specific language
|
||||
;* governing rights and limitations under the License.
|
||||
;*
|
||||
;* ========================================================================
|
||||
;*
|
||||
;* Description: Intel 386 implementation strcmp().
|
||||
;*
|
||||
;*****************************************************************************
|
||||
|
||||
|
||||
include mdef.inc
|
||||
include struct.inc
|
||||
|
||||
ifdef _PROFILE
|
||||
include p5prof.inc
|
||||
endif
|
||||
|
||||
modstart _strcmp,para
|
||||
|
||||
cmp4 macro off
|
||||
mov ebx,off[eax] ; get dword from op1
|
||||
mov ecx,off[edx] ; get dword from op2
|
||||
cmp ecx,ebx ; compare them
|
||||
jne unequal ; quit if not equal
|
||||
ife off-12
|
||||
add eax,off+4 ; point to next group of dwords
|
||||
add edx,off+4 ; ...
|
||||
endif
|
||||
not ecx ; ...
|
||||
add ebx,0FEFEFEFFh ; determine if '\0' is one of bytes
|
||||
and ebx,ecx ; ...
|
||||
and ebx,80808080h ; ebx will be non-zero if '\0' found
|
||||
endm
|
||||
|
||||
defpe strcmp
|
||||
xdefp "C",strcmp
|
||||
ifdef _PROFILE
|
||||
P5Prolog
|
||||
endif
|
||||
ifdef __STACK__
|
||||
mov eax,4[esp] ; get p1
|
||||
mov edx,8[esp] ; get p2
|
||||
endif
|
||||
cmp eax,edx ; pointers equal ?
|
||||
je equalnorst ; yes, return 0
|
||||
ifndef __STACK__
|
||||
push ecx ; save register
|
||||
endif
|
||||
test al,3 ; p1 aligned ?
|
||||
jne realign ; no, go and realign
|
||||
test dl,3 ; p2 aligned ?
|
||||
jne slowcpy ; no, do the slow copy (impossible to align both)
|
||||
|
||||
fastcpy:
|
||||
push ebx ; save register
|
||||
|
||||
align 4
|
||||
_loop ; - loop
|
||||
cmp4 0 ; - - compare first dword
|
||||
_quif ne ; - - quit if end of string
|
||||
cmp4 4 ; - - compare second dword
|
||||
_quif ne ; - - quit if end of string
|
||||
cmp4 8 ; - - compare third dword
|
||||
_quif ne ; - - quit if end of string
|
||||
cmp4 12 ; - - compare fourth dword
|
||||
_until ne ; - until end of string
|
||||
equalrst: ; strings equal, restore registers
|
||||
pop ebx ; restore register
|
||||
ifndef __STACK__
|
||||
pop ecx ; ...
|
||||
endif
|
||||
equalnorst: ; strings equal, skip register restore
|
||||
sub eax,eax ; indicate strings equal
|
||||
ifdef _PROFILE
|
||||
P5Epilog
|
||||
endif
|
||||
ret ; return
|
||||
|
||||
unequal: ; dword was not equal
|
||||
_guess ; guess strings are equal
|
||||
cmp bl,cl ; - check low bytes
|
||||
_quif ne ; - quit if not equal
|
||||
cmp bl,0 ; - stop if end of string
|
||||
je equalrst ; - ...
|
||||
cmp bh,ch ; - check next bytes
|
||||
_quif ne ; - quit if not equal
|
||||
cmp bh,0 ; - stop if end of string
|
||||
je equalrst ; - ...
|
||||
shr ebx,16 ; - shift top 2 bytes to bottom
|
||||
shr ecx,16 ; - ...
|
||||
cmp bl,cl ; - check third byte
|
||||
_quif ne ; - quit if not equal
|
||||
cmp bl,0 ; - stop if end of string
|
||||
je equalrst ; - ...
|
||||
cmp bh,ch ; - check high order byte
|
||||
;; we know at this point that bh != ch, just have to do the compare
|
||||
;; _quif ne ; - quit if not equal
|
||||
;; cmp bh,0 ; - stop if end of string
|
||||
;; je equalrst ; - ...
|
||||
_endguess ; endguess
|
||||
sbb eax,eax ; eax = 0 if op1>op2, -1 if op1<op2
|
||||
or al,1 ; eax = 1 if op1>op2, -1 if op1<op2
|
||||
pop ebx ; restore registers
|
||||
ifndef __STACK__
|
||||
pop ecx ; ...
|
||||
endif
|
||||
ifdef _PROFILE
|
||||
P5Epilog
|
||||
endif
|
||||
ret ; return
|
||||
|
||||
align 4
|
||||
realign:
|
||||
_loop ; - loop
|
||||
mov cl,[eax] ; get byte from p1
|
||||
inc eax ; point to next byte
|
||||
mov ch,[edx] ; get byte from p2
|
||||
inc edx ; point to next byte
|
||||
cmp cl,ch ; bytes equal?
|
||||
jne unequal2 ; unequal, quit
|
||||
or cl,cl ; end of string ?
|
||||
je equal2 ; yes, quit
|
||||
test al,3 ; check alignment
|
||||
_until e ; until aligned
|
||||
test dl,3 ; p2 aligned ?
|
||||
je fastcpy ; yes
|
||||
|
||||
align 4
|
||||
slowcpy:
|
||||
_loop
|
||||
mov ecx,[eax] ; get aligned 4 bytes
|
||||
cmp cl,[edx] ; check 1st byte
|
||||
jne unequal2 ; bytes not equal
|
||||
or cl,cl ; end of string?
|
||||
je equal2 ; yes, quit
|
||||
cmp ch,[edx+1] ; check 2nd byte
|
||||
jne unequal2 ; bytes not equal
|
||||
or ch,ch ; end of string?
|
||||
je equal2 ; yes, quit
|
||||
shr ecx,16 ; move next pair of bytes to be tested
|
||||
cmp cl,[edx+2] ; check 3rd byte
|
||||
jne unequal2 ; bytes not equal
|
||||
or cl,cl ; end of string?
|
||||
je equal2 ; yes, quit
|
||||
cmp ch,[edx+3] ; check 4th byte
|
||||
jne unequal2 ; bytes not equal
|
||||
or ch,ch ; end of string?
|
||||
je equal2 ; yes, quit
|
||||
mov ecx,[eax+4] ; get next aligned 4 bytes
|
||||
cmp cl,[edx+4] ; check 5th byte
|
||||
jne unequal2 ; bytes not equal
|
||||
or cl,cl ; end of string?
|
||||
je equal2 ; yes, quit
|
||||
cmp ch,[edx+5] ; check 6th byte
|
||||
jne unequal2 ; bytes not equal
|
||||
or ch,ch ; end of string?
|
||||
je equal2 ; yes, quit
|
||||
shr ecx,16 ; move next pair of bytes to be tested
|
||||
cmp cl,[edx+6] ; check 7th byte
|
||||
jne unequal2 ; bytes not equal
|
||||
or cl,cl ; end of string?
|
||||
je equal2 ; yes, quit
|
||||
cmp ch,[edx+7] ; check 8th byte
|
||||
jne unequal2 ; bytes not equal
|
||||
add eax,8 ; next 8 bytes
|
||||
add edx,8 ; next 8 bytes
|
||||
or ch,ch ; end of string?
|
||||
_until e ; until equal
|
||||
equal2:
|
||||
xor eax,eax ; return 0
|
||||
ifndef __STACK__
|
||||
pop ecx ; restore registers
|
||||
endif
|
||||
ifdef _PROFILE
|
||||
P5Epilog
|
||||
endif
|
||||
ret ; return
|
||||
|
||||
unequal2:
|
||||
sbb eax,eax ; eax = 0 if op1>op2, -1 if op1<op2
|
||||
or al,1 ; eax = 1 if op1>op2, -1 if op1<op2
|
||||
ifndef __STACK__
|
||||
pop ecx ; restore registers
|
||||
endif
|
||||
ifdef _PROFILE
|
||||
P5Epilog
|
||||
endif
|
||||
ret ; return
|
||||
endproc strcmp
|
||||
|
||||
endmod
|
||||
end
|
Reference in New Issue
Block a user