Browse Source

+ patch by J. Gareth Moreton: improved tests for constant divisions including benchmark,
second part of #38806

git-svn-id: trunk@49291 -

florian 4 years ago
parent
commit
dc13516dee
7 changed files with 2848 additions and 0 deletions
  1. 6 0
      .gitattributes
  2. 469 0
      tests/bench/bdiv.pp
  3. 208 0
      tests/bench/bdiv_s32.inc
  4. 772 0
      tests/bench/bdiv_s64.inc
  5. 769 0
      tests/bench/bdiv_u32.inc
  6. 621 0
      tests/bench/bdiv_u64.inc
  7. 3 0
      tests/test/cg/tmoddiv6.pp

+ 6 - 0
.gitattributes

@@ -12483,6 +12483,11 @@ tests/bench/bansi1.inc svneol=native#text/plain
 tests/bench/bansi1.pp svneol=native#text/plain
 tests/bench/bansi1.pp svneol=native#text/plain
 tests/bench/bansi1mt.pp svneol=native#text/plain
 tests/bench/bansi1mt.pp svneol=native#text/plain
 tests/bench/bcase.pp svneol=native#text/pascal
 tests/bench/bcase.pp svneol=native#text/pascal
+tests/bench/bdiv.pp svneol=native#text/pascal
+tests/bench/bdiv_s32.inc svneol=native#text/plain
+tests/bench/bdiv_s64.inc svneol=native#text/plain
+tests/bench/bdiv_u32.inc svneol=native#text/plain
+tests/bench/bdiv_u64.inc svneol=native#text/plain
 tests/bench/blists1.inc svneol=native#text/plain
 tests/bench/blists1.inc svneol=native#text/plain
 tests/bench/blists1.pp svneol=native#text/plain
 tests/bench/blists1.pp svneol=native#text/plain
 tests/bench/bmd5.pp svneol=native#text/plain
 tests/bench/bmd5.pp svneol=native#text/plain
@@ -14101,6 +14106,7 @@ tests/test/cg/tmoddiv2.pp svneol=native#text/plain
 tests/test/cg/tmoddiv3.pp svneol=native#text/pascal
 tests/test/cg/tmoddiv3.pp svneol=native#text/pascal
 tests/test/cg/tmoddiv4.pp svneol=native#text/pascal
 tests/test/cg/tmoddiv4.pp svneol=native#text/pascal
 tests/test/cg/tmoddiv5.pp svneol=native#text/pascal
 tests/test/cg/tmoddiv5.pp svneol=native#text/pascal
+tests/test/cg/tmoddiv6.pp svneol=native#text/pascal
 tests/test/cg/tmul3264.pp svneol=native#text/plain
 tests/test/cg/tmul3264.pp svneol=native#text/plain
 tests/test/cg/tneg.pp svneol=native#text/plain
 tests/test/cg/tneg.pp svneol=native#text/plain
 tests/test/cg/tnegnotassign1.pp svneol=native#text/plain
 tests/test/cg/tnegnotassign1.pp svneol=native#text/plain

+ 469 - 0
tests/bench/bdiv.pp

@@ -0,0 +1,469 @@
+{ %OPT=-O2 }
+program bdiv;
+
+{$mode objfpc}{$H+}
+
+uses
+  SysUtils;
+
+{ Utility functions }
+function GetRealTime(const st: TSystemTime): Real;
+  begin
+    Result := st.Hour*3600.0 + st.Minute*60.0 + st.Second + st.MilliSecond/1000.0;
+  end;
+
+{$push}
+{$warn 5057 off}
+function GetRealTime : Real;
+  var
+    st:TSystemTime;
+  begin
+    GetLocalTime(st);
+    result:=GetRealTime(st);
+  end;
+{$pop}
+
+const
+  ITERATIONS = 524288;
+  INTERNAL_LOOPS = 64;
+
+{ TTestAncestor }
+type
+  TTestAncestor = class
+    private
+      FStartTime: Real;
+      FEndTime: Real;
+      FAvgTime: Real;
+      procedure SetStartTime;
+      procedure SetEndTime;
+    protected
+      procedure DoTestIteration(Iteration: Integer); virtual; abstract;
+    public
+      constructor Create; virtual;
+      destructor Destroy; override;
+      procedure Run;
+      function TestTitle: shortstring; virtual; abstract;
+      function WriteResults: Boolean; virtual; abstract;
+      property RunTime: Real read FAvgTime;
+  end;
+
+  TTestClass = class of TTestAncestor;
+
+  TUInt32DivTest = class(TTestAncestor)
+    protected
+      FInputArray: array[$00..$FF] of Cardinal;
+      FResultArray: array[$00..$FF] of Cardinal;
+      function GetDivisor: Cardinal; virtual; abstract;
+      function DoVariableDiv(Numerator: Cardinal): Cardinal; inline;
+    public
+      function WriteResults: Boolean; override;
+  end;
+
+  TUInt32ModTest = class(TUInt32DivTest)
+    protected
+      function DoVariableMod(Numerator: Cardinal): Cardinal; inline;
+    public
+      function WriteResults: Boolean; override;
+  end;
+
+  TSInt32DivTest = class(TTestAncestor)
+    protected
+      FInputArray: array[$00..$FF] of Integer;
+      FResultArray: array[$00..$FF] of Integer;
+      function GetDivisor: Integer; virtual; abstract;
+      function DoVariableDiv(Numerator: Integer): Integer; inline;
+    public
+      function WriteResults: Boolean; override;
+  end;
+
+  TSInt32ModTest = class(TSInt32DivTest)
+    protected
+      function DoVariableMod(Numerator: Integer): Integer; inline;
+    public
+      function WriteResults: Boolean; override;
+  end;
+
+  TUInt64DivTest = class(TTestAncestor)
+    protected
+      FInputArray: array[$00..$FF] of QWord;
+      FResultArray: array[$00..$FF] of QWord;
+      function GetDivisor: QWord; virtual; abstract;
+      function DoVariableDiv(Numerator: QWord): QWord; inline;
+    public
+      function WriteResults: Boolean; override;
+  end;
+
+  TUInt64ModTest = class(TUInt64DivTest)
+    protected
+      function DoVariableMod(Numerator: QWord): QWord; inline;
+    public
+      function WriteResults: Boolean; override;
+  end;
+
+  TSInt64DivTest = class(TTestAncestor)
+    protected
+      FInputArray: array[$00..$FF] of Int64;
+      FResultArray: array[$00..$FF] of Int64;
+      function GetDivisor: Int64; virtual; abstract;
+      function DoVariableDiv(Numerator: Int64): Int64; inline;
+    public
+      function WriteResults: Boolean; override;
+  end;
+
+  TSInt64ModTest = class(TSInt64DivTest)
+    protected
+      function DoVariableMod(Numerator: Int64): Int64; inline;
+    public
+      function WriteResults: Boolean; override;
+  end;
+
+{$I bdiv_u32.inc}
+{$I bdiv_u64.inc}
+{$I bdiv_s32.inc}
+{$I bdiv_s64.inc}
+
+{ TTestAncestor }
+
+constructor TTestAncestor.Create;
+  begin
+    FStartTime := 0;
+    FEndTime := 0;
+    FAvgTime := 0;
+  end;
+
+destructor TTestAncestor.Destroy;
+  begin
+    inherited Destroy;
+  end;
+
+procedure TTestAncestor.SetStartTime;
+  begin
+    FStartTime := GetRealTime();
+  end;
+
+procedure TTestAncestor.SetEndTime;
+  begin
+    FEndTime := GetRealTime();
+    if FEndTime < FStartTime then { Happens if the test runs past midnight }
+      FEndTime := FEndTime + 86400.0;
+  end;
+
+procedure TTestAncestor.Run;
+  var
+    X: Integer;
+  begin
+    SetStartTime;
+    for X := 0 to ITERATIONS - 1 do
+      DoTestIteration(X);
+
+    SetEndTime;
+
+    FAvgTime := FEndTime - FStartTime;
+  end;
+
+{ TUInt32DivTest }
+
+function TUInt32DivTest.DoVariableDiv(Numerator: Cardinal): Cardinal;
+  begin
+    Result := Numerator div GetDivisor;
+  end;
+
+function TUInt32DivTest.WriteResults: Boolean;
+  var
+    X: Integer;
+    Expected: Cardinal;
+  begin
+    Result := True;
+    for X := 0 to 255 do
+      begin
+        Expected := DoVariableDiv(FInputArray[X]);
+        if FResultArray[X] <> Expected then
+          begin
+            WriteLn('FAIL - ', FInputArray[X], ' div ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
+            Result := False;
+            Exit;
+          end;
+      end;
+  end;
+
+{ TUInt32ModTest }
+
+function TUInt32ModTest.DoVariableMod(Numerator: Cardinal): Cardinal;
+  begin
+    Result := Numerator mod GetDivisor;
+  end;
+
+function TUInt32ModTest.WriteResults: Boolean;
+  var
+    X: Integer;
+    Expected: Cardinal;
+  begin
+    Result := True;
+    for X := 0 to 255 do
+      begin
+        Expected := DoVariableMod(FInputArray[X]);
+        if FResultArray[X] <> Expected then
+          begin
+            WriteLn('FAIL - ', FInputArray[X], ' mod ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
+            Result := False;
+            Exit;
+          end;
+      end;
+  end;
+
+{ TSInt32DivTest }
+
+function TSInt32DivTest.DoVariableDiv(Numerator: Integer): Integer;
+  begin
+    Result := Numerator div GetDivisor;
+  end;
+
+function TSInt32DivTest.WriteResults: Boolean;
+  var
+    X: Integer;
+    Expected: Integer;
+  begin
+    Result := True;
+    for X := 0 to 255 do
+      begin
+        Expected := DoVariableDiv(FInputArray[X]);
+        if FResultArray[X] <> Expected then
+          begin
+            WriteLn('FAIL - ', FInputArray[X], ' div ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
+            Result := False;
+            Exit;
+          end;
+      end;
+  end;
+
+{ TSInt32ModTest }
+
+function TSInt32ModTest.DoVariableMod(Numerator: Integer): Integer;
+  begin
+    Result := Numerator mod GetDivisor;
+  end;
+
+function TSInt32ModTest.WriteResults: Boolean;
+  var
+    X: Integer;
+    Expected: Integer;
+  begin
+    Result := True;
+    for X := 0 to 255 do
+      begin
+        Expected := DoVariableMod(FInputArray[X]);
+        if FResultArray[X] <> Expected then
+          begin
+            WriteLn('FAIL - ', FInputArray[X], ' mod ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
+            Result := False;
+            Exit;
+          end;
+      end;
+  end;
+
+{ TUInt64DivTest }
+
+function TUInt64DivTest.DoVariableDiv(Numerator: QWord): QWord;
+  begin
+    Result := Numerator div GetDivisor;
+  end;
+
+function TUInt64DivTest.WriteResults: Boolean;
+  var
+    X: Integer;
+    Expected: QWord;
+  begin
+    Result := True;
+    for X := 0 to 255 do
+      begin
+        Expected := DoVariableDiv(FInputArray[X]);
+        if FResultArray[X] <> Expected then
+          begin
+            WriteLn('FAIL - ', FInputArray[X], ' div ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
+            Result := False;
+            Exit;
+          end;
+      end;
+  end;
+
+{ TUInt64ModTest }
+
+function TUInt64ModTest.DoVariableMod(Numerator: QWord): QWord;
+  begin
+    Result := Numerator mod GetDivisor;
+  end;
+
+function TUInt64ModTest.WriteResults: Boolean;
+  var
+    X: Integer;
+    Expected: QWord;
+  begin
+    Result := True;
+    for X := 0 to 255 do
+      begin
+        Expected := DoVariableMod(FInputArray[X]);
+        if FResultArray[X] <> Expected then
+          begin
+            WriteLn('FAIL - ', FInputArray[X], ' mod ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
+            Result := False;
+            Exit;
+          end;
+      end;
+  end;
+
+{ TSInt64DivTest }
+
+function TSInt64DivTest.DoVariableDiv(Numerator: Int64): Int64;
+  begin
+    Result := Numerator div GetDivisor;
+  end;
+
+function TSInt64DivTest.WriteResults: Boolean;
+  var
+    X: Integer;
+    Expected: Int64;
+  begin
+    Result := True;
+    for X := 0 to 255 do
+      begin
+        Expected := DoVariableDiv(FInputArray[X]);
+        if FResultArray[X] <> Expected then
+          begin
+            WriteLn('FAIL - ', FInputArray[X], ' div ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
+            Result := False;
+            Exit;
+          end;
+      end;
+  end;
+
+{ TSInt64ModTest }
+
+function TSInt64ModTest.DoVariableMod(Numerator: Int64): Int64;
+  begin
+    Result := Numerator mod GetDivisor;
+  end;
+
+function TSInt64ModTest.WriteResults: Boolean;
+  var
+    X: Integer;
+    Expected: Int64;
+  begin
+    Result := True;
+    for X := 0 to 255 do
+      begin
+        Expected := DoVariableMod(FInputArray[X]);
+        if FResultArray[X] <> Expected then
+          begin
+            WriteLn('FAIL - ', FInputArray[X], ' mod ', GetDivisor, '; expected ', Expected, ' got ', FResultArray[X]);
+            Result := False;
+            Exit;
+          end;
+      end;
+  end;
+
+{ Main function }
+const
+  TestClasses: array[0..53] of TTestClass = (
+    TUInt32Bit1Test,
+    TUInt32Bit1ModTest,
+    TUInt32Bit2Test,
+    TUInt32Bit2ModTest,
+    TUInt32Bit3Test,
+    TUInt32Bit3ModTest,
+    TUInt32Bit10Test,
+    TUInt32Bit10ModTest,
+    TUInt32Bit100Test,
+    TUInt32Bit100ModTest,
+    TUInt32Bit1000Test,
+    TUInt32Bit1000ModTest,
+    TUInt32Bit60000Test,
+    TUInt32Bit60000ModTest,
+    TUInt32Bit146097Test,
+    TUInt32Bit146097ModTest,
+    TUInt32Bit3600000Test,
+    TUInt32Bit3600000ModTest,
+    TUInt64Bit1Test,
+    TUInt64Bit1ModTest,
+    TUInt64Bit2Test,
+    TUInt64Bit2ModTest,
+    TUInt64Bit3Test,
+    TUInt64Bit3ModTest,
+    TUInt64Bit5Test,
+    TUInt64Bit5ModTest,
+    TUInt64Bit10Test,
+    TUInt64Bit10ModTest,
+    TUInt64Bit100Test,
+    TUInt64Bit100ModTest,
+    TUInt64Bit1000000000Test,
+    TUInt64Bit1000000000ModTest,
+    TSInt32Bit1Test,
+    TSInt32Bit1ModTest,
+    TSInt32Bit100Test,
+    TSInt32Bit100ModTest,
+    TSInt64Bit1Test,
+    TSInt64Bit1ModTest,
+    TSInt64Bit10Test,
+    TSInt64Bit10ModTest,
+    TSInt64Bit18Test,
+    TSInt64Bit18ModTest,
+    TSInt64Bit24Test,
+    TSInt64Bit24ModTest,
+    TSInt64Bit100Test,
+    TSInt64Bit100ModTest,
+    TSInt64Bit153Test,
+    TSInt64Bit153ModTest,
+    TSInt64Bit1461Test,
+    TSInt64Bit1461ModTest,
+    TSInt64Bit10000Test,
+    TSInt64Bit10000ModTest,
+    TSInt64Bit86400000Test,
+    TSInt64Bit86400000ModTest
+  );
+
+var
+  CurrentObject: TTestAncestor;
+  Failed: Boolean;
+  X: Integer;
+  SummedUpAverageDuration, AverageDuration : Double;
+begin
+  SummedUpAverageDuration := 0.0;
+  Failed := False;
+  WriteLn('Division compilation and timing test (using constants from System and Sysutils)');
+  WriteLn('-------------------------------------------------------------------------------');
+  for X := Low(TestClasses) to High(TestClasses) do
+    begin
+      try
+        CurrentObject := TestClasses[X].Create;
+        try
+          Write(CurrentObject.TestTitle:43, ' - ');
+          CurrentObject.Run;
+
+          if CurrentObject.WriteResults then
+            begin
+              AverageDuration := ((CurrentObject.RunTime * 1000000000.0) / (ITERATIONS * INTERNAL_LOOPS));
+              WriteLn('Pass - average iteration duration: ', AverageDuration:1:3, ' ns');
+              SummedUpAverageDuration := SummedUpAverageDuration + AverageDuration;
+            end
+          else
+            { Final average isn't processed if a test failed, so there's no need
+              to calculate and add the average duration to it }
+            Failed := True;
+
+        finally
+          CurrentObject.Free;
+        end;
+      except on E: Exception do
+        begin
+          WriteLn('Exception "', E.ClassName, '" raised while running test object of class "', TestClasses[X].ClassName, '"');
+          Failed := True;
+        end;
+      end;
+    end;
+
+  if Failed then
+    Halt(1);
+
+  WriteLn(#10'ok');
+  WriteLn('- Sum of average durations: ', SummedUpAverageDuration:1:3, ' ns');
+  WriteLn('- Overall average duration: ', (SummedUpAverageDuration / Length(TestClasses)):1:3, ' ns');
+end.

+ 208 - 0
tests/bench/bdiv_s32.inc

@@ -0,0 +1,208 @@
+type
+  { TSInt32Bit1Test }
+
+  TSInt32Bit1Test = class(TSInt32DivTest)
+    protected
+      function GetDivisor: Integer; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt32Bit1ModTest }
+
+  TSInt32Bit1ModTest = class(TSInt32ModTest)
+    protected
+      function GetDivisor: Integer; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt32Bit100Test }
+
+  TSInt32Bit100Test = class(TSInt32DivTest)
+    protected
+      function GetDivisor: Integer; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt32Bit100ModTest }
+
+  TSInt32Bit100ModTest = class(TSInt32ModTest)
+    protected
+      function GetDivisor: Integer; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+{ TSInt32Bit1Test }
+
+function TSInt32Bit1Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 32-bit division by 1';
+  end;
+
+function TSInt32Bit1Test.GetDivisor: Integer;
+  begin
+    Result := 1;
+  end;
+
+procedure TSInt32Bit1Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Integer;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := -2147483648;
+      1:
+        Numerator := -2147483600;
+      2:
+        Numerator := -2147483599;
+      253:
+        Numerator := 2147483599;
+      254:
+        Numerator := 2147483600;
+      255:
+        Numerator := 2147483647;
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 1;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt32Bit1ModTest }
+
+function TSInt32Bit1ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 32-bit modulus by 1';
+  end;
+
+function TSInt32Bit1ModTest.GetDivisor: Integer;
+  begin
+    Result := 1;
+  end;
+
+procedure TSInt32Bit1ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Integer;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := -2147483648;
+      1:
+        Numerator := -2147483600;
+      2:
+        Numerator := -2147483599;
+      253:
+        Numerator := 2147483599;
+      254:
+        Numerator := 2147483600;
+      255:
+        Numerator := 2147483647;
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 1;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt32Bit100Test }
+
+function TSInt32Bit100Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 32-bit division by 100';
+  end;
+
+function TSInt32Bit100Test.GetDivisor: Integer;
+  begin
+    Result := 100;
+  end;
+
+procedure TSInt32Bit100Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Integer;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := -2147483648;
+      1:
+        Numerator := -2147483600;
+      2:
+        Numerator := -2147483599;
+      253:
+        Numerator := 2147483599;
+      254:
+        Numerator := 2147483600;
+      255:
+        Numerator := 2147483647;
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 100;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt32Bit100ModTest }
+
+function TSInt32Bit100ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 32-bit modulus by 100';
+  end;
+
+function TSInt32Bit100ModTest.GetDivisor: Integer;
+  begin
+    Result := 100;
+  end;
+
+procedure TSInt32Bit100ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Integer;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := -2147483648;
+      1:
+        Numerator := -2147483600;
+      2:
+        Numerator := -2147483599;
+      253:
+        Numerator := 2147483599;
+      254:
+        Numerator := 2147483600;
+      255:
+        Numerator := 2147483647;
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 100;
+      
+    FResultArray[Index] := Answer;
+  end;

+ 772 - 0
tests/bench/bdiv_s64.inc

@@ -0,0 +1,772 @@
+type
+  { TSInt64Bit1Test }
+
+  TSInt64Bit1Test = class(TSInt64DivTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit1ModTest }
+
+  TSInt64Bit1ModTest = class(TSInt64ModTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit10Test }
+
+  TSInt64Bit10Test = class(TSInt64DivTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit10ModTest }
+
+  TSInt64Bit10ModTest = class(TSInt64ModTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit18Test }
+
+  TSInt64Bit18Test = class(TSInt64DivTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit18ModTest }
+
+  TSInt64Bit18ModTest = class(TSInt64ModTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit24Test }
+
+  TSInt64Bit24Test = class(TSInt64DivTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit24ModTest }
+
+  TSInt64Bit24ModTest = class(TSInt64ModTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit100Test }
+
+  TSInt64Bit100Test = class(TSInt64DivTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit100ModTest }
+
+  TSInt64Bit100ModTest = class(TSInt64ModTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit153Test }
+const
+  FS64_153Input: array[$0..$F] of Int64 =
+    (0, 1, 152, 153, 154, -1, -152, -153, -154,
+    8000000000000000117, 8000000000000000118, 8000000000000000119, 
+    -8000000000000000117, -8000000000000000118, -8000000000000000119,
+    Int64($8000000000000000));
+
+type
+  TSInt64Bit153Test = class(TSInt64DivTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit153ModTest }
+
+  TSInt64Bit153ModTest = class(TSInt64ModTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit1461Test }
+const
+  FS64_1461Input: array[$0..$F] of Int64 =
+    (0, 1, 1460, 1461, 1462, -1, -1460, -1461, -1462,
+    8000000000000000582, 8000000000000000583, 8000000000000000584, 
+    -8000000000000000582, -8000000000000000583, -8000000000000000584,
+    Int64($8000000000000000));
+
+type
+  TSInt64Bit1461Test = class(TSInt64DivTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit1461ModTest }
+
+  TSInt64Bit1461ModTest = class(TSInt64ModTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit10000Test }
+const
+  FS64_10000Input: array[$0..$F] of Int64 =
+    (0, 1, 9999, 10000, 10001, -1, -9999, -10000, -10001,
+    7999999999999999999, 8000000000000000000, 8000000000000000001, 
+    -7999999999999999999, -8000000000000000000, -8000000000000000001,
+    Int64($8000000000000000));
+
+type
+  TSInt64Bit10000Test = class(TSInt64DivTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit10000ModTest }
+
+  TSInt64Bit10000ModTest = class(TSInt64ModTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+  
+  { TSInt64Bit86400000Test }
+const
+  FS64_86400000Input: array[$0..$F] of Int64 =
+    (0, 1, 86399999, 86400000, 86400001, -1, -86399999, -86400000, -86400001,
+    8639999999999999999, 8640000000000000000, 8640000000000000001, 
+    -8639999999999999999, -8640000000000000000, -8640000000000000001,
+    Int64($8000000000000000));
+
+type
+  TSInt64Bit86400000Test = class(TSInt64DivTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TSInt64Bit86400000ModTest }
+
+  TSInt64Bit86400000ModTest = class(TSInt64ModTest)
+    protected
+      function GetDivisor: Int64; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+{ TSInt64Bit1Test }
+
+function TSInt64Bit1Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit division by 1';
+  end;
+
+function TSInt64Bit1Test.GetDivisor: Int64;
+  begin
+    Result := 1;
+  end;
+
+procedure TSInt64Bit1Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := Int64($8000000000000000);
+      1:
+        Numerator := Int64($8000000000000006);
+      2:
+        Numerator := Int64($8000000000000007);
+      253:
+        Numerator := Int64($7FFFFFFFFFFFFFF9);
+      254:
+        Numerator := Int64($7FFFFFFFFFFFFFFA);
+      255:
+        Numerator := Int64($7FFFFFFFFFFFFFFF);
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 1;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit1ModTest }
+
+function TSInt64Bit1ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit modulus by 1';
+  end;
+
+function TSInt64Bit1ModTest.GetDivisor: Int64;
+  begin
+    Result := 1;
+  end;
+
+procedure TSInt64Bit1ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := Int64($8000000000000000);
+      1:
+        Numerator := Int64($8000000000000006);
+      2:
+        Numerator := Int64($8000000000000007);
+      253:
+        Numerator := Int64($7FFFFFFFFFFFFFF9);
+      254:
+        Numerator := Int64($7FFFFFFFFFFFFFFA);
+      255:
+        Numerator := Int64($7FFFFFFFFFFFFFFF);
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 1;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit10Test }
+
+function TSInt64Bit10Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit division by 10';
+  end;
+
+function TSInt64Bit10Test.GetDivisor: Int64;
+  begin
+    Result := 10;
+  end;
+
+procedure TSInt64Bit10Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := Int64($8000000000000000);
+      1:
+        Numerator := Int64($8000000000000006);
+      2:
+        Numerator := Int64($8000000000000007);
+      253:
+        Numerator := Int64($7FFFFFFFFFFFFFF9);
+      254:
+        Numerator := Int64($7FFFFFFFFFFFFFFA);
+      255:
+        Numerator := Int64($7FFFFFFFFFFFFFFF);
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 10;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit10ModTest }
+
+function TSInt64Bit10ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit modulus by 10';
+  end;
+
+function TSInt64Bit10ModTest.GetDivisor: Int64;
+  begin
+    Result := 10;
+  end;
+
+procedure TSInt64Bit10ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := Int64($8000000000000000);
+      1:
+        Numerator := Int64($8000000000000006);
+      2:
+        Numerator := Int64($8000000000000007);
+      253:
+        Numerator := Int64($7FFFFFFFFFFFFFF9);
+      254:
+        Numerator := Int64($7FFFFFFFFFFFFFFA);
+      255:
+        Numerator := Int64($7FFFFFFFFFFFFFFF);
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 10;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit18Test }
+
+function TSInt64Bit18Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit division by 18';
+  end;
+
+function TSInt64Bit18Test.GetDivisor: Int64;
+  begin
+    Result := 18;
+  end;
+
+procedure TSInt64Bit18Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := Index - 128;
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 18;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit18ModTest }
+
+function TSInt64Bit18ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit modulus by 18';
+  end;
+
+function TSInt64Bit18ModTest.GetDivisor: Int64;
+  begin
+    Result := 18;
+  end;
+
+procedure TSInt64Bit18ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := Index - 128;
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 18;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit24Test }
+
+function TSInt64Bit24Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit division by 24';
+  end;
+
+function TSInt64Bit24Test.GetDivisor: Int64;
+  begin
+    Result := 24;
+  end;
+
+procedure TSInt64Bit24Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := Index - 128;
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 24;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit24ModTest }
+
+function TSInt64Bit24ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit modulus by 24';
+  end;
+
+function TSInt64Bit24ModTest.GetDivisor: Int64;
+  begin
+    Result := 24;
+  end;
+
+procedure TSInt64Bit24ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := Index - 128;
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 24;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit100Test }
+
+function TSInt64Bit100Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit division by 100';
+  end;
+
+function TSInt64Bit100Test.GetDivisor: Int64;
+  begin
+    Result := 100;
+  end;
+
+procedure TSInt64Bit100Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := Int64($8000000000000000);
+      1:
+        Numerator := Int64($8000000000000008);
+      2:
+        Numerator := Int64($8000000000000009);
+      253:
+        Numerator := Int64($7FFFFFFFFFFFFFF7);
+      254:
+        Numerator := Int64($7FFFFFFFFFFFFFF8);
+      255:
+        Numerator := Int64($7FFFFFFFFFFFFFFF);
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 100;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit100ModTest }
+
+function TSInt64Bit100ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit modulus by 100';
+  end;
+
+function TSInt64Bit100ModTest.GetDivisor: Int64;
+  begin
+    Result := 100;
+  end;
+
+procedure TSInt64Bit100ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      0:
+        Numerator := Int64($8000000000000000);
+      1:
+        Numerator := Int64($8000000000000008);
+      2:
+        Numerator := Int64($8000000000000009);
+      253:
+        Numerator := Int64($7FFFFFFFFFFFFFF7);
+      254:
+        Numerator := Int64($7FFFFFFFFFFFFFF8);
+      255:
+        Numerator := Int64($7FFFFFFFFFFFFFFF);
+      else
+        Numerator := Index - 128;
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 100;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit153Test }
+
+function TSInt64Bit153Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit division by 153';
+  end;
+
+function TSInt64Bit153Test.GetDivisor: Int64;
+  begin
+    Result := 153;
+  end;
+
+procedure TSInt64Bit153Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FS64_153Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 153;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit153ModTest }
+
+function TSInt64Bit153ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit modulus by 153';
+  end;
+
+function TSInt64Bit153ModTest.GetDivisor: Int64;
+  begin
+    Result := 153;
+  end;
+
+procedure TSInt64Bit153ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FS64_153Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 153;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit1461Test }
+
+function TSInt64Bit1461Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit division by 1,461';
+  end;
+
+function TSInt64Bit1461Test.GetDivisor: Int64;
+  begin
+    Result := 1461;
+  end;
+
+procedure TSInt64Bit1461Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FS64_1461Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 1461;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit1461ModTest }
+
+function TSInt64Bit1461ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit modulus by 1,461';
+  end;
+
+function TSInt64Bit1461ModTest.GetDivisor: Int64;
+  begin
+    Result := 1461;
+  end;
+
+procedure TSInt64Bit1461ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FS64_1461Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 1461;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit10000Test }
+
+function TSInt64Bit10000Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit division by 10,000 (Currency)';
+  end;
+
+function TSInt64Bit10000Test.GetDivisor: Int64;
+  begin
+    Result := 10000;
+  end;
+
+procedure TSInt64Bit10000Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FS64_10000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 10000;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit10000ModTest }
+
+function TSInt64Bit10000ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit modulus by 10,000 (Currency)';
+  end;
+
+function TSInt64Bit10000ModTest.GetDivisor: Int64;
+  begin
+    Result := 10000;
+  end;
+
+procedure TSInt64Bit10000ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FS64_10000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 10000;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit86400000Test }
+
+function TSInt64Bit86400000Test.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit division by 86,400,000';
+  end;
+
+function TSInt64Bit86400000Test.GetDivisor: Int64;
+  begin
+    Result := 86400000;
+  end;
+
+procedure TSInt64Bit86400000Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FS64_86400000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 86400000;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TSInt64Bit86400000ModTest }
+
+function TSInt64Bit86400000ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Signed 64-bit modulus by 86,400,000';
+  end;
+
+function TSInt64Bit86400000ModTest.GetDivisor: Int64;
+  begin
+    Result := 86400000;
+  end;
+
+procedure TSInt64Bit86400000ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Int64;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FS64_86400000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 86400000;
+      
+    FResultArray[Index] := Answer;
+  end;

+ 769 - 0
tests/bench/bdiv_u32.inc

@@ -0,0 +1,769 @@
+type
+  { TUInt32Bit1Test }
+
+  TUInt32Bit1Test = class(TUInt32DivTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit1ModTest }
+
+  TUInt32Bit1ModTest = class(TUInt32ModTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit2Test }
+
+  TUInt32Bit2Test = class(TUInt32DivTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit2ModTest }
+
+  TUInt32Bit2ModTest = class(TUInt32ModTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit3Test }
+
+  TUInt32Bit3Test = class(TUInt32DivTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit3ModTest }
+
+  TUInt32Bit3ModTest = class(TUInt32ModTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit10Test }
+
+  TUInt32Bit10Test = class(TUInt32DivTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit10ModTest }
+
+  TUInt32Bit10ModTest = class(TUInt32ModTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit100Test }
+
+  TUInt32Bit100Test = class(TUInt32DivTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit100ModTest }
+
+  TUInt32Bit100ModTest = class(TUInt32ModTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit1000Test }
+const
+  FU32_1000Input: array[$0..$F] of Cardinal =
+    (0, 1, 999, 1000, 1001, 1999, 2000, 2001,
+    4294958999, 4294959000, 4294959001,
+    $7FFFFFFE, $7FFFFFFF, $80000000, $80000001, $FFFFFFFF);
+
+type
+  TUInt32Bit1000Test = class(TUInt32DivTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit1000ModTest }
+
+  TUInt32Bit1000ModTest = class(TUInt32ModTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit60000Test }
+const
+  FU32_60000Input: array[$0..$F] of Cardinal =
+    (0, 1, 59999, 60000, 60001, 119999, 120000, 120001,
+    4294919999, 4294920000, 4294920001,
+    $7FFFFFFE, $7FFFFFFF, $80000000, $80000001, $FFFFFFFF);
+
+type
+  TUInt32Bit60000Test = class(TUInt32DivTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit60000ModTest }
+
+  TUInt32Bit60000ModTest = class(TUInt32ModTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit146097Test }
+const
+  FU32_146097Input: array[$0..$F] of Cardinal =
+    (0, 1, 146096, 146097, 146098, 292193, 292194, 292195,
+    4294959605, 4294959606, 4294959607,    
+    $7FFFFFFE, $7FFFFFFF, $80000000, $80000001, $FFFFFFFF);
+
+type
+  TUInt32Bit146097Test = class(TUInt32DivTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit146097ModTest }
+
+  TUInt32Bit146097ModTest = class(TUInt32ModTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+  
+  { TUInt32Bit3600000Test }
+const
+  FU32_3600000Input: array[$0..$F] of Cardinal =
+    (0, 1, 3599999, 3600000, 3600001, 7199999, 7200000, 7200001,
+    3600000000, 4294799999, 4294800000, 4294800001,
+    $7FFFFFFF, $80000000, $80000001, $FFFFFFFF);
+
+type
+  TUInt32Bit3600000Test = class(TUInt32DivTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt32Bit3600000ModTest }
+
+  TUInt32Bit3600000ModTest = class(TUInt32ModTest)
+    protected
+      function GetDivisor: Cardinal; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+
+{ TUInt32Bit1Test }
+
+function TUInt32Bit1Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit division by 1';
+  end;
+
+function TUInt32Bit1Test.GetDivisor: Cardinal;
+  begin
+    Result := 1;
+  end;
+
+procedure TUInt32Bit1Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := 4294967293;
+      254:
+        Numerator := 4294967294;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 1;
+
+    FResultArray[Index] := Answer;
+  end;
+  
+{ TUInt32Bit1Test }
+
+function TUInt32Bit1ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit modulus by 1';
+  end;
+
+function TUInt32Bit1ModTest.GetDivisor: Cardinal;
+  begin
+    Result := 1;
+  end;
+
+procedure TUInt32Bit1ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := 4294967293;
+      254:
+        Numerator := 4294967294;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 1;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit2Test }
+
+function TUInt32Bit2Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit division by 2';
+  end;
+
+function TUInt32Bit2Test.GetDivisor: Cardinal;
+  begin
+    Result := 2;
+  end;
+
+procedure TUInt32Bit2Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := 4294967293;
+      254:
+        Numerator := 4294967294;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 2;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit2ModTest }
+
+function TUInt32Bit2ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit modulus by 2';
+  end;
+
+function TUInt32Bit2ModTest.GetDivisor: Cardinal;
+  begin
+    Result := 2;
+  end;
+
+procedure TUInt32Bit2ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := 4294967293;
+      254:
+        Numerator := 4294967294;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 2;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit3Test }
+
+function TUInt32Bit3Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit division by 3';
+  end;
+
+function TUInt32Bit3Test.GetDivisor: Cardinal;
+  begin
+    Result := 3;
+  end;
+
+procedure TUInt32Bit3Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      254:
+        Numerator := 4294967294;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 3;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit3ModTest }
+
+function TUInt32Bit3ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit modulus by 3';
+  end;
+
+function TUInt32Bit3ModTest.GetDivisor: Cardinal;
+  begin
+    Result := 3;
+  end;
+
+procedure TUInt32Bit3ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      254:
+        Numerator := 4294967294;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 3;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit10Test }
+
+function TUInt32Bit10Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit division by 10';
+  end;
+
+function TUInt32Bit10Test.GetDivisor: Cardinal;
+  begin
+    Result := 10;
+  end;
+
+procedure TUInt32Bit10Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := 4294967289;
+      254:
+        Numerator := 4294967290;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 10;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit10ModTest }
+
+function TUInt32Bit10ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit modulus by 10';
+  end;
+
+function TUInt32Bit10ModTest.GetDivisor: Cardinal;
+  begin
+    Result := 10;
+  end;
+
+procedure TUInt32Bit10ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := 4294967289;
+      254:
+        Numerator := 4294967290;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 10;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit100Test }
+
+function TUInt32Bit100Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit division by 100';
+  end;
+
+function TUInt32Bit100Test.GetDivisor: Cardinal;
+  begin
+    Result := 100;
+  end;
+
+procedure TUInt32Bit100Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := 4294967199;
+      254:
+        Numerator := 4294967200;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 100;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit100ModTest }
+
+function TUInt32Bit100ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit modulus by 100';
+  end;
+
+function TUInt32Bit100ModTest.GetDivisor: Cardinal;
+  begin
+    Result := 100;
+  end;
+
+procedure TUInt32Bit100ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := 4294967199;
+      254:
+        Numerator := 4294967200;
+      255:
+        Numerator := 4294967295;
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 100;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit1000Test }
+
+function TUInt32Bit1000Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit division by 1,000';
+  end;
+
+function TUInt32Bit1000Test.GetDivisor: Cardinal;
+  begin
+    Result := 1000;
+  end;
+
+procedure TUInt32Bit1000Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU32_1000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 1000;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit1000ModTest }
+
+function TUInt32Bit1000ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit modulus by 1,000';
+  end;
+
+function TUInt32Bit1000ModTest.GetDivisor: Cardinal;
+  begin
+    Result := 1000;
+  end;
+
+procedure TUInt32Bit1000ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU32_1000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 1000;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit60000Test }
+
+function TUInt32Bit60000Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit division by 60,000';
+  end;
+
+function TUInt32Bit60000Test.GetDivisor: Cardinal;
+  begin
+    Result := 60000;
+  end;
+
+procedure TUInt32Bit60000Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU32_60000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 60000;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit60000ModTest }
+
+function TUInt32Bit60000ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit modulus by 60,000';
+  end;
+
+function TUInt32Bit60000ModTest.GetDivisor: Cardinal;
+  begin
+    Result := 60000;
+  end;
+
+procedure TUInt32Bit60000ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU32_60000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 60000;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit146097Test }
+
+function TUInt32Bit146097Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit division by 146,097';
+  end;
+
+function TUInt32Bit146097Test.GetDivisor: Cardinal;
+  begin
+    Result := 146097;
+  end;
+
+procedure TUInt32Bit146097Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU32_146097Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 146097;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit146097ModTest }
+
+function TUInt32Bit146097ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit modulus by 146,097';
+  end;
+
+function TUInt32Bit146097ModTest.GetDivisor: Cardinal;
+  begin
+    Result := 146097;
+  end;
+
+procedure TUInt32Bit146097ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU32_146097Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 146097;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit3600000Test }
+
+function TUInt32Bit3600000Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit division by 3,600,000';
+  end;
+
+function TUInt32Bit3600000Test.GetDivisor: Cardinal;
+  begin
+    Result := 3600000;
+  end;
+
+procedure TUInt32Bit3600000Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU32_3600000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 3600000;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt32Bit3600000ModTest }
+
+function TUInt32Bit3600000ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 32-bit modulus by 3,600,000';
+  end;
+
+function TUInt32Bit3600000ModTest.GetDivisor: Cardinal;
+  begin
+    Result := 3600000;
+  end;
+
+procedure TUInt32Bit3600000ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: Cardinal;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU32_3600000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 3600000;
+
+    FResultArray[Index] := Answer;
+  end;

+ 621 - 0
tests/bench/bdiv_u64.inc

@@ -0,0 +1,621 @@
+type
+  { TUInt64Bit1Test }
+
+  TUInt64Bit1Test = class(TUInt64DivTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit1ModTest }
+
+  TUInt64Bit1ModTest = class(TUInt64ModTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit2Test }
+
+  TUInt64Bit2Test = class(TUInt64DivTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit2ModTest }
+
+  TUInt64Bit2ModTest = class(TUInt64ModTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit3Test }
+
+  TUInt64Bit3Test = class(TUInt64DivTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit3ModTest }
+
+  TUInt64Bit3ModTest = class(TUInt64ModTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit5Test }
+
+  TUInt64Bit5Test = class(TUInt64DivTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit5ModTest }
+
+  TUInt64Bit5ModTest = class(TUInt64ModTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit10Test }
+
+  TUInt64Bit10Test = class(TUInt64DivTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit10ModTest }
+
+  TUInt64Bit10ModTest = class(TUInt64ModTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit100Test }
+
+  TUInt64Bit100Test = class(TUInt64DivTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit100ModTest }
+
+  TUInt64Bit100ModTest = class(TUInt64ModTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  { TUInt64Bit1000000000Test }
+const
+  FU64_1000000000Input: array[$0..$F] of QWord =
+    (0, 1, 999999999, 1000000000, 1000000001, 5000000000,
+    7999999999999999999, 8000000000000000000, 8000000000000000001,
+    QWord(15999999999999999999), QWord(16000000000000000000), QWord(16000000000000000001),
+    $7FFFFFFFFFFFFFFF, QWord($8000000000000000), QWord($8000000000000001), QWord($FFFFFFFFFFFFFFFF));
+
+type
+  TUInt64Bit1000000000Test = class(TUInt64DivTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+  TUInt64Bit1000000000ModTest = class(TUInt64ModTest)
+    protected
+      function GetDivisor: QWord; override;
+      procedure DoTestIteration(Iteration: Integer); override;
+    public
+      function TestTitle: shortstring; override;
+  end;
+
+{ TUInt64Bit1Test }
+
+function TUInt64Bit1Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit division by 1';
+  end;
+
+function TUInt64Bit1Test.GetDivisor: QWord;
+  begin
+    Result := 1;
+  end;
+
+procedure TUInt64Bit1Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := QWord($FFFFFFFFFFFFFFFD);
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFE);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 1;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit1ModTest }
+
+function TUInt64Bit1ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit modulus by 1';
+  end;
+
+function TUInt64Bit1ModTest.GetDivisor: QWord;
+  begin
+    Result := 1;
+  end;
+
+procedure TUInt64Bit1ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := QWord($FFFFFFFFFFFFFFFD);
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFE);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 1;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit2Test }
+
+function TUInt64Bit2Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit division by 2';
+  end;
+
+function TUInt64Bit2Test.GetDivisor: QWord;
+  begin
+    Result := 2;
+  end;
+
+procedure TUInt64Bit2Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := QWord($FFFFFFFFFFFFFFFD);
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFE);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 2;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit2ModTest }
+
+function TUInt64Bit2ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit modulus by 2';
+  end;
+
+function TUInt64Bit2ModTest.GetDivisor: QWord;
+  begin
+    Result := 2;
+  end;
+
+procedure TUInt64Bit2ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := QWord($FFFFFFFFFFFFFFFD);
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFE);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 2;
+
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit3Test }
+
+function TUInt64Bit3Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit division by 3';
+  end;
+
+function TUInt64Bit3Test.GetDivisor: QWord;
+  begin
+    Result := 3;
+  end;
+
+procedure TUInt64Bit3Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFE);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 3;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit3ModTest }
+
+function TUInt64Bit3ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit modulus by 3';
+  end;
+
+function TUInt64Bit3ModTest.GetDivisor: QWord;
+  begin
+    Result := 3;
+  end;
+
+procedure TUInt64Bit3ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFE);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 3;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit5Test }
+
+function TUInt64Bit5Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit division by 5';
+  end;
+
+function TUInt64Bit5Test.GetDivisor: QWord;
+  begin
+    Result := 5;
+  end;
+
+procedure TUInt64Bit5Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFE);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 5;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit5ModTest }
+
+function TUInt64Bit5ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit modulus by 5';
+  end;
+
+function TUInt64Bit5ModTest.GetDivisor: QWord;
+  begin
+    Result := 5;
+  end;
+
+procedure TUInt64Bit5ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFE);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 5;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit10Test }
+
+function TUInt64Bit10Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit division by 10';
+  end;
+
+function TUInt64Bit10Test.GetDivisor: QWord;
+  begin
+    Result := 10;
+  end;
+
+procedure TUInt64Bit10Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := QWord($FFFFFFFFFFFFFFF9);
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFA);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 10;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit10ModTest }
+
+function TUInt64Bit10ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit modulus by 10';
+  end;
+
+function TUInt64Bit10ModTest.GetDivisor: QWord;
+  begin
+    Result := 10;
+  end;
+
+procedure TUInt64Bit10ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := QWord($FFFFFFFFFFFFFFF9);
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFFA);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := QWord(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 10;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit100Test }
+
+function TUInt64Bit100Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit division by 100';
+  end;
+
+function TUInt64Bit100Test.GetDivisor: QWord;
+  begin
+    Result := 100;
+  end;
+
+procedure TUInt64Bit100Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := QWord($FFFFFFFFFFFFFFEF);
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFF0);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 100;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit100ModTest }
+
+function TUInt64Bit100ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit modulus by 100';
+  end;
+
+function TUInt64Bit100ModTest.GetDivisor: QWord;
+  begin
+    Result := 100;
+  end;
+
+procedure TUInt64Bit100ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    case Index of
+      253:
+        Numerator := QWord($FFFFFFFFFFFFFFEF);
+      254:
+        Numerator := QWord($FFFFFFFFFFFFFFF0);
+      255:
+        Numerator := QWord($FFFFFFFFFFFFFFFF);
+      else
+        Numerator := Cardinal(Index);
+    end;
+
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 100;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit1000000000Test }
+
+function TUInt64Bit1000000000Test.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit division by 1,000,000,000';
+  end;
+
+function TUInt64Bit1000000000Test.GetDivisor: QWord;
+  begin
+    Result := 1000000000;
+  end;
+
+procedure TUInt64Bit1000000000Test.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU64_1000000000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator div 1000000000;
+      
+    FResultArray[Index] := Answer;
+  end;
+
+{ TUInt64Bit1000000000ModTest }
+
+function TUInt64Bit1000000000ModTest.TestTitle: shortstring;
+  begin
+    Result := 'Unsigned 64-bit modulus by 1,000,000,000';
+  end;
+
+function TUInt64Bit1000000000ModTest.GetDivisor: QWord;
+  begin
+    Result := 1000000000;
+  end;
+
+procedure TUInt64Bit1000000000ModTest.DoTestIteration(Iteration: Integer);
+  var
+    Numerator, Answer: QWord;
+    Index, X: Integer;
+  begin
+    Index := Iteration and $FF;
+    Numerator := FU64_1000000000Input[Index and $F];
+    FInputArray[Index] := Numerator;
+    for X := 0 to INTERNAL_LOOPS - 1 do
+      Answer := Numerator mod 1000000000;
+      
+    FResultArray[Index] := Answer;
+  end;

+ 3 - 0
tests/test/cg/tmoddiv6.pp

@@ -0,0 +1,3 @@
+{ %OPT=-O2 }
+{ this benchmark can be used also as a test case }
+{$I ../../bench/bdiv.pp}