mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 16:09:26 +02:00
* don't use a_call_ref because it can use a parameter register
as temp
This commit is contained in:
parent
5a5b42e927
commit
bf0d3c730f
@ -553,6 +553,9 @@ implementation
|
||||
href,helpref : treference;
|
||||
para_alignment,
|
||||
pop_size : longint;
|
||||
{$ifndef usecallref}
|
||||
pvreg,
|
||||
{$endif usecallref}
|
||||
vmtreg,vmtreg2 : tregister;
|
||||
oldaktcallnode : tcallnode;
|
||||
|
||||
@ -646,47 +649,9 @@ implementation
|
||||
|
||||
|
||||
if (procdefinition.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_stdcall]) then
|
||||
para_alignment:=4
|
||||
para_alignment:=4
|
||||
else
|
||||
para_alignment:=aktalignment.paraalign;
|
||||
|
||||
{ proc variables destroy all registers }
|
||||
if (right=nil) and
|
||||
{ virtual methods too }
|
||||
not(po_virtualmethod in procdefinition.procoptions) then
|
||||
begin
|
||||
if (cs_check_io in aktlocalswitches) and
|
||||
(po_iocheck in procdefinition.procoptions) and
|
||||
not(po_iocheck in current_procinfo.procdef.procoptions) then
|
||||
begin
|
||||
objectlibrary.getaddrlabel(iolabel);
|
||||
cg.a_label(exprasmlist,iolabel);
|
||||
end
|
||||
else
|
||||
iolabel:=nil;
|
||||
|
||||
(*
|
||||
regs_to_alloc:=Tprocdef(procdefinition).usedintregisters;
|
||||
|
||||
{$ifdef i386}
|
||||
regs_to_push_other := tprocdef(procdefinition).usedotherregisters;
|
||||
{$else i386}
|
||||
regs_to_push_other := VOLATILE_FPUREGISTERS;
|
||||
{$endif i386}
|
||||
{ on the ppc, ever procedure saves the non-volatile registers it uses itself }
|
||||
{ and must make sure it saves its volatile registers before doing a call }
|
||||
{$ifdef i386}
|
||||
{ give used registers through }
|
||||
rg.used_in_proc_int:=rg.used_in_proc_int + tprocdef(procdefinition).usedintregisters;
|
||||
rg.used_in_proc_other:=rg.used_in_proc_other + tprocdef(procdefinition).usedotherregisters;
|
||||
{$endif i386}
|
||||
*)
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ no IO check for methods and procedure variables }
|
||||
iolabel:=nil;
|
||||
end;
|
||||
para_alignment:=aktalignment.paraalign;
|
||||
|
||||
regs_to_alloc:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
|
||||
regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
|
||||
@ -801,14 +766,28 @@ implementation
|
||||
vmtreg2:=rg.getabtregisterint(exprasmlist,OS_ADDR);
|
||||
rg.ungetregisterint(exprasmlist,vmtreg2);
|
||||
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,vmtreg,vmtreg2);
|
||||
|
||||
{$ifndef usecallref}
|
||||
pvreg:=rg.getabtregisterint(exprasmlist,OS_ADDR);
|
||||
reference_reset_base(href,vmtreg2,
|
||||
tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber));
|
||||
rg.ungetregisterint(exprasmlist,pvreg);
|
||||
cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,pvreg);
|
||||
{$endif usecallref}
|
||||
|
||||
{ free the resources allocated for the parameters }
|
||||
freeparas;
|
||||
|
||||
rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
|
||||
|
||||
{ call method }
|
||||
{$ifdef usecallref}
|
||||
reference_reset_base(href,vmtreg2,
|
||||
tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber));
|
||||
cg.a_call_ref(exprasmlist,href);
|
||||
{$else usecallref}
|
||||
cg.a_call_reg(exprasmlist,pvreg);
|
||||
{$endif usecallref}
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -829,6 +808,8 @@ implementation
|
||||
{$ifdef i386}
|
||||
secondpass(right);
|
||||
{$endif i386}
|
||||
|
||||
{$ifdef usecallref}
|
||||
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||
begin
|
||||
helpref:=right.location.reference;
|
||||
@ -850,26 +831,38 @@ implementation
|
||||
end
|
||||
else
|
||||
rg.ungetregisterint(exprasmlist,right.location.register);
|
||||
|
||||
location_freetemp(exprasmlist,right.location);
|
||||
{$else usecallref}
|
||||
pvreg:=rg.getabtregisterint(exprasmlist,OS_ADDR);
|
||||
rg.ungetregisterint(exprasmlist,pvreg);
|
||||
{ Only load OS_ADDR from the reference }
|
||||
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||
cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,right.location.reference,pvreg)
|
||||
else
|
||||
cg.a_load_loc_reg(exprasmlist,OS_ADDR,right.location,pvreg);
|
||||
location_release(exprasmlist,right.location);
|
||||
location_freetemp(exprasmlist,right.location);
|
||||
{$endif usecallref}
|
||||
|
||||
{ free the resources allocated for the parameters }
|
||||
freeparas;
|
||||
|
||||
rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
|
||||
|
||||
{ Calling interrupt from the same code requires some
|
||||
extra code }
|
||||
if (po_interrupt in procdefinition.procoptions) then
|
||||
extra_interrupt_code;
|
||||
|
||||
rg.saveotherregvars(exprasmlist,ALL_OTHERREGISTERS);
|
||||
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||
cg.a_call_ref(exprasmlist,helpref)
|
||||
else
|
||||
cg.a_call_reg(exprasmlist,right.location.register);
|
||||
{ cg.a_call_loc(exprasmlist,right.location);}
|
||||
location_release(exprasmlist,right.location);
|
||||
location_freetemp(exprasmlist,right.location);
|
||||
rg.saveotherregvars(exprasmlist,ALL_OTHERREGISTERS);
|
||||
{$ifdef usecallref}
|
||||
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||
cg.a_call_ref(exprasmlist,helpref)
|
||||
else
|
||||
cg.a_call_reg(exprasmlist,right.location.register);
|
||||
{$else usecallref}
|
||||
cg.a_call_reg(exprasmlist,pvreg);
|
||||
{$endif usecallref}
|
||||
end;
|
||||
|
||||
{ Need to remove the parameters from the stack? }
|
||||
@ -926,11 +919,13 @@ implementation
|
||||
location_reset(location,LOC_VOID,OS_NO);
|
||||
|
||||
{ perhaps i/o check ? }
|
||||
if iolabel<>nil then
|
||||
if (cs_check_io in aktlocalswitches) and
|
||||
(po_iocheck in procdefinition.procoptions) and
|
||||
not(po_iocheck in current_procinfo.procdef.procoptions) and
|
||||
{ no IO check for methods and procedure variables }
|
||||
(right=nil) and
|
||||
not(po_virtualmethod in procdefinition.procoptions) then
|
||||
begin
|
||||
//reference_reset_symbol(href,iolabel,0);
|
||||
//cg.a_paramaddr_ref(exprasmlist,href,paramanager.getintparaloc(exprasmlist,1));
|
||||
//paramanager.freeintparaloc(exprasmlist,1);
|
||||
rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
||||
cg.a_call_name(exprasmlist,'FPC_IOCHECK');
|
||||
rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
||||
@ -976,8 +971,6 @@ implementation
|
||||
unusedstate: pointer;
|
||||
pushedother : tpushedsavedother;
|
||||
oldpushedparasize : longint;
|
||||
{ adress returned from an I/O-error }
|
||||
iolabel : tasmlabel;
|
||||
oldaktcallnode : tcallnode;
|
||||
oldprocdef : tprocdef;
|
||||
i : longint;
|
||||
@ -1103,7 +1096,6 @@ implementation
|
||||
end;
|
||||
{$endif GDB}
|
||||
|
||||
iolabel:=nil;
|
||||
rg.saveunusedstate(unusedstate);
|
||||
|
||||
{ if we allocate the temp. location for ansi- or widestrings }
|
||||
@ -1119,22 +1111,8 @@ implementation
|
||||
cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
|
||||
end;
|
||||
|
||||
if (cs_check_io in aktlocalswitches) and
|
||||
(po_iocheck in procdefinition.procoptions) and
|
||||
not(po_iocheck in current_procinfo.procdef.procoptions) then
|
||||
begin
|
||||
objectlibrary.getaddrlabel(iolabel);
|
||||
cg.a_label(exprasmlist,iolabel);
|
||||
end
|
||||
else
|
||||
iolabel:=nil;
|
||||
|
||||
{ save all used registers and possible registers
|
||||
used for the return value }
|
||||
(*
|
||||
regs_to_push_int := tprocdef(procdefinition).usedintregisters;
|
||||
regs_to_push_other := tprocdef(procdefinition).usedotherregisters;
|
||||
*)
|
||||
regs_to_push_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
|
||||
regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
|
||||
if (not is_void(resulttype.def)) then
|
||||
@ -1157,14 +1135,6 @@ implementation
|
||||
|
||||
rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
|
||||
|
||||
(*
|
||||
{$ifdef i386}
|
||||
{ give used registers through }
|
||||
rg.used_in_proc_int:=rg.used_in_proc_int + tprocdef(procdefinition).usedintregisters;
|
||||
rg.used_in_proc_other:=rg.used_in_proc_other + tprocdef(procdefinition).usedotherregisters;
|
||||
{$endif i386}
|
||||
*)
|
||||
|
||||
{ Initialize for pushing the parameters }
|
||||
oldpushedparasize:=pushedparasize;
|
||||
pushedparasize:=0;
|
||||
@ -1232,14 +1202,6 @@ implementation
|
||||
tg.UnGetTemp(exprasmlist,pararef);
|
||||
current_procinfo.procdef.parast.address_fixup:=old_para_fixup;
|
||||
end;
|
||||
{ free return reference }
|
||||
if (resulttype.def.size>0) then
|
||||
begin
|
||||
{ from now on the result can be freed normally }
|
||||
// if assigned(funcretnode) and
|
||||
// paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption) then
|
||||
// tg.ChangeTempType(exprasmlist,funcretnode.location.reference,tt_normal);
|
||||
end;
|
||||
|
||||
{ handle function results }
|
||||
if (not is_void(resulttype.def)) then
|
||||
@ -1248,11 +1210,13 @@ implementation
|
||||
location_reset(location,LOC_VOID,OS_NO);
|
||||
|
||||
{ perhaps i/o check ? }
|
||||
if iolabel<>nil then
|
||||
if (cs_check_io in aktlocalswitches) and
|
||||
(po_iocheck in procdefinition.procoptions) and
|
||||
not(po_iocheck in current_procinfo.procdef.procoptions) and
|
||||
{ no IO check for methods and procedure variables }
|
||||
(right=nil) and
|
||||
not(po_virtualmethod in procdefinition.procoptions) then
|
||||
begin
|
||||
//reference_reset_symbol(href,iolabel,0);
|
||||
//cg.a_paramaddr_ref(exprasmlist,href,paramanager.getintparaloc(exprasmlist,1));
|
||||
//paramanager.freeintparaloc(exprasmlist,1);
|
||||
rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
||||
cg.a_call_name(exprasmlist,'FPC_IOCHECK');
|
||||
rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
||||
@ -1335,7 +1299,11 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.113 2003-09-11 11:54:59 florian
|
||||
Revision 1.114 2003-09-14 19:17:39 peter
|
||||
* don't use a_call_ref because it can use a parameter register
|
||||
as temp
|
||||
|
||||
Revision 1.113 2003/09/11 11:54:59 florian
|
||||
* improved arm code generation
|
||||
* move some protected and private field around
|
||||
* the temp. register for register parameters/arguments are now released
|
||||
|
Loading…
Reference in New Issue
Block a user