* patch by Rika: improve ctuils.newalign/align, part of #39496

This commit is contained in:
florian 2021-12-23 22:00:26 +01:00
parent b4c8c1da12
commit ab969e0a9b

View File

@ -293,13 +293,13 @@ implementation
function newalignment(oldalignment: longint; offset: int64): longint; function newalignment(oldalignment: longint; offset: int64): longint;
var
localoffset: longint;
begin begin
localoffset:=longint(offset); { oldalignment must be power of two.
while (localoffset mod oldalignment)<>0 do Works even for negative offsets (but not alignments),
oldalignment:=oldalignment div 2; as two's complement of, say, 2^4+2^3 is 11000 and -2^4-2^3 is 11...1101000 -
newalignment:=oldalignment; both end with exactly N zeros, where N is the largest power of two that divides the number
(smallest power of two involved in these sums). }
result:=1 shl BsfQWord(qword(offset or oldalignment));
end; end;
@ -340,50 +340,45 @@ implementation
function align(i,a:longint):longint;{$ifdef USEINLINE}inline;{$endif} function align(i,a:longint):longint;{$ifdef USEINLINE}inline;{$endif}
{ {
return value <i> aligned <a> boundary return value <i> aligned <a> boundary. <a> must be power of two.
} }
begin begin
{ for 0 and 1 no aligning is needed } { One-line formula for i >= 0 is
if a<=1 then >>> (i + a - 1) and not (a - 1),
result:=i and for i < 0 is
else >>> i and not (a - 1). }
begin
if i<0 then if a>0 then
result:=((i+1-a) div a) * a a:=a-1; { 'a' is decremented beforehand, this also allows a=0 as a synonym for a=1. }
else if i>=0 then
result:=((i-1+a) div a) * a; i:=i+a;
end; result:=i and not a;
end; end;
function align(i,a:int64):int64;{$ifdef USEINLINE}inline;{$endif} function align(i,a:int64):int64;{$ifdef USEINLINE}inline;{$endif}
{ {
return value <i> aligned <a> boundary return value <i> aligned <a> boundary. <a> must be power of two.
} }
begin begin
{ for 0 and 1 no aligning is needed } { Copy of 'longint' version. }
if a<=1 then if a>0 then
result:=i a:=a-1;
else if i>=0 then
begin i:=i+a;
if i<0 then result:=i and not a;
result:=((i+1-a) div a) * a
else
result:=((i-1+a) div a) * a;
end;
end; end;
function align(i,a:qword):qword;{$ifdef USEINLINE}inline;{$endif} function align(i,a:qword):qword;{$ifdef USEINLINE}inline;{$endif}
{ {
return value <i> aligned <a> boundary return value <i> aligned <a> boundary. <a> must be power of two.
} }
begin begin
{ for 0 and 1 no aligning is needed } { No i < 0 case here. }
if (a<=1) or (i=0) then if a>0 then
result:=i a:=a-1;
else result:=(i+a) and not a;
result:=((i-1+a) div a) * a;
end; end;