2
0
Эх сурвалжийг харах

* constant regvars (addresses of var/out para's and const para's) aren't
saved to memory anymore when their register will be destroyed
* unit has been made mostly processor independent

Jonas Maebe 24 жил өмнө
parent
commit
4d0eae9a7c
1 өөрчлөгдсөн 55 нэмэгдсэн , 128 устгасан
  1. 55 128
      compiler/regvars.pas

+ 55 - 128
compiler/regvars.pas

@@ -35,12 +35,10 @@ interface
     procedure assign_regvars(p: tnode);
     procedure load_regvars(asml: TAAsmoutput; p: tnode);
     procedure cleanup_regvars(asml: TAAsmoutput);
-{$ifdef i386}
     procedure store_regvar(asml: TAAsmoutput; reg: tregister);
     procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
     procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
     procedure load_all_regvars(asml: TAAsmoutput);
-{$endif i386}
 
 implementation
 
@@ -48,7 +46,7 @@ implementation
       globtype,systems,comphook,
       cutils,cclasses,verbose,globals,
       symconst,symbase,symtype,symdef,types,
-      cgbase,cpuasm,tgcpu;
+      cgbase,cpuasm,tgcpu,cgobj,cgcpu,cga;
 
     var
       parasym : boolean;
@@ -130,30 +128,12 @@ implementation
            end;
       end;
 
-{$ifdef i386}
-    function reg32(reg: tregister): tregister;
-      begin
-        case regsize(reg) of
-          S_B: reg32 := reg8toreg32(reg);
-          S_W: reg32 := reg16toreg32(reg);
-          S_L: reg32 := reg;
-        end;
-      end;
-{$else i386}
-    function reg32(reg: tregister): tregister;
-      begin
-        reg32 := reg;
-      end;
-{$endif i386}
-
-
     procedure assign_regvars(p: tnode);
           { register variables }
     var
       regvarinfo: pregvarinfo;
       i: longint;
     begin
-{$ifdef i386}
       { max. optimizations     }
       { only if no asm is used }
       { and no try statement   }
@@ -199,22 +179,20 @@ implementation
                            regvarinfo^.regvars[i].reg:=varregs[i];
                         end
                       else
+{$ifdef i386}
                        if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
                           (torddef(regvarinfo^.regvars[i].vartype.def).size=1) then
                         begin
-{$ifdef i386}
                           regvarinfo^.regvars[i].reg:=reg32toreg8(varregs[i]);
-{$endif}
                         end
                       else
                        if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
                           (torddef(regvarinfo^.regvars[i].vartype.def).size=2) then
                          begin
-{$ifdef i386}
                            regvarinfo^.regvars[i].reg:=reg32toreg16(varregs[i]);
-{$endif}
                          end
                       else
+{$endif i386}
                         begin
                           regvarinfo^.regvars[i].reg:=varregs[i];
                         end;
@@ -273,23 +251,20 @@ implementation
 {$ifdef i386}
                        { reserve place on the FPU stack }
                        regvarinfo^.fpuregvars[i].reg:=correct_fpuregister(R_ST0,i-1);
-{$endif i386}
-{$ifdef m68k}
+{$else i386}
                        regvarinfo^.fpuregvars[i].reg:=fpuvarregs[i];
-{$endif m68k}
+{$endif i386}
                      end;
                   end;
               end;
         end;
-{$endif i386}
      end;
 
 
-{$ifdef i386}
     procedure store_regvar(asml: TAAsmoutput; reg: tregister);
     var
       i: longint;
-      hr: preference;
+      hr: treference;
       regvarinfo: pregvarinfo;
       vsym: tvarsym;
     begin
@@ -298,20 +273,25 @@ implementation
         exit;
       for i := 1 to maxvarregs do
         if assigned(regvarinfo^.regvars[i]) and
-           (reg32(regvarinfo^.regvars[i].reg) = reg) then
+           (makereg32(regvarinfo^.regvars[i].reg) = reg) then
           begin
-            if regvar_loaded[reg32(reg)] then
+            if regvar_loaded[makereg32(reg)] then
               begin
                 vsym := tvarsym(regvarinfo^.regvars[i]);
-                new(hr);
-                reset_reference(hr^);
-                if vsym.owner.symtabletype in [inlinelocalsymtable,localsymtable] then
-                  hr^.offset:=-vsym.address+vsym.owner.address_fixup
-                else hr^.offset:=vsym.address+vsym.owner.address_fixup;
-                hr^.base:=procinfo^.framepointer;
-                asml.concat(Taicpu.op_reg_ref(A_MOV,regsize(vsym.reg),vsym.reg,hr));
-                asml.concat(Tairegalloc.dealloc(reg32(reg)));
-                regvar_loaded[reg32(reg)] := false;
+                { we only have to store the regvar back to memory if it's }
+                { possible that it's been modified  (JM)                  }
+                if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
+                  begin
+                    reset_reference(hr);
+                    if vsym.owner.symtabletype in [inlinelocalsymtable,localsymtable] then
+                      hr.offset:=-vsym.address+vsym.owner.address_fixup
+                    else hr.offset:=vsym.address+vsym.owner.address_fixup;
+                    hr.base:=procinfo^.framepointer;
+                    cg.a_load_reg_ref(exprasmlist,def_cgsize(vsym.vartype.def),vsym.reg,hr);
+{                    asml.concat(Taicpu.op_reg_ref(A_MOV,regsize(vsym.reg),vsym.reg,hr)); }
+                  end;
+                asml.concat(Tairegalloc.dealloc(makereg32(reg)));
+                regvar_loaded[makereg32(reg)] := false;
               end;
             break;
           end;
@@ -319,43 +299,27 @@ implementation
 
     procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
     var
-      hr: preference;
-      opsize: topsize;
-      opcode: tasmop;
+      hr: treference;
+      opsize: tcgsize;
     begin
-      if not regvar_loaded[reg32(vsym.reg)] then
+      if not regvar_loaded[makereg32(vsym.reg)] then
         begin
-          asml.concat(Tairegalloc.alloc(reg32(vsym.reg)));
-          { zero the regvars because the upper 48bits must be clear }
-          { for 8bits vars when using them with btrl                }
-          { don't care about sign extension, since the upper 24/16  }
-          { bits won't be adapted when doing maths anyway (JM)      }
-          case regsize(vsym.reg) of
-            S_L:
-              begin
-                opsize := S_L;
-                opcode := A_MOV;
-              end;
-            S_W:
-              begin
-                opsize := S_WL;
-                opcode := A_MOVZX;
-              end;
-            S_B:
-              begin
-                opsize := S_BL;
-                opcode := A_MOVZX;
-              end;
-          end;
-          asml.concat(Tairegalloc.alloc(reg32(vsym.reg)));
-          new(hr);
-          reset_reference(hr^);
+          asml.concat(Tairegalloc.alloc(makereg32(vsym.reg)));
+          reset_reference(hr);
           if vsym.owner.symtabletype in [inlinelocalsymtable,localsymtable] then
-            hr^.offset:=-vsym.address+vsym.owner.address_fixup
-          else hr^.offset:=vsym.address+vsym.owner.address_fixup;
-          hr^.base:=procinfo^.framepointer;
-          asml.concat(Taicpu.op_ref_reg(opcode,opsize,hr,reg32(vsym.reg)));
-          regvar_loaded[reg32(vsym.reg)] := true;
+            hr.offset:=-vsym.address+vsym.owner.address_fixup
+          else hr.offset:=vsym.address+vsym.owner.address_fixup;
+          hr.base:=procinfo^.framepointer;
+          if (vsym.varspez in [vs_var,vs_out]) or
+             ((vsym.varspez=vs_const) and
+               push_addr_param(vsym.vartype.def)) then
+            {FIXME!!! Needs to be OS_SIZE_OF_POINTER (JM) }
+            opsize := OS_32
+          else
+            opsize := def_cgsize(vsym.vartype.def);
+          cg.a_load_ref_reg(exprasmlist,opsize,hr,makereg32(vsym.reg));
+{          asml.concat(Taicpu.op_ref_reg(opcode,opsize,hr,makereg32(vsym.reg))); }
+          regvar_loaded[makereg32(vsym.reg)] := true;
         end;
     end;
 
@@ -367,10 +331,10 @@ implementation
       regvarinfo := pregvarinfo(aktprocdef.regvarinfo);
       if not assigned(regvarinfo) then
         exit;
-      reg := reg32(reg);
+      reg := makereg32(reg);
       for i := 1 to maxvarregs do
         if assigned(regvarinfo^.regvars[i]) and
-           (reg32(regvarinfo^.regvars[i].reg) = reg) then
+           (makereg32(regvarinfo^.regvars[i].reg) = reg) then
           load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
     end;
 
@@ -384,17 +348,14 @@ implementation
         exit;
       for i := 1 to maxvarregs do
         if assigned(regvarinfo^.regvars[i]) and
-           (reg32(regvarinfo^.regvars[i].reg) in [R_EAX,R_EBX,R_ECX,R_EDX]) then
+           (makereg32(regvarinfo^.regvars[i].reg) in [R_EAX,R_EBX,R_ECX,R_EDX]) then
           load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
     end;
 
-{$endif i386}
-
 
     procedure load_regvars(asml: TAAsmoutput; p: tnode);
     var
       i: longint;
-      {hr      : treference;}
       regvarinfo: pregvarinfo;
     begin
       if (cs_regalloc in aktglobalswitches) and
@@ -404,25 +365,6 @@ implementation
           { can happen when inlining assembler procedures (JM) }
           if not assigned(regvarinfo) then
             exit;
-{$ifdef m68k}
-          for i:=1 to maxvarregs do
-            begin
-              { parameter must be load }
-              if regvarinfo^.regvars_para[i] then
-                begin
-                  { procinfo is there actual,    }
-                  { because we can't never be in a }
-                  { nested procedure        }
-                  { when loading parameter to reg  }
-                  new(hr);
-                  reset_reference(hr^);
-                  hr^.offset:=tvarsym(regvarinfo^.regvars[i])^.address+procinfo^.para_offset;
-                  hr^.base:=procinfo^.framepointer;
-                  asml.concat(Taicpu,op_ref_reg(A_MOVE,regsize(regvarinfo^.regvars[i].reg),
-                    hr,regvarinfo^.regvars[i].reg)));
-                end
-            end;
-{$endif m68k}
           for i:=1 to maxvarregs do
             begin
              if assigned(regvarinfo^.regvars[i]) then
@@ -445,34 +387,14 @@ implementation
                   regvarinfo^.fpuregvars[i].reg:=correct_fpuregister(R_ST0,i-1);
                   asml.concat(Taicpu.op_none(A_FLDZ,S_NO));
 {$endif i386}
-{$ifdef dummy}
-                  { parameter must be load }
-                  if regvarinfo^.fpuregvars_para[i] then
-                    begin
-                      { procinfo is there actual,    }
-                      { because we can't never be in a }
-                      { nested procedure        }
-                      { when loading parameter to reg  }
-                      new(hr);
-                      reset_reference(hr^);
-                      hr^.offset:=tvarsym(regvarinfo^.regvars[i])^.address+procinfo^.para_offset;
-                      hr^.base:=procinfo^.framepointer;
-{$ifdef i386}
-                      asml.concat(Taicpu,op_ref_reg(A_MOV,regsize(regvarinfo^.regvars[i].reg),
-                        hr,regvarinfo^.regvars[i].reg)));
-{$endif i386}
-{$ifdef m68k}
-                      asml.concat(Taicpu,op_ref_reg(A_MOVE,regsize(regvarinfo^.regvars[i].reg),
-                        hr,regvarinfo^.regvars[i].reg)));
-{$endif m68k}
-                    end;
-{$endif dummy}
                 end;
             end;
+{$ifdef i386}
           if assigned(p) then
             if cs_asm_source in aktglobalswitches then
               asml.insert(Tai_asm_comment.Create(strpnew(tostr(p.registersfpu)+
               ' registers on FPU stack used by temp. expressions')));
+{$endif i386}
           for i:=1 to maxfpuvarregs do
             begin
                if assigned(regvarinfo^.fpuregvars[i]) then
@@ -496,7 +418,6 @@ implementation
     var
       i: longint;
     begin
-{$ifdef i386}
       { can happen when inlining assembler procedures (JM) }
       if not assigned(aktprocdef.regvarinfo) then
         exit;
@@ -504,23 +425,29 @@ implementation
          ((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
         with pregvarinfo(aktprocdef.regvarinfo)^ do
           begin
+{$ifdef i386}
             for i:=1 to maxfpuvarregs do
               if assigned(fpuregvars[i]) then
                 { ... and clean it up }
                 asml.concat(Taicpu.op_reg(A_FSTP,S_NO,R_ST0));
+{$endif i386}
             for i := 1 to maxvarregs do
               if assigned(regvars[i]) and
-                 (regvar_loaded[reg32(regvars[i].reg)]) then
-                asml.concat(Tairegalloc.dealloc(reg32(regvars[i].reg)));
+                 (regvar_loaded[makereg32(regvars[i].reg)]) then
+                asml.concat(Tairegalloc.dealloc(makereg32(regvars[i].reg)));
           end;
-{$endif i386}
     end;
 
 end.
 
 {
   $Log$
-  Revision 1.19  2001-11-02 22:58:06  peter
+  Revision 1.20  2001-11-05 16:49:32  jonas
+    * constant regvars (addresses of var/out para's and const para's) aren't
+      saved to memory anymore when their register will be destroyed
+    * unit has been made mostly processor independent
+
+  Revision 1.19  2001/11/02 22:58:06  peter
     * procsym definition rewrite
 
   Revision 1.18  2001/08/26 13:36:49  florian