mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 01:09:31 +02:00
* removevaluepara added to fix the stackpointer so restoring of
saved registers works
This commit is contained in:
parent
7d02a4f264
commit
a4e309d6ae
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user