mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 03:19:47 +01:00 
			
		
		
		
	+ nmat refactored to have simplify
git-svn-id: trunk@142 -
This commit is contained in:
		
							parent
							
								
									9c717f2a35
								
							
						
					
					
						commit
						e920b10d7a
					
				@ -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
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,7 @@ interface
 | 
			
		||||
       tmoddivnode = class(tbinopnode)
 | 
			
		||||
          function pass_1 : tnode;override;
 | 
			
		||||
          function det_resulttype:tnode;override;
 | 
			
		||||
          function simplify : tnode;override;
 | 
			
		||||
         protected
 | 
			
		||||
{$ifndef cpu64bit}
 | 
			
		||||
          { override the following if you want to implement }
 | 
			
		||||
@ -46,6 +47,7 @@ interface
 | 
			
		||||
       tshlshrnode = class(tbinopnode)
 | 
			
		||||
          function pass_1 : tnode;override;
 | 
			
		||||
          function det_resulttype:tnode;override;
 | 
			
		||||
          function simplify : tnode;override;
 | 
			
		||||
{$ifndef cpu64bit}
 | 
			
		||||
          { override the following if you want to implement }
 | 
			
		||||
          { parts explicitely in the code generator (CEC)
 | 
			
		||||
@ -61,6 +63,7 @@ interface
 | 
			
		||||
          constructor create(expr : tnode);virtual;
 | 
			
		||||
          function pass_1 : tnode;override;
 | 
			
		||||
          function det_resulttype:tnode;override;
 | 
			
		||||
          function simplify : tnode;override;
 | 
			
		||||
       end;
 | 
			
		||||
       tunaryminusnodeclass = class of tunaryminusnode;
 | 
			
		||||
 | 
			
		||||
@ -68,6 +71,7 @@ interface
 | 
			
		||||
          constructor create(expr : tnode);virtual;
 | 
			
		||||
          function pass_1 : tnode;override;
 | 
			
		||||
          function det_resulttype:tnode;override;
 | 
			
		||||
          function simplify : tnode;override;
 | 
			
		||||
       {$ifdef state_tracking}
 | 
			
		||||
          function track_state_pass(exec_known:boolean):boolean;override;
 | 
			
		||||
       {$endif}
 | 
			
		||||
@ -80,7 +84,6 @@ interface
 | 
			
		||||
       cunaryminusnode : tunaryminusnodeclass;
 | 
			
		||||
       cnotnode : tnotnodeclass;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
implementation
 | 
			
		||||
 | 
			
		||||
    uses
 | 
			
		||||
@ -96,11 +99,47 @@ implementation
 | 
			
		||||
                              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;
 | 
			
		||||
      var
 | 
			
		||||
         hp,t : tnode;
 | 
			
		||||
         rd,ld : torddef;
 | 
			
		||||
         rv,lv : tconstexprint;
 | 
			
		||||
        hp,t : tnode;
 | 
			
		||||
        rd,ld : torddef;
 | 
			
		||||
        rv : tconstexprint;
 | 
			
		||||
      begin
 | 
			
		||||
         result:=nil;
 | 
			
		||||
         resulttypepass(left);
 | 
			
		||||
@ -131,29 +170,12 @@ implementation
 | 
			
		||||
                 { recover }
 | 
			
		||||
                 rv:=1;
 | 
			
		||||
               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;
 | 
			
		||||
 | 
			
		||||
         result:=simplify;
 | 
			
		||||
         if assigned(result) then
 | 
			
		||||
           exit;
 | 
			
		||||
 | 
			
		||||
         { allow operator overloading }
 | 
			
		||||
         t:=self;
 | 
			
		||||
         if isbinaryoverloaded(t) then
 | 
			
		||||
@ -425,6 +447,27 @@ implementation
 | 
			
		||||
                              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;
 | 
			
		||||
      var
 | 
			
		||||
         t : tnode;
 | 
			
		||||
@ -437,18 +480,9 @@ implementation
 | 
			
		||||
         if codegenerror then
 | 
			
		||||
           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 }
 | 
			
		||||
         t:=self;
 | 
			
		||||
@ -535,6 +569,25 @@ implementation
 | 
			
		||||
      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;
 | 
			
		||||
      var
 | 
			
		||||
         t : tnode;
 | 
			
		||||
@ -545,19 +598,9 @@ implementation
 | 
			
		||||
         if codegenerror then
 | 
			
		||||
           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;
 | 
			
		||||
         if (left.resulttype.def.deftype=floatdef) then
 | 
			
		||||
@ -666,11 +709,78 @@ implementation
 | 
			
		||||
      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;
 | 
			
		||||
      var
 | 
			
		||||
         t : tnode;
 | 
			
		||||
         tt : ttype;
 | 
			
		||||
         v : tconstexprint;
 | 
			
		||||
      begin
 | 
			
		||||
         result:=nil;
 | 
			
		||||
         resulttypepass(left);
 | 
			
		||||
@ -680,65 +790,9 @@ implementation
 | 
			
		||||
 | 
			
		||||
         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
 | 
			
		||||
           begin
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user