mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-20 10:49:20 +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;
|
href,helpref : treference;
|
||||||
para_alignment,
|
para_alignment,
|
||||||
pop_size : longint;
|
pop_size : longint;
|
||||||
|
{$ifndef usecallref}
|
||||||
|
pvreg,
|
||||||
|
{$endif usecallref}
|
||||||
vmtreg,vmtreg2 : tregister;
|
vmtreg,vmtreg2 : tregister;
|
||||||
oldaktcallnode : tcallnode;
|
oldaktcallnode : tcallnode;
|
||||||
|
|
||||||
@ -646,47 +649,9 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
if (procdefinition.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_stdcall]) then
|
if (procdefinition.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_stdcall]) then
|
||||||
para_alignment:=4
|
para_alignment:=4
|
||||||
else
|
else
|
||||||
para_alignment:=aktalignment.paraalign;
|
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;
|
|
||||||
|
|
||||||
regs_to_alloc:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
|
regs_to_alloc:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
|
||||||
regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
|
regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
|
||||||
@ -801,14 +766,28 @@ implementation
|
|||||||
vmtreg2:=rg.getabtregisterint(exprasmlist,OS_ADDR);
|
vmtreg2:=rg.getabtregisterint(exprasmlist,OS_ADDR);
|
||||||
rg.ungetregisterint(exprasmlist,vmtreg2);
|
rg.ungetregisterint(exprasmlist,vmtreg2);
|
||||||
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,vmtreg,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 }
|
{ free the resources allocated for the parameters }
|
||||||
freeparas;
|
freeparas;
|
||||||
|
|
||||||
rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
|
rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
|
||||||
|
|
||||||
{ call method }
|
{ call method }
|
||||||
|
{$ifdef usecallref}
|
||||||
reference_reset_base(href,vmtreg2,
|
reference_reset_base(href,vmtreg2,
|
||||||
tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber));
|
tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber));
|
||||||
cg.a_call_ref(exprasmlist,href);
|
cg.a_call_ref(exprasmlist,href);
|
||||||
|
{$else usecallref}
|
||||||
|
cg.a_call_reg(exprasmlist,pvreg);
|
||||||
|
{$endif usecallref}
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -829,6 +808,8 @@ implementation
|
|||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
secondpass(right);
|
secondpass(right);
|
||||||
{$endif i386}
|
{$endif i386}
|
||||||
|
|
||||||
|
{$ifdef usecallref}
|
||||||
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||||
begin
|
begin
|
||||||
helpref:=right.location.reference;
|
helpref:=right.location.reference;
|
||||||
@ -850,26 +831,38 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
rg.ungetregisterint(exprasmlist,right.location.register);
|
rg.ungetregisterint(exprasmlist,right.location.register);
|
||||||
|
|
||||||
location_freetemp(exprasmlist,right.location);
|
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 }
|
{ free the resources allocated for the parameters }
|
||||||
freeparas;
|
freeparas;
|
||||||
|
|
||||||
rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
|
rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
|
||||||
|
|
||||||
{ Calling interrupt from the same code requires some
|
{ Calling interrupt from the same code requires some
|
||||||
extra code }
|
extra code }
|
||||||
if (po_interrupt in procdefinition.procoptions) then
|
if (po_interrupt in procdefinition.procoptions) then
|
||||||
extra_interrupt_code;
|
extra_interrupt_code;
|
||||||
|
|
||||||
rg.saveotherregvars(exprasmlist,ALL_OTHERREGISTERS);
|
rg.saveotherregvars(exprasmlist,ALL_OTHERREGISTERS);
|
||||||
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
{$ifdef usecallref}
|
||||||
cg.a_call_ref(exprasmlist,helpref)
|
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||||
else
|
cg.a_call_ref(exprasmlist,helpref)
|
||||||
cg.a_call_reg(exprasmlist,right.location.register);
|
else
|
||||||
{ cg.a_call_loc(exprasmlist,right.location);}
|
cg.a_call_reg(exprasmlist,right.location.register);
|
||||||
location_release(exprasmlist,right.location);
|
{$else usecallref}
|
||||||
location_freetemp(exprasmlist,right.location);
|
cg.a_call_reg(exprasmlist,pvreg);
|
||||||
|
{$endif usecallref}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Need to remove the parameters from the stack? }
|
{ Need to remove the parameters from the stack? }
|
||||||
@ -926,11 +919,13 @@ implementation
|
|||||||
location_reset(location,LOC_VOID,OS_NO);
|
location_reset(location,LOC_VOID,OS_NO);
|
||||||
|
|
||||||
{ perhaps i/o check ? }
|
{ 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
|
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));
|
rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
||||||
cg.a_call_name(exprasmlist,'FPC_IOCHECK');
|
cg.a_call_name(exprasmlist,'FPC_IOCHECK');
|
||||||
rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
||||||
@ -976,8 +971,6 @@ implementation
|
|||||||
unusedstate: pointer;
|
unusedstate: pointer;
|
||||||
pushedother : tpushedsavedother;
|
pushedother : tpushedsavedother;
|
||||||
oldpushedparasize : longint;
|
oldpushedparasize : longint;
|
||||||
{ adress returned from an I/O-error }
|
|
||||||
iolabel : tasmlabel;
|
|
||||||
oldaktcallnode : tcallnode;
|
oldaktcallnode : tcallnode;
|
||||||
oldprocdef : tprocdef;
|
oldprocdef : tprocdef;
|
||||||
i : longint;
|
i : longint;
|
||||||
@ -1103,7 +1096,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
{$endif GDB}
|
{$endif GDB}
|
||||||
|
|
||||||
iolabel:=nil;
|
|
||||||
rg.saveunusedstate(unusedstate);
|
rg.saveunusedstate(unusedstate);
|
||||||
|
|
||||||
{ if we allocate the temp. location for ansi- or widestrings }
|
{ if we allocate the temp. location for ansi- or widestrings }
|
||||||
@ -1119,22 +1111,8 @@ implementation
|
|||||||
cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
|
cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
|
||||||
end;
|
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
|
{ save all used registers and possible registers
|
||||||
used for the return value }
|
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_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
|
||||||
regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
|
regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption);
|
||||||
if (not is_void(resulttype.def)) then
|
if (not is_void(resulttype.def)) then
|
||||||
@ -1157,14 +1135,6 @@ implementation
|
|||||||
|
|
||||||
rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
|
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 }
|
{ Initialize for pushing the parameters }
|
||||||
oldpushedparasize:=pushedparasize;
|
oldpushedparasize:=pushedparasize;
|
||||||
pushedparasize:=0;
|
pushedparasize:=0;
|
||||||
@ -1232,14 +1202,6 @@ implementation
|
|||||||
tg.UnGetTemp(exprasmlist,pararef);
|
tg.UnGetTemp(exprasmlist,pararef);
|
||||||
current_procinfo.procdef.parast.address_fixup:=old_para_fixup;
|
current_procinfo.procdef.parast.address_fixup:=old_para_fixup;
|
||||||
end;
|
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 }
|
{ handle function results }
|
||||||
if (not is_void(resulttype.def)) then
|
if (not is_void(resulttype.def)) then
|
||||||
@ -1248,11 +1210,13 @@ implementation
|
|||||||
location_reset(location,LOC_VOID,OS_NO);
|
location_reset(location,LOC_VOID,OS_NO);
|
||||||
|
|
||||||
{ perhaps i/o check ? }
|
{ 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
|
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));
|
rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
||||||
cg.a_call_name(exprasmlist,'FPC_IOCHECK');
|
cg.a_call_name(exprasmlist,'FPC_IOCHECK');
|
||||||
rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
||||||
@ -1335,7 +1299,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$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
|
* improved arm code generation
|
||||||
* move some protected and private field around
|
* move some protected and private field around
|
||||||
* the temp. register for register parameters/arguments are now released
|
* the temp. register for register parameters/arguments are now released
|
||||||
|
Loading…
Reference in New Issue
Block a user