diff --git a/compiler/powerpc64/cgcpu.pas b/compiler/powerpc64/cgcpu.pas index e9eeb153cf..b03717a851 100644 --- a/compiler/powerpc64/cgcpu.pas +++ b/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