Browse Source

Decimate rtl/i386/strings.inc.

Rika Ichinose 1 year ago
parent
commit
ea33fdcdf8
5 changed files with 199 additions and 756 deletions
  1. 0 48
      packages/sdl/src/libxmlparser.pas
  2. 116 545
      rtl/i386/strings.inc
  3. 0 23
      rtl/i386/stringss.inc
  4. 75 122
      rtl/inc/genstr.inc
  5. 8 18
      rtl/inc/genstrs.inc

+ 0 - 48
packages/sdl/src/libxmlparser.pas

@@ -744,54 +744,6 @@ BEGIN
 END;
 
 
-(*
-===============================================================================================
-"Special" Helper Functions
-
-Don't ask me why. But including these functions makes the parser *DRAMATICALLY* faster
-on my K6-233 machine. You can test it yourself just by commenting them out.
-They do exactly the same as the Assembler routines defined in SysUtils.
-(This is where you can see how great the Delphi compiler really is. The compiled code is
-faster than hand-coded assembler!)
-===============================================================================================
---> Just move this line below the StrScan function -->  *)
-
-
-FUNCTION StrPos (CONST Str, SearchStr : PAnsiChar) : PAnsiChar;
-         // Same functionality as SysUtils.StrPos
-VAR
-  First : AnsiChar;
-  Len   : INTEGER;
-BEGIN
-  First  := SearchStr^;
-  Len    := StrLen (SearchStr);
-  Result := Str;
-  REPEAT
-    IF Result^ = First THEN
-      IF StrLComp (Result, SearchStr, Len) = 0 THEN BREAK;
-    IF Result^ = #0 THEN BEGIN
-      Result := NIL;
-      BREAK;
-      END;
-    INC (Result);
-  UNTIL FALSE;
-END;
-
-
-FUNCTION StrScan (CONST Start : PAnsiChar; CONST Ch : AnsiChar) : PAnsiChar;
-         // Same functionality as SysUtils.StrScan
-BEGIN
-  Result := Start;
-  WHILE Result^ <> Ch DO BEGIN
-    IF Result^ = #0 THEN BEGIN
-      Result := NIL;
-      EXIT;
-      END;
-    INC (Result);
-    END;
-END;
-
-
 (*
 ===============================================================================================
 Helper Functions

+ 116 - 545
rtl/i386/strings.inc

@@ -16,287 +16,40 @@
 
 {$ASMMODE ATT}
 
-{$ifndef FPC_UNIT_HAS_STRCOPY}
-{$define FPC_UNIT_HAS_STRCOPY}
-function strcopy(dest,source : PAnsiChar) : PAnsiChar;assembler;
-var
-  saveeax,saveesi,saveedi : longint;
-asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-        movl    %eax,saveeax
-        movl    %edx,%edi
-        testl   %edi,%edi
-        jz      .LStrCopyDone
-        leal    3(%edi),%ecx
-        andl    $-4,%ecx
-        movl    %edi,%esi
-        subl    %edi,%ecx
-        movl    %eax,%edi
-        jz      .LStrCopyAligned
-.LStrCopyAlignLoop:
-        movb    (%esi),%al
-        incl    %edi
-        incl    %esi
-        testb   %al,%al
-        movb    %al,-1(%edi)
-        jz      .LStrCopyDone
-        decl    %ecx
-        jnz     .LStrCopyAlignLoop
-        .balign  16
-.LStrCopyAligned:
-        movl    (%esi),%eax
-        movl    %eax,%edx
-        leal    0x0fefefeff(%eax),%ecx
-        notl    %edx
-        addl    $4,%esi
-        andl    %edx,%ecx
-        andl    $0x080808080,%ecx
-        jnz     .LStrCopyEndFound
-        movl    %eax,(%edi)
-        addl    $4,%edi
-        jmp     .LStrCopyAligned
-.LStrCopyEndFound:
-        testl   $0x0ff,%eax
-        jz      .LStrCopyByte
-        testl   $0x0ff00,%eax
-        jz      .LStrCopyWord
-        testl   $0x0ff0000,%eax
-        jz      .LStrCopy3Bytes
-        movl    %eax,(%edi)
-        jmp     .LStrCopyDone
-.LStrCopy3Bytes:
-        xorb     %dl,%dl
-        movw     %ax,(%edi)
-        movb     %dl,2(%edi)
-        jmp     .LStrCopyDone
-.LStrCopyWord:
-        movw    %ax,(%edi)
-        jmp     .LStrCopyDone
-.LStrCopyByte:
-        movb    %al,(%edi)
-.LStrCopyDone:
-        movl    saveeax,%eax
-        movl    saveedi,%edi
-        movl    saveesi,%esi
-end;
-{$endif FPC_UNIT_HAS_STRCOPY}
-
-
-{$ifndef FPC_UNIT_HAS_STRECOPY}
-{$define FPC_UNIT_HAS_STRECOPY}
-function strecopy(dest,source : PAnsiChar) : PAnsiChar;assembler;
-var
-  saveesi,saveedi : longint;
-asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-        movl    dest,%esi
-        movl    source,%edi
-        movl    $0xffffffff,%ecx
-        xorl    %eax,%eax
-        repne
-        scasb
-        not     %ecx
-        movl    %esi,%edi
-        movl    source,%esi
-        movl    %ecx,%eax
-        shrl    $2,%ecx
-        rep
-        movsl
-        movl    %eax,%ecx
-        andl    $3,%ecx
-        rep
-        movsb
-        decl    %edi
-        movl    %edi,%eax
-        movl    saveedi,%edi
-        movl    saveesi,%esi
-end;
-{$endif FPC_UNIT_HAS_STRECOPY}
-
-
-{$ifndef FPC_UNIT_HAS_STRLCOPY}
-{$define FPC_UNIT_HAS_STRLCOPY}
-function strlcopy(dest,source : PAnsiChar;maxlen : sizeint) : PAnsiChar;assembler;
-var
-  savedest,
-  saveesi,saveedi : longint;
-asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-        movl    source,%esi
-        movl    maxlen,%ecx
-        movl    dest,%edi
-        movl    %edi,savedest
-        orl     %ecx,%ecx
-        jz      .LSTRLCOPY2
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-.LSTRLCOPY1:
-        lodsb
-        stosb
-        decl    %ecx            // Lower maximum
-        jz      .LSTRLCOPY2     // 0 reached ends
-        orb     %al,%al
-        jnz     .LSTRLCOPY1
-        jmp     .LSTRLCOPY3
-.LSTRLCOPY2:
-        xorb    %al,%al         // If cutted
-        stosb                   // add a #0
-.LSTRLCOPY3:
-        movl    savedest,%eax
-        movl    saveedi,%edi
-        movl    saveesi,%esi
-end;
-{$endif FPC_UNIT_HAS_STRLCOPY}
-
-
-{$ifndef FPC_UNIT_HAS_STREND}
-{$define FPC_UNIT_HAS_STREND}
-function strend(p : PAnsiChar) : PAnsiChar;assembler;
-var
-  saveedi : longint;
-asm
-        movl    %edi,saveedi
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-        movl    p,%edi
-        xorl    %eax,%eax
-        orl     %edi,%edi
-        jz      .LStrEndNil
-        movl    $0xffffffff,%ecx
-        repne
-        scasb
-        movl    %edi,%eax
-        decl    %eax
-.LStrEndNil:
-        movl    saveedi,%edi
-end;
-{$endif FPC_UNIT_HAS_STREND}
-
-
-
-{$ifndef FPC_UNIT_HAS_STRCOMP}
-{$define FPC_UNIT_HAS_STRCOMP}
-function strcomp(str1,str2 : pansichar) : longint;assembler;
-var
-  saveeax,saveedx,saveesi,saveedi : longint;
-asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-        movl    %eax,saveeax
-        movl    %edx,saveedx
-        movl    str2,%edi
-        movl    $0xffffffff,%ecx
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-        xorl    %eax,%eax
-        repne
-        scasb
-        not     %ecx
-        movl    saveedx,%edi
-        movl    saveeax,%esi
-        repe
-        cmpsb
-        movb    -1(%esi),%al
-        movzbl  -1(%edi),%ecx
-        subl    %ecx,%eax
-        movl    saveedi,%edi
-        movl    saveesi,%esi
-end;
-{$endif FPC_UNIT_HAS_STRCOMP}
-
-
-
-{$ifndef FPC_UNIT_HAS_STRLCOMP}
-{$define FPC_UNIT_HAS_STRLCOMP}
-function strlcomp(str1,str2 : PAnsiChar;l : sizeint) : longint;assembler;
-var
-  saveeax,saveedx,saveecx,saveesi,saveedi : longint;
-asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-        movl    %eax,saveeax
-        movl    %edx,saveedx
-        movl    %ecx,saveecx
-        movl    str2,%edi
-        movl    $0xffffffff,%ecx
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-        xorl    %eax,%eax
-        repne
-        scasb
-        not     %ecx
-        cmpl    saveecx,%ecx
-        jl      .LSTRLCOMP1
-        movl    saveecx,%ecx
-.LSTRLCOMP1:
-        movl    saveedx,%edi
-        movl    saveeax,%esi
-        repe
-        cmpsb
-        movb    -1(%esi),%al
-        movzbl  -1(%edi),%ecx
-        subl    %ecx,%eax
-        movl    saveedi,%edi
-        movl    saveesi,%esi
-end;
-{$endif FPC_UNIT_HAS_STRLCOMP}
-
-
-
 {$ifndef FPC_UNIT_HAS_STRICOMP}
 {$define FPC_UNIT_HAS_STRICOMP}
-function stricomp(str1,str2 : PAnsiChar) : longint;assembler;
-var
-  saveeax,saveedx,saveesi,saveedi : longint;
+function stricomp(str1,str2 : PAnsiChar) : longint; assembler; nostackframe;
+{ eax = str1, edx = str2 }
 asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-        movl    %eax,saveeax
-        movl    %edx,saveedx
-        movl    str2,%edi
-        movl    $0xffffffff,%ecx
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-        xorl    %eax,%eax
-        repne
-        scasb
-        not     %ecx
-        movl    saveedx,%edi
-        movl    saveeax,%esi
-.LSTRICOMP2:
-        repe
-        cmpsb
-        jz      .LSTRICOMP3     // If last reached then exit
-        movzbl  -1(%esi),%eax
-        movzbl  -1(%edi),%edx
-        cmpb    $97,%al
-        jb      .LSTRICOMP1
-        cmpb    $122,%al
-        ja      .LSTRICOMP1
-        subb    $0x20,%al
-.LSTRICOMP1:
-        cmpb    $97,%dl
-        jb      .LSTRICOMP4
-        cmpb    $122,%dl
-        ja      .LSTRICOMP4
-        subb    $0x20,%dl
-.LSTRICOMP4:
-        subl    %edx,%eax
-        jz      .LSTRICOMP2     // If still equal, compare again
-.LSTRICOMP3:
-        movl    saveedi,%edi
-        movl    saveesi,%esi
+        push    %ebx
+        push    %esi
+        sub     %eax, %edx { edx = str2 - str1 }
+        lea     -1(%eax), %esi { esi = str1 (-1), frees eax to use for str1^ for easier subtraction }
+.balign 16
+.LLoop:
+        add     $1, %esi
+        movzbl  (%esi), %eax { eax = str1^ }
+        movzbl  (%esi,%edx), %ebx { ebx = str2^ }
+        test    %eax, %eax
+        jz      .LSub
+        cmp     %ebx, %eax { Shortcut uppercasing if already equal. }
+        je      .LLoop
+        lea     -97(%eax), %ecx
+        cmp     $25, %ecx
+        ja      .LEaxUppercased
+        sub     $32, %eax
+.LEaxUppercased:
+        lea     -97(%ebx), %ecx
+        cmp     $25, %ecx
+        ja      .LEbxUppercased
+        sub     $32, %ebx
+.LEbxUppercased:
+        cmp     %ebx, %eax
+        je      .LLoop
+.LSub:
+        sub     %ebx, %eax
+        pop     %esi
+        pop     %ebx
 end;
 {$endif FPC_UNIT_HAS_STRICOMP}
 
@@ -304,289 +57,107 @@ end;
 
 {$ifndef FPC_UNIT_HAS_STRLICOMP}
 {$define FPC_UNIT_HAS_STRLICOMP}
-function strlicomp(str1,str2 : PAnsiChar;l : sizeint) : longint;assembler;
-var
-  saveeax,saveedx,saveecx,saveesi,saveedi : longint;
+function strlicomp(str1,str2 : PAnsiChar;l : sizeint) : longint; assembler; nostackframe;
+{ eax = str1, edx = str2, ecx = L }
 asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-        movl    %eax,saveeax
-        movl    %edx,saveedx
-        movl    %ecx,saveecx
-        movl    str2,%edi
-        movl    $0xffffffff,%ecx
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-        xorl    %eax,%eax
-        repne
-        scasb
-        not     %ecx
-        cmpl    saveecx,%ecx
-        jl      .LSTRLICOMP5
-        movl    saveecx,%ecx
-.LSTRLICOMP5:
-        movl    saveedx,%edi
-        movl    saveeax,%esi
-.LSTRLICOMP2:
-        repe
-        cmpsb
-        jz      .LSTRLICOMP3    // If last reached, exit
-        movzbl  -1(%esi),%eax
-        movzbl  -1(%edi),%edx
-        cmpb    $97,%al
-        jb      .LSTRLICOMP1
-        cmpb    $122,%al
-        ja      .LSTRLICOMP1
-        subb    $0x20,%al
-.LSTRLICOMP1:
-        cmpb    $97,%dl
-        jb      .LSTRLICOMP4
-        cmpb    $122,%dl
-        ja      .LSTRLICOMP4
-        subb    $0x20,%dl
-.LSTRLICOMP4:
-        subl    %edx,%eax
-        jz      .LSTRLICOMP2
-.LSTRLICOMP3:
-        movl    saveedi,%edi
-        movl    saveesi,%esi
+        push    %ebx
+        push    %esi
+        push    %edi
+        sub     %eax, %edx { edx = str2 - str1 }
+        lea     -1(%eax), %esi { esi = str1 (-1), frees eax to use for str1^ for easier subtraction }
+.balign 16
+.LLoop:
+        sub     $1, %ecx
+        jl      .LNothing
+        add     $1, %esi
+        movzbl  (%esi), %eax { eax = str1^ }
+        movzbl  (%esi,%edx), %ebx { ebx = str2^ }
+        test    %eax, %eax
+        jz      .LSub
+        cmp     %ebx, %eax { Shortcut uppercasing if already equal. }
+        je      .LLoop
+        lea     -97(%eax), %edi
+        cmp     $25, %edi
+        ja      .LEaxUppercased
+        sub     $32, %eax
+.LEaxUppercased:
+        lea     -97(%ebx), %edi
+        cmp     $25, %edi
+        ja      .LEbxUppercased
+        sub     $32, %ebx
+.LEbxUppercased:
+        cmp     %ebx, %eax
+        je      .LLoop
+.LSub:
+        sub     %ebx, %eax
+        pop     %edi
+        pop     %esi
+        pop     %ebx
+        ret
+.LNothing:
+        xor     %eax, %eax
+        pop     %edi
+        pop     %esi
+        pop     %ebx
 end;
 {$endif FPC_UNIT_HAS_STRLICOMP}
 
 
 
-{$ifndef FPC_UNIT_HAS_STRSCAN}
-{$define FPC_UNIT_HAS_STRSCAN}
-function strscan(p : PAnsiChar;c : AnsiChar) : PAnsiChar;assembler;
-var
-  saveesi,saveedi : longint;
-asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-        xorl    %ecx,%ecx
-        testl   %eax,%eax
-        jz      .LSTRSCAN
-// align
-        movb    c,%cl
-        leal    3(%eax),%esi
-        andl    $-4,%esi
-        movl    %eax,%edi
-        subl    %eax,%esi
-        jz      .LSTRSCANALIGNED
-        xorl    %eax,%eax
-.LSTRSCANALIGNLOOP:
-        movb    (%edi),%al
-// at .LSTRSCANFOUND, one is substracted from edi to calculate the position,
-// so add 1 here already (not after .LSTRSCAN, because then the test/jz and
-// cmp/je can't be paired)
-        incl    %edi
-        testb   %al,%al
-        jz      .LSTRSCAN
-        cmpb    %cl,%al
-        je      .LSTRSCANFOUND
-        decl    %esi
-        jnz     .LSTRSCANALIGNLOOP
-.LSTRSCANALIGNED:
-// fill ecx with cccc
-        movl     %ecx,%eax
-        shll     $8,%eax
-        orl      %eax,%ecx
-        movl     %ecx,%eax
-        shll     $16,%eax
-        orl      %eax,%ecx
-        .balign  16
-.LSTRSCANLOOP:
-// load new 4 bytes
-        movl     (%edi),%edx
-// in eax, we will check if "c" appear in the loaded dword
-        movl     %edx,%eax
-// esi will be used to calculate the mask
-        movl     %edx,%esi
-        notl     %esi
-// in edx we will check for the end of the string
-        addl     $0x0fefefeff,%edx
-        xorl     %ecx,%eax
-        andl     $0x080808080,%esi
-        addl     $4,%edi
-        andl     %esi,%edx
-        movl     %eax,%esi
-        notl     %esi
-        jnz      .LSTRSCANLONGCHECK
-        addl     $0x0fefefeff,%eax
-        andl     $0x080808080,%esi
-        andl     %esi,%eax
-        jz       .LSTRSCANLOOP
-
-// the position in %eax where the char was found is now $80, so keep on
-// shifting 8 bits out of %eax until we find a non-zero bit.
-// first char
-        shrl    $8,%eax
-        jc      .LSTRSCANFOUND1
-// second char
-        shrl    $8,%eax
-        jc      .LSTRSCANFOUND2
-// third char
-        shrl    $8,%eax
-        jc      .LSTRSCANFOUND3
-// fourth char
-        jmp     .LSTRSCANFOUND
-.LSTRSCANLONGCHECK:
-// there's a null somewhere, but we still have to check whether there isn't
-// a 'c' before it.
-        addl     $0x0fefefeff,%eax
-        andl     $0x080808080,%esi
-        andl     %esi,%eax
-// Now, in eax we have $80 on the positions where there were c-chars and in
-// edx we have $80 on the positions where there were #0's. On all other
-// positions, there is now #0
-// first char
-        shrl    $8,%eax
-        jc      .LSTRSCANFOUND1
-        shrl    $8,%edx
-        jc      .LSTRSCANNOTFOUND
-// second char
-        shrl    $8,%eax
-        jc      .LSTRSCANFOUND2
-        shrl    $8,%edx
-        jc      .LSTRSCANNOTFOUND
-// third char
-        shrl    $8,%eax
-        jc      .LSTRSCANFOUND3
-        shrl    $8,%edx
-        jc      .LSTRSCANNOTFOUND
-// we know the fourth char is now #0 (since we only jump to the long check if
-// there is a #0 char somewhere), but it's possible c = #0, and than we have
-// to return the end of the string and not nil!
-        shrl    $8,%eax
-        jc      .LSTRSCANFOUND
-        jmp     .LSTRSCANNOTFOUND
-.LSTRSCANFOUND3:
-        leal   -2(%edi),%eax
-        jmp     .LSTRSCAN
-.LSTRSCANFOUND2:
-        leal   -3(%edi),%eax
-        jmp     .LSTRSCAN
-.LSTRSCANFOUND1:
-        leal    -4(%edi),%eax
-        jmp     .LSTRSCAN
-.LSTRSCANFOUND:
-        leal    -1(%edi),%eax
-        jmp     .LSTRSCAN
-.LSTRSCANNOTFOUND:
-        xorl    %eax,%eax
-.LSTRSCAN:
-        movl    saveedi,%edi
-        movl    saveesi,%esi
-end;
-{$endif FPC_UNIT_HAS_STRSCAN}
-
-
-{$ifndef FPC_UNIT_HAS_STRRSCAN}
-{$define FPC_UNIT_HAS_STRRSCAN}
-function strrscan(p : PAnsiChar;c : AnsiChar) : PAnsiChar;assembler;
-var
-  saveeax,
-  saveedi : longint;
-asm
-        movl    %edi,saveedi
-        movl    %eax,saveeax
-        movl    p,%edi
-        xorl    %eax,%eax
-        orl     %edi,%edi
-        jz      .LSTRRSCAN
-        movl    $0xffffffff,%ecx
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-        xorb    %al,%al
-        repne
-        scasb
-        not     %ecx
-        movb    c,%al
-        movl    saveeax,%edi
-        addl    %ecx,%edi
-        decl    %edi
-        std
-        repne
-        scasb
-        cld
-        movl    $0,%eax
-        jnz     .LSTRRSCAN
-        movl    %edi,%eax
-        incl    %eax
-.LSTRRSCAN:
-        movl    saveedi,%edi
-end;
-{$endif FPC_UNIT_HAS_STRRSCAN}
-
-
 {$ifndef FPC_UNIT_HAS_STRUPPER}
 {$define FPC_UNIT_HAS_STRUPPER}
-function strupper(p : PAnsiChar) : PAnsiChar;assembler;
-var
-  saveeax,saveesi,saveedi : longint;
+function strupper(p : PAnsiChar) : PAnsiChar; assembler; nostackframe;
+{ eax = p }
 asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-        movl    %eax,saveeax
-        movl    p,%esi
-        orl     %esi,%esi
-        jz      .LStrUpperNil
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-        movl    %esi,%edi
-.LSTRUPPER1:
-        lodsb
-        cmpb    $97,%al
-        jb      .LSTRUPPER3
-        cmpb    $122,%al
-        ja      .LSTRUPPER3
-        subb    $0x20,%al
-.LSTRUPPER3:
-        stosb
-        orb     %al,%al
-        jnz     .LSTRUPPER1
-.LStrUpperNil:
-        movl    saveeax,%eax
-        movl    saveedi,%edi
-        movl    saveesi,%esi
+        mov     %eax, %ecx
+        sub     $1, %eax
+.balign 16
+.LLoop:
+        inc     %eax
+        movzbl  (%eax), %edx
+        test    %edx, %edx
+        jz      .LDone
+.LCheckLetterInEdx:
+        sub     $97, %edx
+        cmp     $25, %edx
+        ja      .LLoop
+        add     $(97 - 32), %edx
+        mov     %dl, (%eax)
+        inc     %eax { duplicate loop start instead of jmp .LLoop }
+        movzbl  (%eax), %edx
+        test    %edx, %edx
+        jnz     .LCheckLetterInEdx
+.LDone:
+        mov     %ecx, %eax
 end;
 {$endif FPC_UNIT_HAS_STRUPPER}
 
 
 {$ifndef FPC_UNIT_HAS_STRLOWER}
 {$define FPC_UNIT_HAS_STRLOWER}
-function strlower(p : PAnsiChar) : PAnsiChar;assembler;
-var
-  saveeax,saveesi,saveedi : longint;
+function strlower(p : PAnsiChar) : PAnsiChar; assembler; nostackframe;
+{ eax = p }
 asm
-        movl    %esi,saveesi
-        movl    %edi,saveedi
-        movl    %eax,saveeax
-        movl    p,%esi
-        orl     %esi,%esi
-        jz      .LStrLowerNil
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-        movl    %esi,%edi
-.LSTRLOWER1:
-        lodsb
-        cmpb    $65,%al
-        jb      .LSTRLOWER3
-        cmpb    $90,%al
-        ja      .LSTRLOWER3
-        addb    $0x20,%al
-.LSTRLOWER3:
-        stosb
-        orb     %al,%al
-        jnz     .LSTRLOWER1
-.LStrLowerNil:
-        movl    saveeax,%eax
-        movl    saveedi,%edi
-        movl    saveesi,%esi
+        mov     %eax, %ecx
+        sub     $1, %eax
+.balign 16
+.LLoop:
+        inc     %eax
+        movzbl  (%eax), %edx
+        test    %edx, %edx
+        jz      .LDone
+.LCheckLetterInEdx:
+        sub     $65, %edx
+        cmp     $25, %edx
+        ja      .LLoop
+        add     $(65 + 32), %edx
+        mov     %dl, (%eax)
+        inc     %eax { duplicate loop start instead of jmp .LLoop }
+        movzbl  (%eax), %edx
+        test    %edx, %edx
+        jnz     .LCheckLetterInEdx
+.LDone:
+        mov     %ecx, %eax
 end;
 {$endif FPC_UNIT_HAS_STRLOWER}
 

+ 0 - 23
rtl/i386/stringss.inc

@@ -15,27 +15,4 @@
  **********************************************************************}
 
 
-{$ifndef FPC_UNIT_HAS_STRPCOPY}
-{$define FPC_UNIT_HAS_STRPCOPY}
-function strpcopy(d : PAnsiChar;const s : shortstring) : PAnsiChar;assembler;
-var
-  saveesi,saveedi : longint;
-asm
-        movl    %edi,saveedi
-        movl    %esi,saveesi
-{$ifdef FPC_ENABLED_CLD}
-        cld
-{$endif FPC_ENABLED_CLD}
-
-        movl    %eax,%edi          // load destination address
-        movl    %edx,%esi          // Load Source adress
-        movzbl  (%esi),%ecx        // load length in ECX
-        incl    %esi
-        rep
-        movsb
-        movb    $0,(%edi)
-        movl    saveedi,%edi
-        movl    saveesi,%esi
-end;
-{$endif FPC_UNIT_HAS_STRPCOPY}
 

+ 75 - 122
rtl/inc/genstr.inc

@@ -14,18 +14,10 @@
 
 {$ifndef FPC_UNIT_HAS_STREND}
  Function StrEnd(P: PAnsiChar): PAnsiChar;
- var
-  counter: SizeInt;
  begin
-   counter := 0;
-   if not Assigned(P) then
-     StrEnd:=Nil
-   else  
-     begin
-     while P[counter] <> #0 do
-        Inc(counter);
-     StrEnd := @(P[Counter]);
-     end;
+   StrEnd := P;
+   if Assigned(StrEnd) then
+     Inc(StrEnd, IndexByte(StrEnd^, -1, 0));
  end;
 {$endif FPC_UNIT_HAS_STREND}
 
@@ -86,29 +78,15 @@
 
 {$ifndef FPC_UNIT_HAS_STRSCAN}
  function StrScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
-   Var
-     count: SizeInt;
-  Begin
-   count := 0;
-   { As in Borland Pascal , if looking for NULL return null }
-   if C = #0 then
-   begin
-     StrScan := @(P[StrLen(P)]);
-     exit;
-   end;
-   { Find first matching character of Ch in Str }
-   while P[count] <> #0 do
-   begin
-     if C = P[count] then
-      begin
-          StrScan := @(P[count]);
-          exit;
-      end;
-     Inc(count);
+   Begin
+     dec(P);
+     repeat
+       inc(P);
+     until (P^ = #0) or (P^ = C);
+     if (P^ = #0) and (C <> #0) then
+       P := nil;
+     StrScan := P;
    end;
-   { nothing found. }
-   StrScan := nil;
- end;
 {$endif FPC_UNIT_HAS_STRSCAN}
 
 
@@ -144,28 +122,17 @@
 
 {$ifndef FPC_UNIT_HAS_STRRSCAN}
  function StrRScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
- Var
-  count: SizeInt;
-  index: SizeInt;
  Begin
-   count := Strlen(P);
+   StrRScan := P + IndexByte(P^, -1, 0);
    { As in Borland Pascal , if looking for NULL return null }
    if C = #0 then
-   begin
-     StrRScan := @(P[count]);
      exit;
-   end;
-   Dec(count);
-   for index := count downto 0 do
-   begin
-     if C = P[index] then
-      begin
-          StrRScan := @(P[index]);
-          exit;
-      end;
-   end;
-   { nothing found. }
-   StrRScan := nil;
+   while (StrRScan <> P) and (StrRScan[-1] <> C) do
+     dec(StrRScan);
+   if StrRScan = P then
+     StrRScan := nil
+   else
+     dec(StrRScan);
  end;
 {$endif FPC_UNIT_HAS_STRRSCAN}
 
@@ -219,24 +186,24 @@
 {$ifndef FPC_UNIT_HAS_STRLCOPY}
  Function StrLCopy(Dest,Source: PAnsiChar; MaxLen: SizeInt): PAnsiChar;
   var
-   counter: SizeInt;
- Begin
-   counter := 0;
-   { To be compatible with BP, on a null string, put two nulls }
-   If Source[0] = #0 then
-   Begin
-     Dest[0]:=Source[0];
-     Inc(counter);
-   end;
-   while (Source[counter] <> #0)  and (counter < MaxLen) do
-   Begin
-      Dest[counter] := AnsiChar(Source[counter]);
-      Inc(counter);
-   end;
-   { terminate the string }
-   Dest[counter] := #0;
-   StrLCopy := Dest;
- end;
+   nmove: SizeInt;
+  Begin
+    { To be compatible with BP, on a null string, put two nulls }
+    If Source[0] = #0 then
+      unaligned(PUint16(Dest)^):=0
+    else
+      begin
+        if MaxLen < 0 then MaxLen := 0; { Paranoia. }
+        nmove := IndexByte(Source^,MaxLen,0) + 1;
+        if nmove = 0 then
+          begin
+            nmove := MaxLen;
+            Dest[MaxLen] := #0;
+          end;
+        Move(Source^,Dest^,nmove);
+      end;
+    StrLCopy := Dest;
+  end;
 {$endif FPC_UNIT_HAS_STRLCOPY}
 
 
@@ -244,81 +211,67 @@
  function StrComp(Str1, Str2 : PAnsiChar): SizeInt;
      var
       counter: SizeInt;
+      sample: char;
      Begin
-        counter := 0;
-       While str1[counter] = str2[counter] do
-       Begin
-         if str1[counter] = #0 then
-           break;
-         Inc(counter);
-       end;
-       StrComp := ord(str1[counter]) - ord(str2[counter]);
+       counter := -1;
+       repeat
+         inc(counter);
+         sample := str1[counter];
+       until (sample = #0) or (sample <> str2[counter]);
+       StrComp := ord(sample) - ord(str2[counter]);
      end;
 {$endif FPC_UNIT_HAS_STRCOMP}
 
 
 {$ifndef FPC_UNIT_HAS_STRICOMP}
      function StrIComp(Str1, Str2 : PAnsiChar): SizeInt;
-     var
-      counter: SizeInt;
-      c1, c2: AnsiChar;
      Begin
-        counter := 0;
-        c1 := upcase(str1[counter]);
-        c2 := upcase(str2[counter]);
-       While c1 = c2 do
-       Begin
-         if c1 = #0 then break;
-         Inc(counter);
-         c1 := upcase(str1[counter]);
-         c2 := upcase(str2[counter]);
-      end;
-       StrIComp := ord(c1) - ord(c2);
+       dec(Str1);
+       dec(Str2);
+       repeat
+         inc(Str1);
+         inc(Str2);
+         StrIComp := ord(Str1^) - ord(Str2^);
+         if Str1^ = #0 then break;
+         if StrIComp = 0 then continue;
+         StrIComp := ord(UpCase(Str1^)) - ord(UpCase(Str2^));
+         if StrIComp <> 0 then break; { Making it the loop condition might be suboptimal because of “continue”. }
+       until false;
      end;
 {$endif FPC_UNIT_HAS_STRICOMP}
 
 
 {$ifndef FPC_UNIT_HAS_STRLCOMP}
      function StrLComp(Str1, Str2 : PAnsiChar; L: SizeInt): SizeInt;
-     var
-      counter: SizeInt;
-      c1, c2: AnsiChar;
      Begin
-        counter := 0;
-       if L = 0 then
-       begin
-         StrLComp := 0;
-         exit;
-       end;
-       Repeat
-         c1 := str1[counter];
-         c2 := str2[counter];
-         if (c1 = #0) or (c2 = #0) then break;
-         Inc(counter);
-      Until (c1 <> c2) or (counter >= L);
-      StrLComp := ord(c1) - ord(c2);
+       while (L > 0) and (Str1^ <> #0) and (Str1^ = Str2^) do
+         begin
+           inc(Str1);
+           inc(Str2);
+           dec(L);
+         end;
+       if L <= 0 then StrLComp := 0 else StrLComp := ord(Str1^) - ord(Str2^);
      end;
 {$endif FPC_UNIT_HAS_STRLCOMP}
 
 
 {$ifndef FPC_UNIT_HAS_STRLICOMP}
      function StrLIComp(Str1, Str2 : PAnsiChar; L: SizeInt): SizeInt;
-     var
-      counter: SizeInt;
-      c1, c2: AnsiChar;
      Begin
-        counter := 0;
-       if L = 0 then
-       begin
-         StrLIComp := 0;
-         exit;
-       end;
+       dec(Str1);
+       dec(Str2);
+       inc(L);
+       StrLIComp := 0;
        Repeat
-         c1 := upcase(str1[counter]);
-         c2 := upcase(str2[counter]);
-         if (c1 = #0) or (c2 = #0) then break;
-         Inc(counter);
-      Until (c1 <> c2) or (counter >= L);
-      StrLIComp := ord(c1) - ord(c2);
+         dec(L);
+         if L <= 0 then break;
+         inc(Str1);
+         inc(Str2);
+         StrLIComp := ord(Str1^) - ord(Str2^);
+         if Str1^ = #0 then break;
+         if StrLIComp = 0 then continue;
+         StrLIComp := ord(UpCase(Str1^)) - ord(UpCase(Str2^));
+         if StrLIComp <> 0 then break; { Making it the loop condition might be suboptimal because of “continue”. }
+       until false;
      end;
 {$endif FPC_UNIT_HAS_STRLICOMP}

+ 8 - 18
rtl/inc/genstrs.inc

@@ -13,24 +13,14 @@
  **********************************************************************}
 
 {$ifndef FPC_UNIT_HAS_STRPCOPY}
-   function strpcopy(d : PAnsiChar;const s : shortstring) : PAnsiChar;
-   var
-    counter : byte;
+  function strpcopy(d : PAnsiChar;const s : shortstring) : PAnsiChar;
+  var
+    n: SizeInt;
   Begin
-    counter := 0;
-   { if empty pascal string  }
-   { then setup and exit now }
-   if Length(s)=0 then
-   Begin
-     D[0] := #0;
-     StrPCopy := D;
-     exit;
-   end;
-   for counter:=1 to length(S) do
-     D[counter-1] := S[counter];
-   { terminate the string }
-   D[counter] := #0;
-   StrPCopy:=D;
- end;
+    n:=length(s);
+    Move(s[1], d^, n);
+    d[n]:=#0;
+    StrPCopy:=D;
+  end;
 {$endif FPC_UNIT_HAS_STRPCOPY}