mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 20:49:23 +02:00
* improved Compare(D)Word as well
git-svn-id: trunk@17651 -
This commit is contained in:
parent
0c10a5efff
commit
cd8913b88e
@ -481,30 +481,44 @@ end;
|
|||||||
{$endif FPC_SYSTEM_HAS_COMPAREBYTE}
|
{$endif FPC_SYSTEM_HAS_COMPAREBYTE}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{$ifndef FPC_SYSTEM_HAS_COMPAREWORD}
|
{$ifndef FPC_SYSTEM_HAS_COMPAREWORD}
|
||||||
{$define FPC_SYSTEM_HAS_COMPAREWORD}
|
{$define FPC_SYSTEM_HAS_COMPAREWORD}
|
||||||
function CompareWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler;
|
function CompareWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler; nostackframe;
|
||||||
var
|
|
||||||
saveesi,saveedi,saveebx : longint;
|
|
||||||
asm
|
asm
|
||||||
movl %edi,saveedi
|
cmpl $32,%ecx { empirical average value, on a Athlon XP the
|
||||||
movl %esi,saveesi
|
break even is at 14, on a Core 2 Duo > 100 }
|
||||||
movl %ebx,saveebx
|
jg .LCmpWordFull
|
||||||
|
testl %ecx,%ecx
|
||||||
|
je .LCmpWordZero
|
||||||
|
|
||||||
|
pushl %ebx
|
||||||
|
.LCmpWordLoop:
|
||||||
|
movw (%eax),%bx
|
||||||
|
cmpw (%edx),%bx
|
||||||
|
leal 2(%eax),%eax
|
||||||
|
leal 2(%edx),%edx
|
||||||
|
jne .LCmpWordExitFast
|
||||||
|
decl %ecx
|
||||||
|
jne .LCmpWordLoop
|
||||||
|
.LCmpWordExitFast:
|
||||||
|
movzwl -2(%edx),%ecx { Compare last position }
|
||||||
|
movzwl %bx,%eax
|
||||||
|
subl %ecx,%eax
|
||||||
|
popl %ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
.LCmpWordZero:
|
||||||
|
movl $0,%eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.LCmpWordFull:
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
|
pushl %ebx
|
||||||
cld
|
cld
|
||||||
{$ifdef REGCALL}
|
|
||||||
movl %eax,%edi
|
movl %eax,%edi
|
||||||
movl %edx,%esi
|
movl %edx,%esi
|
||||||
movl %ecx,%eax
|
movl %ecx,%eax
|
||||||
{$else}
|
|
||||||
movl buf2,%esi { Load params}
|
|
||||||
movl buf1,%edi
|
|
||||||
movl len,%eax
|
|
||||||
{$endif}
|
|
||||||
testl %eax,%eax {We address -2(%esi), so we have to deal with len=0}
|
|
||||||
je .LCmpwordExit
|
|
||||||
cmpl $5,%eax {<5 (3 bytes align + 4 bytes cmpsl = 4 words}
|
|
||||||
jl .LCmpword2 { not worth aligning and go through all trouble}
|
|
||||||
movl (%edi),%ebx // Compare alignment bytes.
|
movl (%edi),%ebx // Compare alignment bytes.
|
||||||
cmpl (%esi),%ebx
|
cmpl (%esi),%ebx
|
||||||
jne .LCmpword2 // Aligning will go wrong already. Max 2 words will be scanned Branch NOW
|
jne .LCmpword2 // Aligning will go wrong already. Max 2 words will be scanned Branch NOW
|
||||||
@ -543,35 +557,55 @@ asm
|
|||||||
movzwl -2(%edi),%eax // Compare failing (or equal) position
|
movzwl -2(%edi),%eax // Compare failing (or equal) position
|
||||||
subl %ecx,%eax // calculate end result.
|
subl %ecx,%eax // calculate end result.
|
||||||
.LCmpwordExit:
|
.LCmpwordExit:
|
||||||
movl saveedi,%edi
|
popl %ebx
|
||||||
movl saveesi,%esi
|
popl %edi
|
||||||
movl saveebx,%ebx
|
popl %esi
|
||||||
end;
|
end;
|
||||||
{$endif FPC_SYSTEM_HAS_COMPAREWORD}
|
{$endif FPC_SYSTEM_HAS_COMPAREWORD}
|
||||||
|
|
||||||
|
|
||||||
{$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
|
{$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
|
||||||
{$define FPC_SYSTEM_HAS_COMPAREDWORD}
|
{$define FPC_SYSTEM_HAS_COMPAREDWORD}
|
||||||
function CompareDWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler;
|
function CompareDWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler; nostackframe;
|
||||||
var
|
|
||||||
saveesi,saveedi,saveebx : longint;
|
|
||||||
asm
|
asm
|
||||||
movl %edi,saveedi
|
cmpl $32,%ecx { empirical average value, on a Athlon XP the
|
||||||
movl %esi,saveesi
|
break even is at 12, on a Core 2 Duo > 100 }
|
||||||
|
jg .LCmpDWordFull
|
||||||
|
testl %ecx,%ecx
|
||||||
|
je .LCmpDWordZero
|
||||||
|
|
||||||
|
pushl %ebx
|
||||||
|
.LCmpDWordLoop:
|
||||||
|
movl (%eax),%ebx
|
||||||
|
cmpl (%edx),%ebx
|
||||||
|
leal 4(%eax),%eax
|
||||||
|
leal 4(%edx),%edx
|
||||||
|
jne .LCmpDWordExitFast
|
||||||
|
decl %ecx
|
||||||
|
jne .LCmpDWordLoop
|
||||||
|
.LCmpDWordExitFast:
|
||||||
|
xorl %eax,%eax
|
||||||
|
movl -4(%edx),%edx // Compare failing (or equal) position
|
||||||
|
subl %edx,%ebx // calculate end result.
|
||||||
|
setb %dl
|
||||||
|
seta %cl
|
||||||
|
addb %cl,%al
|
||||||
|
subb %dl,%al
|
||||||
|
movsbl %al,%eax
|
||||||
|
|
||||||
|
popl %ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
.LCmpDWordZero:
|
||||||
|
movl $0,%eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.LCmpDWordFull:
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
cld
|
cld
|
||||||
{$ifdef REGCALL}
|
|
||||||
movl %eax,%edi
|
movl %eax,%edi
|
||||||
movl %edx,%esi
|
movl %edx,%esi
|
||||||
movl %ecx,%eax
|
|
||||||
{$else}
|
|
||||||
movl buf2,%esi { Load params}
|
|
||||||
movl buf1,%edi
|
|
||||||
movl len,%eax
|
|
||||||
movl %eax,%ecx
|
|
||||||
{$endif}
|
|
||||||
testl %eax,%eax
|
|
||||||
je .LCmpDwordExit
|
|
||||||
movl %eax,%ecx
|
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
rep { Compare entire DWords}
|
rep { Compare entire DWords}
|
||||||
cmpsl
|
cmpsl
|
||||||
@ -583,8 +617,8 @@ asm
|
|||||||
subb %dl,%al
|
subb %dl,%al
|
||||||
movsbl %al,%eax
|
movsbl %al,%eax
|
||||||
.LCmpDwordExit:
|
.LCmpDwordExit:
|
||||||
movl saveedi,%edi
|
popl %edi
|
||||||
movl saveesi,%esi
|
popl %esi
|
||||||
end;
|
end;
|
||||||
{$endif FPC_SYSTEM_HAS_COMPAREDWORD}
|
{$endif FPC_SYSTEM_HAS_COMPAREDWORD}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user