|
@@ -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}
|
|
|
|