Browse Source

Implement support for saving and restoring address registers.

cgobj.pas, tcg:
  * g_save_registers: add the amount of used address registers to size as well
  * g_save_registers: save all used address registers
  * g_restore_registers: restore all stored address registers
m68k/cpubase.pas:
  * rename saved_standard_address_registers to saved_address_registers
all other platform's cpubase.{inc,pas} (except alpha, ia64 and vis which are not up to date):
  * add a saved_address_registers variable with one entry of RS_INVALID

At least a "make fullcycle" did complete.

git-svn-id: trunk@25664 -
svenbarth 11 years ago
parent
commit
c48d572996

+ 2 - 1
compiler/aarch64/cpubase.pas

@@ -281,9 +281,10 @@ unit cpubase;
       }
       }
       saved_standard_registers : array[0..9] of tsuperregister =
       saved_standard_registers : array[0..9] of tsuperregister =
         (RS_X19,RS_X20,RS_X21,RS_X22,RS_X23,RS_X24,RS_X25,RS_X26,RS_X27,RS_X28);
         (RS_X19,RS_X20,RS_X21,RS_X22,RS_X23,RS_X24,RS_X25,RS_X26,RS_X27,RS_X28);
+      saved_mm_registers : array[0..7] of tsuperregister = (RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15);
 
 
       { this is only for the generic code which is not used for this architecture }
       { this is only for the generic code which is not used for this architecture }
-      saved_mm_registers : array[0..7] of tsuperregister = (RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15);
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
 
 
 {*****************************************************************************
 {*****************************************************************************
                                   Helpers
                                   Helpers

+ 1 - 0
compiler/arm/cpubase.pas

@@ -330,6 +330,7 @@ unit cpubase;
         (RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,RS_R10);
         (RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,RS_R10);
 
 
       { this is only for the generic code which is not used for this architecture }
       { this is only for the generic code which is not used for this architecture }
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
 
 
       { Required parameter alignment when calling a routine declared as
       { Required parameter alignment when calling a routine declared as

+ 1 - 0
compiler/avr/cpubase.pas

@@ -290,6 +290,7 @@ unit cpubase;
       }
       }
       std_param_align = 4;
       std_param_align = 4;
 
 
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
 
 
 {*****************************************************************************
 {*****************************************************************************

+ 26 - 0
compiler/cgobj.pas

@@ -2184,6 +2184,10 @@ implementation
         for r:=low(saved_standard_registers) to high(saved_standard_registers) do
         for r:=low(saved_standard_registers) to high(saved_standard_registers) do
           if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
           if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
             inc(size,sizeof(aint));
             inc(size,sizeof(aint));
+        if uses_registers(R_ADDRESSREGISTER) then
+          for r:=low(saved_address_registers) to high(saved_address_registers) do
+            if saved_address_registers[r] in rg[R_ADDRESSREGISTER].used_in_proc then
+              inc(size,sizeof(aint));
 
 
         { mm registers }
         { mm registers }
         if uses_registers(R_MMREGISTER) then
         if uses_registers(R_MMREGISTER) then
@@ -2215,6 +2219,17 @@ implementation
                 include(rg[R_INTREGISTER].preserved_by_proc,saved_standard_registers[r]);
                 include(rg[R_INTREGISTER].preserved_by_proc,saved_standard_registers[r]);
               end;
               end;
 
 
+            if uses_registers(R_ADDRESSREGISTER) then
+              for r:=low(saved_address_registers) to high(saved_address_registers) do
+                begin
+                  if saved_address_registers[r] in rg[R_ADDRESSREGISTER].used_in_proc then
+                    begin
+                      a_load_reg_ref(list,OS_ADDR,OS_ADDR,newreg(R_ADDRESSREGISTER,saved_address_registers[r],R_SUBWHOLE),href);
+                      inc(href.offset,sizeof(aint));
+                    end;
+                  include(rg[R_ADDRESSREGISTER].preserved_by_proc,saved_address_registers[r]);
+                end;
+
             if uses_registers(R_MMREGISTER) then
             if uses_registers(R_MMREGISTER) then
               begin
               begin
                 if (href.offset mod tcgsize2size[OS_VECTOR])<>0 then
                 if (href.offset mod tcgsize2size[OS_VECTOR])<>0 then
@@ -2261,6 +2276,17 @@ implementation
               inc(href.offset,sizeof(aint));
               inc(href.offset,sizeof(aint));
             end;
             end;
 
 
+        if uses_registers(R_ADDRESSREGISTER) then
+          for r:=low(saved_address_registers) to high(saved_address_registers) do
+            if saved_address_registers[r] in rg[R_ADDRESSREGISTER].used_in_proc then
+              begin
+                hreg:=newreg(R_ADDRESSREGISTER,saved_address_registers[r],R_SUBWHOLE);
+                { Allocate register so the optimizer does not remove the load }
+                a_reg_alloc(list,hreg);
+                a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,hreg);
+                inc(href.offset,sizeof(aint));
+              end;
+
         if uses_registers(R_MMREGISTER) then
         if uses_registers(R_MMREGISTER) then
           begin
           begin
             if (href.offset mod tcgsize2size[OS_VECTOR])<>0 then
             if (href.offset mod tcgsize2size[OS_VECTOR])<>0 then

+ 1 - 0
compiler/i386/cpubase.inc

@@ -138,6 +138,7 @@
       }
       }
       saved_standard_registers : array[0..3] of tsuperregister = (RS_EBX,RS_ESI,RS_EDI,RS_EBP);
       saved_standard_registers : array[0..3] of tsuperregister = (RS_EBX,RS_ESI,RS_EDI,RS_EBP);
 
 
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       {# Required parameter alignment when calling a routine declared as
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined
          stdcall and cdecl. The alignment value should be the one defined

+ 1 - 0
compiler/i8086/cpubase.inc

@@ -157,6 +157,7 @@
       }
       }
       saved_standard_registers : array[0..0] of tsuperregister = (RS_BP);
       saved_standard_registers : array[0..0] of tsuperregister = (RS_BP);
 
 
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       {# Required parameter alignment when calling a routine declared as
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined
          stdcall and cdecl. The alignment value should be the one defined

+ 1 - 0
compiler/jvm/cpubase.pas

@@ -254,6 +254,7 @@ uses
       );
       );
 
 
       { this is only for the generic code which is not used for this architecture }
       { this is only for the generic code which is not used for this architecture }
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
 
 
       {# Required parameter alignment when calling a routine
       {# Required parameter alignment when calling a routine

+ 1 - 1
compiler/m68k/cpubase.pas

@@ -304,7 +304,7 @@ unit cpubase;
          GCC source.
          GCC source.
       }
       }
       saved_standard_registers : array[0..5] of tsuperregister = (RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7);
       saved_standard_registers : array[0..5] of tsuperregister = (RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7);
-      saved_standard_address_registers : array[0..3] of tsuperregister = (RS_A2,RS_A3,RS_A4,RS_A5);
+      saved_address_registers : array[0..3] of tsuperregister = (RS_A2,RS_A3,RS_A4,RS_A5);
       
       
       { this is only for the generic code which is not used for this architecture }
       { this is only for the generic code which is not used for this architecture }
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);

+ 1 - 0
compiler/mips/cpubase.pas

@@ -249,6 +249,7 @@ unit cpubase;
         (RS_NO);
         (RS_NO);
 
 
       { this is only for the generic code which is not used for this architecture }
       { this is only for the generic code which is not used for this architecture }
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
 
 
       { Required parameter alignment when calling a routine declared as
       { Required parameter alignment when calling a routine declared as

+ 1 - 0
compiler/powerpc/cpubase.pas

@@ -355,6 +355,7 @@ uses
       );
       );
 
 
       { this is only for the generic code which is not used for this architecture }
       { this is only for the generic code which is not used for this architecture }
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
 
 
       {# Required parameter alignment when calling a routine declared as
       {# Required parameter alignment when calling a routine declared as

+ 1 - 0
compiler/powerpc64/cpubase.pas

@@ -353,6 +353,7 @@ const
     );
     );
 
 
   { this is only for the generic code which is not used for this architecture }
   { this is only for the generic code which is not used for this architecture }
+  saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
   saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
   saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
   
   
   {# Required parameter alignment when calling a routine declared as
   {# Required parameter alignment when calling a routine declared as

+ 1 - 0
compiler/sparc/cpubase.pas

@@ -254,6 +254,7 @@ uses
       saved_standard_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_standard_registers : array[0..0] of tsuperregister = (RS_INVALID);
 
 
       { this is only for the generic code which is not used for this architecture }
       { this is only for the generic code which is not used for this architecture }
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
 
 
       {# Required parameter alignment when calling a routine declared as
       {# Required parameter alignment when calling a routine declared as

+ 2 - 0
compiler/x86_64/cpubase.inc

@@ -126,6 +126,8 @@ const
       { these arrays differ between unix and win64 }
       { these arrays differ between unix and win64 }
       saved_standard_registers : array of tsuperregister = nil;
       saved_standard_registers : array of tsuperregister = nil;
       saved_mm_registers : array of tsuperregister = nil;
       saved_mm_registers : array of tsuperregister = nil;
+
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       { Required parameter alignment when calling a routine declared as
       { Required parameter alignment when calling a routine declared as
         stdcall and cdecl. The alignment value should be the one defined
         stdcall and cdecl. The alignment value should be the one defined
         by GCC or the target ABI.
         by GCC or the target ABI.