浏览代码

* do not use an extra register in tcginlinenode.second_IncDec if not needed

git-svn-id: trunk@45177 -
florian 5 年之前
父节点
当前提交
9e0337f248
共有 3 个文件被更改,包括 59 次插入10 次删除
  1. 20 0
      compiler/cg64f32.pas
  2. 1 0
      compiler/cgobj.pas
  3. 38 10
      compiler/ncginl.pas

+ 20 - 0
compiler/cg64f32.pas

@@ -72,6 +72,7 @@ unit cg64f32;
         procedure a_op64_reg_ref(list : TAsmList;op:TOpCG;size : tcgsize;reg : tregister64; const ref: treference);override;
         procedure a_op64_const_loc(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;const l: tlocation);override;
         procedure a_op64_reg_loc(list : TAsmList;op:TOpCG;size : tcgsize;reg : tregister64;const l : tlocation);override;
+        procedure a_op64_ref_loc(list: TAsmList; op: TOpCG; size: tcgsize;const ref: treference; const l: tlocation);override;
         procedure a_op64_loc_reg(list : TAsmList;op:TOpCG;size : tcgsize;const l : tlocation;reg : tregister64);override;
         procedure a_op64_const_ref(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;const ref : treference);override;
 
@@ -705,6 +706,25 @@ unit cg64f32;
       end;
 
 
+    procedure tcg64f32.a_op64_ref_loc(list : TAsmList;op:TOpCG;size : tcgsize;const ref : treference;const l : tlocation);
+      var
+        tempreg: tregister64;
+      begin
+        case l.loc of
+          LOC_REFERENCE, LOC_CREFERENCE:
+            begin
+              tempreg.reghi:=cg.getintregister(list,OS_32);
+              tempreg.reglo:=cg.getintregister(list,OS_32);
+              a_load64_ref_reg(list,ref,tempreg);
+              a_op64_reg_ref(list,op,size,tempreg,l.reference);
+            end;
+          LOC_REGISTER,LOC_CREGISTER:
+            a_op64_ref_reg(list,op,size,ref,l.register64);
+          else
+            internalerror(2020042803);
+        end;
+      end;
+
 
     procedure tcg64f32.a_op64_loc_reg(list : TAsmList;op:TOpCG;size : tcgsize;const l : tlocation;reg : tregister64);
       begin

+ 1 - 0
compiler/cgobj.pas

@@ -519,6 +519,7 @@ unit cgobj;
         procedure a_op64_const_ref(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;const ref : treference);virtual;abstract;
         procedure a_op64_const_loc(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;const l: tlocation);virtual;abstract;
         procedure a_op64_reg_loc(list : TAsmList;op:TOpCG;size : tcgsize;reg : tregister64;const l : tlocation);virtual;abstract;
+        procedure a_op64_ref_loc(list : TAsmList;op:TOpCG;size : tcgsize;const ref : treference;const l : tlocation);virtual;abstract;
         procedure a_op64_loc_reg(list : TAsmList;op:TOpCG;size : tcgsize;const l : tlocation;reg64 : tregister64);virtual;abstract;
         procedure a_op64_const_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);virtual;
         procedure a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);virtual;

+ 38 - 10
compiler/ncginl.pas

@@ -395,6 +395,7 @@ implementation
          hregisterhi,
 {$endif not cpu64bitalu and not cpuhighleveltarget}
          hregister : tregister;
+         hloc: tlocation;
         begin
           { set defaults }
           addconstant:=true;
@@ -435,14 +436,25 @@ implementation
                  addvalue:=addvalue*tpointerconstnode(tcallparanode(tcallparanode(left).right).left).value
               else
                 begin
-                  hlcg.location_force_reg(current_asmdata.CurrAsmList,tcallparanode(tcallparanode(left).right).left.location,tcallparanode(tcallparanode(left).right).left.resultdef,second_incdec_tempregdef,addvalue<=1);
-                  hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
+                  if not(tcallparanode(tcallparanode(left).right).left.location.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE]) or (addvalue>1) or
+                    (def_cgsize(left.resultdef)<>tcallparanode(tcallparanode(left).right).left.location.size) then
+                    begin
+                      hlcg.location_force_reg(current_asmdata.CurrAsmList,tcallparanode(tcallparanode(left).right).left.location,tcallparanode(tcallparanode(left).right).left.resultdef,second_incdec_tempregdef,addvalue<=1);
+                      hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
 {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
-                  hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.register64.reghi;
+                      hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.register64.reghi;
 {$endif not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
-                  { insert multiply with addvalue if its >1 }
-                  if addvalue>1 then
-                    hlcg.a_op_const_reg(current_asmdata.CurrAsmList,OP_IMUL,left.resultdef,addvalue.svalue,hregister);
+                      { insert multiply with addvalue if its >1 }
+                      if addvalue>1 then
+                        hlcg.a_op_const_reg(current_asmdata.CurrAsmList,OP_IMUL,left.resultdef,addvalue.svalue,hregister);
+                    end
+                  else if tcallparanode(tcallparanode(left).right).left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
+                    begin
+                      hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
+{$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
+                      hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.register64.reghi;
+{$endif not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
+                    end;
                   addconstant:=false;
                 end;
             end;
@@ -468,12 +480,28 @@ implementation
              begin
 {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
                if def_cgsize(left.resultdef) in [OS_64,OS_S64] then
-                 cg64.a_op64_reg_loc(current_asmdata.CurrAsmList,addsubop[inlinenumber],def_cgsize(left.resultdef),
-                   joinreg64(hregister,hregisterhi),tcallparanode(left).left.location)
+                 case tcallparanode(tcallparanode(left).right).left.location.loc of
+                   LOC_REFERENCE,LOC_CREFERENCE:
+                     cg64.a_op64_ref_loc(current_asmdata.CurrAsmList,addsubop[inlinenumber],def_cgsize(left.resultdef),
+                       tcallparanode(tcallparanode(left).right).left.location.reference,tcallparanode(left).left.location);
+                   LOC_REGISTER,LOC_CREGISTER:
+                     cg64.a_op64_reg_loc(current_asmdata.CurrAsmList,addsubop[inlinenumber],def_cgsize(left.resultdef),
+                       joinreg64(hregister,hregisterhi),tcallparanode(left).left.location);
+                   else
+                     Internalerror(2020042801);
+                 end
                else
 {$endif not cpu64bitalu and not cpuhighleveltarget}
-                 hlcg.a_op_reg_loc(current_asmdata.CurrAsmList,addsubop[inlinenumber],left.resultdef,
-                   hregister,tcallparanode(left).left.location);
+                 case tcallparanode(tcallparanode(left).right).left.location.loc of
+                   LOC_REFERENCE,LOC_CREFERENCE:
+                     hlcg.a_op_ref_loc(current_asmdata.CurrAsmList,addsubop[inlinenumber],left.resultdef,
+                       tcallparanode(tcallparanode(left).right).left.location.reference,tcallparanode(left).left.location);
+                   LOC_REGISTER,LOC_CREGISTER:
+                     hlcg.a_op_reg_loc(current_asmdata.CurrAsmList,addsubop[inlinenumber],left.resultdef,
+                       hregister,tcallparanode(left).left.location);
+                   else
+                     Internalerror(2020042802);
+                 end;
              end;
           { no overflow checking for pointers (see ninl), and range checking }
           { is not applicable for them                                       }