Browse Source

* register paras and local copies updates

peter 22 years ago
parent
commit
2693582200
1 changed files with 81 additions and 57 deletions
  1. 81 57
      compiler/ncgutil.pas

+ 81 - 57
compiler/ncgutil.pas

@@ -879,15 +879,20 @@ implementation
         href1,href2 : treference;
         href1,href2 : treference;
         list : taasmoutput;
         list : taasmoutput;
         hsym : tvarsym;
         hsym : tvarsym;
+        loadref : boolean;
       begin
       begin
         list:=taasmoutput(arg);
         list:=taasmoutput(arg);
         if (tsym(p).typ=varsym) and
         if (tsym(p).typ=varsym) and
            (tvarsym(p).varspez=vs_value) and
            (tvarsym(p).varspez=vs_value) and
            (paramanager.push_addr_param(tvarsym(p).varspez,tvarsym(p).vartype.def,current_procinfo.procdef.proccalloption)) then
            (paramanager.push_addr_param(tvarsym(p).varspez,tvarsym(p).vartype.def,current_procinfo.procdef.proccalloption)) then
          begin
          begin
+           loadref:=true;
            case tvarsym(p).paraitem.paraloc[calleeside].loc of
            case tvarsym(p).paraitem.paraloc[calleeside].loc of
              LOC_REGISTER :
              LOC_REGISTER :
-               reference_reset_base(href1,tvarsym(p).paraitem.paraloc[calleeside].register,0);
+               begin
+                 reference_reset_base(href1,tvarsym(p).paraitem.paraloc[calleeside].register,0);
+                 loadref:=false;
+               end;
              LOC_REFERENCE :
              LOC_REFERENCE :
                reference_reset_base(href1,tvarsym(p).paraitem.paraloc[calleeside].reference.index,
                reference_reset_base(href1,tvarsym(p).paraitem.paraloc[calleeside].reference.index,
                    tvarsym(p).paraitem.paraloc[calleeside].reference.offset);
                    tvarsym(p).paraitem.paraloc[calleeside].reference.offset);
@@ -921,9 +926,9 @@ implementation
                 internalerror(200309183);
                 internalerror(200309183);
               reference_reset_base(href2,tvarsym(p).localloc.reference.index,tvarsym(p).localloc.reference.offset);
               reference_reset_base(href2,tvarsym(p).localloc.reference.index,tvarsym(p).localloc.reference.offset);
               if is_shortstring(tvarsym(p).vartype.def) then
               if is_shortstring(tvarsym(p).vartype.def) then
-                cg.g_copyshortstring(list,href1,href2,tstringdef(tvarsym(p).vartype.def).len,false,true)
+                cg.g_copyshortstring(list,href1,href2,tstringdef(tvarsym(p).vartype.def).len,false,loadref)
               else
               else
-                cg.g_concatcopy(list,href1,href2,tvarsym(p).vartype.def.size,true,true);
+                cg.g_concatcopy(list,href1,href2,tvarsym(p).vartype.def.size,true,loadref);
             end;
             end;
          end;
          end;
       end;
       end;
@@ -1271,9 +1276,73 @@ implementation
 
 
     procedure gen_initialize_code(list:TAAsmoutput;inlined:boolean);
     procedure gen_initialize_code(list:TAAsmoutput;inlined:boolean);
       var
       var
+        hp : tparaitem;
         href : treference;
         href : treference;
-        paraloc1,paraloc2 : tparalocation;
+        paraloc1,
+        paraloc2 : tparalocation;
+        hregister : tregister;
+        gotregvarparas : boolean;
       begin
       begin
+        { Save register parameters }
+        if assigned(current_procinfo.procdef.parast) and
+           not (po_assembler in current_procinfo.procdef.procoptions) then
+          begin
+            { move register parameters which aren't regable into memory                               }
+            { we do this before init_paras because that one calls routines which may overwrite these  }
+            { registers and it also expects the values to be in memory                                }
+            hp:=tparaitem(current_procinfo.procdef.para.first);
+            gotregvarparas := false;
+            while assigned(hp) do
+              begin
+                if hp.paraloc[calleeside].loc=LOC_REGISTER then
+                  begin
+                    hregister:=rg.getregisterint(list,hp.paraloc[calleeside].size);
+                    rg.ungetregisterint(list,hregister);
+                    cg.a_load_param_reg(list,hp.paraloc[calleeside],hregister);
+                    rg.makeregvarint(getsupreg(hregister));
+                    { Update register }
+                    hp.paraloc[calleeside].register:=hregister;
+                    { Update localloc when there is no local copy }
+                    if not(vo_has_local_copy in tvarsym(hp.parasym).varoptions) then
+                      tvarsym(hp.parasym).localloc:=hp.paraloc[calleeside];
+                    gotregvarparas:=true;
+                  end;
+(*
+                case tvarsym(hp.parasym).localloc.loc of
+                  LOC_REGISTER :
+                    begin
+                      gotregvarparas := true;
+                      { cg.a_load_param_reg will first allocate and then deallocate paraloc }
+                      { register (if the parameter resides in a register) and then allocate }
+                      { the regvar (which is currently not allocated)                       }
+                      cg.a_load_param_reg(list,hp.paraloc[calleeside],tvarsym(hp.parasym).localloc.register);
+                    end;
+                  LOC_REFERENCE :
+                    begin
+                      if hp.paraloc[calleeside].loc<>LOC_REFERENCE then
+                        begin
+                          reference_reset_base(href,tvarsym(hp.parasym).localloc.reference.index,tvarsym(hp.parasym).localloc.reference.offset);
+                          cg.a_load_param_ref(list,hp.paraloc[calleeside],href);
+                        end;
+                    end;
+                  else
+                    internalerror(200309185);
+                end;
+*)
+                hp:=tparaitem(hp.next);
+              end;
+            if gotregvarparas then
+              begin
+                { deallocate all register variables again }
+                hp:=tparaitem(current_procinfo.procdef.para.first);
+                while assigned(hp) do
+                  begin
+                    if (tvarsym(hp.parasym).localloc.loc=LOC_REGISTER) then
+                      rg.ungetregisterint(list,tvarsym(hp.parasym).localloc.register);
+                    hp:=tparaitem(hp.next);
+                  end;
+              end;
+          end;
         { the actual profile code can clobber some registers,
         { the actual profile code can clobber some registers,
           therefore if the context must be saved, do it before
           therefore if the context must be saved, do it before
           the actual call to the profile code
           the actual call to the profile code
@@ -1517,54 +1586,6 @@ implementation
         hp : tparaitem;
         hp : tparaitem;
         gotregvarparas: boolean;
         gotregvarparas: boolean;
       begin
       begin
-        { the actual stack allocation code, symbol entry point and
-          gdb stabs information is generated AFTER the rest of this
-          code, since temp. allocation might occur before - carl
-        }
-        if assigned(current_procinfo.procdef.parast) and
-           not (po_assembler in current_procinfo.procdef.procoptions) then
-          begin
-            { move register parameters which aren't regable into memory                               }
-            { we do this before init_paras because that one calls routines which may overwrite these  }
-            { registers and it also expects the values to be in memory                                }
-            hp:=tparaitem(current_procinfo.procdef.para.first);
-            gotregvarparas := false;
-            while assigned(hp) do
-              begin
-                case tvarsym(hp.parasym).localloc.loc of
-                  LOC_REGISTER :
-                    begin
-                      gotregvarparas := true;
-                      { cg.a_load_param_reg will first allocate and then deallocate paraloc }
-                      { register (if the parameter resides in a register) and then allocate }
-                      { the regvar (which is currently not allocated)                       }
-                      cg.a_load_param_reg(list,hp.paraloc[calleeside],tvarsym(hp.parasym).localloc.register);
-                    end;
-                  LOC_REFERENCE :
-                    begin
-                      if hp.paraloc[calleeside].loc<>LOC_REFERENCE then
-                        begin
-                          reference_reset_base(href,tvarsym(hp.parasym).localloc.reference.index,tvarsym(hp.parasym).localloc.reference.offset);
-                          cg.a_load_param_ref(list,hp.paraloc[calleeside],href);
-                        end;
-                    end;
-                  else
-                    internalerror(200309185);
-                end;
-                hp:=tparaitem(hp.next);
-              end;
-            if gotregvarparas then
-              begin
-                { deallocate all register variables again }
-                hp:=tparaitem(current_procinfo.procdef.para.first);
-                while assigned(hp) do
-                  begin
-                    if (tvarsym(hp.parasym).localloc.loc=LOC_REGISTER) then
-                      rg.ungetregisterint(list,tvarsym(hp.parasym).localloc.register);
-                    hp:=tparaitem(hp.next);
-                  end;
-              end;
-          end;
       end;
       end;
 
 
 
 
@@ -1999,8 +2020,8 @@ implementation
                         { Allocate imaginary register for register parameters }
                         { Allocate imaginary register for register parameters }
                         if paraitem.paraloc[calleeside].loc=LOC_REGISTER then
                         if paraitem.paraloc[calleeside].loc=LOC_REGISTER then
                           begin
                           begin
+                            (*
 {$warning TODO Allocate register paras}
 {$warning TODO Allocate register paras}
-(*
                             localloc.loc:=LOC_REGISTER;
                             localloc.loc:=LOC_REGISTER;
                             localloc.size:=paraitem.paraloc[calleeside].size;
                             localloc.size:=paraitem.paraloc[calleeside].size;
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
@@ -2012,10 +2033,10 @@ implementation
                             else
                             else
 {$endif cpu64bit}
 {$endif cpu64bit}
                               localloc.register:=rg.getregisterint(list,localloc.size);
                               localloc.register:=rg.getregisterint(list,localloc.size);
-*)
-                            localloc.loc:=LOC_REFERENCE;
+                              *)
+                            {localloc.loc:=LOC_REFERENCE;
                             localloc.size:=paraitem.paraloc[calleeside].size;
                             localloc.size:=paraitem.paraloc[calleeside].size;
-                            tg.GetLocal(list,tcgsize2size[localloc.size],localloc.reference);
+                            tg.GetLocal(list,tcgsize2size[localloc.size],localloc.reference);}
                           end
                           end
                         else
                         else
                           localloc:=paraitem.paraloc[calleeside];
                           localloc:=paraitem.paraloc[calleeside];
@@ -2067,7 +2088,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.150  2003-09-28 17:55:03  peter
+  Revision 1.151  2003-09-28 21:47:18  peter
+    * register paras and local copies updates
+
+  Revision 1.150  2003/09/28 17:55:03  peter
     * parent framepointer changed to hidden parameter
     * parent framepointer changed to hidden parameter
     * tloadparentfpnode added
     * tloadparentfpnode added