|
@@ -1,5 +1,5 @@
|
|
{
|
|
{
|
|
- Copyright (c) 2000-2002 by Florian Klaempfl
|
|
|
|
|
|
+ Copyright (c) 2000-2005 by Florian Klaempfl
|
|
|
|
|
|
Type checking and register allocation for math nodes
|
|
Type checking and register allocation for math nodes
|
|
|
|
|
|
@@ -32,6 +32,7 @@ interface
|
|
tmoddivnode = class(tbinopnode)
|
|
tmoddivnode = class(tbinopnode)
|
|
function pass_1 : tnode;override;
|
|
function pass_1 : tnode;override;
|
|
function det_resulttype:tnode;override;
|
|
function det_resulttype:tnode;override;
|
|
|
|
+ function simplify : tnode;override;
|
|
protected
|
|
protected
|
|
{$ifndef cpu64bit}
|
|
{$ifndef cpu64bit}
|
|
{ override the following if you want to implement }
|
|
{ override the following if you want to implement }
|
|
@@ -46,6 +47,7 @@ interface
|
|
tshlshrnode = class(tbinopnode)
|
|
tshlshrnode = class(tbinopnode)
|
|
function pass_1 : tnode;override;
|
|
function pass_1 : tnode;override;
|
|
function det_resulttype:tnode;override;
|
|
function det_resulttype:tnode;override;
|
|
|
|
+ function simplify : tnode;override;
|
|
{$ifndef cpu64bit}
|
|
{$ifndef cpu64bit}
|
|
{ override the following if you want to implement }
|
|
{ override the following if you want to implement }
|
|
{ parts explicitely in the code generator (CEC)
|
|
{ parts explicitely in the code generator (CEC)
|
|
@@ -61,6 +63,7 @@ interface
|
|
constructor create(expr : tnode);virtual;
|
|
constructor create(expr : tnode);virtual;
|
|
function pass_1 : tnode;override;
|
|
function pass_1 : tnode;override;
|
|
function det_resulttype:tnode;override;
|
|
function det_resulttype:tnode;override;
|
|
|
|
+ function simplify : tnode;override;
|
|
end;
|
|
end;
|
|
tunaryminusnodeclass = class of tunaryminusnode;
|
|
tunaryminusnodeclass = class of tunaryminusnode;
|
|
|
|
|
|
@@ -68,6 +71,7 @@ interface
|
|
constructor create(expr : tnode);virtual;
|
|
constructor create(expr : tnode);virtual;
|
|
function pass_1 : tnode;override;
|
|
function pass_1 : tnode;override;
|
|
function det_resulttype:tnode;override;
|
|
function det_resulttype:tnode;override;
|
|
|
|
+ function simplify : tnode;override;
|
|
{$ifdef state_tracking}
|
|
{$ifdef state_tracking}
|
|
function track_state_pass(exec_known:boolean):boolean;override;
|
|
function track_state_pass(exec_known:boolean):boolean;override;
|
|
{$endif}
|
|
{$endif}
|
|
@@ -80,7 +84,6 @@ interface
|
|
cunaryminusnode : tunaryminusnodeclass;
|
|
cunaryminusnode : tunaryminusnodeclass;
|
|
cnotnode : tnotnodeclass;
|
|
cnotnode : tnotnodeclass;
|
|
|
|
|
|
-
|
|
|
|
implementation
|
|
implementation
|
|
|
|
|
|
uses
|
|
uses
|
|
@@ -96,11 +99,47 @@ implementation
|
|
TMODDIVNODE
|
|
TMODDIVNODE
|
|
****************************************************************************}
|
|
****************************************************************************}
|
|
|
|
|
|
|
|
+ function tmoddivnode.simplify:tnode;
|
|
|
|
+ var
|
|
|
|
+ t : tnode;
|
|
|
|
+ rd,ld : torddef;
|
|
|
|
+ rv,lv : tconstexprint;
|
|
|
|
+ begin
|
|
|
|
+ result:=nil;
|
|
|
|
+
|
|
|
|
+ if is_constintnode(right) and is_constintnode(left) then
|
|
|
|
+ begin
|
|
|
|
+ rd:=torddef(right.resulttype.def);
|
|
|
|
+ ld:=torddef(left.resulttype.def);
|
|
|
|
+
|
|
|
|
+ rv:=tordconstnode(right).value;
|
|
|
|
+ lv:=tordconstnode(left).value;
|
|
|
|
+
|
|
|
|
+ case nodetype of
|
|
|
|
+ modn:
|
|
|
|
+ if (torddef(ld).typ <> u64bit) or
|
|
|
|
+ (torddef(rd).typ <> u64bit) then
|
|
|
|
+ t:=genintconstnode(lv mod rv)
|
|
|
|
+ else
|
|
|
|
+ t:=genintconstnode(int64(qword(lv) mod qword(rv)));
|
|
|
|
+ divn:
|
|
|
|
+ if (torddef(ld).typ <> u64bit) or
|
|
|
|
+ (torddef(rd).typ <> u64bit) then
|
|
|
|
+ t:=genintconstnode(lv div rv)
|
|
|
|
+ else
|
|
|
|
+ t:=genintconstnode(int64(qword(lv) div qword(rv)));
|
|
|
|
+ end;
|
|
|
|
+ result:=t;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
function tmoddivnode.det_resulttype:tnode;
|
|
function tmoddivnode.det_resulttype:tnode;
|
|
var
|
|
var
|
|
- hp,t : tnode;
|
|
|
|
- rd,ld : torddef;
|
|
|
|
- rv,lv : tconstexprint;
|
|
|
|
|
|
+ hp,t : tnode;
|
|
|
|
+ rd,ld : torddef;
|
|
|
|
+ rv : tconstexprint;
|
|
begin
|
|
begin
|
|
result:=nil;
|
|
result:=nil;
|
|
resulttypepass(left);
|
|
resulttypepass(left);
|
|
@@ -131,29 +170,12 @@ implementation
|
|
{ recover }
|
|
{ recover }
|
|
rv:=1;
|
|
rv:=1;
|
|
end;
|
|
end;
|
|
- if is_constintnode(left) then
|
|
|
|
- begin
|
|
|
|
- lv:=tordconstnode(left).value;
|
|
|
|
-
|
|
|
|
- case nodetype of
|
|
|
|
- modn:
|
|
|
|
- if (torddef(ld).typ <> u64bit) or
|
|
|
|
- (torddef(rd).typ <> u64bit) then
|
|
|
|
- t:=genintconstnode(lv mod rv)
|
|
|
|
- else
|
|
|
|
- t:=genintconstnode(int64(qword(lv) mod qword(rv)));
|
|
|
|
- divn:
|
|
|
|
- if (torddef(ld).typ <> u64bit) or
|
|
|
|
- (torddef(rd).typ <> u64bit) then
|
|
|
|
- t:=genintconstnode(lv div rv)
|
|
|
|
- else
|
|
|
|
- t:=genintconstnode(int64(qword(lv) div qword(rv)));
|
|
|
|
- end;
|
|
|
|
- result:=t;
|
|
|
|
- exit;
|
|
|
|
- end;
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ result:=simplify;
|
|
|
|
+ if assigned(result) then
|
|
|
|
+ exit;
|
|
|
|
+
|
|
{ allow operator overloading }
|
|
{ allow operator overloading }
|
|
t:=self;
|
|
t:=self;
|
|
if isbinaryoverloaded(t) then
|
|
if isbinaryoverloaded(t) then
|
|
@@ -425,6 +447,27 @@ implementation
|
|
TSHLSHRNODE
|
|
TSHLSHRNODE
|
|
****************************************************************************}
|
|
****************************************************************************}
|
|
|
|
|
|
|
|
+ function tshlshrnode.simplify:tnode;
|
|
|
|
+ var
|
|
|
|
+ t : tnode;
|
|
|
|
+ begin
|
|
|
|
+ result:=nil;
|
|
|
|
+ { constant folding }
|
|
|
|
+ if is_constintnode(left) and is_constintnode(right) then
|
|
|
|
+ begin
|
|
|
|
+ case nodetype of
|
|
|
|
+ shrn:
|
|
|
|
+ t:=genintconstnode(tordconstnode(left).value shr tordconstnode(right).value);
|
|
|
|
+ shln:
|
|
|
|
+ t:=genintconstnode(tordconstnode(left).value shl tordconstnode(right).value);
|
|
|
|
+ end;
|
|
|
|
+ result:=t;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
function tshlshrnode.det_resulttype:tnode;
|
|
function tshlshrnode.det_resulttype:tnode;
|
|
var
|
|
var
|
|
t : tnode;
|
|
t : tnode;
|
|
@@ -437,18 +480,9 @@ implementation
|
|
if codegenerror then
|
|
if codegenerror then
|
|
exit;
|
|
exit;
|
|
|
|
|
|
- { constant folding }
|
|
|
|
- if is_constintnode(left) and is_constintnode(right) then
|
|
|
|
- begin
|
|
|
|
- case nodetype of
|
|
|
|
- shrn:
|
|
|
|
- t:=genintconstnode(tordconstnode(left).value shr tordconstnode(right).value);
|
|
|
|
- shln:
|
|
|
|
- t:=genintconstnode(tordconstnode(left).value shl tordconstnode(right).value);
|
|
|
|
- end;
|
|
|
|
- result:=t;
|
|
|
|
- exit;
|
|
|
|
- end;
|
|
|
|
|
|
+ result:=simplify;
|
|
|
|
+ if assigned(result) then
|
|
|
|
+ exit;
|
|
|
|
|
|
{ allow operator overloading }
|
|
{ allow operator overloading }
|
|
t:=self;
|
|
t:=self;
|
|
@@ -535,6 +569,25 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ function tunaryminusnode.simplify:tnode;
|
|
|
|
+ begin
|
|
|
|
+ result:=nil;
|
|
|
|
+ { constant folding }
|
|
|
|
+ if is_constintnode(left) then
|
|
|
|
+ begin
|
|
|
|
+ result:=genintconstnode(-tordconstnode(left).value);
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ if is_constrealnode(left) then
|
|
|
|
+ begin
|
|
|
|
+ trealconstnode(left).value_real:=-trealconstnode(left).value_real;
|
|
|
|
+ result:=left;
|
|
|
|
+ left:=nil;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
function tunaryminusnode.det_resulttype : tnode;
|
|
function tunaryminusnode.det_resulttype : tnode;
|
|
var
|
|
var
|
|
t : tnode;
|
|
t : tnode;
|
|
@@ -545,19 +598,9 @@ implementation
|
|
if codegenerror then
|
|
if codegenerror then
|
|
exit;
|
|
exit;
|
|
|
|
|
|
- { constant folding }
|
|
|
|
- if is_constintnode(left) then
|
|
|
|
- begin
|
|
|
|
- result:=genintconstnode(-tordconstnode(left).value);
|
|
|
|
- exit;
|
|
|
|
- end;
|
|
|
|
- if is_constrealnode(left) then
|
|
|
|
- begin
|
|
|
|
- trealconstnode(left).value_real:=-trealconstnode(left).value_real;
|
|
|
|
- result:=left;
|
|
|
|
- left:=nil;
|
|
|
|
- exit;
|
|
|
|
- end;
|
|
|
|
|
|
+ result:=simplify;
|
|
|
|
+ if assigned(result) then
|
|
|
|
+ exit;
|
|
|
|
|
|
resulttype:=left.resulttype;
|
|
resulttype:=left.resulttype;
|
|
if (left.resulttype.def.deftype=floatdef) then
|
|
if (left.resulttype.def.deftype=floatdef) then
|
|
@@ -666,11 +709,78 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ function tnotnode.simplify:tnode;
|
|
|
|
+ var
|
|
|
|
+ v : tconstexprint;
|
|
|
|
+ t : tnode;
|
|
|
|
+ tt : ttype;
|
|
|
|
+ begin
|
|
|
|
+ result:=nil;
|
|
|
|
+ { Try optmimizing ourself away }
|
|
|
|
+ if left.nodetype=notn then
|
|
|
|
+ begin
|
|
|
|
+ { Double not. Remove both }
|
|
|
|
+ result:=Tnotnode(left).left;
|
|
|
|
+ tnotnode(left).left:=nil;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if (left.nodetype in [ltn,lten,equaln,unequaln,gtn,gten]) then
|
|
|
|
+ begin
|
|
|
|
+ { Not of boolean expression. Turn around the operator and remove
|
|
|
|
+ the not. This is not allowed for sets with the gten/lten,
|
|
|
|
+ because there is no ltn/gtn support }
|
|
|
|
+ if (taddnode(left).left.resulttype.def.deftype<>setdef) or
|
|
|
|
+ (left.nodetype in [equaln,unequaln]) then
|
|
|
|
+ begin
|
|
|
|
+ result:=left;
|
|
|
|
+ left.nodetype:=boolean_reverse[left.nodetype];
|
|
|
|
+ left:=nil;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ { constant folding }
|
|
|
|
+ if (left.nodetype=ordconstn) then
|
|
|
|
+ begin
|
|
|
|
+ v:=tordconstnode(left).value;
|
|
|
|
+ tt:=left.resulttype;
|
|
|
|
+ case torddef(left.resulttype.def).typ of
|
|
|
|
+ bool8bit,
|
|
|
|
+ bool16bit,
|
|
|
|
+ bool32bit :
|
|
|
|
+ begin
|
|
|
|
+ { here we do a boolean(byte(..)) type cast because }
|
|
|
|
+ { boolean(<int64>) is buggy in 1.00 }
|
|
|
|
+ v:=byte(not(boolean(byte(v))));
|
|
|
|
+ end;
|
|
|
|
+ uchar,
|
|
|
|
+ uwidechar,
|
|
|
|
+ u8bit,
|
|
|
|
+ s8bit,
|
|
|
|
+ u16bit,
|
|
|
|
+ s16bit,
|
|
|
|
+ u32bit,
|
|
|
|
+ s32bit,
|
|
|
|
+ s64bit,
|
|
|
|
+ u64bit :
|
|
|
|
+ begin
|
|
|
|
+ v:=int64(not int64(v)); { maybe qword is required }
|
|
|
|
+ int_to_type(v,tt);
|
|
|
|
+ end;
|
|
|
|
+ else
|
|
|
|
+ CGMessage(type_e_mismatch);
|
|
|
|
+ end;
|
|
|
|
+ t:=cordconstnode.create(v,tt,true);
|
|
|
|
+ result:=t;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
function tnotnode.det_resulttype : tnode;
|
|
function tnotnode.det_resulttype : tnode;
|
|
var
|
|
var
|
|
t : tnode;
|
|
t : tnode;
|
|
- tt : ttype;
|
|
|
|
- v : tconstexprint;
|
|
|
|
begin
|
|
begin
|
|
result:=nil;
|
|
result:=nil;
|
|
resulttypepass(left);
|
|
resulttypepass(left);
|
|
@@ -680,65 +790,9 @@ implementation
|
|
|
|
|
|
resulttype:=left.resulttype;
|
|
resulttype:=left.resulttype;
|
|
|
|
|
|
- { Try optmimizing ourself away }
|
|
|
|
- if left.nodetype=notn then
|
|
|
|
- begin
|
|
|
|
- { Double not. Remove both }
|
|
|
|
- result:=Tnotnode(left).left;
|
|
|
|
- Tnotnode(left).left:=nil;
|
|
|
|
- exit;
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
- if (left.nodetype in [ltn,lten,equaln,unequaln,gtn,gten]) then
|
|
|
|
- begin
|
|
|
|
- { Not of boolean expression. Turn around the operator and remove
|
|
|
|
- the not. This is not allowed for sets with the gten/lten,
|
|
|
|
- because there is no ltn/gtn support }
|
|
|
|
- if (taddnode(left).left.resulttype.def.deftype<>setdef) or
|
|
|
|
- (left.nodetype in [equaln,unequaln]) then
|
|
|
|
- begin
|
|
|
|
- result:=left;
|
|
|
|
- left.nodetype:=boolean_reverse[left.nodetype];
|
|
|
|
- left:=nil;
|
|
|
|
- exit;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
- { constant folding }
|
|
|
|
- if (left.nodetype=ordconstn) then
|
|
|
|
- begin
|
|
|
|
- v:=tordconstnode(left).value;
|
|
|
|
- tt:=left.resulttype;
|
|
|
|
- case torddef(left.resulttype.def).typ of
|
|
|
|
- bool8bit,
|
|
|
|
- bool16bit,
|
|
|
|
- bool32bit :
|
|
|
|
- begin
|
|
|
|
- { here we do a boolean(byte(..)) type cast because }
|
|
|
|
- { boolean(<int64>) is buggy in 1.00 }
|
|
|
|
- v:=byte(not(boolean(byte(v))));
|
|
|
|
- end;
|
|
|
|
- uchar,
|
|
|
|
- uwidechar,
|
|
|
|
- u8bit,
|
|
|
|
- s8bit,
|
|
|
|
- u16bit,
|
|
|
|
- s16bit,
|
|
|
|
- u32bit,
|
|
|
|
- s32bit,
|
|
|
|
- s64bit,
|
|
|
|
- u64bit :
|
|
|
|
- begin
|
|
|
|
- v:=int64(not int64(v)); { maybe qword is required }
|
|
|
|
- int_to_type(v,tt);
|
|
|
|
- end;
|
|
|
|
- else
|
|
|
|
- CGMessage(type_e_mismatch);
|
|
|
|
- end;
|
|
|
|
- t:=cordconstnode.create(v,tt,true);
|
|
|
|
- result:=t;
|
|
|
|
- exit;
|
|
|
|
- end;
|
|
|
|
|
|
+ result:=simplify;
|
|
|
|
+ if assigned(result) then
|
|
|
|
+ exit;
|
|
|
|
|
|
if is_boolean(resulttype.def) then
|
|
if is_boolean(resulttype.def) then
|
|
begin
|
|
begin
|