Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ;*****************************************************************************
  2. ;*
  3. ;*                            Open Watcom Project
  4. ;*
  5. ;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. ;*
  7. ;*  ========================================================================
  8. ;*
  9. ;*    This file contains Original Code and/or Modifications of Original
  10. ;*    Code as defined in and that are subject to the Sybase Open Watcom
  11. ;*    Public License version 1.0 (the 'License'). You may not use this file
  12. ;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. ;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. ;*    provided with the Original Code and Modifications, and is also
  15. ;*    available at www.sybase.com/developer/opensource.
  16. ;*
  17. ;*    The Original Code and all software distributed under the License are
  18. ;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. ;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. ;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. ;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. ;*    NON-INFRINGEMENT. Please see the License for the specific language
  23. ;*    governing rights and limitations under the License.
  24. ;*
  25. ;*  ========================================================================
  26. ;*
  27. ;* Description:  Intel 386 implementation strcmp().
  28. ;*
  29. ;*****************************************************************************
  30.  
  31.  
  32. include mdef.inc
  33. include struct.inc
  34.  
  35. ifdef _PROFILE
  36. include p5prof.inc
  37. endif
  38.  
  39.         modstart _strcmp,para
  40.  
  41. cmp4    macro   off
  42.         mov     ebx,off[eax]            ; get dword from op1
  43.         mov     ecx,off[edx]            ; get dword from op2
  44.         cmp     ecx,ebx                 ; compare them
  45.         jne     unequal                 ; quit if not equal
  46.         ife     off-12
  47.          add    eax,off+4               ; point to next group of dwords
  48.          add    edx,off+4               ; ...
  49.         endif
  50.         not     ecx                     ; ...
  51.         add     ebx,0FEFEFEFFh          ; determine if '\0' is one of bytes
  52.         and     ebx,ecx                 ; ...
  53.         and     ebx,80808080h           ; ebx will be non-zero if '\0' found
  54.         endm
  55.  
  56.         defpe   strcmp
  57.         xdefp   "C",strcmp
  58.     ifdef _PROFILE
  59.         P5Prolog
  60.     endif
  61.     ifdef __STACK__
  62.         mov     eax,4[esp]              ; get p1
  63.         mov     edx,8[esp]              ; get p2
  64.     endif
  65.         cmp     eax,edx                 ; pointers equal ?
  66.         je      equalnorst              ; yes, return 0
  67.     ifndef __STACK__
  68.         push    ecx                     ; save register
  69.     endif
  70.         test    al,3                    ; p1 aligned ?
  71.         jne     realign                 ; no, go and realign
  72.         test    dl,3                    ; p2 aligned ?
  73.         jne     slowcpy                 ; no, do the slow copy (impossible to align both)
  74.  
  75. fastcpy:
  76.         push    ebx                     ; save register
  77.  
  78.         align   4
  79.         _loop                           ; - loop
  80.           cmp4  0                       ; - - compare first dword
  81.           _quif ne                      ; - - quit if end of string
  82.           cmp4  4                       ; - - compare second dword
  83.           _quif ne                      ; - - quit if end of string
  84.           cmp4  8                       ; - - compare third dword
  85.           _quif ne                      ; - - quit if end of string
  86.           cmp4  12                      ; - - compare fourth dword
  87.         _until  ne                      ; - until end of string
  88. equalrst:                               ; strings equal, restore registers
  89.         pop     ebx                     ; restore register
  90.     ifndef __STACK__
  91.         pop     ecx                     ; ...
  92.     endif
  93. equalnorst:                             ; strings equal, skip register restore
  94.         sub     eax,eax                 ; indicate strings equal
  95.     ifdef _PROFILE
  96.         P5Epilog
  97.     endif
  98.         ret                             ; return
  99.  
  100. unequal:                                ; dword was not equal
  101.         _guess                          ; guess strings are equal
  102.           cmp   bl,cl                   ; - check low bytes
  103.           _quif ne                      ; - quit if not equal
  104.           cmp   bl,0                    ; - stop if end of string
  105.           je    equalrst                ; - ...
  106.           cmp   bh,ch                   ; - check next bytes
  107.           _quif ne                      ; - quit if not equal
  108.           cmp   bh,0                    ; - stop if end of string
  109.           je    equalrst                ; - ...
  110.           shr   ebx,16                  ; - shift top 2 bytes to bottom
  111.           shr   ecx,16                  ; - ...
  112.           cmp   bl,cl                   ; - check third byte
  113.           _quif ne                      ; - quit if not equal
  114.           cmp   bl,0                    ; - stop if end of string
  115.           je    equalrst                ; - ...
  116.           cmp   bh,ch                   ; - check high order byte
  117. ;;        we know at this point that bh != ch, just have to do the compare
  118. ;;        _quif ne                      ; - quit if not equal
  119. ;;        cmp   bh,0                    ; - stop if end of string
  120. ;;        je    equalrst                ; - ...
  121.         _endguess                       ; endguess
  122.         sbb     eax,eax                 ; eax = 0 if op1>op2, -1 if op1<op2
  123.         or      al,1                    ; eax = 1 if op1>op2, -1 if op1<op2
  124.         pop     ebx                     ; restore registers
  125.     ifndef __STACK__
  126.         pop     ecx                     ; ...
  127.     endif
  128.     ifdef _PROFILE
  129.         P5Epilog
  130.     endif
  131.         ret                             ; return
  132.  
  133.         align   4
  134. realign:
  135.         _loop                           ; - loop
  136.           mov   cl,[eax]                ; get byte from p1
  137.           inc   eax                     ; point to next byte
  138.           mov   ch,[edx]                ; get byte from p2
  139.           inc   edx                     ; point to next byte
  140.           cmp   cl,ch                   ; bytes equal?
  141.           jne   unequal2                ; unequal, quit
  142.           or    cl,cl                   ; end of string ?
  143.           je    equal2                  ; yes, quit
  144.           test  al,3                    ; check alignment
  145.         _until  e                       ; until aligned
  146.         test    dl,3                    ; p2 aligned ?
  147.         je fastcpy                      ; yes
  148.  
  149.         align   4
  150. slowcpy:
  151.         _loop
  152.           mov   ecx,[eax]               ; get aligned 4 bytes
  153.           cmp   cl,[edx]                ; check 1st byte
  154.           jne   unequal2                ; bytes not equal
  155.           or    cl,cl                   ; end of string?
  156.           je    equal2                  ; yes, quit
  157.           cmp   ch,[edx+1]              ; check 2nd byte
  158.           jne   unequal2                ; bytes not equal
  159.           or    ch,ch                   ; end of string?
  160.           je    equal2                  ; yes, quit
  161.           shr   ecx,16                  ; move next pair of bytes to be tested
  162.           cmp   cl,[edx+2]              ; check 3rd byte
  163.           jne   unequal2                ; bytes not equal
  164.           or    cl,cl                   ; end of string?
  165.           je    equal2                  ; yes, quit
  166.           cmp   ch,[edx+3]              ; check 4th byte
  167.           jne   unequal2                ; bytes not equal
  168.           or    ch,ch                   ; end of string?
  169.           je    equal2                  ; yes, quit
  170.           mov   ecx,[eax+4]             ; get next aligned 4 bytes
  171.           cmp   cl,[edx+4]              ; check 5th byte
  172.           jne   unequal2                ; bytes not equal
  173.           or    cl,cl                   ; end of string?
  174.           je    equal2                  ; yes, quit
  175.           cmp   ch,[edx+5]              ; check 6th byte
  176.           jne   unequal2                ; bytes not equal
  177.           or    ch,ch                   ; end of string?
  178.           je    equal2                  ; yes, quit
  179.           shr   ecx,16                  ; move next pair of bytes to be tested
  180.           cmp   cl,[edx+6]              ; check 7th byte
  181.           jne   unequal2                ; bytes not equal
  182.           or    cl,cl                   ; end of string?
  183.           je    equal2                  ; yes, quit
  184.           cmp   ch,[edx+7]              ; check 8th byte
  185.           jne   unequal2                ; bytes not equal
  186.           add   eax,8                   ; next 8 bytes
  187.           add   edx,8                   ; next 8 bytes
  188.           or    ch,ch                   ; end of string?
  189.         _until  e                       ; until equal
  190. equal2:
  191.         xor     eax,eax                 ; return 0
  192.     ifndef __STACK__
  193.         pop     ecx                     ; restore registers
  194.     endif
  195.     ifdef _PROFILE
  196.         P5Epilog
  197.     endif
  198.         ret                             ; return
  199.  
  200. unequal2:
  201.         sbb     eax,eax                 ; eax = 0 if op1>op2, -1 if op1<op2
  202.         or      al,1                    ; eax = 1 if op1>op2, -1 if op1<op2
  203.     ifndef __STACK__
  204.         pop     ecx                     ; restore registers
  205.     endif
  206.     ifdef _PROFILE
  207.         P5Epilog
  208.     endif
  209.         ret                             ; return
  210.         endproc strcmp
  211.  
  212.         endmod
  213.         end
  214.