Просмотр исходного кода

* when targeting the ELFv2 ABI, don't reserve space for the (never used)
words in the linkage area reserved for use by the compiler and linker

git-svn-id: trunk@30206 -

Jonas Maebe 10 лет назад
Родитель
Сommit
33ed32b024

+ 1 - 0
compiler/powerpc/cpubase.pas

@@ -380,6 +380,7 @@ uses
       LA_LR_SYSV = 4;
       { offset in the linkage area for the saved RTOC register}
       LA_RTOC_AIX = 20;
+      LA_RTOC_ELFV2 = 12;
 
       PARENT_FRAMEPOINTER_OFFSET = 12;
 

+ 18 - 2
compiler/powerpc64/cgcpu.pas

@@ -305,6 +305,22 @@ begin
 end;
 
 
+function get_rtoc_offset: longint;
+begin
+  result:=0;
+  case target_info.abi of
+    abi_powerpc_aix,
+    abi_powerpc_darwin:
+      result:=LA_RTOC_AIX;
+    abi_powerpc_elfv1:
+      result:=LA_RTOC_SYSV;
+    abi_powerpc_elfv2:
+      result:=LA_RTOC_ELFV2;
+    else
+      internalerror(2015021001);
+  end;
+end;
+
 { calling a procedure by address }
 
 procedure tcgppc.a_call_reg(list: TAsmList; reg: tregister);
@@ -322,7 +338,7 @@ begin
     a_load_ref_reg(list, OS_ADDR, OS_ADDR, tmpref, tempreg);
 
     { save TOC pointer in stackframe }
-    reference_reset_base(tmpref, NR_STACK_POINTER_REG, LA_RTOC_SYSV, 8);
+    reference_reset_base(tmpref, NR_STACK_POINTER_REG, get_rtoc_offset, 8);
     a_load_reg_ref(list, OS_ADDR, OS_ADDR, NR_RTOC, tmpref);
 
     { move actual function pointer to CTR register }
@@ -349,7 +365,7 @@ begin
   end;
 
   { we need to load the old RTOC from stackframe because we changed it}
-  reference_reset_base(tmpref, NR_STACK_POINTER_REG, LA_RTOC_SYSV, 8);
+  reference_reset_base(tmpref, NR_STACK_POINTER_REG, get_rtoc_offset, 8);
   a_load_ref_reg(list, OS_ADDR, OS_ADDR, tmpref, NR_RTOC);
 
   include(current_procinfo.flags, pi_do_call);

+ 3 - 0
compiler/powerpc64/cpubase.pas

@@ -361,6 +361,7 @@ const
   *****************************************************************************}
 
   LinkageAreaSizeELF = 48;
+  LinkageAreaSizeELFv2 = 32;
   { offset in the linkage area for the saved stack pointer }
   LA_SP = 0;
   { offset in the linkage area for the saved conditional register}
@@ -371,6 +372,7 @@ const
   { offset in the linkage area for the saved RTOC register}
   LA_RTOC_SYSV = 40;
   LA_RTOC_AIX = 40;
+  LA_RTOC_ELFV2 = 24;
 
   PARENT_FRAMEPOINTER_OFFSET = 24;
 
@@ -384,6 +386,7 @@ const
   
   { minimum size of the stack frame if one exists }
   MINIMUM_STACKFRAME_SIZE = 112;
+  MINIMUM_STACKFRAME_SIZE_ELFV2 = 112 - 16;
 
   maxfpuregs = 8;
 

+ 17 - 4
compiler/powerpc64/cpupi.pas

@@ -70,17 +70,30 @@ end;
 
 procedure tppcprocinfo.set_first_temp_offset;
 var
-  ofs: aword;
+  ofs,
+  lasize,
+  minstacksize: aword;
 begin
   if not (po_assembler in procdef.procoptions) then begin
     { align the stack properly }
-    ofs := align(maxpushedparasize + LinkageAreaSizeELF, ELF_STACK_ALIGN);
+    if target_info.abi<>abi_powerpc_elfv2 then
+      begin
+        { same for AIX/Darwin }
+        lasize:=LinkageAreaSizeELF;
+        minstacksize:=MINIMUM_STACKFRAME_SIZE;
+      end
+    else
+      begin
+        lasize:=LinkageAreaSizeELFv2;
+        minstacksize:=MINIMUM_STACKFRAME_SIZE_ELFV2;
+      end;
+    ofs := align(maxpushedparasize + lasize, ELF_STACK_ALIGN);
 
     { the ABI specification says that it is required to always allocate space for 8 * 8 bytes
       for registers R3-R10 and stack header if there's a stack frame, but GCC doesn't do that,
       so we don't that too. Uncomment the next three lines if this is required }
-    if (cs_profile in init_settings.moduleswitches) and (ofs < MINIMUM_STACKFRAME_SIZE) then begin
-      ofs := MINIMUM_STACKFRAME_SIZE;
+    if (cs_profile in init_settings.moduleswitches) and (ofs < minstacksize) then begin
+      ofs := minstacksize;
     end;
     tg.setfirsttemp(ofs);
   end else begin