Explorar el Código

* patch by Rika: second part of #39496, resolves #30496
+ extended test

florian hace 3 años
padre
commit
781b2d0a80
Se han modificado 2 ficheros con 33 adiciones y 8 borrados
  1. 16 7
      rtl/inc/generic.inc
  2. 17 1
      tests/test/units/system/talign.pp

+ 16 - 7
rtl/inc/generic.inc

@@ -16,20 +16,29 @@
 
 
 function align(addr : PtrUInt;alignment : PtrUInt) : PtrUInt;{$ifdef SYSTEMINLINE}inline;{$endif}
 function align(addr : PtrUInt;alignment : PtrUInt) : PtrUInt;{$ifdef SYSTEMINLINE}inline;{$endif}
   var
   var
-    tmp: PtrUInt;
+    tmp,am1 : PtrUInt;
   begin
   begin
-    tmp:=addr+PtrUInt(alignment-1);
-    result:=tmp-(tmp mod alignment)
+    am1:=alignment-1;
+    tmp:=addr+am1;
+    if alignment and am1=0 then
+      { Alignment is a power of two. In practice alignments are powers of two 100% of the time. }
+      result:=tmp and not am1
+    else
+      result:=tmp-(tmp mod alignment);
   end;
   end;
 
 
 
 
 {$ifndef cpujvm}
 {$ifndef cpujvm}
 function align(addr : Pointer;alignment : PtrUInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
 function align(addr : Pointer;alignment : PtrUInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
   var
   var
-    tmp: PtrUInt;
-  begin
-    tmp:=PtrUInt(addr)+(alignment-1);
-    result:=pointer(ptruint(tmp-(tmp mod alignment)));
+    tmp,am1 : PtrUInt;
+  begin
+    am1:=alignment-1;
+    tmp:=PtrUint(addr)+am1;
+    if alignment and am1=0 then
+      result:=pointer(tmp and not am1)
+    else
+      result:=pointer(ptruint(tmp-(tmp mod alignment)));
   end;
   end;
 {$endif}
 {$endif}
 
 

+ 17 - 1
tests/test/units/system/talign.pp

@@ -11,13 +11,29 @@ begin
   for i:=0 to 39 do
   for i:=0 to 39 do
     if align(p+i,40)<>pointer(80) then
     if align(p+i,40)<>pointer(80) then
       halt(2);
       halt(2);
+  p:=pointer(1);
+  for i:=0 to 40 do
+    if align(p+i,41)<pointer(41) then
+      halt(3);
+  p:=pointer(42);
+  for i:=0 to 40 do
+    if align(p+i,41)<>pointer(82) then
+      halt(4);
 
 
   u:=1;
   u:=1;
   for i:=0 to 15 do
   for i:=0 to 15 do
     if align(u+i,16)<>16 then
     if align(u+i,16)<>16 then
-      halt(3);
+      halt(101);
   u:=41;
   u:=41;
   for i:=0 to 39 do
   for i:=0 to 39 do
     if align(u+i,40)<>80 then
     if align(u+i,40)<>80 then
+      halt(102);
+  u:=1;
+  for i:=0 to 40 do
+    if align(u+i,41)<>41 then
+      halt(103);
+  u:=42;
+  for i:=0 to 40 do
+    if align(u+i,41)<>82 then
       halt(4);
       halt(4);
 end.
 end.