mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 08:09:33 +02:00
* 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 -
This commit is contained in:
parent
3fc1a274c8
commit
cec20e1c34
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user