mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 19:09:16 +02:00
* patch by Rika: Improve generic CompareByte, resolves #40120
This commit is contained in:
parent
06a7610a35
commit
218da184e6
@ -429,68 +429,48 @@ end;
|
|||||||
{$ifndef FPC_SYSTEM_HAS_COMPAREBYTE}
|
{$ifndef FPC_SYSTEM_HAS_COMPAREBYTE}
|
||||||
function CompareByte(Const buf1,buf2;len:SizeInt):SizeInt;
|
function CompareByte(Const buf1,buf2;len:SizeInt):SizeInt;
|
||||||
var
|
var
|
||||||
aligncount : sizeint;
|
psrc,pdest,pend,pendpart : pbyte;
|
||||||
psrc,pdest,pend : pbyte;
|
|
||||||
b : ptrint;
|
|
||||||
begin
|
begin
|
||||||
b:=0;
|
|
||||||
psrc:=@buf1;
|
psrc:=@buf1;
|
||||||
pdest:=@buf2;
|
pdest:=@buf2;
|
||||||
if (len>4*sizeof(ptruint)-1)
|
pend:=psrc+len;
|
||||||
|
if (pend<psrc) then
|
||||||
|
pend:=pbyte(high(ptruint));
|
||||||
|
if (len>=2*sizeof(ptruint))
|
||||||
{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
|
{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||||
and ((PtrUInt(pdest) and (sizeof(PtrUInt)-1))=(PtrUInt(psrc) and (sizeof(PtrUInt)-1)))
|
and ((PtrUInt(pdest) and (sizeof(PtrUInt)-1))=(PtrUInt(psrc) and (sizeof(PtrUInt)-1)))
|
||||||
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||||
then
|
then
|
||||||
begin
|
begin
|
||||||
{ Align on native pointer size }
|
{ Align "psrc" on native pointer size. }
|
||||||
aligncount:=(sizeof(PtrUInt)-(PtrUInt(pdest) and (sizeof(PtrUInt)-1))) and (sizeof(PtrUInt)-1);
|
PtrUint(pendpart):=PtrUint(psrc+(sizeof(PtrUint)-1)) and PtrUint(not PtrUint(sizeof(PtrUint)-1));
|
||||||
dec(len,aligncount);
|
if psrc<pendpart then
|
||||||
pend:=psrc+aligncount;
|
|
||||||
while psrc<pend do
|
|
||||||
begin
|
begin
|
||||||
b:=(ptrint(psrc^)-ptrint(pdest^));
|
while (psrc<pendpart) and (psrc^=pdest^) do
|
||||||
if b<>0 then
|
|
||||||
begin
|
begin
|
||||||
if b<0 then
|
inc(pdest);
|
||||||
exit(-1)
|
inc(psrc);
|
||||||
else
|
|
||||||
exit(1);
|
|
||||||
end;
|
end;
|
||||||
inc(pdest);
|
if psrc<pendpart then
|
||||||
inc(psrc);
|
exit(sizeint(psrc^)-sizeint(pdest^));
|
||||||
end;
|
end;
|
||||||
{ use sizeuint typecast to force shr optimization }
|
{ "pend" is the end of "psrc" and "psrc" is aligned, so aligned "pend" can be obtained this way. }
|
||||||
pptruint(pend):=pptruint(psrc)+(sizeuint(len) div sizeof(ptruint));
|
PtrUint(pendpart):=PtrUint(pend) and PtrUint(not PtrUint(sizeof(PtrUint)-1));
|
||||||
len:=len and (sizeof(PtrUInt)-1);
|
while (psrc<pendpart) and (pptruint(psrc)^=pptruint(pdest)^) do
|
||||||
while psrc<pend do
|
|
||||||
begin
|
begin
|
||||||
b:=(pptrint(psrc)^-pptrint(pdest)^);
|
|
||||||
if b<>0 then
|
|
||||||
begin
|
|
||||||
len:=sizeof(ptruint);
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
inc(pptruint(pdest));
|
inc(pptruint(pdest));
|
||||||
inc(pptruint(psrc));
|
inc(pptruint(psrc));
|
||||||
end;
|
end;
|
||||||
|
if psrc<pendpart then
|
||||||
|
pend:=psrc+sizeof(ptruint);
|
||||||
end;
|
end;
|
||||||
if (psrc+len >= psrc) then
|
while (psrc<pend) and (psrc^=pdest^) do
|
||||||
pend:=psrc+len
|
|
||||||
else
|
|
||||||
pend:=pbyte(high(ptruint)-1);
|
|
||||||
while psrc<pend do
|
|
||||||
begin
|
begin
|
||||||
b:=(ptrint(psrc^)-ptrint(pdest^));
|
|
||||||
if b<>0 then
|
|
||||||
begin
|
|
||||||
if b<0 then
|
|
||||||
exit(-1)
|
|
||||||
else
|
|
||||||
exit(1);
|
|
||||||
end;
|
|
||||||
inc(pdest);
|
inc(pdest);
|
||||||
inc(psrc);
|
inc(psrc);
|
||||||
end;
|
end;
|
||||||
|
if psrc<pend then
|
||||||
|
exit(sizeint(psrc^)-sizeint(pdest^));
|
||||||
result:=0;
|
result:=0;
|
||||||
end;
|
end;
|
||||||
{$endif not FPC_SYSTEM_HAS_COMPAREBYTE}
|
{$endif not FPC_SYSTEM_HAS_COMPAREBYTE}
|
||||||
|
Loading…
Reference in New Issue
Block a user