|
@@ -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
|