Browse Source

* synchronized with trunk

git-svn-id: branches/wasm@46956 -
nickysn 4 years ago
parent
commit
ca239b4e21

+ 2 - 1
.gitattributes

@@ -12308,7 +12308,6 @@ rtl/z80/stringss.inc svneol=native#text/plain
 rtl/z80/z80.inc svneol=native#text/plain
 rtl/zxspectrum/Makefile svneol=native#text/plain
 rtl/zxspectrum/Makefile.fpc svneol=native#text/plain
-rtl/zxspectrum/prt0.asm svneol=native#text/plain
 rtl/zxspectrum/rtldefs.inc svneol=native#text/plain
 rtl/zxspectrum/si_prc.pp svneol=native#text/plain
 rtl/zxspectrum/sysdir.inc svneol=native#text/plain
@@ -13391,6 +13390,7 @@ tests/tbs/tb0674.pp svneol=native#text/pascal
 tests/tbs/tb0675.pp svneol=native#text/pascal
 tests/tbs/tb0676.pp svneol=native#text/pascal
 tests/tbs/tb0676a.pp svneol=native#text/plain
+tests/tbs/tb0677.pp svneol=native#text/pascal
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain
 tests/tbs/ub0119.pp svneol=native#text/plain
@@ -18516,6 +18516,7 @@ tests/webtbs/tw37779.pp svneol=native#text/pascal
 tests/webtbs/tw3778.pp svneol=native#text/plain
 tests/webtbs/tw37780.pp svneol=native#text/plain
 tests/webtbs/tw3780.pp svneol=native#text/plain
+tests/webtbs/tw37806.pp svneol=native#text/pascal
 tests/webtbs/tw3782.pp svneol=native#text/plain
 tests/webtbs/tw3796.pp svneol=native#text/plain
 tests/webtbs/tw3805.pp svneol=native#text/plain

+ 1 - 0
compiler/hlcgobj.pas

@@ -5138,6 +5138,7 @@ implementation
     begin
       list:=TAsmList(arg);
       if (tsym(p).typ=paravarsym) and
+         (tparavarsym(p).is_used) and
          ((vo_has_local_copy in tparavarsym(p).varoptions) or
           (not(target_info.system in systems_caller_copy_addr_value_para) and
            (is_open_array(tparavarsym(p).vardef) or

+ 2 - 0
compiler/i386/aoptcpu.pas

@@ -139,6 +139,8 @@ unit aoptcpu;
               case taicpu(p).opcode Of
                 A_AND:
                   Result:=OptPass1And(p);
+                A_IMUL:
+                  Result:=OptPass1Imul(p);
                 A_CMP:
                   Result:=OptPass1Cmp(p);
                 A_VPXOR:

+ 1 - 1
compiler/ninl.pas

@@ -3477,7 +3477,7 @@ implementation
                       inserttypeconv(tcallparanode(tcallparanode(left).right).left,
                         tsetdef(left.resultdef).elementdef);
                     end
-                  else
+                  else if left.resultdef.typ<>undefineddef then
                     CGMessage(type_e_mismatch);
                 end;
               in_pack_x_y_z,

+ 33 - 0
compiler/x86/aoptx86.pas

@@ -138,6 +138,7 @@ unit aoptx86;
         function OptPass1Cmp(var p : tai) : boolean;
         function OptPass1PXor(var p : tai) : boolean;
         function OptPass1VPXor(var p: tai): boolean;
+        function OptPass1Imul(var p : tai) : boolean;
 
         function OptPass2MOV(var p : tai) : boolean;
         function OptPass2Imul(var p : tai) : boolean;
@@ -4194,6 +4195,38 @@ unit aoptx86;
          end;
      end;
 
+   function TX86AsmOptimizer.OptPass1Imul(var p: tai): boolean;
+     var
+       hp1 : tai;
+     begin
+       result:=false;
+       { replace
+           IMul   const,%mreg1,%mreg2
+           Mov    %reg2,%mreg3
+           dealloc  %mreg3
+
+           by
+           Imul   const,%mreg1,%mreg23
+       }
+       if (taicpu(p).ops=3) and
+         GetNextInstruction(p,hp1) and
+         MatchInstruction(hp1,A_MOV,[taicpu(p).opsize]) and
+         MatchOperand(taicpu(p).oper[2]^,taicpu(hp1).oper[0]^) and
+         (taicpu(hp1).oper[1]^.typ=top_reg) then
+         begin
+           TransferUsedRegs(TmpUsedRegs);
+           UpdateUsedRegs(TmpUsedRegs, tai(p.next));
+           if not(RegUsedAfterInstruction(taicpu(hp1).oper[0]^.reg,hp1,TmpUsedRegs)) then
+             begin
+               taicpu(p).loadoper(2,taicpu(hp1).oper[1]^);
+               DebugMsg(SPeepholeOptimization + 'ImulMov2Imul done',p);
+               RemoveInstruction(hp1);
+               result:=true;
+             end;
+         end;
+     end;
+
+
 
    function TX86AsmOptimizer.OptPass2MOV(var p : tai) : boolean;
 

+ 4 - 0
compiler/x86_64/aoptcpu.pas

@@ -73,6 +73,8 @@ uses
               case taicpu(p).opcode of
                 A_AND:
                   Result:=OptPass1AND(p);
+                A_IMUL:
+                  Result:=OptPass1Imul(p);
                 A_MOV:
                   Result:=OptPass1MOV(p);
                 A_MOVSX,
@@ -88,6 +90,8 @@ uses
                 A_VMOVUPS,
                 A_VMOVUPD:
                   result:=OptPass1_V_MOVAP(p);
+                A_VSQRTSD,
+                A_VSQRTSS,
                 A_VDIVSD,
                 A_VDIVSS,
                 A_VSUBSD,

+ 50 - 22
packages/pastojs/src/fppas2js.pp

@@ -672,6 +672,7 @@ type
     pbivnMessageInt,
     pbivnMessageStr,
     pbivnLocalModuleRef,
+    pbivnLocalProcRef,
     pbivnLocalTypeRef,
     pbivnLoop,
     pbivnLoopEnd,
@@ -854,6 +855,7 @@ const
     '$msgint', // pbivnMessageInt
     '$msgstr', // pbivnMessageStr
     '$lm', // pbivnLocalModuleRef
+    '$lp', // pbivnLocalProcRef
     '$lt', // pbivnLocalTypeRef
     '$l', // pbivnLoop
     '$end', // pbivnLoopEnd
@@ -2003,6 +2005,8 @@ type
     Function CreateReferencePathExpr(El: TPasElement; AContext : TConvertContext;
       Full: boolean = false; Ref: TResolvedReference = nil): TJSElement; virtual;
     Function CreateGlobalTypePath(El: TPasType; AContext : TConvertContext): string; virtual;
+    Function CreateStaticProcPath(El: TPasProcedure; AContext : TConvertContext): string; virtual;
+    Function CreateGlobalElPath(El: TPasElement; AContext : TConvertContext): string; virtual;
     // section
     Function CreateImplementationSection(El: TPasModule; IntfContext: TInterfaceSectionContext): TJSFunctionDeclarationStatement; virtual;
     Procedure CreateInitSection(El: TPasModule; Src: TJSSourceElements; AContext: TConvertContext); virtual;
@@ -3676,7 +3680,6 @@ procedure TPas2JSResolver.RenameSpecialized(SpecializedItem: TPRSpecializedItem
 var
   GenScope: TPasGenericScope;
   NewName: String;
-  ProcScope: TPas2JSProcedureScope;
 begin
   if SpecializedItem=nil then exit;
   NewName:=SpecializedItem.GenericEl.Name+'$G'+IntToStr(SpecializedItem.Index+1);
@@ -3690,19 +3693,11 @@ begin
   else if GenScope is TPas2JSProcTypeScope then
     TPas2JSProcTypeScope(GenScope).JSName:=NewName
   else if GenScope is TPas2JSProcedureScope then
-    begin
-    ProcScope:=TPas2JSProcedureScope(GenScope);
-    if ProcScope.OverloadName<>'' then
-      NewName:=ProcScope.OverloadName
-    else
-      NewName:=SpecializedItem.GenericEl.Name;
-    NewName:=LastDottedIdentifier(NewName);
-    ProcScope.JSName:=NewName+'$G'+IntToStr(SpecializedItem.Index+1);
-    end
+    // handled in GetOverloadName
   else
     RaiseNotYetImplemented(20200906203342,SpecializedItem.SpecializedEl,GetObjName(GenScope));
   {$IFDEF VerbosePas2JS}
-  //writeln('TPas2JSResolver.RenameSpecialized GenericEl=',GetObjPath(SpecializedItem.GenericEl),' Spec=',GetObjPath(SpecializedItem.SpecializedEl),' JSName="',NewName,'"');
+  writeln('TPas2JSResolver.RenameSpecialized GenericEl=',GetObjPath(SpecializedItem.GenericEl),' Spec=',GetObjPath(SpecializedItem.SpecializedEl),' JSName="',NewName,'"');
   {$ENDIF}
 end;
 
@@ -6824,13 +6819,13 @@ begin
       ProcScope:=TPas2JSProcedureScope(Data);
       if ProcScope.SpecializedFromItem<>nil then
         begin
-        // specialized proc -> generic name + 's' + index
+        // specialized proc -> generic name + '$G' + index
         GenEl:=ProcScope.SpecializedFromItem.GenericEl;
         GenScope:=TPas2JSProcedureScope(GenEl.CustomData);
         Result:=GenScope.OverloadName;
         if Result='' then
           Result:=GenEl.Name+'$';
-        Result:=Result+'s'+IntToStr(ProcScope.SpecializedFromItem.Index);
+        Result:=Result+'G'+IntToStr(ProcScope.SpecializedFromItem.Index+1);
         end
       else
         Result:=ProcScope.OverloadName;
@@ -23752,6 +23747,15 @@ var
          and not TPasProcedure(Proc).IsStatic;
   end;
 
+  function ProcHasNoSelf(Proc: TPasProcedure): boolean;
+  begin
+    if Proc=nil then exit(false);
+    if not (Proc.Parent is TPasMembersType) then
+      exit(true);
+    if Proc.IsStatic then exit(true);
+    Result:=false;
+  end;
+
   procedure Append_GetClass(Member: TPasElement);
   var
     P: TPasElement;
@@ -23928,10 +23932,18 @@ begin
     if El.Parent=nil then
       RaiseNotSupported(El,AContext,20170201172141,GetObjName(El));
 
-    if (coShortRefGlobals in Options) and (El is TPasType) and (Kind=rpkPathAndName) then
+    if (coShortRefGlobals in Options) and (Kind=rpkPathAndName) then
       begin
-      Result:=CreateGlobalTypePath(TPasType(El),AContext);
-      exit;
+      if (El is TPasType) then
+        begin
+        Result:=CreateGlobalTypePath(TPasType(El),AContext);
+        exit;
+        end
+      else if (El is TPasProcedure) and ProcHasNoSelf(TPasProcedure(El)) then
+        begin
+        Result:=CreateStaticProcPath(TPasProcedure(El),AContext);
+        exit;
+        end;
       end;
 
     El:=ImplToDecl(El);
@@ -24126,12 +24138,27 @@ function TPasToJSConverter.CreateGlobalTypePath(El: TPasType;
   AContext: TConvertContext): string;
 var
   aType: TPasType;
+begin
+  aType:=AContext.Resolver.ResolveAliasType(El);
+  Result:=CreateGlobalElPath(aType,AContext);
+end;
+
+function TPasToJSConverter.CreateStaticProcPath(El: TPasProcedure;
+  AContext: TConvertContext): string;
+begin
+  if (not El.IsStatic) and (El.Parent is TPasMembersType) then
+    RaiseNotSupported(El,AContext,20200925104007);
+  Result:=CreateGlobalElPath(El,AContext);
+end;
+
+function TPasToJSConverter.CreateGlobalElPath(El: TPasElement;
+  AContext: TConvertContext): string;
+var
+  ShortRefGlobals: Boolean;
   Parent: TPasElement;
   CurModule: TPasModule;
-  ShortRefGlobals: Boolean;
 begin
-  aType:=AContext.Resolver.ResolveAliasType(El);
-  Result:=AContext.GetLocalName(aType,[cvkGlobal]);
+  Result:=AContext.GetLocalName(El,[cvkGlobal]);
   if Result<>'' then
     exit; // already exists
   ShortRefGlobals:=coShortRefGlobals in Options;
@@ -24157,8 +24184,8 @@ begin
   else if Parent is TPasModule then
     Result:=TransformModuleName(TPasModule(Parent),true,AContext)
   else
-    RaiseNotSupported(El,AContext,20200609230526,GetObjName(aType));
-  Result:=Result+'.'+TransformElToJSName(aType,AContext);
+    RaiseNotSupported(El,AContext,20200609230526,GetObjPath(El));
+  Result:=Result+'.'+TransformElToJSName(El,AContext);
   if ShortRefGlobals then
     Result:=CreateGlobalAlias(El,Result,AContext);
 end;
@@ -25947,12 +25974,13 @@ begin
       Result:=GetBIName(pbivnLocalModuleRef)
     else if El is TPasType then
       Result:=GetBIName(pbivnLocalTypeRef)
+    else if El is TPasProcedure then
+      Result:=GetBIName(pbivnLocalProcRef)
     else
       RaiseNotSupported(El,AContext,20200608160225);
     Result:=FuncContext.CreateLocalIdentifier(Result);
     SectionContext.AddLocalVar(Result,El,cvkGlobal,false);
 
-    // ToDo: check if from a unit used by impl uses section
     if aResolver.ImplementationUsesUnit(ElModule) then
       begin
       // insert var $lm = null;

+ 54 - 54
packages/pastojs/tests/tcgenerics.pas

@@ -1720,7 +1720,7 @@ begin
   CheckSource('TestGenProc_Function_ObjFPC',
     LinesToStr([ // statements
     'this.w = 0;',
-    'this.Run$s0 = function (a) {',
+    'this.Run$G1 = function (a) {',
     '  var Result = 0;',
     '  var i = 0;',
     '  a = i;',
@@ -1729,7 +1729,7 @@ begin
     '};',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.w = $mod.Run$s0(3);',
+    '$mod.w = $mod.Run$G1(3);',
     '']));
 end;
 
@@ -1752,7 +1752,7 @@ begin
   CheckSource('TestGenProc_Function_Delphi',
     LinesToStr([ // statements
     'this.w = 0;',
-    'this.Run$s0 = function (a) {',
+    'this.Run$G1 = function (a) {',
     '  var Result = 0;',
     '  var i = 0;',
     '  a = i;',
@@ -1761,7 +1761,7 @@ begin
     '};',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.w = $mod.Run$s0(3);',
+    '$mod.w = $mod.Run$G1(3);',
     '']));
 end;
 
@@ -1784,20 +1784,20 @@ begin
   ConvertProgram;
   CheckSource('TestGenProc_Overload',
     LinesToStr([ // statements
-    'this.DoIt$s0 = function (a, w) {',
+    'this.DoIt$G1 = function (a, w) {',
     '};',
-    'this.DoIt$s1 = function (a, w) {',
+    'this.DoIt$G2 = function (a, w) {',
     '};',
-    'this.DoIt$1s0 = function (a, b) {',
+    'this.DoIt$1G1 = function (a, b) {',
     '};',
-    'this.DoIt$1s1 = function (a, b) {',
+    'this.DoIt$1G2 = function (a, b) {',
     '};',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.DoIt$s0(3, 4);',
-    '$mod.DoIt$s1(false, 5);',
-    '$mod.DoIt$1s0(6, true);',
-    '$mod.DoIt$1s1(7.3, true);',
+    '$mod.DoIt$G1(3, 4);',
+    '$mod.DoIt$G2(false, 5);',
+    '$mod.DoIt$1G1(6, true);',
+    '$mod.DoIt$1G2(7.3, true);',
     '']));
 end;
 
@@ -1817,15 +1817,15 @@ begin
   ConvertProgram;
   CheckSource('TestGenProc_infer_OverloadForward',
     LinesToStr([ // statements
-    'this.Run$s0 = function (a, b) {',
-    '  $mod.Run$s0(1, true);',
+    'this.Run$G1 = function (a, b) {',
+    '  $mod.Run$G1(1, true);',
     '};',
-    'this.Run$s1 = function (a, b) {',
-    '  $mod.Run$s0(1, true);',
+    'this.Run$G2 = function (a, b) {',
+    '  $mod.Run$G1(1, true);',
     '};',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.Run$s1(1.3, true);',
+    '$mod.Run$G2(1.3, true);',
     '']));
 end;
 
@@ -1857,20 +1857,20 @@ begin
   ConvertProgram;
   CheckSource('TestGenProc_infer_OverloadForward',
     LinesToStr([ // statements
-    'this.Run$s0 = function (a, b) {',
-    '  $mod.Run$s0(1, true);',
-    '  $mod.Run$1s0(2, 3);',
-    '  $mod.Run$2s0("foo", "bar");',
+    'this.Run$G1 = function (a, b) {',
+    '  $mod.Run$G1(1, true);',
+    '  $mod.Run$1G1(2, 3);',
+    '  $mod.Run$2G1("foo", "bar");',
     '};',
-    'this.Run$1s0 = function (a, w) {',
+    'this.Run$1G1 = function (a, w) {',
     '};',
-    'this.Run$2s0 = function (a, b) {',
+    'this.Run$2G1 = function (a, b) {',
     '};',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.Run$s0(1, true);',
-    '$mod.Run$1s0(2, 3);',
-    '$mod.Run$2s0("foo", "bar");',
+    '$mod.Run$G1(1, true);',
+    '$mod.Run$1G1(2, 3);',
+    '$mod.Run$2G1("foo", "bar");',
     '']));
 end;
 
@@ -1894,20 +1894,20 @@ begin
   ConvertProgram;
   CheckSource('TestGenProc_TypeInfo',
     LinesToStr([ // statements
-    'this.Run$s0 = function (a) {',
+    'this.Run$G1 = function (a) {',
     '  var p = null;',
     '  p = rtl.word;',
     '  p = rtl.word;',
     '};',
-    'this.Run$s1 = function (a) {',
+    'this.Run$G2 = function (a) {',
     '  var p = null;',
     '  p = rtl.string;',
     '  p = rtl.string;',
     '};',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.Run$s0(3);',
-    '$mod.Run$s1("foo");',
+    '$mod.Run$G1(3);',
+    '$mod.Run$G2("foo");',
     '']));
 end;
 
@@ -1931,21 +1931,21 @@ begin
   ConvertProgram;
   CheckSource('TestGenProc_Infer_Widen',
     LinesToStr([ // statements
-    'this.Run$s0 = function (a, b) {',
+    'this.Run$G1 = function (a, b) {',
     '};',
-    'this.Run$s1 = function (a, b) {',
+    'this.Run$G2 = function (a, b) {',
     '};',
-    'this.Run$s2 = function (a, b) {',
+    'this.Run$G3 = function (a, b) {',
     '};',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.Run$s0(1, 2);',
-    '$mod.Run$s0(2, 2);',
-    '$mod.Run$s1(3, 2);',
-    '$mod.Run$s1(4, 2);',
-    '$mod.Run$s1(5, 2);',
-    '$mod.Run$s2("a", "foo");',
-    '$mod.Run$s2("bar", "c");',
+    '$mod.Run$G1(1, 2);',
+    '$mod.Run$G1(2, 2);',
+    '$mod.Run$G2(3, 2);',
+    '$mod.Run$G2(4, 2);',
+    '$mod.Run$G2(5, 2);',
+    '$mod.Run$G3("a", "foo");',
+    '$mod.Run$G3("bar", "c");',
     '']));
 end;
 
@@ -1967,17 +1967,17 @@ begin
   ConvertProgram;
   CheckSource('TestGenProc_Infer_PassAsArg',
     LinesToStr([ // statements
-    'this.Run$s0 = function (a) {',
+    'this.Run$G1 = function (a) {',
     '  var Result = 0;',
     '  var b = 0;',
-    '  $mod.Run$s0($mod.Run$s0(3));',
-    '  $mod.Run$s0($mod.Run$s0(4));',
+    '  $mod.Run$G1($mod.Run$G1(3));',
+    '  $mod.Run$G1($mod.Run$G1(4));',
     '  return Result;',
     '};',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.Run$s0($mod.Run$s0(5));',
-    '$mod.Run$s0($mod.Run$s0(6));',
+    '$mod.Run$G1($mod.Run$G1(5));',
+    '$mod.Run$G1($mod.Run$G1(6));',
     '']));
 end;
 
@@ -2019,22 +2019,22 @@ begin
     '  };',
     '  this.$final = function () {',
     '  };',
-    '  this.Run$s0 = function (a, b) {',
-    '    this.Run$s0(1, true);',
-    '    this.Run$1s0(2, 3);',
-    '    this.Run$2s0("foo", "bar");',
+    '  this.Run$G1 = function (a, b) {',
+    '    this.Run$G1(1, true);',
+    '    this.Run$1G1(2, 3);',
+    '    this.Run$2G1("foo", "bar");',
     '  };',
-    '  this.Run$1s0 = function (a, w) {',
+    '  this.Run$1G1 = function (a, w) {',
     '  };',
-    '  this.Run$2s0 = function (a, b) {',
+    '  this.Run$2G1 = function (a, b) {',
     '  };',
     '});',
     'this.o = null;',
     '']),
     LinesToStr([ // $mod.$main
-    '$mod.o.Run$s0(1, true);',
-    '$mod.o.Run$1s0(2, 3);',
-    '$mod.o.Run$2s0("foo", "bar");',
+    '$mod.o.Run$G1(1, true);',
+    '$mod.o.Run$1G1(2, 3);',
+    '$mod.o.Run$2G1("foo", "bar");',
     '']));
 end;
 

+ 46 - 0
packages/pastojs/tests/tcoptimizations.pas

@@ -60,6 +60,7 @@ type
     procedure TestOptShortRefGlobals_Program;
     procedure TestOptShortRefGlobals_Unit_FromIntfImpl_ToIntfImpl;
     procedure TestOptShortRefGlobals_Property;
+    procedure TestOptShortRefGlobals_GenericFunction;
 
     // Whole Program Optimization
     procedure TestWPO_OmitLocalVar;
@@ -444,6 +445,51 @@ begin
     '']));
 end;
 
+procedure TTestOptimizations.TestOptShortRefGlobals_GenericFunction;
+begin
+  AddModuleWithIntfImplSrc('UnitA.pas',
+  LinesToStr([
+    'generic function Run<T>(a: T): T;',
+    '']),
+  LinesToStr([
+    'generic function Run<T>(a: T): T;',
+    'begin',
+    'end;',
+    '']));
+  StartUnit(true,[supTObject]);
+  Add([
+  '{$optimization JSShortRefGlobals}',
+  'interface',
+  'uses unita;',
+  'type',
+  '  TEagle = class',
+  '  end;',
+  'procedure Fly;',
+  'implementation',
+  'procedure Fly;',
+  'begin',
+  '  specialize Run<TEagle>(nil);',
+  'end;',
+  '']);
+  ConvertUnit;
+  CheckSource('TestOptShortRefGlobals_GenericFunction',
+    LinesToStr([
+    'var $lm = pas.system;',
+    'var $lt = $lm.TObject;',
+    'var $lm1 = pas.UnitA;',
+    'var $lp = $lm1.Run$G1;',
+    'rtl.createClass(this, "TEagle", $lt, function () {',
+    '});',
+    'this.Fly = function () {',
+    '  $lp(null);',
+    '};',
+    '']),
+    LinesToStr([
+    '']),
+    LinesToStr([
+    '']));
+end;
+
 procedure TTestOptimizations.TestWPO_OmitLocalVar;
 begin
   StartProgram(false);

+ 1 - 1
rtl/objpas/sysutils/syshelp.inc

@@ -960,7 +960,7 @@ begin
   if (I>LS) then
     I:=LS;
   I:=I-L+1;
-  M:=AStartIndex-ACount+1; // 1 based
+  M:=AStartIndex-ACount+2; // 1 based
   if M<1 then
     M:=1;
   while (Result=-1) and (I>=M) do

+ 0 - 339
rtl/zxspectrum/Makefile

@@ -673,315 +673,6 @@ endif
 ifeq ($(FULL_TARGET),z80-amstradcpc)
 override TARGET_UNITS+=system si_prc
 endif
-ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-android)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i386-aros)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),m68k-macosclassic)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc-macosclassic)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc-aix)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-haiku)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-iphonesim)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-android)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-aros)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),x86_64-dragonfly)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-netbsd)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-android)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-aros)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-freertos)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),arm-ios)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),powerpc64-aix)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),mips-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),mipsel-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),mipsel-android)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),mips64el-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),jvm-java)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),jvm-android)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i8086-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i8086-msdos)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),i8086-win16)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),aarch64-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),aarch64-darwin)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),aarch64-win64)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),aarch64-android)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),aarch64-ios)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),wasm-wasm)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),sparc64-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),riscv32-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),riscv32-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),riscv64-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),riscv64-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),xtensa-linux)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),xtensa-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),xtensa-freertos)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),z80-embedded)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),z80-zxspectrum)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),z80-msxdos)
-override TARGET_LOADERS+=prt0
-endif
-ifeq ($(FULL_TARGET),z80-amstradcpc)
-override TARGET_LOADERS+=prt0
-endif
 override INSTALL_FPCPACKAGE=y
 ifeq ($(FULL_TARGET),i386-linux)
 override COMPILER_INCLUDEDIR+=$(INC) $(PROCINC)
@@ -2521,33 +2212,6 @@ else
 EXECPPAS:=@$(PPAS)
 endif
 endif
-.PHONY: fpc_loaders
-ifneq ($(TARGET_LOADERS),)
-override ALLTARGET+=fpc_loaders
-override CLEANTARGET+=fpc_loaders_clean
-override INSTALLTARGET+=fpc_loaders_install
-override LOADEROFILES:=$(addsuffix $(OEXT),$(TARGET_LOADERS))
-endif
-%$(OEXT): %$(LOADEREXT)
-ifdef COMPILER_UNITTARGETDIR
-	$(AS) -o $(COMPILER_UNITTARGETDIR)/$*$(OEXT) $<
-else
-	$(AS) -o $*$(OEXT) $<
-endif
-fpc_loaders: $(COMPILER_UNITTARGETDIR) $(LOADEROFILES)
-fpc_loaders_clean:
-ifdef COMPILER_UNITTARGETDIR
-	-$(DEL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROFILES))
-else
-	-$(DEL) $(LOADEROFILES)
-endif
-fpc_loaders_install:
-	$(MKDIR) $(INSTALL_UNITDIR)
-ifdef COMPILER_UNITTARGETDIR
-	$(INSTALL) $(addprefix $(COMPILER_UNITTARGETDIR)/,$(LOADEROFILES)) $(INSTALL_UNITDIR)
-else
-	$(INSTALL) $(LOADEROFILES) $(INSTALL_UNITDIR)
-endif
 .PHONY: fpc_units
 ifneq ($(TARGET_UNITS)$(TARGET_IMPLICITUNITS),)
 override ALLTARGET+=fpc_units
@@ -2931,9 +2595,6 @@ SYSINCDEPS=$(addprefix $(INC)/,$(SYSINCNAMES))
 include $(PROCINC)/makefile.cpu
 SYSCPUDEPS=$(addprefix $(PROCINC)/,$(CPUINCNAMES))
 SYSDEPS=$(SYSINCDEPS) $(SYSCPUDEPS)
-prt0$(OEXT) : prt0.asm
-	$(MAKE) $(COMPILER_UNITTARGETDIR)
-	sdasz80 -o $(UNITTARGETDIRPREFIX)prt0$(OEXT) prt0.asm
 system$(PPUEXT) : system.pp $(SYSDEPS)
 	$(COMPILER) $(FPC_SYSTEM_OPT) -Us -Sg system.pp
 	$(EXECPPAS)

+ 1 - 7
rtl/zxspectrum/Makefile.fpc

@@ -4,7 +4,7 @@
 [package]
 main=rtl
 [target]
-loaders=prt0
+loaders=
 units=system si_prc
 
 [require]
@@ -49,13 +49,7 @@ include $(PROCINC)/makefile.cpu
 SYSCPUDEPS=$(addprefix $(PROCINC)/,$(CPUINCNAMES))
 # Put system unit dependencies together.
 SYSDEPS=$(SYSINCDEPS) $(SYSCPUDEPS)
-#
-# Loaders
-#
 
-prt0$(OEXT) : prt0.asm
-        $(MAKE) $(COMPILER_UNITTARGETDIR)
-        sdasz80 -o $(UNITTARGETDIRPREFIX)prt0$(OEXT) prt0.asm
 #
 # System Units (System, Objpas, Strings)
 #

+ 0 - 10
rtl/zxspectrum/prt0.asm

@@ -1,10 +0,0 @@
-                        .area _CODE
-                        .globl PASCALMAIN
-                        .globl FPC_SAVE_IY
-                        .globl __fpc_stackarea_start
-                        .globl __fpc_stackarea_end
-
-start::
-                        ld sp, #__fpc_stackarea_end
-                        ld (FPC_SAVE_IY), iy
-                        jp PASCALMAIN

+ 40 - 0
tests/tbs/tb0677.pp

@@ -0,0 +1,40 @@
+{ %NORUN }
+
+program tb0677;
+
+{$mode objfpc}
+
+type
+  TEnum = (eOne, eTwo, eThree, eFour);
+  TSet = set of TEnum;
+
+  generic TTest<SetType, EnumType> = class
+    procedure Test;
+  end;
+
+procedure TTest.Test;
+var
+  s1: TSet;
+  s2: SetType;
+  e1: TEnum;
+  e2: EnumType;
+begin
+  Include(s1, e1);
+  Exclude(s1, e1);
+
+  Include(s2, e1);
+  Exclude(s2, e1);
+
+  Include(s2, e2);
+  Exclude(s2, e2);
+
+  Include(s2, e1);
+  Exclude(s2, e2);
+end;
+
+type
+  TTestTypes = specialize TTest<TSet, TEnum>;
+
+begin
+
+end.

+ 26 - 0
tests/webtbs/tw37806.pp

@@ -0,0 +1,26 @@
+program tw37806;
+
+{$mode delphi}
+
+procedure TurnSetElem<TSet, TElem>(var aSet: TSet; aElem: TElem; aOn: Boolean);
+begin
+  if aOn then
+    Include(aSet, aElem)
+  else
+    Exclude(aSet, aElem);
+end;
+
+type
+  TElem = (One, Two, Three, Four, Five);
+  TSet = set of TElem;
+
+var
+  s: TSet = [];
+
+begin
+  TurnSetElem<TSet, TElem>(s, Two, True);
+  TurnSetElem<TSet, TElem>(s, Five, True);
+  if not((Two in s) and (Five in s)) then
+    Halt(1);
+    //WriteLn('does not work');
+end.