Ver Fonte

Implement volatile address registers. Fixes quite some tests, but also breaks others... (overall more are fixed than are broken :) )

paramgr.pas, tparamanager:
  + add virtual get_volatile_registers_address method which by default returns an empty set
cgobj.pas, tcg:
  * allocallcpuregisters: also allocate address registers if needed
  * deallocallcpuregisters: also deallocate address registers if needed
ncgcal.pas, tcgcallnode.pass_generate_code:
  * (de)allocate address registers
  * keep result from being deallocated if it should be an address register (currently by no architecture...)
m68k/cpupara.pas, tm68kparamanager:
  + get_volatile_registers_address: return a0 and a1 as volatile registers
m68k/n68kmat.pas, tm68kmoddivnode.call_rtl_divmod_reg_reg:
  * (de)allocate address registers

git-svn-id: trunk@25633 -
svenbarth há 11 anos atrás
pai
commit
235c06ab34
4 ficheiros alterados com 37 adições e 2 exclusões
  1. 4 0
      compiler/cgobj.pas
  2. 11 1
      compiler/m68k/cpupara.pas
  3. 15 1
      compiler/ncgcal.pas
  4. 7 0
      compiler/paramgr.pas

+ 4 - 0
compiler/cgobj.pas

@@ -702,6 +702,8 @@ implementation
     procedure tcg.allocallcpuregisters(list:TAsmList);
       begin
         alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        if uses_registers(R_ADDRESSREGISTER) then
+          alloccpuregisters(list,R_ADDRESSREGISTER,paramanager.get_volatile_registers_address(pocall_default));
 {$if not(defined(i386)) and not(defined(i8086)) and not(defined(avr))}
         if uses_registers(R_FPUREGISTER) then
           alloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
@@ -725,6 +727,8 @@ implementation
     procedure tcg.deallocallcpuregisters(list:TAsmList);
       begin
         dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+        if uses_registers(R_ADDRESSREGISTER) then
+          dealloccpuregisters(list,R_ADDRESSREGISTER,paramanager.get_volatile_registers_address(pocall_default));
 {$if not(defined(i386)) and not(defined(i8086)) and not(defined(avr))}
         if uses_registers(R_FPUREGISTER) then
           dealloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));

+ 11 - 1
compiler/m68k/cpupara.pas

@@ -50,6 +50,7 @@ unit cpupara;
           function parseparaloc(p : tparavarsym;const s : string) : boolean;override;
           function parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;override;
           function get_volatile_registers_int(calloption:tproccalloption):tcpuregisterset;override;
+          function get_volatile_registers_address(calloption:tproccalloption):tcpuregisterset;override;
          private
           procedure init_values(var curintreg, curfloatreg: tsuperregister; var cur_stack_offset: aword);
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
@@ -495,11 +496,20 @@ unit cpupara;
 
     function tm68kparamanager.get_volatile_registers_int(calloption:tproccalloption):tcpuregisterset;
       begin
-        { for now we set all int registers as volatile }
+        { d0 and d1 are considered volatile (ToDo: results in "procedure too
+          complex when compiling unicodedata.pas) }
+        //Result:=[RS_D0,RS_D1];
         Result:=[RS_D0..RS_D7];
       end;
 
 
+    function tm68kparamanager.get_volatile_registers_address(calloption:tproccalloption):tcpuregisterset;
+      begin
+        { a0 and a1 are considered volatile }
+        Result:=[RS_A0,RS_A1];
+      end;
+
+
     function tm68kparamanager.parseparaloc(p : tparavarsym;const s : string) : boolean;
       var
         paraloc : pcgparalocation;

+ 15 - 1
compiler/ncgcal.pas

@@ -744,6 +744,7 @@ implementation
       var
         name_to_call: shortstring;
         regs_to_save_int,
+        regs_to_save_address,
         regs_to_save_fpu,
         regs_to_save_mm   : Tcpuregisterset;
         href : treference;
@@ -773,6 +774,7 @@ implementation
            secondpass(tnode(callinitblock));
 
          regs_to_save_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
+         regs_to_save_address:=paramanager.get_volatile_registers_address(procdefinition.proccalloption);
          regs_to_save_fpu:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
          regs_to_save_mm:=paramanager.get_volatile_registers_mm(procdefinition.proccalloption);
 
@@ -800,6 +802,7 @@ implementation
               begin
                 case retlocitem^.loc of
                   LOC_REGISTER:
+
                     include(regs_to_save_int,getsupreg(retlocitem^.register));
                   LOC_FPUREGISTER:
                     include(regs_to_save_fpu,getsupreg(retlocitem^.register));
@@ -922,6 +925,8 @@ implementation
                    end;
 {$endif i8086}
                  cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int);
+                 if cg.uses_registers(R_ADDRESSREGISTER) then
+                   cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address);
                  if cg.uses_registers(R_FPUREGISTER) then
                    cg.alloccpuregisters(current_asmdata.CurrAsmList,R_FPUREGISTER,regs_to_save_fpu);
                  if cg.uses_registers(R_MMREGISTER) then
@@ -950,6 +955,8 @@ implementation
                     end;
 
                   cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int);
+                  if cg.uses_registers(R_ADDRESSREGISTER) then
+                    cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address);
                   if cg.uses_registers(R_FPUREGISTER) then
                     cg.alloccpuregisters(current_asmdata.CurrAsmList,R_FPUREGISTER,regs_to_save_fpu);
                   if cg.uses_registers(R_MMREGISTER) then
@@ -1008,6 +1015,8 @@ implementation
                 end;
 
               cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int);
+              if cg.uses_registers(R_ADDRESSREGISTER) then
+                cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address);
               if cg.uses_registers(R_FPUREGISTER) then
                 cg.alloccpuregisters(current_asmdata.CurrAsmList,R_FPUREGISTER,regs_to_save_fpu);
               if cg.uses_registers(R_MMREGISTER) then
@@ -1052,7 +1061,10 @@ implementation
                begin
                  case retlocitem^.loc of
                    LOC_REGISTER:
-                     exclude(regs_to_save_int,getsupreg(retlocitem^.register));
+                     if getregtype(retlocitem^.register)=R_INTREGISTER then
+                       exclude(regs_to_save_int,getsupreg(retlocitem^.register))
+                     else
+                       exclude(regs_to_save_address,getsupreg(retlocitem^.register));
                    LOC_FPUREGISTER:
                      exclude(regs_to_save_fpu,getsupreg(retlocitem^.register));
                    LOC_MMREGISTER:
@@ -1071,6 +1083,8 @@ implementation
            cg.dealloccpuregisters(current_asmdata.CurrAsmList,R_MMREGISTER,regs_to_save_mm);
          if cg.uses_registers(R_FPUREGISTER) then
            cg.dealloccpuregisters(current_asmdata.CurrAsmList,R_FPUREGISTER,regs_to_save_fpu);
+         if cg.uses_registers(R_ADDRESSREGISTER) then
+           cg.dealloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address);
          cg.dealloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int);
 
 {$ifdef SUPPORT_SAFECALL}

+ 7 - 0
compiler/paramgr.pas

@@ -76,6 +76,7 @@ unit paramgr;
           }
           function get_para_align(calloption : tproccalloption):byte;virtual;
           function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;virtual;
+          function get_volatile_registers_address(calloption : tproccalloption):tcpuregisterset;virtual;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;virtual;
           function get_volatile_registers_flags(calloption : tproccalloption):tcpuregisterset;virtual;
           function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;virtual;
@@ -255,6 +256,12 @@ implementation
       end;
 
 
+    function tparamanager.get_volatile_registers_address(calloption : tproccalloption):tcpuregisterset;
+      begin
+        result:=[];
+      end;
+
+
     function tparamanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;
       begin
         result:=[];