Parcourir la source

+ AIX support for a_call_reg()
* renamed some ppc64 stackframe offset constants to the same names as their
32 bit counterparts so they can be used in shared ppc code

git-svn-id: trunk@20794 -

Jonas Maebe il y a 13 ans
Parent
commit
95966da949
3 fichiers modifiés avec 40 ajouts et 8 suppressions
  1. 5 5
      compiler/powerpc64/cgcpu.pas
  2. 5 3
      compiler/powerpc64/cpubase.pas
  3. 30 0
      compiler/ppcgen/cgppc.pas

+ 5 - 5
compiler/powerpc64/cgcpu.pas

@@ -541,7 +541,7 @@ var
   tmpref: treference;
   tempreg : TRegister;
 begin
-  if (target_info.system = system_powerpc64_darwin) then
+  if (target_info.abi<>abi_powerpc_sysv) then
     inherited a_call_reg(list,reg)
   else if (not (cs_opt_size in current_settings.optimizerswitches)) then begin
     tempreg := cg.getintregister(current_asmdata.CurrAsmList, OS_INT);
@@ -551,7 +551,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_ELF, 8);
+    reference_reset_base(tmpref, NR_STACK_POINTER_REG, LA_RTOC_SYSV, 8);
     a_load_reg_ref(list, OS_ADDR, OS_ADDR, NR_RTOC, tmpref);
 
     { move actual function pointer to CTR register }
@@ -578,7 +578,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_ELF, 8);
+  reference_reset_base(tmpref, NR_STACK_POINTER_REG, LA_RTOC_SYSV, 8);
   a_load_ref_reg(list, OS_ADDR, OS_ADDR, tmpref, NR_RTOC);
 
   include(current_procinfo.flags, pi_do_call);
@@ -1482,7 +1482,7 @@ var
 
     { we may need to store R0 (=LR) ourselves }
     if ((cs_profile in init_settings.moduleswitches) or (mayNeedLRStore)) and (needslinkreg) then begin
-      reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_ELF, 8);
+      reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_SYSV, 8);
       list.concat(taicpu.op_reg_ref(A_STD, NR_R0, href));
     end;
   end;
@@ -1620,7 +1620,7 @@ var
 
       { restore LR (if needed) }
       if (needslinkreg) then begin
-        reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_ELF, 8);
+        reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_SYSV, 8);
         list.concat(taicpu.op_reg_ref(A_LD, NR_R0, href));
         list.concat(taicpu.op_reg(A_MTLR, NR_R0));
       end;

+ 5 - 3
compiler/powerpc64/cpubase.pas

@@ -366,11 +366,13 @@ const
   { offset in the linkage area for the saved stack pointer }
   LA_SP = 0;
   { offset in the linkage area for the saved conditional register}
-  LA_CR_ELF = 8;
+  LA_CR_SYSV = 8;
   { offset in the linkage area for the saved link register}
-  LA_LR_ELF = 16;
+  LA_LR_AIX = 16;
+  LA_LR_SYSV = 16;
   { offset in the linkage area for the saved RTOC register}
-  LA_RTOC_ELF = 40;
+  LA_RTOC_SYSV = 40;
+  LA_RTOC_AIX = 40;
 
   PARENT_FRAMEPOINTER_OFFSET = 24;
 

+ 30 - 0
compiler/ppcgen/cgppc.pas

@@ -420,9 +420,39 @@ unit cgppc;
 
     { calling a procedure by address }
     procedure tcgppcgen.a_call_reg(list : TAsmList;reg: tregister);
+      var
+        tmpref: treference;
+        tmpreg: tregister;
       begin
+        if target_info.system in systems_aix then
+          begin
+            { load function address in R0, and swap "reg" for R0 }
+            reference_reset_base(tmpref,reg,0,sizeof(pint));
+            a_load_ref_reg(list,OS_ADDR,OS_ADDR,tmpref,NR_R0);
+            tmpreg:=reg;
+            { no need to allocate/free R0, is already allocated by call node
+              because it's a volatile register }
+            reg:=NR_R0;
+            { save current TOC }
+            reference_reset_base(tmpref,NR_STACK_POINTER_REG,LA_RTOC_AIX,sizeof(pint));
+            a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_RTOC,tmpref);
+          end;
         list.concat(taicpu.op_reg(A_MTCTR,reg));
+        if target_info.system in systems_aix then
+          begin
+            { load target TOC and possible link register }
+            reference_reset_base(tmpref,tmpreg,sizeof(pint),sizeof(pint));
+            a_load_ref_reg(list,OS_ADDR,OS_ADDR,tmpref,NR_RTOC);
+            tmpref.offset:=2*sizeof(pint);
+            a_load_ref_reg(list,OS_ADDR,OS_ADDR,tmpref,NR_R11);
+          end;
         list.concat(taicpu.op_none(A_BCTRL));
+        if target_info.system in systems_aix then
+          begin
+            { restore our TOC }
+            reference_reset_base(tmpref,NR_STACK_POINTER_REG,LA_RTOC_AIX,sizeof(pint));
+            a_load_ref_reg(list,OS_ADDR,OS_ADDR,tmpref,NR_RTOC);
+          end;
         include(current_procinfo.flags,pi_do_call);
       end;