* removevaluepara added to fix the stackpointer so restoring of

saved registers works
This commit is contained in:
peter 2002-09-01 14:42:41 +00:00
parent 7d02a4f264
commit a4e309d6ae
2 changed files with 92 additions and 18 deletions

View File

@ -116,25 +116,30 @@ implementation
begin begin
{ always calculate boolean AND and OR from left to right } { always calculate boolean AND and OR from left to right }
if (p.nodetype in [orn,andn]) and if (p.nodetype in [orn,andn]) and
(p.left.resulttype.def.deftype=orddef) and is_boolean(p.left.resulttype.def) then
(torddef(p.left.resulttype.def).typ in [bool8bit,bool16bit,bool32bit]) then
begin begin
{ p.swaped:=false}
if nf_swaped in p.flags then if nf_swaped in p.flags then
internalerror(234234); internalerror(234234);
end end
else else
if (((p.location.loc=LOC_FPUREGISTER) and if (
(p.right.registersfpu > p.left.registersfpu)) or (p.location.loc=LOC_FPUREGISTER) and
((((p.left.registersfpu = 0) and (p.right.registersfpu > p.left.registersfpu)
(p.right.registersfpu = 0)) or ) or
(p.location.loc<>LOC_FPUREGISTER)) and (
(p.left.registers32<p.right.registers32))) and (
{ the following check is appropriate, because all } (
{ 4 registers are rarely used and it is thereby } ((p.left.registersfpu = 0) and (p.right.registersfpu = 0)) or
{ achieved that the extra code is being dropped } (p.location.loc<>LOC_FPUREGISTER)
{ by exchanging not commutative operators } ) and
(p.right.registers32<=c_countusableregsint) then (p.left.registers32<p.right.registers32)
) and
{ the following check is appropriate, because all }
{ 4 registers are rarely used and it is thereby }
{ achieved that the extra code is being dropped }
{ by exchanging not commutative operators }
(p.right.registers32<=c_countusableregsint)
) then
begin begin
hp:=p.left; hp:=p.left;
p.left:=p.right; p.left:=p.right;
@ -764,7 +769,13 @@ implementation
if inlined then if inlined then
begin begin
reference_reset_base(href,procinfo.framepointer,para_offset-pushedparasize); reference_reset_base(href,procinfo.framepointer,para_offset-pushedparasize);
cg64.a_load64_loc_ref(exprasmlist,p.location,href); if p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
begin
size:=align(p.resulttype.def.size,alignment);
cg.g_concatcopy(exprasmlist,p.location.reference,href,size,false,false)
end
else
cg64.a_load64_loc_ref(exprasmlist,p.location,href);
end end
else else
cg64.a_param64_loc(exprasmlist,p.location,locpara); cg64.a_param64_loc(exprasmlist,p.location,locpara);
@ -795,7 +806,13 @@ implementation
if inlined then if inlined then
begin begin
reference_reset_base(href,procinfo.framepointer,para_offset-pushedparasize); reference_reset_base(href,procinfo.framepointer,para_offset-pushedparasize);
cg.a_load_loc_ref(exprasmlist,p.location,href); if p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
begin
size:=align(p.resulttype.def.size,alignment);
cg.g_concatcopy(exprasmlist,p.location.reference,href,size,false,false)
end
else
cg.a_load_loc_ref(exprasmlist,p.location,href);
end end
else else
cg.a_param_loc(exprasmlist,p.location,locpara); cg.a_param_loc(exprasmlist,p.location,locpara);
@ -857,6 +874,24 @@ implementation
end; end;
procedure removevalueparas(p : tnamedindexitem;arg:pointer);
var
href1 : treference;
list : taasmoutput;
begin
list:=taasmoutput(arg);
if (tsym(p).typ=varsym) and
(tvarsym(p).varspez=vs_value) and
(is_open_array(tvarsym(p).vartype.def) or
is_array_of_const(tvarsym(p).vartype.def)) and
(paramanager.push_addr_param(tvarsym(p).vartype.def,false)) then
begin
reference_reset_base(href1,procinfo.framepointer,tvarsym(p).address+procinfo.para_offset);
cg.g_removevaluepara_openarray(list,href1,tarraydef(tvarsym(p).vartype.def).elesize);
end;
end;
procedure initialize_threadvar(p : tnamedindexitem;arg:pointer); procedure initialize_threadvar(p : tnamedindexitem;arg:pointer);
var var
href : treference; href : treference;
@ -1565,6 +1600,14 @@ implementation
end; end;
{$endif GDB} {$endif GDB}
{ remove copies of call by value parameters when there are also
registers saved on the stack }
if ((po_saveregisters in aktprocdef.procoptions) or
(po_savestdregs in aktprocdef.procoptions)) and
not(po_assembler in aktprocdef.procoptions) and
not(aktprocdef.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_palmossyscall,pocall_system]) then
aktprocdef.parast.foreach_static({$ifndef TP}@{$endif}removevalueparas,list);
{ for the save all registers we can simply use a pusha,popa which { for the save all registers we can simply use a pusha,popa which
push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax } push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
if (po_saveregisters in aktprocdef.procoptions) then if (po_saveregisters in aktprocdef.procoptions) then
@ -1732,7 +1775,11 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.43 2002-08-25 19:25:18 peter Revision 1.44 2002-09-01 14:42:41 peter
* removevaluepara added to fix the stackpointer so restoring of
saved registers works
Revision 1.43 2002/08/25 19:25:18 peter
* sym.insert_in_data removed * sym.insert_in_data removed
* symtable.insertvardata/insertconstdata added * symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be * removed insert_in_data call from symtable.insert, it needs to be

View File

@ -107,6 +107,7 @@ unit cgx86;
{ entry/exit code helpers } { entry/exit code helpers }
procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer);override; procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer);override;
procedure g_removevaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer);override;
procedure g_interrupt_stackframe_entry(list : taasmoutput);override; procedure g_interrupt_stackframe_entry(list : taasmoutput);override;
procedure g_interrupt_stackframe_exit(list : taasmoutput;selfused,accused,acchiused:boolean);override; procedure g_interrupt_stackframe_exit(list : taasmoutput;selfused,accused,acchiused:boolean);override;
procedure g_profilecode(list : taasmoutput);override; procedure g_profilecode(list : taasmoutput);override;
@ -1347,6 +1348,28 @@ unit cgx86;
end; end;
procedure tcgx86.g_removevaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer);
var
lenref : treference;
power,len : longint;
begin
lenref:=ref;
inc(lenref.offset,4);
{ caluclate size and adjust stack space }
rg.getexplicitregisterint(list,R_EDI);
list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,R_EDI));
list.concat(Taicpu.op_reg(A_INC,S_L,R_EDI));
if (elesize<>1) then
begin
if ispowerof2(elesize, power) then
list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,R_EDI))
else
list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,R_EDI));
end;
list.concat(Taicpu.op_reg_reg(A_ADD,S_L,R_EDI,R_ESP));
end;
procedure tcgx86.g_interrupt_stackframe_entry(list : taasmoutput); procedure tcgx86.g_interrupt_stackframe_entry(list : taasmoutput);
begin begin
{ .... also the segment registers } { .... also the segment registers }
@ -1651,7 +1674,11 @@ unit cgx86;
end. end.
{ {
$Log$ $Log$
Revision 1.13 2002-09-01 12:09:27 peter Revision 1.14 2002-09-01 14:42:41 peter
* removevaluepara added to fix the stackpointer so restoring of
saved registers works
Revision 1.13 2002/09/01 12:09:27 peter
+ a_call_reg, a_call_loc added + a_call_reg, a_call_loc added
* removed exprasmlist references * removed exprasmlist references