mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 22:06:40 +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
|
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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user