|
@@ -27,9 +27,10 @@ unit nflw;
|
|
interface
|
|
interface
|
|
|
|
|
|
uses
|
|
uses
|
|
- node,cpubase,
|
|
|
|
- aasmbase,aasmtai,aasmcpu,symnot,
|
|
|
|
- symtype,symbase,symdef,symsym;
|
|
|
|
|
|
+ classes,
|
|
|
|
+ node,cpubase,
|
|
|
|
+ symnot,
|
|
|
|
+ symtype,symbase,symdef,symsym;
|
|
|
|
|
|
type
|
|
type
|
|
{ flags used by loop nodes }
|
|
{ flags used by loop nodes }
|
|
@@ -51,6 +52,8 @@ interface
|
|
loopflagsequal = [lnf_backward];
|
|
loopflagsequal = [lnf_backward];
|
|
|
|
|
|
type
|
|
type
|
|
|
|
+ tlabelnode = class;
|
|
|
|
+
|
|
tloopnode = class(tbinarynode)
|
|
tloopnode = class(tbinarynode)
|
|
t1,t2 : tnode;
|
|
t1,t2 : tnode;
|
|
loopflags : tloopflags;
|
|
loopflags : tloopflags;
|
|
@@ -84,6 +87,10 @@ interface
|
|
tifnodeclass = class of tifnode;
|
|
tifnodeclass = class of tifnode;
|
|
|
|
|
|
tfornode = class(tloopnode)
|
|
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;
|
|
loopvar_notid:cardinal;
|
|
constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;
|
|
constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;
|
|
procedure loop_var_access(not_type:Tnotification_flag;symbol:Tsym);
|
|
procedure loop_var_access(not_type:Tnotification_flag;symbol:Tsym);
|
|
@@ -116,11 +123,14 @@ interface
|
|
tcontinuenodeclass = class of tcontinuenode;
|
|
tcontinuenodeclass = class of tcontinuenode;
|
|
|
|
|
|
tgotonode = class(tnode)
|
|
tgotonode = class(tnode)
|
|
- labsym : tlabelsym;
|
|
|
|
- labsymderef : tderef;
|
|
|
|
|
|
+ { we still need this for resolving forward gotos }
|
|
|
|
+ labelsym : tlabelsym;
|
|
|
|
+ labelnode : tlabelnode;
|
|
exceptionblock : integer;
|
|
exceptionblock : integer;
|
|
{ internlab : tinterngotolabel;}
|
|
{ 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 createintern(g:tinterngotolabel);}
|
|
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
|
|
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
|
|
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
|
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
|
@@ -134,12 +144,12 @@ interface
|
|
tgotonodeclass = class of tgotonode;
|
|
tgotonodeclass = class of tgotonode;
|
|
|
|
|
|
tlabelnode = class(tunarynode)
|
|
tlabelnode = class(tunarynode)
|
|
- labelnr : tasmlabel;
|
|
|
|
- labsym : tlabelsym;
|
|
|
|
- labsymderef : tderef;
|
|
|
|
exceptionblock : integer;
|
|
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;
|
|
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
|
|
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
|
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
|
procedure buildderefimpl;override;
|
|
procedure buildderefimpl;override;
|
|
@@ -359,14 +369,14 @@ implementation
|
|
|
|
|
|
{A not node can be removed.}
|
|
{A not node can be removed.}
|
|
if left.nodetype=notn then
|
|
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 }
|
|
{ loop instruction }
|
|
if assigned(right) then
|
|
if assigned(right) then
|
|
resulttypepass(right);
|
|
resulttypepass(right);
|
|
@@ -886,18 +896,31 @@ implementation
|
|
TGOTONODE
|
|
TGOTONODE
|
|
*****************************************************************************}
|
|
*****************************************************************************}
|
|
|
|
|
|
- constructor tgotonode.create(p : tlabelsym);
|
|
|
|
|
|
+ constructor tgotonode.create(p : tlabelnode);
|
|
begin
|
|
begin
|
|
inherited create(goton);
|
|
inherited create(goton);
|
|
exceptionblock:=aktexceptblock;
|
|
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;
|
|
end;
|
|
|
|
|
|
|
|
|
|
constructor tgotonode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
|
|
constructor tgotonode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
|
|
begin
|
|
begin
|
|
inherited ppuload(t,ppufile);
|
|
inherited ppuload(t,ppufile);
|
|
- ppufile.getderef(labsymderef);
|
|
|
|
|
|
+ labelnode:=tlabelnode(ppuloadnoderef(ppufile));
|
|
exceptionblock:=ppufile.getbyte;
|
|
exceptionblock:=ppufile.getbyte;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -905,7 +928,7 @@ implementation
|
|
procedure tgotonode.ppuwrite(ppufile:tcompilerppufile);
|
|
procedure tgotonode.ppuwrite(ppufile:tcompilerppufile);
|
|
begin
|
|
begin
|
|
inherited ppuwrite(ppufile);
|
|
inherited ppuwrite(ppufile);
|
|
- ppufile.putderef(labsymderef);
|
|
|
|
|
|
+ ppuwritenoderef(ppufile,labelnode);
|
|
ppufile.putbyte(exceptionblock);
|
|
ppufile.putbyte(exceptionblock);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -913,14 +936,14 @@ implementation
|
|
procedure tgotonode.buildderefimpl;
|
|
procedure tgotonode.buildderefimpl;
|
|
begin
|
|
begin
|
|
inherited buildderefimpl;
|
|
inherited buildderefimpl;
|
|
- labsymderef.build(labsym);
|
|
|
|
|
|
+ //!!! deref(labelnode);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure tgotonode.derefimpl;
|
|
procedure tgotonode.derefimpl;
|
|
begin
|
|
begin
|
|
inherited derefimpl;
|
|
inherited derefimpl;
|
|
- labsym:=tlabelsym(labsymderef.resolve);
|
|
|
|
|
|
+ //!!! deref(labelnode);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -933,23 +956,53 @@ implementation
|
|
|
|
|
|
function tgotonode.pass_1 : tnode;
|
|
function tgotonode.pass_1 : tnode;
|
|
begin
|
|
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;
|
|
end;
|
|
|
|
|
|
|
|
|
|
function tgotonode.getcopy : tnode;
|
|
function tgotonode.getcopy : tnode;
|
|
var
|
|
var
|
|
- p : tgotonode;
|
|
|
|
|
|
+ p : tgotonode;
|
|
|
|
+ i : aint;
|
|
begin
|
|
begin
|
|
p:=tgotonode(inherited getcopy);
|
|
p:=tgotonode(inherited getcopy);
|
|
- p.labsym:=labsym;
|
|
|
|
|
|
+ {
|
|
p.exceptionblock:=exceptionblock;
|
|
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;
|
|
result:=p;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -964,32 +1017,16 @@ implementation
|
|
TLABELNODE
|
|
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
|
|
begin
|
|
inherited create(labeln,l);
|
|
inherited create(labeln,l);
|
|
exceptionblock:=aktexceptblock;
|
|
exceptionblock:=aktexceptblock;
|
|
- labsym:=p;
|
|
|
|
- labelnr:=p.lab;
|
|
|
|
- { save the current labelnode in the labelsym }
|
|
|
|
- p.code:=self;
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
constructor tlabelnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
|
|
constructor tlabelnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
|
|
begin
|
|
begin
|
|
inherited ppuload(t,ppufile);
|
|
inherited ppuload(t,ppufile);
|
|
- ppufile.getderef(labsymderef);
|
|
|
|
- labelnr:=tasmlabel(ppufile.getasmsymbol);
|
|
|
|
exceptionblock:=ppufile.getbyte;
|
|
exceptionblock:=ppufile.getbyte;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -997,8 +1034,6 @@ implementation
|
|
procedure tlabelnode.ppuwrite(ppufile:tcompilerppufile);
|
|
procedure tlabelnode.ppuwrite(ppufile:tcompilerppufile);
|
|
begin
|
|
begin
|
|
inherited ppuwrite(ppufile);
|
|
inherited ppuwrite(ppufile);
|
|
- ppufile.putderef(labsymderef);
|
|
|
|
- ppufile.putasmsymbol(labelnr);
|
|
|
|
ppufile.putbyte(exceptionblock);
|
|
ppufile.putbyte(exceptionblock);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1006,15 +1041,12 @@ implementation
|
|
procedure tlabelnode.buildderefimpl;
|
|
procedure tlabelnode.buildderefimpl;
|
|
begin
|
|
begin
|
|
inherited buildderefimpl;
|
|
inherited buildderefimpl;
|
|
- labsymderef.build(labsym);
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure tlabelnode.derefimpl;
|
|
procedure tlabelnode.derefimpl;
|
|
begin
|
|
begin
|
|
inherited derefimpl;
|
|
inherited derefimpl;
|
|
- labsym:=tlabelsym(labsymderef.resolve);
|
|
|
|
- objectlibrary.derefasmsymbol(tasmsymbol(labelnr));
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -1049,9 +1081,8 @@ implementation
|
|
p : tlabelnode;
|
|
p : tlabelnode;
|
|
begin
|
|
begin
|
|
p:=tlabelnode(inherited getcopy);
|
|
p:=tlabelnode(inherited getcopy);
|
|
- p.labelnr:=labelnr;
|
|
|
|
p.exceptionblock:=exceptionblock;
|
|
p.exceptionblock:=exceptionblock;
|
|
- p.labsym:=labsym;
|
|
|
|
|
|
+
|
|
result:=p;
|
|
result:=p;
|
|
end;
|
|
end;
|
|
|
|
|