* 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
{ always calculate boolean AND and OR from left to right }
if (p.nodetype in [orn,andn]) and
(p.left.resulttype.def.deftype=orddef) and
(torddef(p.left.resulttype.def).typ in [bool8bit,bool16bit,bool32bit]) then
is_boolean(p.left.resulttype.def) then
begin
{ p.swaped:=false}
if nf_swaped in p.flags then
internalerror(234234);
end
else
if (((p.location.loc=LOC_FPUREGISTER) and
(p.right.registersfpu > p.left.registersfpu)) or
((((p.left.registersfpu = 0) and
(p.right.registersfpu = 0)) 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 }
{ achieved that the extra code is being dropped }
{ by exchanging not commutative operators }
(p.right.registers32<=c_countusableregsint) then
if (
(p.location.loc=LOC_FPUREGISTER) and
(p.right.registersfpu > p.left.registersfpu)
) or
(
(
(
((p.left.registersfpu = 0) and (p.right.registersfpu = 0)) 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 }
{ achieved that the extra code is being dropped }
{ by exchanging not commutative operators }
(p.right.registers32<=c_countusableregsint)
) then
begin
hp:=p.left;
p.left:=p.right;
@ -764,7 +769,13 @@ implementation
if inlined then
begin
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
else
cg64.a_param64_loc(exprasmlist,p.location,locpara);
@ -795,7 +806,13 @@ implementation
if inlined then
begin
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
else
cg.a_param_loc(exprasmlist,p.location,locpara);
@ -857,6 +874,24 @@ implementation
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);
var
href : treference;
@ -1565,6 +1600,14 @@ implementation
end;
{$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
push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax }
if (po_saveregisters in aktprocdef.procoptions) then
@ -1732,7 +1775,11 @@ implementation
end.
{
$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
* symtable.insertvardata/insertconstdata added
* removed insert_in_data call from symtable.insert, it needs to be

View File

@ -107,6 +107,7 @@ unit cgx86;
{ entry/exit code helpers }
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_exit(list : taasmoutput;selfused,accused,acchiused:boolean);override;
procedure g_profilecode(list : taasmoutput);override;
@ -1347,6 +1348,28 @@ unit cgx86;
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);
begin
{ .... also the segment registers }
@ -1651,7 +1674,11 @@ unit cgx86;
end.
{
$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
* removed exprasmlist references