mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 10:09:20 +02:00
* optimized releasing of registers
This commit is contained in:
parent
409b982075
commit
540691bf02
@ -510,8 +510,8 @@ implementation
|
|||||||
LOC_CREFERENCE :
|
LOC_CREFERENCE :
|
||||||
begin
|
begin
|
||||||
location_force_reg(exprasmlist,left.location,def_cgsize(resulttype.def),true);
|
location_force_reg(exprasmlist,left.location,def_cgsize(resulttype.def),true);
|
||||||
emit_reg_reg(A_TEST,opsize,left.location.register,left.location.register);
|
|
||||||
location_release(exprasmlist,left.location);
|
location_release(exprasmlist,left.location);
|
||||||
|
emit_reg_reg(A_TEST,opsize,left.location.register,left.location.register);
|
||||||
location_reset(location,LOC_FLAGS,OS_NO);
|
location_reset(location,LOC_FLAGS,OS_NO);
|
||||||
location.resflags:=F_E;
|
location.resflags:=F_E;
|
||||||
end;
|
end;
|
||||||
@ -569,7 +569,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.61 2003-09-28 21:48:20 peter
|
Revision 1.62 2003-09-29 20:58:56 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.61 2003/09/28 21:48:20 peter
|
||||||
* fix register leaks
|
* fix register leaks
|
||||||
|
|
||||||
Revision 1.60 2003/09/03 15:55:01 peter
|
Revision 1.60 2003/09/03 15:55:01 peter
|
||||||
|
@ -107,8 +107,8 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
cg.a_loadaddr_ref_reg(exprasmlist,location.reference,location.reference.index);
|
|
||||||
rg.ungetregisterint(exprasmlist,location.reference.base);
|
rg.ungetregisterint(exprasmlist,location.reference.base);
|
||||||
|
cg.a_loadaddr_ref_reg(exprasmlist,location.reference,location.reference.index);
|
||||||
reference_reset_base(location.reference,location.reference.index,0);
|
reference_reset_base(location.reference,location.reference.index,0);
|
||||||
end;
|
end;
|
||||||
{ insert the new index register and scalefactor or
|
{ insert the new index register and scalefactor or
|
||||||
@ -142,7 +142,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.54 2003-09-03 15:55:01 peter
|
Revision 1.55 2003-09-29 20:58:56 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.54 2003/09/03 15:55:01 peter
|
||||||
* NEWRA branch merged
|
* NEWRA branch merged
|
||||||
|
|
||||||
Revision 1.53.2.2 2003/08/31 15:46:26 peter
|
Revision 1.53.2.2 2003/08/31 15:46:26 peter
|
||||||
|
@ -35,6 +35,9 @@ interface
|
|||||||
tcgcallparanode = class(tcallparanode)
|
tcgcallparanode = class(tcallparanode)
|
||||||
private
|
private
|
||||||
tempparaloc : tparalocation;
|
tempparaloc : tparalocation;
|
||||||
|
procedure allocate_tempparaloc;
|
||||||
|
procedure push_addr_para;
|
||||||
|
procedure push_value_para(calloption:tproccalloption;alignment:byte);
|
||||||
public
|
public
|
||||||
procedure secondcallparan(calloption:tproccalloption;alignment:byte);override;
|
procedure secondcallparan(calloption:tproccalloption;alignment:byte);override;
|
||||||
end;
|
end;
|
||||||
@ -97,12 +100,231 @@ implementation
|
|||||||
TCGCALLPARANODE
|
TCGCALLPARANODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
|
procedure tcgcallparanode.allocate_tempparaloc;
|
||||||
|
begin
|
||||||
|
{ Allocate (temporary) paralocation }
|
||||||
|
tempparaloc:=paraitem.paraloc[callerside];
|
||||||
|
if tempparaloc.loc=LOC_REGISTER then
|
||||||
|
paramanager.alloctempregs(exprasmlist,tempparaloc)
|
||||||
|
else
|
||||||
|
paramanager.allocparaloc(exprasmlist,tempparaloc);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcgcallparanode.push_addr_para;
|
||||||
|
begin
|
||||||
|
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
||||||
|
internalerror(200304235);
|
||||||
|
location_release(exprasmlist,left.location);
|
||||||
|
allocate_tempparaloc;
|
||||||
|
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcgcallparanode.push_value_para(calloption:tproccalloption;alignment:byte);
|
||||||
|
var
|
||||||
|
href : treference;
|
||||||
|
{$ifdef i386}
|
||||||
|
tempreference : treference;
|
||||||
|
sizetopush : longint;
|
||||||
|
{$endif i386}
|
||||||
|
size : longint;
|
||||||
|
cgsize : tcgsize;
|
||||||
|
begin
|
||||||
|
{ we've nothing to push when the size of the parameter is 0 }
|
||||||
|
if left.resulttype.def.size=0 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{ Move flags and jump in register to make it less complex }
|
||||||
|
if left.location.loc in [LOC_FLAGS,LOC_JUMP] then
|
||||||
|
location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
|
||||||
|
|
||||||
|
{ Handle Floating point types differently }
|
||||||
|
if left.resulttype.def.deftype=floatdef then
|
||||||
|
begin
|
||||||
|
(*
|
||||||
|
if calloption=pocall_inline then
|
||||||
|
begin
|
||||||
|
size:=align(tfloatdef(p.resulttype.def).size,alignment);
|
||||||
|
inc(pushedparasize,size);
|
||||||
|
reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize);
|
||||||
|
case left.location.loc of
|
||||||
|
LOC_FPUREGISTER,
|
||||||
|
LOC_CFPUREGISTER:
|
||||||
|
cg.a_loadfpu_reg_ref(exprasmlist,def_cgsize(p.resulttype.def),left.location.register,href);
|
||||||
|
LOC_REFERENCE,
|
||||||
|
LOC_CREFERENCE :
|
||||||
|
cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false,false);
|
||||||
|
else
|
||||||
|
internalerror(200204243);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
*)
|
||||||
|
begin
|
||||||
|
location_release(exprasmlist,left.location);
|
||||||
|
allocate_tempparaloc;
|
||||||
|
{$ifdef i386}
|
||||||
|
case left.location.loc of
|
||||||
|
LOC_FPUREGISTER,
|
||||||
|
LOC_CFPUREGISTER:
|
||||||
|
begin
|
||||||
|
if tempparaloc.loc<>LOC_REFERENCE then
|
||||||
|
internalerror(200309291);
|
||||||
|
size:=align(tfloatdef(left.resulttype.def).size,alignment);
|
||||||
|
inc(pushedparasize,size);
|
||||||
|
cg.g_stackpointer_alloc(exprasmlist,size);
|
||||||
|
reference_reset_base(href,NR_STACK_POINTER_REG,0);
|
||||||
|
cg.a_loadfpu_reg_ref(exprasmlist,def_cgsize(left.resulttype.def),left.location.register,href);
|
||||||
|
end;
|
||||||
|
LOC_REFERENCE,
|
||||||
|
LOC_CREFERENCE :
|
||||||
|
begin
|
||||||
|
sizetopush:=align(left.resulttype.def.size,alignment);
|
||||||
|
tempreference:=left.location.reference;
|
||||||
|
inc(tempreference.offset,sizetopush);
|
||||||
|
while (sizetopush>0) do
|
||||||
|
begin
|
||||||
|
if sizetopush>=4 then
|
||||||
|
begin
|
||||||
|
cgsize:=OS_32;
|
||||||
|
inc(pushedparasize,4);
|
||||||
|
dec(tempreference.offset,4);
|
||||||
|
dec(sizetopush,4);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
cgsize:=OS_16;
|
||||||
|
inc(pushedparasize,2);
|
||||||
|
dec(tempreference.offset,2);
|
||||||
|
dec(sizetopush,2);
|
||||||
|
end;
|
||||||
|
cg.a_param_ref(exprasmlist,cgsize,tempreference,tempparaloc);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
internalerror(200204243);
|
||||||
|
end;
|
||||||
|
{$else i386}
|
||||||
|
case left.location.loc of
|
||||||
|
LOC_FPUREGISTER,
|
||||||
|
LOC_CFPUREGISTER:
|
||||||
|
cg.a_paramfpu_reg(exprasmlist,def_cgsize(p.resulttype.def),left.location.register,tempparaloc);
|
||||||
|
LOC_REFERENCE,
|
||||||
|
LOC_CREFERENCE :
|
||||||
|
cg.a_paramfpu_ref(exprasmlist,def_cgsize(p.resulttype.def),left.location.reference,tempparaloc)
|
||||||
|
else
|
||||||
|
internalerror(200204243);
|
||||||
|
end;
|
||||||
|
{$endif i386}
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ copy the value on the stack or use normal parameter push? }
|
||||||
|
if paramanager.copy_value_on_stack(paraitem.paratyp,left.resulttype.def,calloption) then
|
||||||
|
begin
|
||||||
|
location_release(exprasmlist,left.location);
|
||||||
|
allocate_tempparaloc;
|
||||||
|
{$ifdef i386}
|
||||||
|
if tempparaloc.loc<>LOC_REFERENCE then
|
||||||
|
internalerror(200309292);
|
||||||
|
if not (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
||||||
|
internalerror(200204241);
|
||||||
|
{ push on stack }
|
||||||
|
size:=align(left.resulttype.def.size,alignment);
|
||||||
|
inc(pushedparasize,size);
|
||||||
|
cg.g_stackpointer_alloc(exprasmlist,size);
|
||||||
|
reference_reset_base(href,NR_STACK_POINTER_REG,0);
|
||||||
|
cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false,false);
|
||||||
|
{$else i386}
|
||||||
|
cg.a_param_copy_ref(exprasmlist,left.resulttype.def.size,left.location.reference,tempparaloc);
|
||||||
|
{$endif i386}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
case left.location.loc of
|
||||||
|
LOC_CONSTANT,
|
||||||
|
LOC_REGISTER,
|
||||||
|
LOC_CREGISTER,
|
||||||
|
LOC_REFERENCE,
|
||||||
|
LOC_CREFERENCE :
|
||||||
|
begin
|
||||||
|
cgsize:=def_cgsize(left.resulttype.def);
|
||||||
|
if cgsize in [OS_64,OS_S64] then
|
||||||
|
begin
|
||||||
|
inc(pushedparasize,8);
|
||||||
|
(*
|
||||||
|
if calloption=pocall_inline then
|
||||||
|
begin
|
||||||
|
reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize);
|
||||||
|
if left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||||
|
begin
|
||||||
|
size:=align(p.resulttype.def.size,alignment);
|
||||||
|
cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false,false)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
cg64.a_load64_loc_ref(exprasmlist,left.location,href);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
*)
|
||||||
|
allocate_tempparaloc;
|
||||||
|
cg64.a_param64_loc(exprasmlist,left.location,tempparaloc);
|
||||||
|
location_release(exprasmlist,left.location);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
location_release(exprasmlist,left.location);
|
||||||
|
allocate_tempparaloc;
|
||||||
|
inc(pushedparasize,alignment);
|
||||||
|
(*
|
||||||
|
if calloption=pocall_inline then
|
||||||
|
begin
|
||||||
|
reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize);
|
||||||
|
if left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||||
|
begin
|
||||||
|
size:=align(p.resulttype.def.size,alignment);
|
||||||
|
cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false,false)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
cg.a_load_loc_ref(exprasmlist,left.location.size,left.location,href);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
*)
|
||||||
|
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{$ifdef SUPPORT_MMX}
|
||||||
|
LOC_MMXREGISTER,
|
||||||
|
LOC_CMMXREGISTER:
|
||||||
|
begin
|
||||||
|
location_release(exprasmlist,left.location);
|
||||||
|
allocate_tempparaloc;
|
||||||
|
inc(pushedparasize,8);
|
||||||
|
(*
|
||||||
|
if calloption=pocall_inline then
|
||||||
|
begin
|
||||||
|
reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize);
|
||||||
|
cg.a_loadmm_reg_ref(exprasmlist,left.location.register,href);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
*)
|
||||||
|
cg.a_parammm_reg(exprasmlist,left.location.register);
|
||||||
|
end;
|
||||||
|
{$endif SUPPORT_MMX}
|
||||||
|
else
|
||||||
|
internalerror(200204241);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
procedure tcgcallparanode.secondcallparan(calloption:tproccalloption;alignment:byte);
|
procedure tcgcallparanode.secondcallparan(calloption:tproccalloption;alignment:byte);
|
||||||
var
|
var
|
||||||
otlabel,
|
otlabel,
|
||||||
oflabel : tasmlabel;
|
oflabel : tasmlabel;
|
||||||
tmpreg : tregister;
|
|
||||||
href : treference;
|
|
||||||
begin
|
begin
|
||||||
if not(assigned(paraitem.paratype.def) or
|
if not(assigned(paraitem.paratype.def) or
|
||||||
assigned(paraitem.parasym)) then
|
assigned(paraitem.parasym)) then
|
||||||
@ -119,24 +341,13 @@ implementation
|
|||||||
objectlibrary.getlabel(falselabel);
|
objectlibrary.getlabel(falselabel);
|
||||||
secondpass(left);
|
secondpass(left);
|
||||||
|
|
||||||
{ Allocate (temporary) paralocation }
|
|
||||||
tempparaloc:=paraitem.paraloc[callerside];
|
|
||||||
if tempparaloc.loc=LOC_REGISTER then
|
|
||||||
paramanager.alloctempregs(exprasmlist,tempparaloc)
|
|
||||||
else
|
|
||||||
paramanager.allocparaloc(exprasmlist,tempparaloc);
|
|
||||||
|
|
||||||
{ handle varargs first, because defcoll is not valid }
|
{ handle varargs first, because defcoll is not valid }
|
||||||
if (nf_varargs_para in flags) then
|
if (nf_varargs_para in flags) then
|
||||||
begin
|
begin
|
||||||
if paramanager.push_addr_param(vs_value,left.resulttype.def,calloption) then
|
if paramanager.push_addr_param(vs_value,left.resulttype.def,calloption) then
|
||||||
begin
|
push_addr_para
|
||||||
inc(pushedparasize,POINTER_SIZE);
|
|
||||||
location_release(exprasmlist,left.location);
|
|
||||||
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
push_value_para(exprasmlist,left,vs_value,calloption,alignment,tempparaloc);
|
push_value_para(calloption,alignment);
|
||||||
end
|
end
|
||||||
{ hidden parameters }
|
{ hidden parameters }
|
||||||
else if paraitem.is_hidden then
|
else if paraitem.is_hidden then
|
||||||
@ -146,18 +357,9 @@ implementation
|
|||||||
if (vo_is_funcret in tvarsym(paraitem.parasym).varoptions) or
|
if (vo_is_funcret in tvarsym(paraitem.parasym).varoptions) or
|
||||||
(not(left.resulttype.def.deftype in [pointerdef,classrefdef]) and
|
(not(left.resulttype.def.deftype in [pointerdef,classrefdef]) and
|
||||||
paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,calloption)) then
|
paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,calloption)) then
|
||||||
begin
|
push_addr_para
|
||||||
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
|
||||||
internalerror(200305071);
|
|
||||||
|
|
||||||
inc(pushedparasize,POINTER_SIZE);
|
|
||||||
location_release(exprasmlist,left.location);
|
|
||||||
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
push_value_para(calloption,alignment);
|
||||||
push_value_para(exprasmlist,left,paraitem.paratyp,calloption,alignment,tempparaloc);
|
|
||||||
end;
|
|
||||||
end
|
end
|
||||||
{ filter array of const c styled args }
|
{ filter array of const c styled args }
|
||||||
else if is_array_of_const(left.resulttype.def) and (nf_cargs in left.flags) then
|
else if is_array_of_const(left.resulttype.def) and (nf_cargs in left.flags) then
|
||||||
@ -174,21 +376,16 @@ implementation
|
|||||||
location_force_mem(exprasmlist,left.location);
|
location_force_mem(exprasmlist,left.location);
|
||||||
|
|
||||||
{ allow @var }
|
{ allow @var }
|
||||||
inc(pushedparasize,POINTER_SIZE);
|
|
||||||
if (left.nodetype=addrn) and
|
if (left.nodetype=addrn) and
|
||||||
(not(nf_procvarload in left.flags)) then
|
(not(nf_procvarload in left.flags)) then
|
||||||
begin
|
begin
|
||||||
|
inc(pushedparasize,POINTER_SIZE);
|
||||||
location_release(exprasmlist,left.location);
|
location_release(exprasmlist,left.location);
|
||||||
|
allocate_tempparaloc;
|
||||||
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
|
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
push_addr_para;
|
||||||
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
|
||||||
internalerror(200304235);
|
|
||||||
|
|
||||||
location_release(exprasmlist,left.location);
|
|
||||||
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
|
|
||||||
end;
|
|
||||||
end
|
end
|
||||||
{ Normal parameter }
|
{ Normal parameter }
|
||||||
else
|
else
|
||||||
@ -211,18 +408,13 @@ implementation
|
|||||||
is_self_node(left)) then
|
is_self_node(left)) then
|
||||||
internalerror(200106041);
|
internalerror(200106041);
|
||||||
end;
|
end;
|
||||||
{ Move to memory }
|
{ Force to be in memory }
|
||||||
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
|
||||||
location_force_mem(exprasmlist,left.location);
|
location_force_mem(exprasmlist,left.location);
|
||||||
{ Push address }
|
push_addr_para;
|
||||||
inc(pushedparasize,POINTER_SIZE);
|
|
||||||
location_release(exprasmlist,left.location);
|
|
||||||
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
push_value_para(calloption,alignment);
|
||||||
push_value_para(exprasmlist,left,paraitem.paratyp,calloption,alignment,tempparaloc);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
truelabel:=otlabel;
|
truelabel:=otlabel;
|
||||||
falselabel:=oflabel;
|
falselabel:=oflabel;
|
||||||
@ -429,7 +621,7 @@ implementation
|
|||||||
{ adress returned from an I/O-error }
|
{ adress returned from an I/O-error }
|
||||||
iolabel : tasmlabel;
|
iolabel : tasmlabel;
|
||||||
{ help reference pointer }
|
{ help reference pointer }
|
||||||
href,helpref : treference;
|
href : treference;
|
||||||
para_alignment,
|
para_alignment,
|
||||||
pop_size : longint;
|
pop_size : longint;
|
||||||
pvreg,
|
pvreg,
|
||||||
@ -553,9 +745,6 @@ implementation
|
|||||||
oldpushedparasize:=pushedparasize;
|
oldpushedparasize:=pushedparasize;
|
||||||
pushedparasize:=0;
|
pushedparasize:=0;
|
||||||
|
|
||||||
{ Align stack if required }
|
|
||||||
pop_size:=align_parasize;
|
|
||||||
|
|
||||||
{ Process parameters, register parameters will be loaded
|
{ Process parameters, register parameters will be loaded
|
||||||
in imaginary registers. The actual load to the correct
|
in imaginary registers. The actual load to the correct
|
||||||
register is done just before the call }
|
register is done just before the call }
|
||||||
@ -565,6 +754,9 @@ implementation
|
|||||||
tcallparanode(left).secondcallparan(procdefinition.proccalloption,procdefinition.paraalign);
|
tcallparanode(left).secondcallparan(procdefinition.proccalloption,procdefinition.paraalign);
|
||||||
aktcallnode:=oldaktcallnode;
|
aktcallnode:=oldaktcallnode;
|
||||||
|
|
||||||
|
{ Align stack if required }
|
||||||
|
pop_size:=align_parasize;
|
||||||
|
|
||||||
{ procedure variable or normal function call ? }
|
{ procedure variable or normal function call ? }
|
||||||
if (right=nil) then
|
if (right=nil) then
|
||||||
begin
|
begin
|
||||||
@ -642,11 +834,12 @@ implementation
|
|||||||
{ now procedure variable case }
|
{ now procedure variable case }
|
||||||
begin
|
begin
|
||||||
secondpass(right);
|
secondpass(right);
|
||||||
|
|
||||||
location_release(exprasmlist,right.location);
|
location_release(exprasmlist,right.location);
|
||||||
pvreg:=rg.getabtregisterint(exprasmlist,OS_ADDR);
|
pvreg:=rg.getabtregisterint(exprasmlist,OS_ADDR);
|
||||||
rg.ungetregisterint(exprasmlist,pvreg);
|
rg.ungetregisterint(exprasmlist,pvreg);
|
||||||
{ Only load OS_ADDR from the reference }
|
{ Only load OS_ADDR from the reference }
|
||||||
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||||
cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,right.location.reference,pvreg)
|
cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,right.location.reference,pvreg)
|
||||||
else
|
else
|
||||||
cg.a_load_loc_reg(exprasmlist,OS_ADDR,right.location,pvreg);
|
cg.a_load_loc_reg(exprasmlist,OS_ADDR,right.location,pvreg);
|
||||||
@ -1111,7 +1304,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.119 2003-09-28 17:55:03 peter
|
Revision 1.120 2003-09-29 20:58:55 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.119 2003/09/28 17:55:03 peter
|
||||||
* parent framepointer changed to hidden parameter
|
* parent framepointer changed to hidden parameter
|
||||||
* tloadparentfpnode added
|
* tloadparentfpnode added
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ interface
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
cutils,
|
||||||
systems,
|
systems,
|
||||||
verbose,globtype,globals,
|
verbose,globtype,globals,
|
||||||
symconst,symtype,symdef,symsym,symtable,defutil,paramgr,
|
symconst,symtype,symdef,symsym,symtable,defutil,paramgr,
|
||||||
@ -695,6 +696,129 @@ implementation
|
|||||||
elesize : longint;
|
elesize : longint;
|
||||||
tmpreg : tregister;
|
tmpreg : tregister;
|
||||||
paraloc : tparalocation;
|
paraloc : tparalocation;
|
||||||
|
|
||||||
|
procedure push_value(p:tnode);
|
||||||
|
var
|
||||||
|
href : treference;
|
||||||
|
{$ifdef i386}
|
||||||
|
tempreference : treference;
|
||||||
|
sizetopush : longint;
|
||||||
|
{$endif i386}
|
||||||
|
size : longint;
|
||||||
|
cgsize : tcgsize;
|
||||||
|
begin
|
||||||
|
{ we've nothing to push when the size of the parameter is 0 }
|
||||||
|
if p.resulttype.def.size=0 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
if p.location.loc in [LOC_FLAGS,LOC_JUMP] then
|
||||||
|
internalerror(200309293);
|
||||||
|
|
||||||
|
{ Handle Floating point types differently }
|
||||||
|
if p.resulttype.def.deftype=floatdef then
|
||||||
|
begin
|
||||||
|
location_release(exprasmlist,p.location);
|
||||||
|
{$ifdef i386}
|
||||||
|
case p.location.loc of
|
||||||
|
LOC_FPUREGISTER,
|
||||||
|
LOC_CFPUREGISTER:
|
||||||
|
begin
|
||||||
|
size:=align(tfloatdef(p.resulttype.def).size,std_param_align);
|
||||||
|
inc(pushedparasize,size);
|
||||||
|
cg.g_stackpointer_alloc(exprasmlist,size);
|
||||||
|
reference_reset_base(href,NR_STACK_POINTER_REG,0);
|
||||||
|
cg.a_loadfpu_reg_ref(exprasmlist,def_cgsize(p.resulttype.def),p.location.register,href);
|
||||||
|
end;
|
||||||
|
LOC_REFERENCE,
|
||||||
|
LOC_CREFERENCE :
|
||||||
|
begin
|
||||||
|
sizetopush:=align(p.resulttype.def.size,std_param_align);
|
||||||
|
tempreference:=p.location.reference;
|
||||||
|
inc(tempreference.offset,sizetopush);
|
||||||
|
while (sizetopush>0) do
|
||||||
|
begin
|
||||||
|
if sizetopush>=4 then
|
||||||
|
begin
|
||||||
|
cgsize:=OS_32;
|
||||||
|
inc(pushedparasize,4);
|
||||||
|
dec(tempreference.offset,4);
|
||||||
|
dec(sizetopush,4);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
cgsize:=OS_16;
|
||||||
|
inc(pushedparasize,2);
|
||||||
|
dec(tempreference.offset,2);
|
||||||
|
dec(sizetopush,2);
|
||||||
|
end;
|
||||||
|
cg.a_param_ref(exprasmlist,cgsize,tempreference,paraloc);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
internalerror(200204243);
|
||||||
|
end;
|
||||||
|
{$else i386}
|
||||||
|
case p.location.loc of
|
||||||
|
LOC_FPUREGISTER,
|
||||||
|
LOC_CFPUREGISTER:
|
||||||
|
cg.a_paramfpu_reg(exprasmlist,def_cgsize(p.resulttype.def),p.location.register,locpara);
|
||||||
|
LOC_REFERENCE,
|
||||||
|
LOC_CREFERENCE :
|
||||||
|
cg.a_paramfpu_ref(exprasmlist,def_cgsize(p.resulttype.def),p.location.reference,locpara)
|
||||||
|
else
|
||||||
|
internalerror(200204243);
|
||||||
|
end;
|
||||||
|
{$endif i386}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ copy the value on the stack or use normal parameter push? }
|
||||||
|
if paramanager.copy_value_on_stack(vs_value,p.resulttype.def,pocall_cdecl) then
|
||||||
|
begin
|
||||||
|
location_release(exprasmlist,p.location);
|
||||||
|
if not (p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
||||||
|
internalerror(200204241);
|
||||||
|
{$ifdef i386}
|
||||||
|
{ push on stack }
|
||||||
|
size:=align(p.resulttype.def.size,std_param_align);
|
||||||
|
inc(pushedparasize,size);
|
||||||
|
cg.g_stackpointer_alloc(exprasmlist,size);
|
||||||
|
reference_reset_base(href,NR_STACK_POINTER_REG,0);
|
||||||
|
cg.g_concatcopy(exprasmlist,p.location.reference,href,size,false,false);
|
||||||
|
{$else i386}
|
||||||
|
cg.a_param_copy_ref(exprasmlist,p.resulttype.def.size,p.location.reference,locpara);
|
||||||
|
{$endif i386}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
case p.location.loc of
|
||||||
|
LOC_CONSTANT,
|
||||||
|
LOC_REGISTER,
|
||||||
|
LOC_CREGISTER,
|
||||||
|
LOC_REFERENCE,
|
||||||
|
LOC_CREFERENCE :
|
||||||
|
begin
|
||||||
|
cgsize:=def_cgsize(p.resulttype.def);
|
||||||
|
if cgsize in [OS_64,OS_S64] then
|
||||||
|
begin
|
||||||
|
inc(pushedparasize,8);
|
||||||
|
cg64.a_param64_loc(exprasmlist,p.location,paraloc);
|
||||||
|
location_release(exprasmlist,p.location);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
location_release(exprasmlist,p.location);
|
||||||
|
inc(pushedparasize,std_param_align);
|
||||||
|
cg.a_param_loc(exprasmlist,p.location,paraloc);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
internalerror(200204241);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
dovariant:=(nf_forcevaria in flags) or tarraydef(resulttype.def).isvariant;
|
dovariant:=(nf_forcevaria in flags) or tarraydef(resulttype.def).isvariant;
|
||||||
if dovariant then
|
if dovariant then
|
||||||
@ -838,7 +962,7 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
if vtype in [vtInt64,vtQword,vtExtended] then
|
if vtype in [vtInt64,vtQword,vtExtended] then
|
||||||
push_value_para(exprasmlist,hp.left,vs_value,pocall_cdecl,std_param_align,paraloc)
|
push_value(hp.left)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
cg.a_param_loc(exprasmlist,hp.left.location,paraloc);
|
cg.a_param_loc(exprasmlist,hp.left.location,paraloc);
|
||||||
@ -921,7 +1045,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.87 2003-09-28 21:46:18 peter
|
Revision 1.88 2003-09-29 20:58:56 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.87 2003/09/28 21:46:18 peter
|
||||||
* fix allocation of threadvar parameter
|
* fix allocation of threadvar parameter
|
||||||
|
|
||||||
Revision 1.86 2003/09/28 17:55:03 peter
|
Revision 1.86 2003/09/28 17:55:03 peter
|
||||||
|
@ -289,9 +289,8 @@ implementation
|
|||||||
paramanager.allocparaloc(exprasmlist,paraloc1);
|
paramanager.allocparaloc(exprasmlist,paraloc1);
|
||||||
cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
|
cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
|
||||||
paramanager.freeparaloc(exprasmlist,paraloc1);
|
paramanager.freeparaloc(exprasmlist,paraloc1);
|
||||||
rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
{ FPC_CHECKPOINTER uses saveregisters }
|
||||||
cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
|
cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
|
||||||
rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -342,15 +341,14 @@ implementation
|
|||||||
paramanager.allocparaloc(exprasmlist,paraloc1);
|
paramanager.allocparaloc(exprasmlist,paraloc1);
|
||||||
cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
|
cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
|
||||||
paramanager.freeparaloc(exprasmlist,paraloc1);
|
paramanager.freeparaloc(exprasmlist,paraloc1);
|
||||||
rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
{ FPC_CHECKPOINTER uses saveregisters }
|
||||||
cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
|
cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
|
||||||
rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else if is_interfacecom(left.resulttype.def) then
|
else if is_interfacecom(left.resulttype.def) then
|
||||||
begin
|
begin
|
||||||
tg.GetTemp(exprasmlist,pointer_size,tt_interfacecom,location.reference);
|
tg.GetTemp(exprasmlist,pointer_size,tt_interfacecom,location.reference);
|
||||||
cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,location.reference);
|
cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,location.reference);
|
||||||
{ implicit deferencing also for interfaces }
|
{ implicit deferencing also for interfaces }
|
||||||
if (cs_gdb_heaptrc in aktglobalswitches) and
|
if (cs_gdb_heaptrc in aktglobalswitches) and
|
||||||
(cs_checkpointer in aktglobalswitches) and
|
(cs_checkpointer in aktglobalswitches) and
|
||||||
@ -360,11 +358,9 @@ implementation
|
|||||||
paramanager.allocparaloc(exprasmlist,paraloc1);
|
paramanager.allocparaloc(exprasmlist,paraloc1);
|
||||||
cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
|
cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paraloc1);
|
||||||
paramanager.freeparaloc(exprasmlist,paraloc1);
|
paramanager.freeparaloc(exprasmlist,paraloc1);
|
||||||
rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
{ FPC_CHECKPOINTER uses saveregisters }
|
||||||
cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
|
cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
|
||||||
rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default));
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
location_copy(location,left.location);
|
location_copy(location,left.location);
|
||||||
@ -537,6 +533,7 @@ implementation
|
|||||||
objectlibrary.getlabel(neglabel);
|
objectlibrary.getlabel(neglabel);
|
||||||
objectlibrary.getlabel(poslabel);
|
objectlibrary.getlabel(poslabel);
|
||||||
cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_LT,0,hreg,poslabel);
|
cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_LT,0,hreg,poslabel);
|
||||||
|
location_release(exprasmlist,hightree.location);
|
||||||
cg.a_cmp_loc_reg_label(exprasmlist,OS_INT,OC_BE,hightree.location,hreg,neglabel);
|
cg.a_cmp_loc_reg_label(exprasmlist,OS_INT,OC_BE,hightree.location,hreg,neglabel);
|
||||||
if freereg then
|
if freereg then
|
||||||
rg.ungetregisterint(exprasmlist,hreg);
|
rg.ungetregisterint(exprasmlist,hreg);
|
||||||
@ -544,7 +541,6 @@ implementation
|
|||||||
cg.a_call_name(exprasmlist,'FPC_RANGEERROR');
|
cg.a_call_name(exprasmlist,'FPC_RANGEERROR');
|
||||||
cg.a_label(exprasmlist,neglabel);
|
cg.a_label(exprasmlist,neglabel);
|
||||||
{ release hightree }
|
{ release hightree }
|
||||||
location_release(exprasmlist,hightree.location);
|
|
||||||
hightree.free;
|
hightree.free;
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
@ -874,7 +870,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.75 2003-09-28 21:45:52 peter
|
Revision 1.76 2003-09-29 20:58:56 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.75 2003/09/28 21:45:52 peter
|
||||||
* fix register leak in with debug
|
* fix register leak in with debug
|
||||||
|
|
||||||
Revision 1.74 2003/09/28 17:55:03 peter
|
Revision 1.74 2003/09/28 17:55:03 peter
|
||||||
|
@ -50,22 +50,16 @@ interface
|
|||||||
|
|
||||||
function maybe_pushfpu(list:taasmoutput;needed : byte;var l:tlocation) : boolean;
|
function maybe_pushfpu(list:taasmoutput;needed : byte;var l:tlocation) : boolean;
|
||||||
|
|
||||||
procedure push_value_para(list:taasmoutput;p:tnode;
|
|
||||||
varspez:tvarspez;
|
|
||||||
calloption:tproccalloption;
|
|
||||||
alignment:byte;
|
|
||||||
const locpara : tparalocation);
|
|
||||||
|
|
||||||
procedure gen_load_return_value(list:TAAsmoutput; var uses_acc,uses_acchi,uses_fpu : boolean);
|
|
||||||
procedure gen_initialize_code(list:TAAsmoutput;inlined:boolean);
|
|
||||||
procedure gen_finalize_code(list : TAAsmoutput;inlined:boolean);
|
|
||||||
|
|
||||||
procedure gen_proc_symbol(list:Taasmoutput);
|
procedure gen_proc_symbol(list:Taasmoutput);
|
||||||
|
procedure gen_proc_symbol_end(list:Taasmoutput);
|
||||||
procedure gen_stackalloc_code(list:Taasmoutput);
|
procedure gen_stackalloc_code(list:Taasmoutput);
|
||||||
|
procedure gen_stackfree_code(list:Taasmoutput;usesacc,usesacchi:boolean);
|
||||||
procedure gen_save_used_regs(list : TAAsmoutput);
|
procedure gen_save_used_regs(list : TAAsmoutput);
|
||||||
procedure gen_restore_used_regs(list : TAAsmoutput;usesacc,usesacchi,usesfpu:boolean);
|
procedure gen_restore_used_regs(list : TAAsmoutput;usesacc,usesacchi,usesfpu:boolean);
|
||||||
procedure gen_entry_code(list:TAAsmoutput;inlined:boolean);
|
procedure gen_initialize_code(list:TAAsmoutput;inlined:boolean);
|
||||||
procedure gen_exit_code(list:TAAsmoutput;inlined,usesacc,usesacchi:boolean);
|
procedure gen_finalize_code(list : TAAsmoutput;inlined:boolean);
|
||||||
|
procedure gen_load_para_value(list:TAAsmoutput);
|
||||||
|
procedure gen_load_return_value(list:TAAsmoutput; var uses_acc,uses_acchi,uses_fpu : boolean);
|
||||||
|
|
||||||
(*
|
(*
|
||||||
procedure geninlineentrycode(list : TAAsmoutput;stackframe:longint);
|
procedure geninlineentrycode(list : TAAsmoutput;stackframe:longint);
|
||||||
@ -322,13 +316,17 @@ implementation
|
|||||||
|
|
||||||
{$ifndef cpu64bit}
|
{$ifndef cpu64bit}
|
||||||
{ 32-bit version }
|
{ 32-bit version }
|
||||||
procedure location_force(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
|
procedure location_force_reg(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
|
||||||
var
|
var
|
||||||
hregister,
|
hregister,
|
||||||
hregisterhi : tregister;
|
hregisterhi : tregister;
|
||||||
hreg64 : tregister64;
|
hreg64 : tregister64;
|
||||||
hl : tasmlabel;
|
hl : tasmlabel;
|
||||||
|
oldloc : tlocation;
|
||||||
begin
|
begin
|
||||||
|
oldloc:=l;
|
||||||
|
if dst_size=OS_NO then
|
||||||
|
internalerror(200309144);
|
||||||
{ handle transformations to 64bit separate }
|
{ handle transformations to 64bit separate }
|
||||||
if dst_size in [OS_64,OS_S64] then
|
if dst_size in [OS_64,OS_S64] then
|
||||||
begin
|
begin
|
||||||
@ -341,7 +339,10 @@ implementation
|
|||||||
cg.a_load_reg_reg(list,l.size,OS_32,l.registerlow,hregister);
|
cg.a_load_reg_reg(list,l.size,OS_32,l.registerlow,hregister);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
hregister:=rg.getregisterint(list,OS_INT);
|
begin
|
||||||
|
location_release(list,l);
|
||||||
|
hregister:=rg.getregisterint(list,OS_INT);
|
||||||
|
end;
|
||||||
{ load value in low register }
|
{ load value in low register }
|
||||||
case l.loc of
|
case l.loc of
|
||||||
LOC_FLAGS :
|
LOC_FLAGS :
|
||||||
@ -396,6 +397,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
hregister:=rg.getregisterint(list,OS_INT);
|
hregister:=rg.getregisterint(list,OS_INT);
|
||||||
hregisterhi:=rg.getregisterint(list,OS_INT);
|
hregisterhi:=rg.getregisterint(list,OS_INT);
|
||||||
|
location_release(list,l);
|
||||||
end;
|
end;
|
||||||
hreg64.reglo:=hregister;
|
hreg64.reglo:=hregister;
|
||||||
hreg64.reghi:=hregisterhi;
|
hreg64.reghi:=hregisterhi;
|
||||||
@ -415,12 +417,11 @@ implementation
|
|||||||
rg.ungetregisterint(list,l.registerhigh);
|
rg.ungetregisterint(list,l.registerhigh);
|
||||||
l.registerhigh:=NR_NO;
|
l.registerhigh:=NR_NO;
|
||||||
end;
|
end;
|
||||||
if l.loc=LOC_REGISTER then
|
|
||||||
rg.ungetregisterint(list,l.register);
|
|
||||||
{Do not bother to recycle the existing register. The register
|
{Do not bother to recycle the existing register. The register
|
||||||
allocator eliminates unnecessary moves, so it's not needed
|
allocator eliminates unnecessary moves, so it's not needed
|
||||||
and trying to recycle registers can cause problems because
|
and trying to recycle registers can cause problems because
|
||||||
the registers changes size and may need aditional constraints.}
|
the registers changes size and may need aditional constraints.}
|
||||||
|
location_release(list,l);
|
||||||
hregister:=rg.getregisterint(list,dst_size);
|
hregister:=rg.getregisterint(list,dst_size);
|
||||||
{ load value in new register }
|
{ load value in new register }
|
||||||
case l.loc of
|
case l.loc of
|
||||||
@ -470,24 +471,34 @@ implementation
|
|||||||
location_reset(l,LOC_CREGISTER,dst_size);
|
location_reset(l,LOC_CREGISTER,dst_size);
|
||||||
l.register:=hregister;
|
l.register:=hregister;
|
||||||
end;
|
end;
|
||||||
|
{ Release temp when it was a reference }
|
||||||
|
if oldloc.loc=LOC_REFERENCE then
|
||||||
|
location_freetemp(list,oldloc);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$else cpu64bit}
|
{$else cpu64bit}
|
||||||
|
|
||||||
{ 64-bit version }
|
{ 64-bit version }
|
||||||
procedure location_force(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
|
procedure location_force_reg(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
|
||||||
var
|
var
|
||||||
hregister : tregister;
|
hregister : tregister;
|
||||||
hl : tasmlabel;
|
hl : tasmlabel;
|
||||||
|
oldloc : tlocation;
|
||||||
begin
|
begin
|
||||||
|
oldloc:=l;
|
||||||
|
if dst_size=OS_NO then
|
||||||
|
internalerror(200309144);
|
||||||
{ handle transformations to 64bit separate }
|
{ handle transformations to 64bit separate }
|
||||||
if dst_size in [OS_64,OS_S64] then
|
if dst_size in [OS_64,OS_S64] then
|
||||||
begin
|
begin
|
||||||
{ load a smaller size to OS_64 }
|
{ load a smaller size to OS_64 }
|
||||||
if l.loc=LOC_REGISTER then
|
if l.loc=LOC_REGISTER then
|
||||||
hregister:=rg.makeregsize(l.register,OS_INT)
|
hregister:=rg.makeregsize(l.register,OS_INT)
|
||||||
else
|
else
|
||||||
hregister:=rg.getregisterint(list,OS_INT);
|
begin
|
||||||
|
location_release(list,l);
|
||||||
|
hregister:=rg.getregisterint(list,OS_INT);
|
||||||
|
end;
|
||||||
{ load value in low register }
|
{ load value in low register }
|
||||||
case l.loc of
|
case l.loc of
|
||||||
{$ifdef cpuflags}
|
{$ifdef cpuflags}
|
||||||
@ -526,7 +537,10 @@ implementation
|
|||||||
(TCGSize2Size[dst_size]=TCGSize2Size[l.size]) then
|
(TCGSize2Size[dst_size]=TCGSize2Size[l.size]) then
|
||||||
hregister:=l.register
|
hregister:=l.register
|
||||||
else
|
else
|
||||||
hregister:=rg.getregisterint(list,OS_INT);
|
begin
|
||||||
|
location_release(list,l);
|
||||||
|
hregister:=rg.getregisterint(list,OS_INT);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
hregister:=rg.makeregsize(hregister,dst_size);
|
hregister:=rg.makeregsize(hregister,dst_size);
|
||||||
{ load value in new register }
|
{ load value in new register }
|
||||||
@ -576,28 +590,13 @@ implementation
|
|||||||
location_reset(l,LOC_REGISTER,dst_size);
|
location_reset(l,LOC_REGISTER,dst_size);
|
||||||
l.register:=hregister;
|
l.register:=hregister;
|
||||||
end;
|
end;
|
||||||
|
{ Release temp when it was a reference }
|
||||||
|
if oldloc.loc=LOC_REFERENCE then
|
||||||
|
location_freetemp(list,oldloc);
|
||||||
end;
|
end;
|
||||||
{$endif cpu64bit}
|
{$endif cpu64bit}
|
||||||
|
|
||||||
|
|
||||||
procedure location_force_reg(list: TAAsmoutput;var l:tlocation;dst_size:TCGSize;maybeconst:boolean);
|
|
||||||
|
|
||||||
var oldloc:Tlocation;
|
|
||||||
|
|
||||||
begin
|
|
||||||
if dst_size=OS_NO then
|
|
||||||
internalerror(200309144);
|
|
||||||
oldloc:=l;
|
|
||||||
location_force(list, l, dst_size, maybeconst);
|
|
||||||
{ release previous location before demanding a new register }
|
|
||||||
if (oldloc.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
|
||||||
begin
|
|
||||||
location_freetemp(list,oldloc);
|
|
||||||
location_release(list,oldloc);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure location_force_fpureg(list: TAAsmoutput;var l: tlocation;maybeconst:boolean);
|
procedure location_force_fpureg(list: TAAsmoutput;var l: tlocation;maybeconst:boolean);
|
||||||
var
|
var
|
||||||
reg : tregister;
|
reg : tregister;
|
||||||
@ -672,204 +671,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
|
||||||
Push Value Para
|
|
||||||
*****************************************************************************}
|
|
||||||
|
|
||||||
procedure push_value_para(list:taasmoutput;p:tnode;
|
|
||||||
varspez:tvarspez;
|
|
||||||
calloption:tproccalloption;
|
|
||||||
alignment:byte;
|
|
||||||
const locpara : tparalocation);
|
|
||||||
var
|
|
||||||
href : treference;
|
|
||||||
{$ifdef i386}
|
|
||||||
tempreference : treference;
|
|
||||||
sizetopush : longint;
|
|
||||||
{$endif i386}
|
|
||||||
size : longint;
|
|
||||||
cgsize : tcgsize;
|
|
||||||
begin
|
|
||||||
{ we've nothing to push when the size of the parameter is 0 }
|
|
||||||
if p.resulttype.def.size=0 then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
{ Move flags and jump in register to make it less complex }
|
|
||||||
if p.location.loc in [LOC_FLAGS,LOC_JUMP] then
|
|
||||||
location_force_reg(list,p.location,def_cgsize(p.resulttype.def),false);
|
|
||||||
|
|
||||||
{ Handle Floating point types differently }
|
|
||||||
if p.resulttype.def.deftype=floatdef then
|
|
||||||
begin
|
|
||||||
(*
|
|
||||||
if calloption=pocall_inline then
|
|
||||||
begin
|
|
||||||
size:=align(tfloatdef(p.resulttype.def).size,alignment);
|
|
||||||
inc(pushedparasize,size);
|
|
||||||
reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize);
|
|
||||||
case p.location.loc of
|
|
||||||
LOC_FPUREGISTER,
|
|
||||||
LOC_CFPUREGISTER:
|
|
||||||
cg.a_loadfpu_reg_ref(list,def_cgsize(p.resulttype.def),p.location.register,href);
|
|
||||||
LOC_REFERENCE,
|
|
||||||
LOC_CREFERENCE :
|
|
||||||
cg.g_concatcopy(list,p.location.reference,href,size,false,false);
|
|
||||||
else
|
|
||||||
internalerror(200204243);
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
*)
|
|
||||||
begin
|
|
||||||
location_release(list,p.location);
|
|
||||||
{$ifdef i386}
|
|
||||||
case p.location.loc of
|
|
||||||
LOC_FPUREGISTER,
|
|
||||||
LOC_CFPUREGISTER:
|
|
||||||
begin
|
|
||||||
size:=align(tfloatdef(p.resulttype.def).size,alignment);
|
|
||||||
inc(pushedparasize,size);
|
|
||||||
cg.g_stackpointer_alloc(list,size);
|
|
||||||
reference_reset_base(href,NR_STACK_POINTER_REG,0);
|
|
||||||
cg.a_loadfpu_reg_ref(list,def_cgsize(p.resulttype.def),p.location.register,href);
|
|
||||||
end;
|
|
||||||
LOC_REFERENCE,
|
|
||||||
LOC_CREFERENCE :
|
|
||||||
begin
|
|
||||||
sizetopush:=align(p.resulttype.def.size,alignment);
|
|
||||||
tempreference:=p.location.reference;
|
|
||||||
inc(tempreference.offset,sizetopush);
|
|
||||||
while (sizetopush>0) do
|
|
||||||
begin
|
|
||||||
if sizetopush>=4 then
|
|
||||||
begin
|
|
||||||
cgsize:=OS_32;
|
|
||||||
inc(pushedparasize,4);
|
|
||||||
dec(tempreference.offset,4);
|
|
||||||
dec(sizetopush,4);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
cgsize:=OS_16;
|
|
||||||
inc(pushedparasize,2);
|
|
||||||
dec(tempreference.offset,2);
|
|
||||||
dec(sizetopush,2);
|
|
||||||
end;
|
|
||||||
cg.a_param_ref(list,cgsize,tempreference,locpara);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
internalerror(200204243);
|
|
||||||
end;
|
|
||||||
{$else i386}
|
|
||||||
case p.location.loc of
|
|
||||||
LOC_FPUREGISTER,
|
|
||||||
LOC_CFPUREGISTER:
|
|
||||||
cg.a_paramfpu_reg(list,def_cgsize(p.resulttype.def),p.location.register,locpara);
|
|
||||||
LOC_REFERENCE,
|
|
||||||
LOC_CREFERENCE :
|
|
||||||
cg.a_paramfpu_ref(list,def_cgsize(p.resulttype.def),p.location.reference,locpara)
|
|
||||||
else
|
|
||||||
internalerror(200204243);
|
|
||||||
end;
|
|
||||||
{$endif i386}
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
{ copy the value on the stack or use normal parameter push? }
|
|
||||||
if paramanager.copy_value_on_stack(varspez,p.resulttype.def,calloption) then
|
|
||||||
begin
|
|
||||||
location_release(list,p.location);
|
|
||||||
{$ifdef i386}
|
|
||||||
if not (p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
|
||||||
internalerror(200204241);
|
|
||||||
{ push on stack }
|
|
||||||
size:=align(p.resulttype.def.size,alignment);
|
|
||||||
inc(pushedparasize,size);
|
|
||||||
cg.g_stackpointer_alloc(list,size);
|
|
||||||
reference_reset_base(href,NR_STACK_POINTER_REG,0);
|
|
||||||
cg.g_concatcopy(list,p.location.reference,href,size,false,false);
|
|
||||||
{$else i386}
|
|
||||||
cg.a_param_copy_ref(list,p.resulttype.def.size,p.location.reference,locpara);
|
|
||||||
{$endif i386}
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
case p.location.loc of
|
|
||||||
LOC_CONSTANT,
|
|
||||||
LOC_REGISTER,
|
|
||||||
LOC_CREGISTER,
|
|
||||||
LOC_REFERENCE,
|
|
||||||
LOC_CREFERENCE :
|
|
||||||
begin
|
|
||||||
cgsize:=def_cgsize(p.resulttype.def);
|
|
||||||
if cgsize in [OS_64,OS_S64] then
|
|
||||||
begin
|
|
||||||
inc(pushedparasize,8);
|
|
||||||
(*
|
|
||||||
if calloption=pocall_inline then
|
|
||||||
begin
|
|
||||||
reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize);
|
|
||||||
if p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
|
||||||
begin
|
|
||||||
size:=align(p.resulttype.def.size,alignment);
|
|
||||||
cg.g_concatcopy(list,p.location.reference,href,size,false,false)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
cg64.a_load64_loc_ref(list,p.location,href);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
*)
|
|
||||||
cg64.a_param64_loc(list,p.location,locpara);
|
|
||||||
location_release(list,p.location);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
location_release(list,p.location);
|
|
||||||
inc(pushedparasize,alignment);
|
|
||||||
(*
|
|
||||||
if calloption=pocall_inline then
|
|
||||||
begin
|
|
||||||
reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize);
|
|
||||||
if p.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
|
||||||
begin
|
|
||||||
size:=align(p.resulttype.def.size,alignment);
|
|
||||||
cg.g_concatcopy(list,p.location.reference,href,size,false,false)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
cg.a_load_loc_ref(list,p.location.size,p.location,href);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
*)
|
|
||||||
cg.a_param_loc(list,p.location,locpara);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
{$ifdef SUPPORT_MMX}
|
|
||||||
LOC_MMXREGISTER,
|
|
||||||
LOC_CMMXREGISTER:
|
|
||||||
begin
|
|
||||||
location_release(list,p.location);
|
|
||||||
inc(pushedparasize,8);
|
|
||||||
(*
|
|
||||||
if calloption=pocall_inline then
|
|
||||||
begin
|
|
||||||
reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize);
|
|
||||||
cg.a_loadmm_reg_ref(list,p.location.register,href);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
*)
|
|
||||||
cg.a_parammm_reg(list,p.location.register);
|
|
||||||
end;
|
|
||||||
{$endif SUPPORT_MMX}
|
|
||||||
else
|
|
||||||
internalerror(200204241);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
Init/Finalize Code
|
Init/Finalize Code
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
@ -879,7 +680,9 @@ implementation
|
|||||||
href1,href2 : treference;
|
href1,href2 : treference;
|
||||||
list : taasmoutput;
|
list : taasmoutput;
|
||||||
hsym : tvarsym;
|
hsym : tvarsym;
|
||||||
|
l : longint;
|
||||||
loadref : boolean;
|
loadref : boolean;
|
||||||
|
localcopyloc : tparalocation;
|
||||||
begin
|
begin
|
||||||
list:=taasmoutput(arg);
|
list:=taasmoutput(arg);
|
||||||
if (tsym(p).typ=varsym) and
|
if (tsym(p).typ=varsym) and
|
||||||
@ -887,15 +690,15 @@ implementation
|
|||||||
(paramanager.push_addr_param(tvarsym(p).varspez,tvarsym(p).vartype.def,current_procinfo.procdef.proccalloption)) then
|
(paramanager.push_addr_param(tvarsym(p).varspez,tvarsym(p).vartype.def,current_procinfo.procdef.proccalloption)) then
|
||||||
begin
|
begin
|
||||||
loadref:=true;
|
loadref:=true;
|
||||||
case tvarsym(p).paraitem.paraloc[calleeside].loc of
|
case tvarsym(p).localloc.loc of
|
||||||
LOC_REGISTER :
|
LOC_REGISTER :
|
||||||
begin
|
begin
|
||||||
reference_reset_base(href1,tvarsym(p).paraitem.paraloc[calleeside].register,0);
|
reference_reset_base(href1,tvarsym(p).localloc.register,0);
|
||||||
loadref:=false;
|
loadref:=false;
|
||||||
end;
|
end;
|
||||||
LOC_REFERENCE :
|
LOC_REFERENCE :
|
||||||
reference_reset_base(href1,tvarsym(p).paraitem.paraloc[calleeside].reference.index,
|
reference_reset_base(href1,tvarsym(p).localloc.reference.index,
|
||||||
tvarsym(p).paraitem.paraloc[calleeside].reference.offset);
|
tvarsym(p).localloc.reference.offset);
|
||||||
else
|
else
|
||||||
internalerror(200309181);
|
internalerror(200309181);
|
||||||
end;
|
end;
|
||||||
@ -924,11 +727,20 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if tvarsym(p).localloc.loc<>LOC_REFERENCE then
|
if tvarsym(p).localloc.loc<>LOC_REFERENCE then
|
||||||
internalerror(200309183);
|
internalerror(200309183);
|
||||||
reference_reset_base(href2,tvarsym(p).localloc.reference.index,tvarsym(p).localloc.reference.offset);
|
{ Allocate space for the local copy }
|
||||||
|
l:=tvarsym(p).getvaluesize;
|
||||||
|
localcopyloc.loc:=LOC_REFERENCE;
|
||||||
|
localcopyloc.size:=int_cgsize(l);
|
||||||
|
tg.GetLocal(list,l,localcopyloc.reference);
|
||||||
|
{ Copy data }
|
||||||
|
reference_reset_base(href2,localcopyloc.reference.index,localcopyloc.reference.offset);
|
||||||
if is_shortstring(tvarsym(p).vartype.def) then
|
if is_shortstring(tvarsym(p).vartype.def) then
|
||||||
cg.g_copyshortstring(list,href1,href2,tstringdef(tvarsym(p).vartype.def).len,false,loadref)
|
cg.g_copyshortstring(list,href1,href2,tstringdef(tvarsym(p).vartype.def).len,false,loadref)
|
||||||
else
|
else
|
||||||
cg.g_concatcopy(list,href1,href2,tvarsym(p).vartype.def.size,true,loadref);
|
cg.g_concatcopy(list,href1,href2,tvarsym(p).vartype.def.size,true,loadref);
|
||||||
|
{ update localloc of varsym }
|
||||||
|
tg.Ungetlocal(list,tvarsym(p).localloc.reference);
|
||||||
|
tvarsym(p).localloc:=localcopyloc;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1274,16 +1086,13 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure gen_initialize_code(list:TAAsmoutput;inlined:boolean);
|
procedure gen_load_para_value(list:TAAsmoutput);
|
||||||
var
|
var
|
||||||
hp : tparaitem;
|
hp : tparaitem;
|
||||||
href : treference;
|
href : treference;
|
||||||
paraloc1,
|
|
||||||
paraloc2 : tparalocation;
|
|
||||||
hregister : tregister;
|
|
||||||
gotregvarparas : boolean;
|
gotregvarparas : boolean;
|
||||||
begin
|
begin
|
||||||
{ Save register parameters }
|
{ Store register parameters in reference or in register variable }
|
||||||
if assigned(current_procinfo.procdef.parast) and
|
if assigned(current_procinfo.procdef.parast) and
|
||||||
not (po_assembler in current_procinfo.procdef.procoptions) then
|
not (po_assembler in current_procinfo.procdef.procoptions) then
|
||||||
begin
|
begin
|
||||||
@ -1294,20 +1103,6 @@ implementation
|
|||||||
gotregvarparas := false;
|
gotregvarparas := false;
|
||||||
while assigned(hp) do
|
while assigned(hp) do
|
||||||
begin
|
begin
|
||||||
if hp.paraloc[calleeside].loc=LOC_REGISTER then
|
|
||||||
begin
|
|
||||||
hregister:=rg.getregisterint(list,hp.paraloc[calleeside].size);
|
|
||||||
rg.ungetregisterint(list,hregister);
|
|
||||||
cg.a_load_param_reg(list,hp.paraloc[calleeside],hregister);
|
|
||||||
rg.makeregvarint(getsupreg(hregister));
|
|
||||||
{ Update register }
|
|
||||||
hp.paraloc[calleeside].register:=hregister;
|
|
||||||
{ Update localloc when there is no local copy }
|
|
||||||
if not(vo_has_local_copy in tvarsym(hp.parasym).varoptions) then
|
|
||||||
tvarsym(hp.parasym).localloc:=hp.paraloc[calleeside];
|
|
||||||
gotregvarparas:=true;
|
|
||||||
end;
|
|
||||||
(*
|
|
||||||
case tvarsym(hp.parasym).localloc.loc of
|
case tvarsym(hp.parasym).localloc.loc of
|
||||||
LOC_REGISTER :
|
LOC_REGISTER :
|
||||||
begin
|
begin
|
||||||
@ -1328,7 +1123,6 @@ implementation
|
|||||||
else
|
else
|
||||||
internalerror(200309185);
|
internalerror(200309185);
|
||||||
end;
|
end;
|
||||||
*)
|
|
||||||
hp:=tparaitem(hp.next);
|
hp:=tparaitem(hp.next);
|
||||||
end;
|
end;
|
||||||
if gotregvarparas then
|
if gotregvarparas then
|
||||||
@ -1343,6 +1137,21 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ generate copies of call by value parameters, must be done before
|
||||||
|
the initialization and body is parsed because the refcounts are
|
||||||
|
incremented using the local copies }
|
||||||
|
if not(po_assembler in current_procinfo.procdef.procoptions) then
|
||||||
|
current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}copyvalueparas,list);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure gen_initialize_code(list:TAAsmoutput;inlined:boolean);
|
||||||
|
var
|
||||||
|
href : treference;
|
||||||
|
paraloc1,
|
||||||
|
paraloc2 : tparalocation;
|
||||||
|
begin
|
||||||
{ the actual profile code can clobber some registers,
|
{ the actual profile code can clobber some registers,
|
||||||
therefore if the context must be saved, do it before
|
therefore if the context must be saved, do it before
|
||||||
the actual call to the profile code
|
the actual call to the profile code
|
||||||
@ -1381,12 +1190,6 @@ implementation
|
|||||||
{ initialisizes temp. ansi/wide string data }
|
{ initialisizes temp. ansi/wide string data }
|
||||||
inittempvariables(list);
|
inittempvariables(list);
|
||||||
|
|
||||||
{ generate copies of call by value parameters, must be done before
|
|
||||||
the initialization because the refcounts are incremented using
|
|
||||||
the local copies }
|
|
||||||
if not(po_assembler in current_procinfo.procdef.procoptions) then
|
|
||||||
current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}copyvalueparas,list);
|
|
||||||
|
|
||||||
{ initialize ansi/widesstring para's }
|
{ initialize ansi/widesstring para's }
|
||||||
current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}init_paras,list);
|
current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}init_paras,list);
|
||||||
|
|
||||||
@ -1516,140 +1319,20 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure gen_stackalloc_code(list:Taasmoutput);
|
procedure gen_proc_symbol_end(list:Taasmoutput);
|
||||||
var
|
|
||||||
stackframe : longint;
|
|
||||||
begin
|
|
||||||
{ Calculate size of stackframe }
|
|
||||||
stackframe:=current_procinfo.calc_stackframe_size;
|
|
||||||
|
|
||||||
{$ifndef powerpc}
|
|
||||||
{ at least for the ppc this applies always, so this code isn't usable (FK) }
|
|
||||||
{ omit stack frame ? }
|
|
||||||
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
|
||||||
begin
|
|
||||||
CGmessage(cg_d_stackframe_omited);
|
|
||||||
if stackframe<>0 then
|
|
||||||
cg.g_stackpointer_alloc(list,stackframe);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
{$endif powerpc}
|
|
||||||
begin
|
|
||||||
if (po_interrupt in current_procinfo.procdef.procoptions) then
|
|
||||||
cg.g_interrupt_stackframe_entry(list);
|
|
||||||
|
|
||||||
cg.g_stackframe_entry(list,stackframe);
|
|
||||||
|
|
||||||
{Never call stack checking before the standard system unit
|
|
||||||
has been initialized.}
|
|
||||||
if (cs_check_stack in aktlocalswitches) and (current_procinfo.procdef.proctypeoption<>potype_proginit) then
|
|
||||||
cg.g_stackcheck(list,stackframe);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure gen_save_used_regs(list : TAAsmoutput);
|
|
||||||
begin
|
|
||||||
{ Pure assembler routines need to save the registers themselves }
|
|
||||||
if (po_assembler in current_procinfo.procdef.procoptions) then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
{ 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 current_procinfo.procdef.procoptions) then
|
|
||||||
cg.g_save_all_registers(list)
|
|
||||||
else
|
|
||||||
if current_procinfo.procdef.proccalloption in savestdregs_pocalls then
|
|
||||||
cg.g_save_standard_registers(list,rg.used_in_proc_int);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure gen_restore_used_regs(list : TAAsmoutput;usesacc,usesacchi,usesfpu:boolean);
|
|
||||||
begin
|
|
||||||
{ Pure assembler routines need to save the registers themselves }
|
|
||||||
if (po_assembler in current_procinfo.procdef.procoptions) then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
{ 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 current_procinfo.procdef.procoptions) then
|
|
||||||
cg.g_restore_all_registers(list,usesacc,usesacchi)
|
|
||||||
else
|
|
||||||
if current_procinfo.procdef.proccalloption in savestdregs_pocalls then
|
|
||||||
cg.g_restore_standard_registers(list,rg.used_in_proc_int);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure gen_entry_code(list:TAAsmoutput;inlined:boolean);
|
|
||||||
var
|
|
||||||
href : treference;
|
|
||||||
hp : tparaitem;
|
|
||||||
gotregvarparas: boolean;
|
|
||||||
begin
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure gen_exit_code(list:TAAsmoutput;inlined,usesacc,usesacchi:boolean);
|
|
||||||
var
|
|
||||||
{$ifdef GDB}
|
{$ifdef GDB}
|
||||||
|
var
|
||||||
stabsendlabel : tasmlabel;
|
stabsendlabel : tasmlabel;
|
||||||
mangled_length : longint;
|
mangled_length : longint;
|
||||||
p : pchar;
|
p : pchar;
|
||||||
{$endif GDB}
|
{$endif GDB}
|
||||||
stacksize,
|
|
||||||
retsize : longint;
|
|
||||||
begin
|
begin
|
||||||
|
list.concat(Tai_symbol_end.Createname(current_procinfo.procdef.mangledname));
|
||||||
{$ifdef GDB}
|
{$ifdef GDB}
|
||||||
if ((cs_debuginfo in aktmoduleswitches) and not inlined) then
|
if (cs_debuginfo in aktmoduleswitches) then
|
||||||
begin
|
begin
|
||||||
objectlibrary.getlabel(stabsendlabel);
|
objectlibrary.getlabel(stabsendlabel);
|
||||||
cg.a_label(list,stabsendlabel);
|
cg.a_label(list,stabsendlabel);
|
||||||
end;
|
|
||||||
{$endif GDB}
|
|
||||||
|
|
||||||
{$ifndef powerpc}
|
|
||||||
{ remove stackframe }
|
|
||||||
if not inlined then
|
|
||||||
begin
|
|
||||||
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
|
||||||
begin
|
|
||||||
stacksize:=current_procinfo.calc_stackframe_size;
|
|
||||||
if (stacksize<>0) then
|
|
||||||
cg.a_op_const_reg(list,OP_ADD,OS_32,stacksize,current_procinfo.framepointer);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
cg.g_restore_frame_pointer(list);
|
|
||||||
end;
|
|
||||||
{$endif}
|
|
||||||
|
|
||||||
{ at last, the return is generated }
|
|
||||||
if not inlined then
|
|
||||||
begin
|
|
||||||
if (po_interrupt in current_procinfo.procdef.procoptions) then
|
|
||||||
cg.g_interrupt_stackframe_exit(list,usesacc,usesacchi)
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if current_procinfo.procdef.proccalloption in clearstack_pocalls then
|
|
||||||
begin
|
|
||||||
retsize:=0;
|
|
||||||
if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption) then
|
|
||||||
inc(retsize,POINTER_SIZE);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
retsize:=current_procinfo.para_stack_size;
|
|
||||||
end;
|
|
||||||
cg.g_return_from_proc(list,retsize);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if not inlined then
|
|
||||||
list.concat(Tai_symbol_end.Createname(current_procinfo.procdef.mangledname));
|
|
||||||
|
|
||||||
{$ifdef GDB}
|
|
||||||
if (cs_debuginfo in aktmoduleswitches) and not inlined then
|
|
||||||
begin
|
|
||||||
{ define calling EBP as pseudo local var PM }
|
{ define calling EBP as pseudo local var PM }
|
||||||
{ this enables test if the function is a local one !! }
|
{ this enables test if the function is a local one !! }
|
||||||
{if assigned(current_procinfo.parent) and
|
{if assigned(current_procinfo.parent) and
|
||||||
@ -1714,6 +1397,104 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure gen_stackalloc_code(list:Taasmoutput);
|
||||||
|
var
|
||||||
|
stackframe : longint;
|
||||||
|
begin
|
||||||
|
{ Calculate size of stackframe }
|
||||||
|
stackframe:=current_procinfo.calc_stackframe_size;
|
||||||
|
|
||||||
|
{$ifndef powerpc}
|
||||||
|
{ at least for the ppc this applies always, so this code isn't usable (FK) }
|
||||||
|
{ omit stack frame ? }
|
||||||
|
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
||||||
|
begin
|
||||||
|
CGmessage(cg_d_stackframe_omited);
|
||||||
|
if stackframe<>0 then
|
||||||
|
cg.g_stackpointer_alloc(list,stackframe);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{$endif powerpc}
|
||||||
|
begin
|
||||||
|
if (po_interrupt in current_procinfo.procdef.procoptions) then
|
||||||
|
cg.g_interrupt_stackframe_entry(list);
|
||||||
|
|
||||||
|
cg.g_stackframe_entry(list,stackframe);
|
||||||
|
|
||||||
|
{Never call stack checking before the standard system unit
|
||||||
|
has been initialized.}
|
||||||
|
if (cs_check_stack in aktlocalswitches) and (current_procinfo.procdef.proctypeoption<>potype_proginit) then
|
||||||
|
cg.g_stackcheck(list,stackframe);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure gen_stackfree_code(list:Taasmoutput;usesacc,usesacchi:boolean);
|
||||||
|
var
|
||||||
|
stacksize,
|
||||||
|
retsize : longint;
|
||||||
|
begin
|
||||||
|
{$ifndef powerpc}
|
||||||
|
{ remove stackframe }
|
||||||
|
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
||||||
|
begin
|
||||||
|
stacksize:=current_procinfo.calc_stackframe_size;
|
||||||
|
if (stacksize<>0) then
|
||||||
|
cg.a_op_const_reg(list,OP_ADD,OS_32,stacksize,current_procinfo.framepointer);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
cg.g_restore_frame_pointer(list);
|
||||||
|
{$endif}
|
||||||
|
{ at last, the return is generated }
|
||||||
|
if (po_interrupt in current_procinfo.procdef.procoptions) then
|
||||||
|
cg.g_interrupt_stackframe_exit(list,usesacc,usesacchi)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if current_procinfo.procdef.proccalloption in clearstack_pocalls then
|
||||||
|
begin
|
||||||
|
retsize:=0;
|
||||||
|
if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption) then
|
||||||
|
inc(retsize,POINTER_SIZE);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
retsize:=current_procinfo.para_stack_size;
|
||||||
|
cg.g_return_from_proc(list,retsize);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure gen_save_used_regs(list : TAAsmoutput);
|
||||||
|
begin
|
||||||
|
{ Pure assembler routines need to save the registers themselves }
|
||||||
|
if (po_assembler in current_procinfo.procdef.procoptions) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{ 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 current_procinfo.procdef.procoptions) then
|
||||||
|
cg.g_save_all_registers(list)
|
||||||
|
else
|
||||||
|
if current_procinfo.procdef.proccalloption in savestdregs_pocalls then
|
||||||
|
cg.g_save_standard_registers(list,rg.used_in_proc_int);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure gen_restore_used_regs(list : TAAsmoutput;usesacc,usesacchi,usesfpu:boolean);
|
||||||
|
begin
|
||||||
|
{ Pure assembler routines need to save the registers themselves }
|
||||||
|
if (po_assembler in current_procinfo.procdef.procoptions) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{ 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 current_procinfo.procdef.procoptions) then
|
||||||
|
cg.g_restore_all_registers(list,usesacc,usesacchi)
|
||||||
|
else
|
||||||
|
if current_procinfo.procdef.proccalloption in savestdregs_pocalls then
|
||||||
|
cg.g_restore_standard_registers(list,rg.used_in_proc_int);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
Inlining
|
Inlining
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
@ -1997,7 +1778,6 @@ implementation
|
|||||||
procedure gen_alloc_parast(list: taasmoutput;st:tparasymtable);
|
procedure gen_alloc_parast(list: taasmoutput;st:tparasymtable);
|
||||||
var
|
var
|
||||||
sym : tsym;
|
sym : tsym;
|
||||||
l : longint;
|
|
||||||
begin
|
begin
|
||||||
sym:=tsym(st.symindex.first);
|
sym:=tsym(st.symindex.first);
|
||||||
while assigned(sym) do
|
while assigned(sym) do
|
||||||
@ -2006,41 +1786,29 @@ implementation
|
|||||||
begin
|
begin
|
||||||
with tvarsym(sym) do
|
with tvarsym(sym) do
|
||||||
begin
|
begin
|
||||||
l:=getvaluesize;
|
{ Allocate imaginary register for register parameters }
|
||||||
{ Allocate local copy? }
|
if paraitem.paraloc[calleeside].loc=LOC_REGISTER then
|
||||||
if (vo_has_local_copy in varoptions) and
|
|
||||||
(l>0) then
|
|
||||||
begin
|
begin
|
||||||
localloc.loc:=LOC_REFERENCE;
|
(*
|
||||||
localloc.size:=int_cgsize(l);
|
|
||||||
tg.GetLocal(list,l,localloc.reference);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
{ Allocate imaginary register for register parameters }
|
|
||||||
if paraitem.paraloc[calleeside].loc=LOC_REGISTER then
|
|
||||||
begin
|
|
||||||
(*
|
|
||||||
{$warning TODO Allocate register paras}
|
{$warning TODO Allocate register paras}
|
||||||
localloc.loc:=LOC_REGISTER;
|
localloc.loc:=LOC_REGISTER;
|
||||||
localloc.size:=paraitem.paraloc[calleeside].size;
|
localloc.size:=paraitem.paraloc[calleeside].size;
|
||||||
{$ifndef cpu64bit}
|
{$ifndef cpu64bit}
|
||||||
if localloc.size in [OS_64,OS_S64] then
|
if localloc.size in [OS_64,OS_S64] then
|
||||||
begin
|
begin
|
||||||
localloc.registerlow:=rg.getregisterint(list,OS_32);
|
localloc.registerlow:=rg.getregisterint(list,OS_32);
|
||||||
localloc.registerhigh:=rg.getregisterint(list,OS_32);
|
localloc.registerhigh:=rg.getregisterint(list,OS_32);
|
||||||
end
|
|
||||||
else
|
|
||||||
{$endif cpu64bit}
|
|
||||||
localloc.register:=rg.getregisterint(list,localloc.size);
|
|
||||||
*)
|
|
||||||
{localloc.loc:=LOC_REFERENCE;
|
|
||||||
localloc.size:=paraitem.paraloc[calleeside].size;
|
|
||||||
tg.GetLocal(list,tcgsize2size[localloc.size],localloc.reference);}
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
localloc:=paraitem.paraloc[calleeside];
|
{$endif cpu64bit}
|
||||||
end;
|
localloc.register:=rg.getregisterint(list,localloc.size);
|
||||||
|
*)
|
||||||
|
localloc.loc:=LOC_REFERENCE;
|
||||||
|
localloc.size:=paraitem.paraloc[calleeside].size;
|
||||||
|
tg.GetLocal(list,tcgsize2size[localloc.size],localloc.reference);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
localloc:=paraitem.paraloc[calleeside];
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
sym:=tsym(sym.indexnext);
|
sym:=tsym(sym.indexnext);
|
||||||
@ -2088,7 +1856,10 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.151 2003-09-28 21:47:18 peter
|
Revision 1.152 2003-09-29 20:58:56 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.151 2003/09/28 21:47:18 peter
|
||||||
* register paras and local copies updates
|
* register paras and local copies updates
|
||||||
|
|
||||||
Revision 1.150 2003/09/28 17:55:03 peter
|
Revision 1.150 2003/09/28 17:55:03 peter
|
||||||
|
@ -102,12 +102,6 @@ implementation
|
|||||||
{$endif}
|
{$endif}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
const
|
|
||||||
{ Maximum number of loops when spilling registers }
|
|
||||||
maxspillingcounter = 20;
|
|
||||||
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
PROCEDURE/FUNCTION BODY PARSING
|
PROCEDURE/FUNCTION BODY PARSING
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
@ -584,6 +578,9 @@ implementation
|
|||||||
usesacc,
|
usesacc,
|
||||||
usesfpu,
|
usesfpu,
|
||||||
usesacchi : boolean;
|
usesacchi : boolean;
|
||||||
|
{$ifdef ra_debug}
|
||||||
|
i,
|
||||||
|
{$endif ra_debug}
|
||||||
spillingcounter : integer;
|
spillingcounter : integer;
|
||||||
fastspill:boolean;
|
fastspill:boolean;
|
||||||
begin
|
begin
|
||||||
@ -622,10 +619,17 @@ implementation
|
|||||||
paramanager.create_paraloc_info(current_procinfo.procdef,calleeside);
|
paramanager.create_paraloc_info(current_procinfo.procdef,calleeside);
|
||||||
|
|
||||||
{ Allocate space in temp/registers for parast and localst }
|
{ Allocate space in temp/registers for parast and localst }
|
||||||
|
aktfilepos:=entrypos;
|
||||||
gen_alloc_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
|
gen_alloc_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
|
||||||
if current_procinfo.procdef.localst.symtabletype=localsymtable then
|
if current_procinfo.procdef.localst.symtabletype=localsymtable then
|
||||||
gen_alloc_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
|
gen_alloc_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
|
||||||
|
|
||||||
|
{ Load register parameters in temps and insert local copies
|
||||||
|
for values parameters. This must be done before the body is parsed
|
||||||
|
because the localloc is updated }
|
||||||
|
aktfilepos:=entrypos;
|
||||||
|
gen_load_para_value(aktproccode);
|
||||||
|
|
||||||
{$warning FIXME!!}
|
{$warning FIXME!!}
|
||||||
{ FIXME!! If a procedure contains assembler blocks (or is pure assembler), }
|
{ FIXME!! If a procedure contains assembler blocks (or is pure assembler), }
|
||||||
{ then rg.used_in_proc_int already contains info because of that. However, }
|
{ then rg.used_in_proc_int already contains info because of that. However, }
|
||||||
@ -688,9 +692,7 @@ implementation
|
|||||||
aktfilepos:=entrypos;
|
aktfilepos:=entrypos;
|
||||||
gen_proc_symbol(templist);
|
gen_proc_symbol(templist);
|
||||||
headertai:=tai(templist.last);
|
headertai:=tai(templist.last);
|
||||||
{ add entry code after header }
|
{ insert symbol }
|
||||||
gen_entry_code(templist,false);
|
|
||||||
{ insert symbol and entry code }
|
|
||||||
aktproccode.insertlist(templist);
|
aktproccode.insertlist(templist);
|
||||||
|
|
||||||
{ Free space in temp/registers for parast and localst, must be
|
{ Free space in temp/registers for parast and localst, must be
|
||||||
@ -708,7 +710,7 @@ implementation
|
|||||||
spillingcounter:=0;
|
spillingcounter:=0;
|
||||||
repeat
|
repeat
|
||||||
{$ifdef ra_debug}
|
{$ifdef ra_debug}
|
||||||
if aktfilepos.line=2502 then
|
if aktfilepos.line=1206 then
|
||||||
rg.writegraph(spillingcounter);
|
rg.writegraph(spillingcounter);
|
||||||
{$endif ra_debug}
|
{$endif ra_debug}
|
||||||
rg.prepare_colouring;
|
rg.prepare_colouring;
|
||||||
@ -718,8 +720,21 @@ implementation
|
|||||||
if rg.spillednodes<>'' then
|
if rg.spillednodes<>'' then
|
||||||
begin
|
begin
|
||||||
inc(spillingcounter);
|
inc(spillingcounter);
|
||||||
if spillingcounter>maxspillingcounter then
|
if spillingcounter>20 then
|
||||||
|
{$ifdef ra_debug}
|
||||||
|
break;
|
||||||
|
{$else ra_debug}
|
||||||
internalerror(200309041);
|
internalerror(200309041);
|
||||||
|
{$endif ra_debug}
|
||||||
|
|
||||||
|
{$ifdef ra_debug}
|
||||||
|
if aktfilepos.line=1207 then
|
||||||
|
begin
|
||||||
|
writeln('Spilling registers:');
|
||||||
|
for i:=1 to length(rg.spillednodes) do
|
||||||
|
writeln(ord(rg.spillednodes[i]));
|
||||||
|
end;
|
||||||
|
{$endif ra_debug}
|
||||||
fastspill:=rg.spill_registers(aktproccode,headertai,rg.spillednodes);
|
fastspill:=rg.spill_registers(aktproccode,headertai,rg.spillednodes);
|
||||||
end;
|
end;
|
||||||
until (rg.spillednodes='') or not fastspill;
|
until (rg.spillednodes='') or not fastspill;
|
||||||
@ -747,7 +762,11 @@ implementation
|
|||||||
aktproccode.insertlistafter(headertai,templist);
|
aktproccode.insertlistafter(headertai,templist);
|
||||||
{ Add exit code at the end }
|
{ Add exit code at the end }
|
||||||
aktfilepos:=exitpos;
|
aktfilepos:=exitpos;
|
||||||
gen_exit_code(templist,false,usesacc,usesacchi);
|
gen_stackfree_code(templist,usesacc,usesacchi);
|
||||||
|
aktproccode.concatlist(templist);
|
||||||
|
{ Add end symbol and debug info }
|
||||||
|
aktfilepos:=exitpos;
|
||||||
|
gen_proc_symbol_end(templist);
|
||||||
aktproccode.concatlist(templist);
|
aktproccode.concatlist(templist);
|
||||||
|
|
||||||
{ save local data (casetable) also in the same file }
|
{ save local data (casetable) also in the same file }
|
||||||
@ -1288,7 +1307,10 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.153 2003-09-28 17:55:04 peter
|
Revision 1.154 2003-09-29 20:58:56 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.153 2003/09/28 17:55:04 peter
|
||||||
* parent framepointer changed to hidden parameter
|
* parent framepointer changed to hidden parameter
|
||||||
* tloadparentfpnode added
|
* tloadparentfpnode added
|
||||||
|
|
||||||
|
@ -1663,9 +1663,8 @@ unit rgobj;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Trgobj.select_spill;
|
procedure Trgobj.select_spill;
|
||||||
|
var
|
||||||
var n:char;
|
n : char;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
{This code is WAY too naive. We need not to select just a register, but
|
{This code is WAY too naive. We need not to select just a register, but
|
||||||
the register that is used the least...}
|
the register that is used the least...}
|
||||||
@ -1735,7 +1734,7 @@ unit rgobj;
|
|||||||
include(used_in_proc_int,colour[k]);
|
include(used_in_proc_int,colour[k]);
|
||||||
end;
|
end;
|
||||||
{$ifdef ra_debug}
|
{$ifdef ra_debug}
|
||||||
if aktfilepos.line=2502 then
|
if aktfilepos.line=-1 then
|
||||||
begin
|
begin
|
||||||
writeln('colourlist ',length(freezeworklist));
|
writeln('colourlist ',length(freezeworklist));
|
||||||
for i:=0 to maxintreg do
|
for i:=0 to maxintreg do
|
||||||
@ -1926,16 +1925,17 @@ unit rgobj;
|
|||||||
adj:=igraph.adjlist[Tsuperregister(i)];
|
adj:=igraph.adjlist[Tsuperregister(i)];
|
||||||
if adj=nil then
|
if adj=nil then
|
||||||
begin
|
begin
|
||||||
|
p:=i;
|
||||||
min:=0;
|
min:=0;
|
||||||
break; {We won't find smaller ones.}
|
break; {We won't find smaller ones.}
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if length(adj^)<min then
|
if length(adj^)<min then
|
||||||
begin
|
begin
|
||||||
|
p:=i;
|
||||||
min:=length(adj^);
|
min:=length(adj^);
|
||||||
if min=0 then
|
if min=0 then
|
||||||
break; {We won't find smaller ones.}
|
break; {We won't find smaller ones.}
|
||||||
p:=i;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1950,6 +1950,10 @@ unit rgobj;
|
|||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$ifdef ra_debug}
|
||||||
|
writeln('Spilling temp: ',p,' min ',min);
|
||||||
|
{$endif ra_debug}
|
||||||
|
|
||||||
exclude(unusedregsint,p);
|
exclude(unusedregsint,p);
|
||||||
include(used_in_proc_int,p);
|
include(used_in_proc_int,p);
|
||||||
r:=newreg(R_INTREGISTER,p,subreg);
|
r:=newreg(R_INTREGISTER,p,subreg);
|
||||||
@ -2257,7 +2261,10 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.78 2003-09-28 13:41:12 peter
|
Revision 1.79 2003-09-29 20:58:56 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.78 2003/09/28 13:41:12 peter
|
||||||
* return reg 255 when allowdupreg is defined
|
* return reg 255 when allowdupreg is defined
|
||||||
|
|
||||||
Revision 1.77 2003/09/25 16:19:32 peter
|
Revision 1.77 2003/09/25 16:19:32 peter
|
||||||
|
@ -2218,7 +2218,7 @@ implementation
|
|||||||
oper[1].typ:=top_reg;
|
oper[1].typ:=top_reg;
|
||||||
oper[1].reg:=helpreg;
|
oper[1].reg:=helpreg;
|
||||||
list.insertafter(helpins,self);
|
list.insertafter(helpins,self);
|
||||||
rgunget(list,helpins,helpreg);
|
rgunget(list,self,helpreg);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2233,7 +2233,7 @@ implementation
|
|||||||
A_BT,A_BTS,
|
A_BT,A_BTS,
|
||||||
A_BTC,A_BTR :
|
A_BTC,A_BTR :
|
||||||
begin
|
begin
|
||||||
{Yikes! We just changed the destination register into
|
{Yikes! We just changed the source register into
|
||||||
a memory location above here.
|
a memory location above here.
|
||||||
|
|
||||||
Situation example:
|
Situation example:
|
||||||
@ -2255,7 +2255,7 @@ implementation
|
|||||||
dispose(oper[0].ref);
|
dispose(oper[0].ref);
|
||||||
oper[0].typ:=top_reg;
|
oper[0].typ:=top_reg;
|
||||||
oper[0].reg:=helpreg;
|
oper[0].reg:=helpreg;
|
||||||
rgunget(list,self,helpreg);
|
rgunget(list,helpins,helpreg);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2317,7 +2317,10 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.28 2003-09-28 21:49:30 peter
|
Revision 1.29 2003-09-29 20:58:56 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.28 2003/09/28 21:49:30 peter
|
||||||
* fixed invalid opcode handling in spill registers
|
* fixed invalid opcode handling in spill registers
|
||||||
|
|
||||||
Revision 1.27 2003/09/28 13:37:07 peter
|
Revision 1.27 2003/09/28 13:37:07 peter
|
||||||
|
@ -1111,14 +1111,14 @@ unit cgx86;
|
|||||||
cgsize:=OS_16;
|
cgsize:=OS_16;
|
||||||
end;
|
end;
|
||||||
dec(len,copysize);
|
dec(len,copysize);
|
||||||
r:=rg.getregisterint(list,cgsize);
|
|
||||||
a_load_ref_reg(list,cgsize,cgsize,srcref,r);
|
|
||||||
if (len=0) and delsource then
|
if (len=0) and delsource then
|
||||||
reference_release(list,source);
|
reference_release(list,source);
|
||||||
|
r:=rg.getregisterint(list,cgsize);
|
||||||
|
a_load_ref_reg(list,cgsize,cgsize,srcref,r);
|
||||||
|
rg.ungetregisterint(list,r);
|
||||||
a_load_reg_ref(list,cgsize,cgsize,r,dstref);
|
a_load_reg_ref(list,cgsize,cgsize,r,dstref);
|
||||||
inc(srcref.offset,copysize);
|
inc(srcref.offset,copysize);
|
||||||
inc(dstref.offset,copysize);
|
inc(dstref.offset,copysize);
|
||||||
rg.ungetregisterint(list,r);
|
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1598,7 +1598,10 @@ unit cgx86;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.67 2003-09-28 13:37:19 peter
|
Revision 1.68 2003-09-29 20:58:56 peter
|
||||||
|
* optimized releasing of registers
|
||||||
|
|
||||||
|
Revision 1.67 2003/09/28 13:37:19 peter
|
||||||
* a_call_ref removed
|
* a_call_ref removed
|
||||||
|
|
||||||
Revision 1.66 2003/09/25 21:29:16 peter
|
Revision 1.66 2003/09/25 21:29:16 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user