* improved Compare(D)Word as well

git-svn-id: trunk@17651 -
This commit is contained in:
florian 2011-06-03 20:35:55 +00:00
parent 0c10a5efff
commit cd8913b88e

View File

@ -481,30 +481,44 @@ end;
{$endif FPC_SYSTEM_HAS_COMPAREBYTE}
{$ifndef FPC_SYSTEM_HAS_COMPAREWORD}
{$define FPC_SYSTEM_HAS_COMPAREWORD}
function CompareWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler;
var
saveesi,saveedi,saveebx : longint;
function CompareWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler; nostackframe;
asm
movl %edi,saveedi
movl %esi,saveesi
movl %ebx,saveebx
cmpl $32,%ecx { empirical average value, on a Athlon XP the
break even is at 14, on a Core 2 Duo > 100 }
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
{$ifdef REGCALL}
movl %eax,%edi
movl %edx,%esi
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.
cmpl (%esi),%ebx
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
subl %ecx,%eax // calculate end result.
.LCmpwordExit:
movl saveedi,%edi
movl saveesi,%esi
movl saveebx,%ebx
popl %ebx
popl %edi
popl %esi
end;
{$endif FPC_SYSTEM_HAS_COMPAREWORD}
{$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
{$define FPC_SYSTEM_HAS_COMPAREDWORD}
function CompareDWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler;
var
saveesi,saveedi,saveebx : longint;
function CompareDWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler; nostackframe;
asm
movl %edi,saveedi
movl %esi,saveesi
cmpl $32,%ecx { empirical average value, on a Athlon XP the
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
{$ifdef REGCALL}
movl %eax,%edi
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
rep { Compare entire DWords}
cmpsl
@ -583,8 +617,8 @@ asm
subb %dl,%al
movsbl %al,%eax
.LCmpDwordExit:
movl saveedi,%edi
movl saveesi,%esi
popl %edi
popl %esi
end;
{$endif FPC_SYSTEM_HAS_COMPAREDWORD}