unit FastcodeStrLowerCaseUnit; //Version : 0.1 Preliminary version //Only direct calling supported interface function LowerCaseFastcodeP3(const S: String): String; function LowerCaseFastcodeP4(const S: String): String; function LowerCaseFastcodePrescott(const S: String): String; function LowerCaseFastcodeXP(const S: String): String; function LowerCaseFastcodeOpteron(const S: String): String; function LowerCaseFastcodeRTL(const S: String): String; function LowerCaseFastcodePascal(const S: String): String; function LowerCaseFastcodeBlended(const S: String): String; implementation uses SysUtils; var LookUpTable : array of Char; procedure InitializeLookUpTable; var I : Byte; S1, S2 : AnsiString; begin SetLength(LookUpTable, 256); for I := 0 to 255 do begin S1 := Char(I); S2 := LowerCase(S1); LookUpTable[I] := S2[1]; end; end; //Author: Dennis Kjaer Christensen //Date: 9/1 2004 //Optimized for: P4 //Instructionset(s): IA32 //Original name: LowerCaseDKC_IA32_1 function LowerCaseFastcodeP4(const S: String): String; asm push ebx push esi push edi mov ebx,eax test eax,eax jz @LStrLenExit mov eax,[eax-$04] @LStrLenExit : mov esi,eax mov edi,edx //SetLength(Result, Max); mov eax,edx mov edx,esi call System.@LStrSetLength //if Max > 0 then test esi,esi jbe @Exit1 //PResult := Pointer(Result); mov edi,[edi] sub ebx,1 sub edi,1 mov ecx,[LookUpTable] @RepeatBegin : movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 //until(CharNo >= Max); jnbe @RepeatBegin @Exit1 : pop edi pop esi pop ebx end; //Author: Aleksandr Sharahov //Date: N/A //Optimized for: Prescott //Instructionset(s): IA32 //Original name: LowerCaseShaPas2_d {$UNDEF SaveQ} {$IFOPT Q+} {$Q-} {$DEFINE SaveQ} {$ENDIF} {$UNDEF SaveR} {$IFOPT R+} {$R-} {$DEFINE SaveR} {$ENDIF} function LowerCaseFastcodePrescott(const s: string): string; var ch1, ch2, ch3, dist, term: integer; p: pchar; label loop, last; begin if s='' then begin; Result:=''; exit; end; p:=pointer(s); //If need pure Pascal change the next line to term:=Length(s); term:=pinteger(@p[-4])^; SetLength(Result,term); if term<>0 then begin; dist:=integer(Result); term:=integer(p+term); dist:=dist-integer(p)-4; loop: ch1:=pinteger(p)^; ch3:=$7F7F7F7F; ch2:=ch1; ch3:=ch3 and ch1; ch2:=ch2 xor (-1); ch3:=ch3 + $25252525; ch2:=ch2 and $80808080; ch3:=ch3 and $7F7F7F7F; ch3:=ch3 + $1A1A1A1A; inc(p,4); ch3:=ch3 and ch2; if cardinal(p)>=cardinal(term) then goto last; ch3:=ch3 shr 2; ch1:=ch1 + ch3; pinteger(p+dist)^:=ch1; goto loop; last: ch3:=ch3 shr 2; term:=term-integer(p); p:=p+dist; ch1:=ch1 + ch3; if term<-1 then pword(p)^:=word(ch1) else pinteger(p)^:=ch1; end; end; {$IFDEF SaveQ} {$Q+} {$UNDEF SaveQ} {$ENDIF} {$IFDEF SaveR} {$R+} {$UNDEF SaveR} {$ENDIF} //Author: Dennis Kjaer Christensen //Date: 9/1 2004 //Optimized for: P3 //Instructionset(s): IA32 //Original name: LowerCaseDKC_IA32_1 function LowerCaseFastcodeP3(const S: String): String; asm push ebx push esi push edi mov ebx,eax test eax,eax jz @LStrLenExit mov eax,[eax-$04] @LStrLenExit : mov esi,eax mov edi,edx //SetLength(Result, Max); mov eax,edx mov edx,esi call System.@LStrSetLength //if Max > 0 then test esi,esi jbe @Exit1 //PResult := Pointer(Result); mov edi,[edi] sub ebx,1 sub edi,1 mov ecx,[LookUpTable] @RepeatBegin : movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 jbe @Exit1 movzx edx,[ebx+esi] movzx edx,[ecx+edx] mov [edi+esi],dl sub esi,1 //until(CharNo >= Max); jnbe @RepeatBegin @Exit1 : pop edi pop esi pop ebx end; //Author: Aleksandr Sharahov //Date: N/A //Optimized for: XP //Instructionset(s): IA32 //Original name: LowerCaseShaPas2_d {$UNDEF SaveQ} {$IFOPT Q+} {$Q-} {$DEFINE SaveQ} {$ENDIF} {$UNDEF SaveR} {$IFOPT R+} {$R-} {$DEFINE SaveR} {$ENDIF} function LowerCaseFastcodeXP(const s: string): string; var ch1, ch2, ch3, dist, term: integer; p: pchar; label loop, last; begin if s='' then begin; Result:=''; exit; end; p:=pointer(s); //If need pure Pascal change the next line to term:=Length(s); term:=pinteger(@p[-4])^; SetLength(Result,term); if term<>0 then begin; dist:=integer(Result); term:=integer(p+term); dist:=dist-integer(p)-4; loop: ch1:=pinteger(p)^; ch3:=$7F7F7F7F; ch2:=ch1; ch3:=ch3 and ch1; ch2:=ch2 xor (-1); ch3:=ch3 + $25252525; ch2:=ch2 and $80808080; ch3:=ch3 and $7F7F7F7F; ch3:=ch3 + $1A1A1A1A; inc(p,4); ch3:=ch3 and ch2; if cardinal(p)>=cardinal(term) then goto last; ch3:=ch3 shr 2; ch1:=ch1 + ch3; pinteger(p+dist)^:=ch1; goto loop; last: ch3:=ch3 shr 2; term:=term-integer(p); p:=p+dist; ch1:=ch1 + ch3; if term<-1 then pword(p)^:=word(ch1) else pinteger(p)^:=ch1; end; end; {$IFDEF SaveQ} {$Q+} {$UNDEF SaveQ} {$ENDIF} {$IFDEF SaveR} {$R+} {$UNDEF SaveR} {$ENDIF} //Author: Aleksandr Sharahov //Date: N/A //Optimized for: Opteron //Instructionset(s): IA32 //Original name: LowerCaseShaPas2_d {$UNDEF SaveQ} {$IFOPT Q+} {$Q-} {$DEFINE SaveQ} {$ENDIF} {$UNDEF SaveR} {$IFOPT R+} {$R-} {$DEFINE SaveR} {$ENDIF} function LowerCaseFastcodeOpteron(const s: string): string; var ch1, ch2, ch3, dist, term: integer; p: pchar; label loop, last; begin if s='' then begin; Result:=''; exit; end; p:=pointer(s); //If need pure Pascal change the next line to term:=Length(s); term:=pinteger(@p[-4])^; SetLength(Result,term); if term<>0 then begin; dist:=integer(Result); term:=integer(p+term); dist:=dist-integer(p)-4; loop: ch1:=pinteger(p)^; ch3:=$7F7F7F7F; ch2:=ch1; ch3:=ch3 and ch1; ch2:=ch2 xor (-1); ch3:=ch3 + $25252525; ch2:=ch2 and $80808080; ch3:=ch3 and $7F7F7F7F; ch3:=ch3 + $1A1A1A1A; inc(p,4); ch3:=ch3 and ch2; if cardinal(p)>=cardinal(term) then goto last; ch3:=ch3 shr 2; ch1:=ch1 + ch3; pinteger(p+dist)^:=ch1; goto loop; last: ch3:=ch3 shr 2; term:=term-integer(p); p:=p+dist; ch1:=ch1 + ch3; if term<-1 then pword(p)^:=word(ch1) else pinteger(p)^:=ch1; end; end; {$IFDEF SaveQ} {$Q+} {$UNDEF SaveQ} {$ENDIF} {$IFDEF SaveR} {$R+} {$UNDEF SaveR} {$ENDIF} //Author: Aleksandr Sharahov //Date: N/A //Optimized for: RTL //Instructionset(s): IA32 //Original name: LowerCaseShaPas2_d {$UNDEF SaveQ} {$IFOPT Q+} {$Q-} {$DEFINE SaveQ} {$ENDIF} {$UNDEF SaveR} {$IFOPT R+} {$R-} {$DEFINE SaveR} {$ENDIF} function LowerCaseFastcodeRTL(const s: string): string; var ch1, ch2, ch3, dist, term: integer; p: pchar; label loop, last; begin if s='' then begin; Result:=''; exit; end; p:=pointer(s); //If need pure Pascal change the next line to term:=Length(s); term:=pinteger(@p[-4])^; SetLength(Result,term); if term<>0 then begin; dist:=integer(Result); term:=integer(p+term); dist:=dist-integer(p)-4; loop: ch1:=pinteger(p)^; ch3:=$7F7F7F7F; ch2:=ch1; ch3:=ch3 and ch1; ch2:=ch2 xor (-1); ch3:=ch3 + $25252525; ch2:=ch2 and $80808080; ch3:=ch3 and $7F7F7F7F; ch3:=ch3 + $1A1A1A1A; inc(p,4); ch3:=ch3 and ch2; if cardinal(p)>=cardinal(term) then goto last; ch3:=ch3 shr 2; ch1:=ch1 + ch3; pinteger(p+dist)^:=ch1; goto loop; last: ch3:=ch3 shr 2; term:=term-integer(p); p:=p+dist; ch1:=ch1 + ch3; if term<-1 then pword(p)^:=word(ch1) else pinteger(p)^:=ch1; end; end; {$IFDEF SaveQ} {$Q+} {$UNDEF SaveQ} {$ENDIF} {$IFDEF SaveR} {$R+} {$UNDEF SaveR} {$ENDIF} //Author: Aleksandr Sharahov //Date: N/A //Optimized for: Pascal //Instructionset(s): IA32 //Original name: LowerCaseShaPas2_d {$UNDEF SaveQ} {$IFOPT Q+} {$Q-} {$DEFINE SaveQ} {$ENDIF} {$UNDEF SaveR} {$IFOPT R+} {$R-} {$DEFINE SaveR} {$ENDIF} function LowerCaseFastcodePascal(const s: string): string; var ch1, ch2, ch3, dist, term: integer; p: pchar; label loop, last; begin if s='' then begin; Result:=''; exit; end; p:=pointer(s); //If need pure Pascal change the next line to term:=Length(s); term:=pinteger(@p[-4])^; SetLength(Result,term); if term<>0 then begin; dist:=integer(Result); term:=integer(p+term); dist:=dist-integer(p)-4; loop: ch1:=pinteger(p)^; ch3:=$7F7F7F7F; ch2:=ch1; ch3:=ch3 and ch1; ch2:=ch2 xor (-1); ch3:=ch3 + $25252525; ch2:=ch2 and $80808080; ch3:=ch3 and $7F7F7F7F; ch3:=ch3 + $1A1A1A1A; inc(p,4); ch3:=ch3 and ch2; if cardinal(p)>=cardinal(term) then goto last; ch3:=ch3 shr 2; ch1:=ch1 + ch3; pinteger(p+dist)^:=ch1; goto loop; last: ch3:=ch3 shr 2; term:=term-integer(p); p:=p+dist; ch1:=ch1 + ch3; if term<-1 then pword(p)^:=word(ch1) else pinteger(p)^:=ch1; end; end; {$IFDEF SaveQ} {$Q+} {$UNDEF SaveQ} {$ENDIF} {$IFDEF SaveR} {$R+} {$UNDEF SaveR} {$ENDIF} //Author: Aleksandr Sharahov //Date: N/A //Optimized for: Blended //Instructionset(s): IA32 //Original name: LowerCaseShaPas2_d {$UNDEF SaveQ} {$IFOPT Q+} {$Q-} {$DEFINE SaveQ} {$ENDIF} {$UNDEF SaveR} {$IFOPT R+} {$R-} {$DEFINE SaveR} {$ENDIF} function LowerCaseFastcodeBlended(const s: string): string; var ch1, ch2, ch3, dist, term: integer; p: pchar; label loop, last; begin if s='' then begin; Result:=''; exit; end; p:=pointer(s); //If need pure Pascal change the next line to term:=Length(s); term:=pinteger(@p[-4])^; SetLength(Result,term); if term<>0 then begin; dist:=integer(Result); term:=integer(p+term); dist:=dist-integer(p)-4; loop: ch1:=pinteger(p)^; ch3:=$7F7F7F7F; ch2:=ch1; ch3:=ch3 and ch1; ch2:=ch2 xor (-1); ch3:=ch3 + $25252525; ch2:=ch2 and $80808080; ch3:=ch3 and $7F7F7F7F; ch3:=ch3 + $1A1A1A1A; inc(p,4); ch3:=ch3 and ch2; if cardinal(p)>=cardinal(term) then goto last; ch3:=ch3 shr 2; ch1:=ch1 + ch3; pinteger(p+dist)^:=ch1; goto loop; last: ch3:=ch3 shr 2; term:=term-integer(p); p:=p+dist; ch1:=ch1 + ch3; if term<-1 then pword(p)^:=word(ch1) else pinteger(p)^:=ch1; end; end; {$IFDEF SaveQ} {$Q+} {$UNDEF SaveQ} {$ENDIF} {$IFDEF SaveR} {$R+} {$UNDEF SaveR} {$ENDIF} initialization InitializeLookUpTable; end.