浏览代码

* specify the branch opcode to use for a_call_name_direct/a_jmp_name_direct,
because it's sometimes different for AIX and other platforms (AIX uses
absolute branches for entry/exit code helpers)

git-svn-id: trunk@21050 -

Jonas Maebe 13 年之前
父节点
当前提交
cec20e1c34
共有 1 个文件被更改,包括 34 次插入19 次删除
  1. 34 19
      compiler/powerpc64/cgcpu.pas

+ 34 - 19
compiler/powerpc64/cgcpu.pas

@@ -127,10 +127,10 @@ type
      if includeCall is true, the method is marked as having a call, not if false. This
      option is particularly useful to prevent generation of a larger stack frame for the
      register save and restore helper functions. }
-    procedure a_call_name_direct(list: TAsmList; s: string; weak: boolean; prependDot : boolean;
+    procedure a_call_name_direct(list: TAsmList; opc: tasmop; s: string; weak: boolean; prependDot : boolean;
       addNOP : boolean; includeCall : boolean = true);
 
-    procedure a_jmp_name_direct(list : TAsmList; s : string; prependDot : boolean);
+    procedure a_jmp_name_direct(list : TAsmList; opc: tasmop; s : string; prependDot : boolean);
 
     { emits code to store the given value a into the TOC (if not already in there), and load it from there
      as well }
@@ -387,7 +387,7 @@ end;
 procedure tcgppc.a_call_name(list: TAsmList; const s: string; weak: boolean);
 begin
     if (target_info.system <> system_powerpc64_darwin) then
-      a_call_name_direct(list, s, weak, false, true)
+      a_call_name_direct(list, A_BL, s, weak, target_info.system=system_powerpc64_aix, true)
     else
       begin
         list.concat(taicpu.op_sym(A_BL,get_darwin_call_stub(s,weak)));
@@ -396,14 +396,14 @@ begin
 end;
 
 
-procedure tcgppc.a_call_name_direct(list: TAsmList; s: string; weak: boolean; prependDot : boolean; addNOP : boolean; includeCall : boolean);
+procedure tcgppc.a_call_name_direct(list: TAsmList; opc: tasmop; s: string; weak: boolean; prependDot : boolean; addNOP : boolean; includeCall : boolean);
 begin
   if (prependDot) then
     s := '.' + s;
   if not(weak) then
-    list.concat(taicpu.op_sym(A_BL, current_asmdata.RefAsmSymbol(s)))
+    list.concat(taicpu.op_sym(opc, current_asmdata.RefAsmSymbol(s)))
   else
-    list.concat(taicpu.op_sym(A_BL, current_asmdata.WeakRefAsmSymbol(s)));
+    list.concat(taicpu.op_sym(opc, current_asmdata.WeakRefAsmSymbol(s)));
   if (addNOP) then
     list.concat(taicpu.op_none(A_NOP));
 
@@ -452,7 +452,7 @@ begin
     in R11 }
     a_reg_alloc(list, NR_R11);
     a_load_reg_reg(list, OS_ADDR, OS_ADDR, reg, NR_R11);
-    a_call_name_direct(list, '.ptrgl', false, false, false);
+    a_call_name_direct(list, A_BL, '.ptrgl', false, false, false);
     a_reg_dealloc(list, NR_R11);
   end;
 
@@ -1100,13 +1100,13 @@ begin
   a_jmp(list, A_BC, TOpCmp2AsmCond[cmp_op], 0, l);
 end;
 
-procedure tcgppc.a_jmp_name_direct(list : TAsmList; s : string; prependDot : boolean);
+procedure tcgppc.a_jmp_name_direct(list : TAsmList; opc: tasmop; s : string; prependDot : boolean);
 var
   p: taicpu;
 begin
   if (prependDot) then
     s := '.' + s;
-  p := taicpu.op_sym(A_B, current_asmdata.RefAsmSymbol(s));
+  p := taicpu.op_sym(opc, current_asmdata.RefAsmSymbol(s));
   p.is_jmp := true;
   list.concat(p)
 end;
@@ -1122,7 +1122,7 @@ begin
       list.concat(p)
     end
   else
-    a_jmp_name_direct(list, s, true);
+    a_jmp_name_direct(list, A_B, s, true);
 end;
 
 procedure tcgppc.a_jmp_always(list: TAsmList; l: tasmlabel);
@@ -1292,7 +1292,7 @@ procedure tcgppc.g_profilecode(list: TAsmList);
 begin
   current_procinfo.procdef.paras.ForEachCall(TObjectListCallback(@profilecode_savepara), list);
 
-  a_call_name_direct(list, '_mcount', false, false, true);
+  a_call_name_direct(list, A_BL, '_mcount', false, false, true);
 
   current_procinfo.procdef.paras.ForEachCall(TObjectListCallback(@profilecode_restorepara), list);
 end;
@@ -1321,6 +1321,7 @@ var
     regcount : TSuperRegister;
     href : TReference;
     mayNeedLRStore : boolean;
+    opc : tasmop;
   begin
     { there are two ways to do this: manually, by generating a few "std" instructions,
      or via the restore helper functions. The latter are selected by the -Og switch,
@@ -1329,13 +1330,17 @@ var
        (target_info.system <> system_powerpc64_darwin) then begin
       mayNeedLRStore := false;
       if ((fprcount > 0) and (gprcount > 0)) then begin
+        if target_info.system=system_powerpc64_aix then
+          opc:=A_BLA
+        else
+          opc:=A_BL;
         a_op_const_reg_reg(list, OP_SUB, OS_INT, 8 * fprcount, NR_R1, NR_R12);
-        a_call_name_direct(list, '_savegpr1_' + intToStr(32-gprcount), false, false, false, false);
-        a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false, false, false);
+        a_call_name_direct(list, opc, '_savegpr1_' + intToStr(32-gprcount), false, false, false, false);
+        a_call_name_direct(list, opc, '_savefpr_' + intToStr(32-fprcount), false, false, false, false);
       end else if (gprcount > 0) then
-        a_call_name_direct(list, '_savegpr0_' + intToStr(32-gprcount), false, false, false, false)
+        a_call_name_direct(list, opc, '_savegpr0_' + intToStr(32-gprcount), false, false, false, false)
       else if (fprcount > 0) then
-        a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false, false, false)
+        a_call_name_direct(list, opc, '_savefpr_' + intToStr(32-fprcount), false, false, false, false)
       else
         mayNeedLRStore := true;
     end else begin
@@ -1459,20 +1464,30 @@ var
     needsExitCode : Boolean;
     href : treference;
     regcount : TSuperRegister;
+    callopc,
+    jmpopc: tasmop;
   begin
     { there are two ways to do this: manually, by generating a few "ld" instructions,
      or via the restore helper functions. The latter are selected by the -Og switch,
      i.e. "optimize for size" }
     if (cs_opt_size in current_settings.optimizerswitches) then begin
+      if target_info.system=system_powerpc64_aix then begin
+        callopc:=A_BLA;
+        jmpopc:=A_BA;
+      end
+      else begin
+        callopc:=A_BL;
+        jmpopc:=A_B;
+      end;
       needsExitCode := false;
       if ((fprcount > 0) and (gprcount > 0)) then begin
         a_op_const_reg_reg(list, OP_SUB, OS_INT, 8 * fprcount, NR_R1, NR_R12);
-        a_call_name_direct(list, '_restgpr1_' + intToStr(32-gprcount), false, false, false, false);
-        a_jmp_name_direct(list, '_restfpr_' + intToStr(32-fprcount), false);
+        a_call_name_direct(list, callopc, '_restgpr1_' + intToStr(32-gprcount), false, false, false, false);
+        a_jmp_name_direct(list, jmpopc, '_restfpr_' + intToStr(32-fprcount), false);
       end else if (gprcount > 0) then
-        a_jmp_name_direct(list, '_restgpr0_' + intToStr(32-gprcount), false)
+        a_jmp_name_direct(list, jmpopc, '_restgpr0_' + intToStr(32-gprcount), false)
       else if (fprcount > 0) then
-        a_jmp_name_direct(list, '_restfpr_' + intToStr(32-fprcount), false)
+        a_jmp_name_direct(list, jmpopc, '_restfpr_' + intToStr(32-fprcount), false)
       else
         needsExitCode := true;
     end else begin