* generate code for procvar first before pushing parameters. Made

the already existing code for powerpc available for all platforms
This commit is contained in:
peter 2003-05-13 15:18:18 +00:00
parent 4ba5171726
commit 5e40220d67

View File

@ -440,9 +440,20 @@ implementation
{ we have only to handle the result if it is used } { we have only to handle the result if it is used }
if (nf_return_value_used in flags) then if (nf_return_value_used in flags) then
begin begin
case resulttype.def.deftype of if (resulttype.def.deftype=floatdef) then
enumdef, begin
orddef : location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
{$ifdef cpufpemu}
if cs_fp_emulation in aktmoduleswitches then
location.register.enum := accumulator
else
{$endif cpufpemu}
location.register.enum:=FPU_RESULT_REG;
{$ifdef x86}
inc(trgcpu(rg).fpuvaroffset);
{$endif x86}
end
else
begin begin
cgsize:=def_cgsize(resulttype.def); cgsize:=def_cgsize(resulttype.def);
@ -506,55 +517,11 @@ implementation
{$endif newra} {$endif newra}
cg.a_load_reg_reg(exprasmlist,cgsize,cgsize,r,location.register); cg.a_load_reg_reg(exprasmlist,cgsize,cgsize,r,location.register);
end; end;
end;
end;
floatdef :
begin
location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
{$ifdef cpufpemu}
if cs_fp_emulation in aktmoduleswitches then
location.register.enum := accumulator
else
{$endif cpufpemu}
location.register.enum:=FPU_RESULT_REG;
{$ifdef x86}
inc(trgcpu(rg).fpuvaroffset);
{$endif x86}
end;
{$ifdef TEST_WIN32_RECORDS}
recorddef :
begin
if (target_info.system=system_i386_win32) then
begin
location_reset(location,LOC_REFERENCE,def_cgsize(resulttype.def));
tg.GetTemp(exprasmlist,resulttype.size,tt_normal,location);
{$ifndef cpu64bit}
if cgsize in [OS_64,OS_S64] then
cg64.a_load64_reg_loc(exprasmlist,joinreg64(accumulator,accumulatorhigh),location)
else
{$endif cpu64bit}
cg.a_load_reg_loc(exprasmlist,accumulator,location);
end end
else
internalerror(200211141);
end;
{$endif TEST_WIN32_RECORDS}
else else
begin begin
location_reset(location,LOC_REGISTER,OS_INT); if resulttype.def.size>0 then
r.enum:=R_INTREGISTER; internalerror(200305131);
r.number:=NR_ACCUMULATOR;
{$ifdef newra}
rg.getexplicitregisterint(exprasmlist,NR_ACCUMULATOR);
rg.ungetregisterint(exprasmlist,r);
location.register:=rg.getregisterint(exprasmlist,OS_INT);
{$else newra}
if RS_ACCUMULATOR in rg.unusedregsint then
location.register:=rg.getexplicitregisterint(exprasmlist,NR_ACCUMULATOR)
else
location.register:=rg.getregisterint(exprasmlist,OS_INT);
{$endif newra}
cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,r,location.register);
end; end;
end; end;
end end
@ -579,13 +546,13 @@ implementation
pp : tcallparanode; pp : tcallparanode;
inlined : boolean; inlined : boolean;
inlinecode : tprocinlinenode; inlinecode : tprocinlinenode;
pushedregs : tmaybesave;
store_parast_fixup, store_parast_fixup,
para_alignment, para_alignment,
para_offset : longint; para_offset : longint;
pop_size : longint; pop_size : longint;
returnref, returnref,
pararef : treference; pararef : treference;
vmtreg,
accreg : tregister; accreg : tregister;
oldaktcallnode : tcallnode; oldaktcallnode : tcallnode;
begin begin
@ -701,7 +668,6 @@ implementation
oldaktcallnode:=aktcallnode; oldaktcallnode:=aktcallnode;
aktcallnode:=self; aktcallnode:=self;
{$ifdef powerpc}
{ process procvar. Done here already, because otherwise it may } { process procvar. Done here already, because otherwise it may }
{ destroy registers containing a parameter for the actual } { destroy registers containing a parameter for the actual }
{ function call (e.g. if it's a function, its result will } { function call (e.g. if it's a function, its result will }
@ -718,25 +684,31 @@ implementation
begin begin
secondpass(methodpointer); secondpass(methodpointer);
location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false); location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
vmtreg:=methodpointer.location.register;
{ virtual methods require an index } { virtual methods require an index }
if tprocdef(procdefinition).extnumber=-1 then if tprocdef(procdefinition).extnumber=-1 then
internalerror(200304021); internalerror(200304021);
{ VMT should already be loaded in a register } { VMT should already be loaded in a register }
if vmtreg.number=NR_NO then if methodpointer.location.register.number=NR_NO then
internalerror(200304022); internalerror(200304022);
{ test validity of VMT } { test validity of VMT }
if not(is_interface(tprocdef(procdefinition)._class)) and if not(is_interface(tprocdef(procdefinition)._class)) and
not(is_cppclass(tprocdef(procdefinition)._class)) then not(is_cppclass(tprocdef(procdefinition)._class)) then
cg.g_maybe_testvmt(exprasmlist,vmtreg,tprocdef(procdefinition)._class); cg.g_maybe_testvmt(exprasmlist,methodpointer.location.register,tprocdef(procdefinition)._class);
end; end;
end; end;
{$endif powerpc}
if assigned(left) then if assigned(left) then
begin begin
{$ifndef newra}
if assigned(right) then
maybe_save(exprasmlist,left.registers32,right.location,pushedregs)
else
if assigned(methodpointer) then
maybe_save(exprasmlist,left.registers32,methodpointer.location,pushedregs);
{$endif}
{ be found elsewhere } { be found elsewhere }
if inlined then if inlined then
para_offset:=tprocdef(procdefinition).parast.address_fixup+ para_offset:=tprocdef(procdefinition).parast.address_fixup+
@ -752,6 +724,13 @@ implementation
tcallparanode(left).secondcallparan( tcallparanode(left).secondcallparan(
(po_leftright in procdefinition.procoptions),procdefinition.proccalloption, (po_leftright in procdefinition.procoptions),procdefinition.proccalloption,
para_alignment,para_offset); para_alignment,para_offset);
{$ifndef newra}
if assigned(right) then
maybe_restore(exprasmlist,right.location,pushedregs)
else
if assigned(methodpointer) then
maybe_restore(exprasmlist,methodpointer.location,pushedregs);
{$endif newra}
end; end;
aktcallnode:=oldaktcallnode; aktcallnode:=oldaktcallnode;
@ -783,31 +762,13 @@ implementation
if (po_virtualmethod in procdefinition.procoptions) and if (po_virtualmethod in procdefinition.procoptions) and
assigned(methodpointer) then assigned(methodpointer) then
begin begin
{$ifndef powerpc}
secondpass(methodpointer);
location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
vmtreg:=methodpointer.location.register;
{ virtual methods require an index }
if tprocdef(procdefinition).extnumber=-1 then
internalerror(200304021);
{ VMT should already be loaded in a register }
if vmtreg.number=NR_NO then
internalerror(200304022);
{ test validity of VMT }
if not(is_interface(tprocdef(procdefinition)._class)) and
not(is_cppclass(tprocdef(procdefinition)._class)) then
cg.g_maybe_testvmt(exprasmlist,vmtreg,tprocdef(procdefinition)._class);
{$endif powerpc}
{ call method } { call method }
reference_reset_base(href,vmtreg, reference_reset_base(href,methodpointer.location.register,
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);
{ release self } { release self }
rg.ungetaddressregister(exprasmlist,vmtreg); rg.ungetaddressregister(exprasmlist,methodpointer.location.register);
end end
else else
begin begin
@ -833,10 +794,6 @@ implementation
else else
{ now procedure variable case } { now procedure variable case }
begin begin
{$ifndef powerpc}
secondpass(right);
{$endif not powerpc}
{ 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
@ -877,8 +834,7 @@ implementation
pop_size:=pushedparasize; pop_size:=pushedparasize;
{ for Cdecl functions we don't need to pop the funcret when it { for Cdecl functions we don't need to pop the funcret when it
was pushed by para } was pushed by para }
if (procdefinition.proccalloption in [pocall_cdecl,pocall_cppdecl]) and if paramanager.ret_in_param(procdefinition.rettype.def,procdefinition.proccalloption) then
paramanager.ret_in_param(procdefinition.rettype.def,procdefinition.proccalloption) then
dec(pop_size,POINTER_SIZE); dec(pop_size,POINTER_SIZE);
end; end;
@ -1184,7 +1140,11 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.61 2003-05-12 18:17:55 jonas Revision 1.62 2003-05-13 15:18:18 peter
* generate code for procvar first before pushing parameters. Made
the already existing code for powerpc available for all platforms
Revision 1.61 2003/05/12 18:17:55 jonas
* moved fpc_check_object call earlier for the ppc, so it can't destroy * moved fpc_check_object call earlier for the ppc, so it can't destroy
already-loaded parameter registers already-loaded parameter registers