Bladeren bron

* moved g_external_wrapper() code from powerpc64/cgcpu to ppcgen/cgppc,
made it 32/64 bit neutral and adjusted it so it can be used for
linux/ppc64, aix/ppc and aix/ppc64

git-svn-id: trunk@20795 -

Jonas Maebe 13 jaren geleden
bovenliggende
commit
4123df9cb8
4 gewijzigde bestanden met toevoegingen van 59 en 49 verwijderingen
  1. 3 1
      compiler/powerpc/cgcpu.pas
  2. 3 0
      compiler/powerpc/cpubase.pas
  3. 2 48
      compiler/powerpc64/cgcpu.pas
  4. 51 0
      compiler/ppcgen/cgppc.pas

+ 3 - 1
compiler/powerpc/cgcpu.pas

@@ -199,7 +199,9 @@ const
          if not(pi_do_call in current_procinfo.flags) then
            internalerror(2003060703);
 }
-       include(current_procinfo.flags,pi_do_call);
+       { not assigned while generating external wrappers }
+       if assigned(current_procinfo) then
+         include(current_procinfo.flags,pi_do_call);
       end;
 
     { calling a procedure by address }

+ 3 - 0
compiler/powerpc/cpubase.pas

@@ -384,6 +384,9 @@ uses
 
       maxfpuregs = 8;
 
+      { minimum size of the stack frame if one exists }
+      MINIMUM_STACKFRAME_SIZE = 56;
+
 {*****************************************************************************
                                   Helpers
 *****************************************************************************}

+ 2 - 48
compiler/powerpc64/cgcpu.pas

@@ -108,8 +108,6 @@ type
     procedure g_concatcopy(list: TAsmList; const source, dest: treference;
       len: aint); override;
 
-    procedure g_external_wrapper(list: TAsmList; pd: TProcDef; const externalname: string); override;
-
   private
 
     procedure a_load_regconst_subsetreg_intern(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister; slopt: tsubsetloadopt); override;
@@ -529,7 +527,8 @@ begin
   if (addNOP) then
     list.concat(taicpu.op_none(A_NOP));
 
-  if (includeCall) then
+  if (includeCall) and
+    assigned(current_procinfo) then
     include(current_procinfo.flags, pi_do_call);
 end;
 
@@ -1929,51 +1928,6 @@ begin
 
 end;
 
-procedure tcgppc.g_external_wrapper(list: TAsmList; pd: TProcDef; const externalname: string);
-var
-  href : treference;
-begin
-  if (target_info.system <> system_powerpc64_linux) then begin
-    inherited;
-    exit;
-  end;
-
-  { for ppc64/linux emit correct code which sets up a stack frame and then calls the
-  external method normally to ensure that the GOT/TOC will be loaded correctly if
-  required.
-
-  It's not really advantageous to use cg methods here because they are too specialized.
-
-  I.e. the resulting code sequence looks as follows:
-
-  mflr r0
-  std r0, 16(r1)
-  stdu r1, -112(r1)
-  bl <external_method>
-  nop
-  addi r1, r1, 112
-  ld r0, 16(r1)
-  mtlr r0
-  blr
-
-  }
-  list.concat(taicpu.op_reg(A_MFLR, NR_R0));
-  reference_reset_base(href, NR_STACK_POINTER_REG, 16, 8);
-  list.concat(taicpu.op_reg_ref(A_STD, NR_R0, href));
-  reference_reset_base(href, NR_STACK_POINTER_REG, -MINIMUM_STACKFRAME_SIZE, 8);
-  list.concat(taicpu.op_reg_ref(A_STDU, NR_STACK_POINTER_REG, href));
-
-  list.concat(taicpu.op_sym(A_BL, current_asmdata.RefAsmSymbol(externalname)));
-  list.concat(taicpu.op_none(A_NOP));
-
-  list.concat(taicpu.op_reg_reg_const(A_ADDI, NR_STACK_POINTER_REG, NR_STACK_POINTER_REG, MINIMUM_STACKFRAME_SIZE));
-
-  reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_ELF, 8);
-  list.concat(taicpu.op_reg_ref(A_LD, NR_R0, href));
-  list.concat(taicpu.op_reg(A_MTLR, NR_R0));
-  list.concat(taicpu.op_none(A_BLR));
-end;
-
 {***************** This is private property, keep out! :) *****************}
 
 procedure tcgppc.maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);

+ 51 - 0
compiler/ppcgen/cgppc.pas

@@ -68,6 +68,7 @@ unit cgppc;
         procedure g_stackpointer_alloc(list : TAsmList;localsize : longint);override;
 
         function get_aix_toc_sym(const symname: string; const flags: tindsymflags):tasmsymbol;
+        procedure g_external_wrapper(list: TAsmList; pd: TProcDef; const externalname: string); override;
        protected
         function  get_darwin_call_stub(const s: string; weak: boolean): tasmsymbol;
         procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tcgsize; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
@@ -843,6 +844,56 @@ unit cgppc;
     end;
 
 
+    procedure tcgppcgen.g_external_wrapper(list: TAsmList; pd: TProcDef; const externalname: string);
+      var
+        href : treference;
+      begin
+        if not(target_info.system in ([system_powerpc64_linux]+systems_aix)) then begin
+          inherited;
+          exit;
+        end;
+
+        { for ppc64/linux and aix emit correct code which sets up a stack frame
+          and then calls the external method normally to ensure that the GOT/TOC
+          will be loaded correctly if required.
+
+        The resulting code sequence looks as follows:
+
+        mflr r0
+        stw/d r0, 16(r1)
+        stw/du r1, -112(r1)
+        bl <external_method>
+        nop
+        addi r1, r1, 112
+        lwz/d r0, 16(r1)
+        mtlr r0
+        blr
+
+        }
+        list.concat(taicpu.op_reg(A_MFLR, NR_R0));
+        if target_info.abi=abi_powerpc_sysv then
+          reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_SYSV, 8)
+        else
+          reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_AIX, 8);
+        a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_R0,href);
+        reference_reset_base(href, NR_STACK_POINTER_REG, -MINIMUM_STACKFRAME_SIZE, 8);
+        list.concat(taicpu.op_reg_ref({$ifdef cpu64bitaddr}A_STDU{$else}A_STWU{$endif}, NR_STACK_POINTER_REG, href));
+
+        a_call_name(list,externalname,false);
+
+        list.concat(taicpu.op_reg_reg_const(A_ADDI, NR_STACK_POINTER_REG, NR_STACK_POINTER_REG, MINIMUM_STACKFRAME_SIZE));
+
+
+        if target_info.abi=abi_powerpc_sysv then
+          reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_SYSV, 8)
+        else
+          reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_AIX, 8);
+        a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_R0);
+        list.concat(taicpu.op_reg(A_MTLR, NR_R0));
+        list.concat(taicpu.op_none(A_BLR));
+      end;
+
+
     function tcgppcgen.fixref(list: TAsmList; var ref: treference): boolean;
       var
         tmpreg: tregister;