* fixed code generation for -Og switch

* copied createtempparaloc() method from i386 parameter manager to avoid copying for larger value parameters (see 2692)
* do not copy memory if references are equal in g_concatcopy()
* do not emit some strings used for debugging into assembly file in g_concatcopy by default anymore
* simplification of boolean expression in calc_stackframe_size()

git-svn-id: trunk@2694 -
This commit is contained in:
tom_at_work 2006-02-26 17:30:49 +00:00
parent a9dbc0c8ab
commit b309574e22
3 changed files with 43 additions and 15 deletions

View File

@ -154,7 +154,14 @@ type
immediate as required by some PowerPC instructions }
function hasLargeOffset(const ref : TReference) : Boolean; inline;
procedure a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean; addNOP : boolean);
{ generates code to call a method with the given string name. The boolean options
control code generation. If prependDot is true, a single dot character is prepended to
the string, if addNOP is true a single NOP instruction is added after the call, and
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: taasmoutput; s: string; prependDot : boolean;
addNOP : boolean; includeCall : boolean = true);
{ emits code to store the given value a into the TOC (if not already in there), and load it from there
as well }
@ -552,7 +559,7 @@ begin
a_call_name_direct(list, s, true, true);
end;
procedure tcgppc.a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean; addNOP : boolean);
procedure tcgppc.a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean; addNOP : boolean; includeCall : boolean);
begin
if (prependDot) then
s := '.' + s;
@ -560,9 +567,9 @@ begin
AT_FUNCTION)));
if (addNOP) then
list.concat(taicpu.op_none(A_NOP));
{ the compiler does not properly set this flag anymore in pass 1, and
for now we only need it after pass 2 (I hope) (JM) }
include(current_procinfo.flags, pi_do_call);
if (includeCall) then
include(current_procinfo.flags, pi_do_call);
end;
@ -1326,12 +1333,12 @@ var
mayNeedLRStore := 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, '_savegpr1_' + intToStr(32-gprcount), false, false);
a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false);
a_call_name_direct(list, '_savegpr1_' + intToStr(32-gprcount), false, false, false);
a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false, false);
end else if (gprcount > 0) then
a_call_name_direct(list, '_savegpr0_' + intToStr(32-gprcount), false, false)
a_call_name_direct(list, '_savegpr0_' + intToStr(32-gprcount), false, false, false)
else if (fprcount > 0) then
a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false)
a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false, false)
else
mayNeedLRStore := true;
end else begin
@ -1461,7 +1468,7 @@ var
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);
a_call_name_direct(list, '_restgpr1_' + intToStr(32-gprcount), false, false, false);
a_jmp_name(list, '_restfpr_' + intToStr(32-fprcount));
end else if (gprcount > 0) then
a_jmp_name(list, '_restgpr0_' + intToStr(32-gprcount))
@ -1520,7 +1527,6 @@ begin
{ calculate stack frame }
localsize := tppcprocinfo(current_procinfo).calc_stackframe_size(
gprcount, fprcount);
{ CR register not supported }
{ restore stack pointer }
@ -1656,15 +1662,21 @@ begin
internalerror(2002072704);
list.concat(tai_comment.create(strpnew('g_concatcopy1 ' + inttostr(len) + ' bytes left ')));
{$ENDIF extdebug}
{ if the references are equal, exit, there is no need to copy anything }
if (references_equal(source, dest)) then
exit;
{ make sure short loads are handled as optimally as possible;
note that the data here never overlaps, so we can do a forward
copy at all times.
NOTE: maybe use some scratch registers to pair load/store instructions
}
if (len <= maxmoveunit) then begin
src := source; dst := dest;
{$IFDEF extdebug}
list.concat(tai_comment.create(strpnew('g_concatcopy3 ' + inttostr(src.offset) + ' ' + inttostr(dst.offset))));
{$ENDIF extdebug}
while (len <> 0) do begin
if (len = 8) then begin
a_load_ref_ref(list, OS_64, OS_64, src, dst);
@ -2167,7 +2179,7 @@ begin
ref.refaddr := addr_pic;
{$IFDEF EXTDEBUG}
list.concat(tai_comment.create(strpnew('loading value from TOC reference for ' + symbol)));
list.concat(tai_comment.create(strpnew('loading value from TOC reference for ' + symname)));
{$ENDIF EXTDEBUG}
cg.a_load_ref_reg(list, OS_INT, OS_INT, ref, reg);
end;

View File

@ -47,6 +47,7 @@ type
tvarargsparalist): longint; override;
procedure create_funcretloc_info(p: tabstractprocdef; side: tcallercallee);
procedure createtempparaloc(list: taasmoutput;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
private
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister;
var cur_stack_offset: aword);
@ -487,6 +488,20 @@ begin
result := true;
end;
procedure tppcparamanager.createtempparaloc(list: taasmoutput;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
var
paraloc : pcgparalocation;
begin
paraloc:=parasym.paraloc[callerside].location;
{ Do not create a temporary if the value is pushed }
if assigned(paraloc) and
(paraloc^.loc=LOC_REFERENCE) and
(paraloc^.reference.index=NR_STACK_POINTER_REG) then
duplicateparaloc(list,calloption,parasym,cgpara)
else
inherited createtempparaloc(list,calloption,parasym,cgpara);
end;
begin
paramanager := tppcparamanager.create;
end.

View File

@ -106,9 +106,10 @@ begin
result := align(numgpr * tcgsize2size[OS_INT] +
numfpr * tcgsize2size[OS_FLOAT], ELF_STACK_ALIGN);
if not ((not (pi_do_call in flags)) and (tg.lasttemp = tg.firsttemp) and
(result <= RED_ZONE_SIZE)) then
if (pi_do_call in flags) or (tg.lasttemp <> tg.firsttemp) or
(result > RED_ZONE_SIZE) then begin
result := align(result + tg.lasttemp, ELF_STACK_ALIGN);
end;
end else
result := align(tg.lasttemp, ELF_STACK_ALIGN);
end;