Browse Source

* merge r446 goto/label refactoring, needed for r1274

git-svn-id: branches/fixes_2_0@1293 -
peter 20 years ago
parent
commit
93a614ff77

+ 2 - 1
compiler/i386/cpubase.inc

@@ -33,7 +33,8 @@
         S_FS,S_FL,S_FX,S_FV,S_FXX,
         S_MD,
         S_NEAR,S_FAR,S_SHORT,
-        S_T
+        S_T,
+        S_XMM
       );
 
 

+ 2 - 2
compiler/i386/daopt386.pas

@@ -57,7 +57,7 @@ const
     OS_F32,OS_F64,OS_F80,OS_C64,OS_F128,
     OS_M32,
     OS_ADDR,OS_NO,OS_NO,
-    OS_NO);
+    OS_NO,OS_NO);
 
 
 
@@ -1129,7 +1129,7 @@ begin
           ((p.typ in (SkipInstr - [ait_RegAlloc])) or
            ((p.typ = ait_label) and
             labelCanBeSkipped(tai_label(p))) or
-           ((p.typ = ait_marker) and 
+           ((p.typ = ait_marker) and
             (tai_Marker(p).Kind in [AsmBlockend,inlinestart,inlineend]))) do
          p := tai(p.next);
     while assigned(p) and

+ 19 - 4
compiler/ncgflw.pas

@@ -27,7 +27,7 @@ unit ncgflw;
 interface
 
     uses
-      node,nflw;
+      aasmbase,node,nflw;
 
     type
        tcgwhilerepeatnode = class(twhilerepeatnode)
@@ -59,6 +59,10 @@ interface
        end;
 
        tcglabelnode = class(tlabelnode)
+       private
+          asmlabel : tasmlabel;
+       public
+          function getasmlabel : tasmlabel;
           procedure pass_2;override;
        end;
 
@@ -82,7 +86,7 @@ implementation
 
     uses
       verbose,globals,systems,globtype,
-      symconst,symdef,symsym,aasmbase,aasmtai,aasmcpu,defutil,
+      symconst,symdef,symsym,aasmtai,aasmcpu,defutil,
       procinfo,cgbase,pass_2,parabase,
       cpubase,cpuinfo,
       nld,ncon,
@@ -423,6 +427,9 @@ implementation
               cg.a_op_const_loc(exprasmlist,hop,1,left.location);
             end;
 
+         if assigned(entrylabel) then
+           cg.a_jmp_always(exprasmlist,tcglabelnode(entrylabel).getasmlabel);
+
          { align loop target }
          if not(cs_littlesize in aktglobalswitches) then
             exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
@@ -745,7 +752,7 @@ implementation
 {$ifdef OLDREGVARS}
          load_all_regvars(exprasmlist);
 {$endif OLDREGVARS}
-         cg.a_jmp_always(exprasmlist,labsym.lab)
+         cg.a_jmp_always(exprasmlist,tcglabelnode(labelnode).getasmlabel)
        end;
 
 
@@ -753,6 +760,14 @@ implementation
                              SecondLabel
 *****************************************************************************}
 
+    function tcglabelnode.getasmlabel : tasmlabel;
+      begin
+        if not(assigned(asmlabel)) then
+          objectlibrary.getlabel(asmlabel);
+        result:=asmlabel
+      end;
+
+
     procedure tcglabelnode.pass_2;
       begin
          location_reset(location,LOC_VOID,OS_NO);
@@ -760,7 +775,7 @@ implementation
 {$ifdef OLDREGVARS}
          load_all_regvars(exprasmlist);
 {$endif OLDREGVARS}
-         cg.a_label(exprasmlist,labelnr);
+         cg.a_label(exprasmlist,getasmlabel);
          secondpass(left);
       end;
 

+ 89 - 58
compiler/nflw.pas

@@ -27,9 +27,10 @@ unit nflw;
 interface
 
     uses
-       node,cpubase,
-       aasmbase,aasmtai,aasmcpu,symnot,
-       symtype,symbase,symdef,symsym;
+      classes,
+      node,cpubase,
+      symnot,
+      symtype,symbase,symdef,symsym;
 
     type
        { flags used by loop nodes }
@@ -51,6 +52,8 @@ interface
          loopflagsequal = [lnf_backward];
 
     type
+       tlabelnode = class;
+
        tloopnode = class(tbinarynode)
           t1,t2 : tnode;
           loopflags : tloopflags;
@@ -84,6 +87,10 @@ interface
        tifnodeclass = class of tifnode;
 
        tfornode = class(tloopnode)
+          { if count isn divisable by unrolls then
+            the for loop must jump to this label to get the correct
+            number of executions }
+          entrylabel : tnode;
           loopvar_notid:cardinal;
           constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;
           procedure loop_var_access(not_type:Tnotification_flag;symbol:Tsym);
@@ -116,11 +123,14 @@ interface
        tcontinuenodeclass = class of tcontinuenode;
 
        tgotonode = class(tnode)
-          labsym : tlabelsym;
-          labsymderef : tderef;
+          { we still need this for resolving forward gotos }
+          labelsym : tlabelsym;
+          labelnode : tlabelnode;
           exceptionblock : integer;
 {          internlab : tinterngotolabel;}
-          constructor create(p : tlabelsym);virtual;
+          constructor create(p : tlabelnode);virtual;
+          { as long as we don't know the label node we can't resolve it }
+          constructor create_sym(p : tlabelsym);virtual;
 {          constructor createintern(g:tinterngotolabel);}
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -134,12 +144,12 @@ interface
        tgotonodeclass = class of tgotonode;
 
        tlabelnode = class(tunarynode)
-          labelnr : tasmlabel;
-          labsym : tlabelsym;
-          labsymderef : tderef;
           exceptionblock : integer;
-          constructor createcase(p : tasmlabel;l:tnode);virtual;
-          constructor create(p : tlabelsym;l:tnode);virtual;
+          { when copying trees, this points to the newly created copy of a label }
+          copiedto : tlabelnode;
+          { contains all goto nodesrefering to this label }
+          referinggotonodes : tlist;
+          constructor create(l:tnode);virtual;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure buildderefimpl;override;
@@ -359,14 +369,14 @@ implementation
 
          {A not node can be removed.}
          if left.nodetype=notn then
-            begin
-                t:=Tunarynode(left);
-                left:=Tunarynode(left).left;
-                t.left:=nil;
-                t.destroy;
-                {Symdif operator, in case you are wondering:}
-                loopflags:=loopflags >< [lnf_checknegate];
-            end;
+           begin
+             t:=Tunarynode(left);
+             left:=Tunarynode(left).left;
+             t.left:=nil;
+             t.destroy;
+             {Symdif operator, in case you are wondering:}
+             loopflags:=loopflags >< [lnf_checknegate];
+           end;
          { loop instruction }
          if assigned(right) then
            resulttypepass(right);
@@ -886,18 +896,31 @@ implementation
                              TGOTONODE
 *****************************************************************************}
 
-    constructor tgotonode.create(p : tlabelsym);
+    constructor tgotonode.create(p : tlabelnode);
       begin
         inherited create(goton);
         exceptionblock:=aktexceptblock;
-        labsym:=p;
+        labelnode:=p;
+        labelsym:=nil;
+      end;
+
+
+    constructor tgotonode.create_sym(p : tlabelsym);
+      begin
+        inherited create(goton);
+        exceptionblock:=aktexceptblock;
+        if assigned(p.code) then
+          labelnode:=tlabelnode(p.code)
+        else
+          labelnode:=nil;
+        labelsym:=p;
       end;
 
 
     constructor tgotonode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
       begin
         inherited ppuload(t,ppufile);
-        ppufile.getderef(labsymderef);
+        labelnode:=tlabelnode(ppuloadnoderef(ppufile));
         exceptionblock:=ppufile.getbyte;
       end;
 
@@ -905,7 +928,7 @@ implementation
     procedure tgotonode.ppuwrite(ppufile:tcompilerppufile);
       begin
         inherited ppuwrite(ppufile);
-        ppufile.putderef(labsymderef);
+        ppuwritenoderef(ppufile,labelnode);
         ppufile.putbyte(exceptionblock);
       end;
 
@@ -913,14 +936,14 @@ implementation
     procedure tgotonode.buildderefimpl;
       begin
         inherited buildderefimpl;
-        labsymderef.build(labsym);
+        //!!! deref(labelnode);
       end;
 
 
     procedure tgotonode.derefimpl;
       begin
         inherited derefimpl;
-        labsym:=tlabelsym(labsymderef.resolve);
+        //!!! deref(labelnode);
       end;
 
 
@@ -933,23 +956,53 @@ implementation
 
     function tgotonode.pass_1 : tnode;
       begin
-         result:=nil;
-         expectloc:=LOC_VOID;
-         { check if }
-         if assigned(labsym) and
-            assigned(labsym.code) and
-            (exceptionblock<>tlabelnode(labsym.code).exceptionblock) then
-           CGMessage(cg_e_goto_inout_of_exception_block);
+        result:=nil;
+        expectloc:=LOC_VOID;
+
+        if not(assigned(labelnode)) then
+          begin
+            if assigned(labelsym.code) then
+              labelnode:=tlabelnode(labelsym.code)
+            else
+              internalerror(200506183);
+          end;
+
+        { check if we don't mess with exception blocks }
+        if assigned(labelnode) and
+           (exceptionblock<>labelnode.exceptionblock) then
+          CGMessage(cg_e_goto_inout_of_exception_block);
       end;
 
 
    function tgotonode.getcopy : tnode;
      var
-        p : tgotonode;
+       p : tgotonode;
+       i : aint;
      begin
         p:=tgotonode(inherited getcopy);
-        p.labsym:=labsym;
+        {
         p.exceptionblock:=exceptionblock;
+        { When we copying, we do an ugly trick to determine if the label used
+          by the current goto node is already copied: if the referinggotonodes
+          contains the current label, it isn't copied yet, so copy also the
+          label node and set the copiedto field to the newly created node.
+
+          If a label to copy is reached the copiedto field is checked. If it's non nil
+          the copiedto field is returned and the copiedto field is reset to nil.
+        }
+        { assume no copying }
+        newlabelnode:=labelnode;
+        for i:=0 to labelnode.copiedto.referingotonodes.count-1 do
+          begin
+            { copy labelnode? }
+            if labelnode.copiedto.referinggotonodes[i]=self then
+              begin
+                oldlabelnode.copiedto:=newlabelnode;
+              end;
+          end;
+        p.labelnode:=newlabelnode;
+        p.labelnode.referinggotonodes.add(self);
+        }
         result:=p;
      end;
 
@@ -964,32 +1017,16 @@ implementation
                              TLABELNODE
 *****************************************************************************}
 
-    constructor tlabelnode.createcase(p : tasmlabel;l:tnode);
-      begin
-        inherited create(labeln,l);
-        { it shouldn't be possible to jump to case labels using goto }
-        exceptionblock:=-1;
-        labsym:=nil;
-        labelnr:=p;
-      end;
-
-
-    constructor tlabelnode.create(p : tlabelsym;l:tnode);
+    constructor tlabelnode.create(l:tnode);
       begin
         inherited create(labeln,l);
         exceptionblock:=aktexceptblock;
-        labsym:=p;
-        labelnr:=p.lab;
-        { save the current labelnode in the labelsym }
-        p.code:=self;
       end;
 
 
     constructor tlabelnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
       begin
         inherited ppuload(t,ppufile);
-        ppufile.getderef(labsymderef);
-        labelnr:=tasmlabel(ppufile.getasmsymbol);
         exceptionblock:=ppufile.getbyte;
       end;
 
@@ -997,8 +1034,6 @@ implementation
     procedure tlabelnode.ppuwrite(ppufile:tcompilerppufile);
       begin
         inherited ppuwrite(ppufile);
-        ppufile.putderef(labsymderef);
-        ppufile.putasmsymbol(labelnr);
         ppufile.putbyte(exceptionblock);
       end;
 
@@ -1006,15 +1041,12 @@ implementation
     procedure tlabelnode.buildderefimpl;
       begin
         inherited buildderefimpl;
-        labsymderef.build(labsym);
       end;
 
 
     procedure tlabelnode.derefimpl;
       begin
         inherited derefimpl;
-        labsym:=tlabelsym(labsymderef.resolve);
-        objectlibrary.derefasmsymbol(tasmsymbol(labelnr));
       end;
 
 
@@ -1049,9 +1081,8 @@ implementation
         p : tlabelnode;
      begin
         p:=tlabelnode(inherited getcopy);
-        p.labelnr:=labelnr;
         p.exceptionblock:=exceptionblock;
-        p.labsym:=labsym;
+
         result:=p;
      end;
 

+ 16 - 0
compiler/node.pas

@@ -397,6 +397,8 @@ interface
     procedure ppuwritenode(ppufile:tcompilerppufile;n:tnode);
     function ppuloadnodetree(ppufile:tcompilerppufile):tnode;
     procedure ppuwritenodetree(ppufile:tcompilerppufile;n:tnode);
+    procedure ppuwritenoderef(ppufile:tcompilerppufile;n:tnode);
+    function ppuloadnoderef(ppufile:tcompilerppufile) : tnode;
 
     const
       printnodespacing = '   ';
@@ -521,6 +523,20 @@ implementation
       end;
 
 
+    procedure ppuwritenoderef(ppufile:tcompilerppufile;n:tnode);
+      begin
+        { writing of node references isn't implemented yet (FK) }
+        internalerror(200506181);
+      end;
+
+
+    function ppuloadnoderef(ppufile:tcompilerppufile) : tnode;
+      begin
+        { reading of node references isn't implemented yet (FK) }
+        internalerror(200506182);
+      end;
+
+
     function ppuloadnodetree(ppufile:tcompilerppufile):tnode;
       begin
         if ppufile.readentry<>ibnodetree then

+ 2 - 3
compiler/pdecl.pas

@@ -259,11 +259,10 @@ implementation
              consume(_ID)
            else
              begin
-                objectlibrary.getlabel(hl);
                 if token=_ID then
-                 symtablestack.insert(tlabelsym.create(orgpattern,hl))
+                 symtablestack.insert(tlabelsym.create(orgpattern))
                 else
-                 symtablestack.insert(tlabelsym.create(pattern,hl));
+                 symtablestack.insert(tlabelsym.create(pattern));
                 consume(token);
              end;
            if token<>_SEMICOLON then consume(_COMMA);

+ 2 - 1
compiler/pexpr.pas

@@ -1470,7 +1470,8 @@ implementation
                         if tlabelsym(srsym).defined then
                           Message(sym_e_label_already_defined);
                         tlabelsym(srsym).defined:=true;
-                        p1:=clabelnode.create(tlabelsym(srsym),nil);
+                        p1:=clabelnode.create(nil);
+                        tlabelsym(srsym).code:=p1;
                       end;
                   end;
 

+ 4 - 3
compiler/pstatmnt.pas

@@ -946,8 +946,8 @@ implementation
                          { goto is only allowed to labels within the current scope }
                          if srsym.owner<>current_procinfo.procdef.localst then
                            CGMessage(parser_e_goto_outside_proc);
-                         code:=cgotonode.create(tlabelsym(srsym));
-                         tgotonode(code).labsym:=tlabelsym(srsym);
+                         code:=cgotonode.create_sym(tlabelsym(srsym));
+                         tgotonode(code).labelsym:=tlabelsym(srsym);
                          { set flag that this label is used }
                          tlabelsym(srsym).used:=true;
                        end;
@@ -1011,7 +1011,8 @@ implementation
                    if tlabelsym(srsym).defined then
                     Message(sym_e_label_already_defined);
                    tlabelsym(srsym).defined:=true;
-                   p:=clabelnode.create(tlabelsym(srsym),nil);
+                   p:=clabelnode.create(nil);
+                   tlabelsym(srsym).code:=p;
                  end
                 else
                  begin

+ 3 - 1
compiler/rautils.pas

@@ -1387,7 +1387,9 @@ Begin
   case sym.typ of
     labelsym :
       begin
-        hl:=tlabelsym(sym).lab;
+        if not(assigned(tlabelsym(sym).asmblocklabel)) then
+          objectlibrary.getlabel(tlabelsym(sym).asmblocklabel);
+        hl:=tlabelsym(sym).asmblocklabel;
         if emit then
          tlabelsym(sym).defined:=true
         else

+ 10 - 15
compiler/symsym.pas

@@ -56,13 +56,18 @@ interface
        end;
 
        tlabelsym = class(tstoredsym)
-          lab     : tasmlabel;
           used,
           defined : boolean;
-          code : pointer; { should be tnode }
-          constructor create(const n : string; l : tasmlabel);
+          { points to the matching node, only valid resulttype pass is run and
+            the goto<->label relation in the node tree is created, should
+            be a tnode }
+          code : pointer;
+
+          { when the label is defined in an asm block, this points to the
+            generated asmlabel }
+          asmblocklabel : tasmlabel;
+          constructor create(const n : string);
           constructor ppuload(ppufile:tcompilerppufile);
-          function mangledname:string;override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
 {$ifdef GDB}
           function  stabstring : pchar;override;
@@ -512,11 +517,10 @@ implementation
                                  TLABELSYM
 ****************************************************************************}
 
-    constructor tlabelsym.create(const n : string; l : tasmlabel);
+    constructor tlabelsym.create(const n : string);
       begin
          inherited create(n);
          typ:=labelsym;
-         lab:=l;
          used:=false;
          defined:=false;
          code:=nil;
@@ -527,21 +531,12 @@ implementation
       begin
          inherited ppuload(ppufile);
          typ:=labelsym;
-         { this is all dummy
-           it is only used for local browsing }
-         lab:=nil;
          code:=nil;
          used:=false;
          defined:=true;
       end;
 
 
-    function tlabelsym.mangledname:string;
-      begin
-        result:=lab.name;
-      end;
-
-
     procedure tlabelsym.ppuwrite(ppufile:tcompilerppufile);
       begin
          if owner.symtabletype=globalsymtable then

+ 6 - 0
compiler/x86/aasmcpu.pas

@@ -359,6 +359,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          ),
          (OT_NONE,
@@ -367,6 +368,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          ),
          (OT_NONE,
@@ -375,6 +377,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          )
        );
@@ -391,6 +394,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          ),
          (OT_NONE,
@@ -399,6 +403,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          ),
          (OT_NONE,
@@ -407,6 +412,7 @@ implementation
           OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_NONE,
           OT_BITS64,
           OT_NEAR,OT_FAR,OT_SHORT,
+          OT_NONE,
           OT_NONE
          )
       );

+ 4 - 2
compiler/x86/itcpugas.pas

@@ -49,7 +49,8 @@ interface
        's','l','t','v','x',
        'd',
        '','','',
-       't'
+       't',
+       ''
      );
 {$else x86_64}
      gas_opsize2str : array[topsize] of string[2] = ('',
@@ -58,7 +59,8 @@ interface
        's','l','t','v','',
        'd',
        '','','',
-       't'
+       't',
+       ''
      );
 {$endif x86_64}
 

+ 2 - 1
compiler/x86/nx86inl.pas

@@ -68,7 +68,8 @@ implementation
       aasmtai,aasmcpu,
       cgbase,pass_2,
       cpuinfo,cpubase,paramgr,
-      nbas,ncon,ncal,ncnv,nld,
+      symdef,symconst,
+      nbas,ncon,ncal,ncnv,nld,ncgutil,
       cga,cgutils,cgx86,cgobj;