mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 19:29:39 +02:00
* much faster strcopy and strscan procedures
This commit is contained in:
parent
f0f4a1d74e
commit
9cf6b9f89d
@ -19,26 +19,50 @@
|
|||||||
|
|
||||||
function strcopy(dest,source : pchar) : pchar;assembler;
|
function strcopy(dest,source : pchar) : pchar;assembler;
|
||||||
asm
|
asm
|
||||||
cld
|
|
||||||
movl source,%edi
|
movl source,%edi
|
||||||
orl %edi,%edi
|
testl %edi,%edi
|
||||||
jz .LStrCopyNil
|
jz .LStrCopyDone
|
||||||
movl $0xffffffff,%ecx
|
movl %edi,%ecx
|
||||||
xorb %al,%al
|
andl $0x0fffffff8,%edi
|
||||||
repne
|
|
||||||
scasb
|
|
||||||
not %ecx
|
|
||||||
movl dest,%edi
|
|
||||||
movl source,%esi
|
movl source,%esi
|
||||||
movl %ecx,%eax
|
subl %edi,%ecx
|
||||||
shrl $2,%ecx
|
movl dest,%edi
|
||||||
rep
|
jz .LStrCopyAligned
|
||||||
movsl
|
.LStrCopyAlignLoop:
|
||||||
movl %eax,%ecx
|
movb (%esi),%al
|
||||||
andl $3,%ecx
|
incl %edi
|
||||||
rep
|
incl %esi
|
||||||
movsb
|
testb %al,%al
|
||||||
.LStrCopyNil:
|
movb %al,-1(%edi)
|
||||||
|
jz .LStrCopyDone
|
||||||
|
decl %ecx
|
||||||
|
jnz .LStrCopyAlignLoop
|
||||||
|
.align 16
|
||||||
|
.LStrCopyAligned:
|
||||||
|
movl (%esi),%eax
|
||||||
|
addl $4,%esi
|
||||||
|
testl $0x0ff,%eax
|
||||||
|
jz .LStrCopyByte
|
||||||
|
testl $0x0ff00,%eax
|
||||||
|
jz .LStrCopyWord
|
||||||
|
testl $0x0ff0000,%eax
|
||||||
|
jz .LStrCopy3Bytes
|
||||||
|
movl %eax,(%edi)
|
||||||
|
testl $0x0ff000000,%eax
|
||||||
|
jz .LStrCopyDone
|
||||||
|
addl $4,%edi
|
||||||
|
jmp .LStrCopyAligned
|
||||||
|
.LStrCopy3Bytes:
|
||||||
|
movw %ax,(%edi)
|
||||||
|
xorl %eax,%eax
|
||||||
|
addl $2,%edi
|
||||||
|
jmp .LStrCopyByte
|
||||||
|
.LStrCopyWord:
|
||||||
|
movw %ax,(%edi)
|
||||||
|
jmp .LStrCopyDone
|
||||||
|
.LStrCopyByte:
|
||||||
|
movb %al,(%edi)
|
||||||
|
.LStrCopyDone:
|
||||||
movl dest,%eax
|
movl dest,%eax
|
||||||
end ['EAX','ECX','ESI','EDI'];
|
end ['EAX','ECX','ESI','EDI'];
|
||||||
|
|
||||||
@ -243,25 +267,78 @@ end ['EAX','ECX','ESI','EDI'];
|
|||||||
|
|
||||||
function strscan(p : pchar;c : char) : pchar;assembler;
|
function strscan(p : pchar;c : char) : pchar;assembler;
|
||||||
asm
|
asm
|
||||||
xorl %eax,%eax
|
movl p,%eax
|
||||||
movl p,%edi
|
xorl %ecx,%ecx
|
||||||
orl %edi,%edi
|
testl %eax,%eax
|
||||||
jz .LSTRSCAN
|
jz .LSTRSCAN
|
||||||
movl $0xffffffff,%ecx
|
// align
|
||||||
cld
|
movb c,%cl
|
||||||
repne
|
movl %eax,%esi
|
||||||
scasb
|
andl $0xfffffff8,%eax
|
||||||
not %ecx
|
movl $0xff,%edx
|
||||||
movb c,%al
|
|
||||||
movl p,%edi
|
movl p,%edi
|
||||||
repne
|
subl %eax,%esi
|
||||||
scasb
|
jz .LSTRSCANLOOP
|
||||||
movl $0,%eax
|
.LSTRSCANALIGNLOOP:
|
||||||
jnz .LSTRSCAN
|
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
|
||||||
|
jmp .LSTRSCANLOOP
|
||||||
|
.align 16
|
||||||
|
.LSTRSCANLOOP:
|
||||||
|
movl (%edi),%eax
|
||||||
|
movl %eax,%esi
|
||||||
|
// first char
|
||||||
|
andl %edx,%eax
|
||||||
|
// end of string -> stop
|
||||||
|
jz .LSTRSCAN
|
||||||
|
shrl $8,%esi
|
||||||
|
cmpl %ecx,%eax
|
||||||
|
movl %esi,%eax
|
||||||
|
je .LSTRSCANFOUND1
|
||||||
|
// second char
|
||||||
|
andl %edx,%eax
|
||||||
|
jz .LSTRSCAN
|
||||||
|
shrl $8,%esi
|
||||||
|
cmpl %ecx,%eax
|
||||||
|
movl %esi,%eax
|
||||||
|
je .LSTRSCANFOUND2
|
||||||
|
// third char
|
||||||
|
andl %edx,%eax
|
||||||
|
jz .LSTRSCAN
|
||||||
|
shrl $8,%esi
|
||||||
|
cmpl %ecx,%eax
|
||||||
|
movl %esi,%eax
|
||||||
|
je .LSTRSCANFOUND3
|
||||||
|
// fourth char
|
||||||
|
// all upper bits have already been cleared
|
||||||
|
testl %eax,%eax
|
||||||
|
jz .LSTRSCAN
|
||||||
|
addl $4,%edi
|
||||||
|
cmpl %ecx,%eax
|
||||||
|
je .LSTRSCANFOUND
|
||||||
|
jmp .LSTRSCANLOOP
|
||||||
|
.LSTRSCANFOUND3:
|
||||||
|
leal 2(%edi),%eax
|
||||||
|
jmp .LSTRSCAN
|
||||||
|
.LSTRSCANFOUND2:
|
||||||
|
leal 1(%edi),%eax
|
||||||
|
jmp .LSTRSCAN
|
||||||
|
.LSTRSCANFOUND1:
|
||||||
movl %edi,%eax
|
movl %edi,%eax
|
||||||
decl %eax
|
jmp .LSTRSCAN
|
||||||
|
.LSTRSCANFOUND:
|
||||||
|
leal -1(%edi),%eax
|
||||||
.LSTRSCAN:
|
.LSTRSCAN:
|
||||||
end ['EAX','ECX','EDI'];
|
end ['EAX','ECX','ESI','EDI','EDX'];
|
||||||
|
|
||||||
|
|
||||||
function strrscan(p : pchar;c : char) : pchar;assembler;
|
function strrscan(p : pchar;c : char) : pchar;assembler;
|
||||||
@ -337,7 +414,10 @@ end ['EAX','ESI','EDI'];
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.8 2000-03-28 11:14:33 jonas
|
Revision 1.9 2000-06-11 14:25:23 jonas
|
||||||
|
* much faster strcopy and strscan procedures
|
||||||
|
|
||||||
|
Revision 1.8 2000/03/28 11:14:33 jonas
|
||||||
* added missing register that is destroyed by strecopy
|
* added missing register that is destroyed by strecopy
|
||||||
+ some destroyed register lists for procedures that didn't have one yet
|
+ some destroyed register lists for procedures that didn't have one yet
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user