* delayed paraloc allocation, a_param_*() gets extra parameter

if it needs to allocate temp or real paralocation
  * optimized/simplified int-real loading
This commit is contained in:
peter 2003-12-03 23:13:19 +00:00
parent 07f38cd53a
commit 64b0a0eadf
16 changed files with 358 additions and 354 deletions

View File

@ -72,10 +72,10 @@ unit cg64f32;
procedure a_op64_loc_reg(list : taasmoutput;op:TOpCG;const l : tlocation;reg : tregister64);override;
procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;value : qword;const ref : treference);override;
procedure a_param64_reg(list : taasmoutput;reg : tregister64;const locpara : tparalocation);override;
procedure a_param64_const(list : taasmoutput;value : qword;const locpara : tparalocation);override;
procedure a_param64_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);override;
procedure a_param64_loc(list : taasmoutput;const l : tlocation;const locpara : tparalocation);override;
procedure a_param64_reg(list : taasmoutput;reg : tregister64;var locpara : tparalocation;alloctemp:boolean);override;
procedure a_param64_const(list : taasmoutput;value : qword;var locpara : tparalocation;alloctemp:boolean);override;
procedure a_param64_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);override;
procedure a_param64_loc(list : taasmoutput;const l : tlocation;var locpara : tparalocation;alloctemp:boolean);override;
{# This routine tries to optimize the a_op64_const_reg operation, by
removing superfluous opcodes. Returns TRUE if normal processing
@ -452,31 +452,43 @@ unit cg64f32;
end;
procedure tcg64f32.a_param64_reg(list : taasmoutput;reg : tregister64;const locpara : tparalocation);
procedure tcg64f32.a_param64_reg(list : taasmoutput;reg : tregister64;var locpara : tparalocation;alloctemp:boolean);
var
tmplochi,tmploclo: tparalocation;
begin
if alloctemp then
paramanager.alloctempparaloc(list,locpara)
else
paramanager.allocparaloc(list,locpara);
paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
cg.a_param_reg(list,OS_32,reg.reghi,tmplochi);
cg.a_param_reg(list,OS_32,reg.reglo,tmploclo);
cg.a_param_reg(list,OS_32,reg.reghi,tmplochi,false);
cg.a_param_reg(list,OS_32,reg.reglo,tmploclo,false);
end;
procedure tcg64f32.a_param64_const(list : taasmoutput;value : qword;const locpara : tparalocation);
procedure tcg64f32.a_param64_const(list : taasmoutput;value : qword;var locpara : tparalocation;alloctemp:boolean);
var
tmplochi,tmploclo: tparalocation;
begin
if alloctemp then
paramanager.alloctempparaloc(list,locpara)
else
paramanager.allocparaloc(list,locpara);
paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
cg.a_param_const(list,OS_32,hi(value),tmplochi);
cg.a_param_const(list,OS_32,lo(value),tmploclo);
cg.a_param_const(list,OS_32,hi(value),tmplochi,false);
cg.a_param_const(list,OS_32,lo(value),tmploclo,false);
end;
procedure tcg64f32.a_param64_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
procedure tcg64f32.a_param64_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);
var
tmprefhi,tmpreflo : treference;
tmploclo,tmplochi : tparalocation;
begin
if alloctemp then
paramanager.alloctempparaloc(list,locpara)
else
paramanager.allocparaloc(list,locpara);
paramanager.splitparaloc64(locpara,tmploclo,tmplochi);
tmprefhi:=r;
tmpreflo:=r;
@ -484,22 +496,22 @@ unit cg64f32;
inc(tmpreflo.offset,4)
else
inc(tmprefhi.offset,4);
cg.a_param_ref(list,OS_32,tmprefhi,tmplochi);
cg.a_param_ref(list,OS_32,tmpreflo,tmploclo);
cg.a_param_ref(list,OS_32,tmprefhi,tmplochi,false);
cg.a_param_ref(list,OS_32,tmpreflo,tmploclo,false);
end;
procedure tcg64f32.a_param64_loc(list : taasmoutput;const l:tlocation;const locpara : tparalocation);
procedure tcg64f32.a_param64_loc(list : taasmoutput;const l:tlocation;var locpara : tparalocation;alloctemp:boolean);
begin
case l.loc of
LOC_REGISTER,
LOC_CREGISTER :
a_param64_reg(list,l.register64,locpara);
a_param64_reg(list,l.register64,locpara,alloctemp);
LOC_CONSTANT :
a_param64_const(list,l.valueqword,locpara);
a_param64_const(list,l.valueqword,locpara,alloctemp);
LOC_CREFERENCE,
LOC_REFERENCE :
a_param64_ref(list,l.reference,locpara);
a_param64_ref(list,l.reference,locpara,alloctemp);
else
internalerror(200203287);
end;
@ -761,7 +773,12 @@ begin
end.
{
$Log$
Revision 1.52 2003-10-10 17:48:13 peter
Revision 1.53 2003-12-03 23:13:19 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.52 2003/10/10 17:48:13 peter
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
* tregisteralloctor renamed to trgobj
* removed rgobj from a lot of units

View File

@ -117,7 +117,7 @@ unit cgobj;
@param(r register source of the operand)
@param(locpara where the parameter will be stored)
}
procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);virtual;
procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;var locpara : tparalocation;alloctemp:boolean);virtual;
{# Pass a parameter, which is a constant, to a routine.
A generic version is provided. This routine should
@ -128,7 +128,7 @@ unit cgobj;
@param(a value of constant to send)
@param(locpara where the parameter will be stored)
}
procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);virtual;
procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;var locpara : tparalocation;alloctemp:boolean);virtual;
{# Pass the value of a parameter, which is located in memory, to a routine.
A generic version is provided. This routine should
@ -139,7 +139,7 @@ unit cgobj;
@param(r Memory reference of value to send)
@param(locpara where the parameter will be stored)
}
procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);virtual;
procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;var locpara : tparalocation;alloctemp:boolean);virtual;
{# Pass the value of a parameter, which can be located either in a register or memory location,
to a routine.
@ -149,7 +149,7 @@ unit cgobj;
@param(nr parameter number (starting from one) of routine (from left to right))
@param(locpara where the parameter will be stored)
}
procedure a_param_loc(list : taasmoutput;const l : tlocation;const locpara : tparalocation);
procedure a_param_loc(list : taasmoutput;const l : tlocation;var locpara : tparalocation;alloctemp:boolean);
{# Pass the address of a reference to a routine. This routine
will calculate the address of the reference, and pass this
calculated address as a parameter.
@ -161,10 +161,10 @@ unit cgobj;
@param(r reference to get address from)
@param(nr parameter number (starting from one) of routine (from left to right))
}
procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);virtual;
procedure a_paramaddr_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);virtual;
{ Copies a whole memory block to the stack, the locpara must be a memory location }
procedure a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;const locpara : tparalocation);
procedure a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;var locpara : tparalocation;alloctemp:boolean);
{ Remarks:
* If a method specifies a size you have only to take care
of that number of bits, i.e. load_const_reg with OP_8 must
@ -475,10 +475,10 @@ unit cgobj;
procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : qword;regsrc,regdst : tregister64);virtual;
procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);virtual;
procedure a_param64_reg(list : taasmoutput;reg64 : tregister64;const loc : tparalocation);virtual;abstract;
procedure a_param64_const(list : taasmoutput;value : qword;const loc : tparalocation);virtual;abstract;
procedure a_param64_ref(list : taasmoutput;const r : treference;const loc : tparalocation);virtual;abstract;
procedure a_param64_loc(list : taasmoutput;const l : tlocation;const loc : tparalocation);virtual;abstract;
procedure a_param64_reg(list : taasmoutput;reg64 : tregister64;var loc : tparalocation;alloctemp:boolean);virtual;abstract;
procedure a_param64_const(list : taasmoutput;value : qword;var loc : tparalocation;alloctemp:boolean);virtual;abstract;
procedure a_param64_ref(list : taasmoutput;const r : treference;var loc : tparalocation;alloctemp:boolean);virtual;abstract;
procedure a_param64_loc(list : taasmoutput;const l : tlocation;var loc : tparalocation;alloctemp:boolean);virtual;abstract;
{
This routine tries to optimize the const_reg opcode, and should be
@ -600,10 +600,14 @@ implementation
for better code generation these methods should be overridden
******************************************************************************}
procedure tcg.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);
procedure tcg.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;var locpara : tparalocation;alloctemp:boolean);
var
ref : treference;
begin
if alloctemp then
paramanager.alloctempparaloc(list,locpara)
else
paramanager.allocparaloc(list,locpara);
case locpara.loc of
LOC_REGISTER,LOC_CREGISTER:
a_load_reg_reg(list,size,locpara.size,r,locpara.register);
@ -619,8 +623,8 @@ implementation
end;
end;
procedure tcg.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
procedure tcg.a_param_const(list : taasmoutput;size : tcgsize;a : aword;var locpara : tparalocation;alloctemp:boolean);
var
hr : tregister;
@ -628,49 +632,50 @@ implementation
hr:=getintregister(list,size);
a_load_const_reg(list,size,a,hr);
ungetregister(list,hr);
a_param_reg(list,size,hr,locpara);
a_param_reg(list,size,hr,locpara,alloctemp);
end;
procedure tcg.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);
procedure tcg.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;var locpara : tparalocation;alloctemp:boolean);
var
hr : tregister;
begin
hr:=getintregister(list,size);
a_load_ref_reg(list,size,size,r,hr);
ungetregister(list,hr);
a_param_reg(list,size,hr,locpara);
a_param_reg(list,size,hr,locpara,alloctemp);
end;
procedure tcg.a_param_loc(list : taasmoutput;const l:tlocation;const locpara : tparalocation);
procedure tcg.a_param_loc(list : taasmoutput;const l:tlocation;var locpara : tparalocation;alloctemp:boolean);
begin
case l.loc of
LOC_REGISTER,
LOC_CREGISTER :
a_param_reg(list,l.size,l.register,locpara);
a_param_reg(list,l.size,l.register,locpara,alloctemp);
LOC_CONSTANT :
a_param_const(list,l.size,l.value,locpara);
a_param_const(list,l.size,l.value,locpara,alloctemp);
LOC_CREFERENCE,
LOC_REFERENCE :
a_param_ref(list,l.size,l.reference,locpara);
a_param_ref(list,l.size,l.reference,locpara,alloctemp);
else
internalerror(2002032211);
end;
end;
procedure tcg.a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
procedure tcg.a_paramaddr_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);
var
hr : tregister;
begin
hr:=getaddressregister(list);
a_loadaddr_ref_reg(list,r,hr);
ungetregister(list,hr);
a_param_reg(list,OS_ADDR,hr,locpara);
a_param_reg(list,OS_ADDR,hr,locpara,alloctemp);
end;
procedure tcg.a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;const locpara : tparalocation);
procedure tcg.a_param_copy_ref(list : taasmoutput;size : qword;const r : treference;var locpara : tparalocation;alloctemp:boolean);
var
ref : treference;
begin
@ -1273,17 +1278,14 @@ implementation
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paraloc2:=paramanager.getintparaloc(pocall_default,2);
paraloc3:=paramanager.getintparaloc(pocall_default,3);
paramanager.allocparaloc(list,paraloc3);
a_paramaddr_ref(list,dest,paraloc3);
paramanager.allocparaloc(list,paraloc2);
a_paramaddr_ref(list,dest,paraloc3,false);
if loadref then
a_param_ref(list,OS_ADDR,source,paraloc2)
a_param_ref(list,OS_ADDR,source,paraloc2,false)
else
a_paramaddr_ref(list,source,paraloc2);
a_paramaddr_ref(list,source,paraloc2,false);
if delsource then
reference_release(list,source);
paramanager.allocparaloc(list,paraloc1);
a_param_const(list,OS_INT,len,paraloc1);
a_param_const(list,OS_INT,len,paraloc1,false);
paramanager.freeparaloc(list,paraloc3);
paramanager.freeparaloc(list,paraloc2);
paramanager.freeparaloc(list,paraloc1);
@ -1317,8 +1319,7 @@ implementation
if incrfunc<>'' then
begin
{ these functions get the pointer by value }
paramanager.allocparaloc(list,paraloc1);
a_param_ref(list,OS_ADDR,ref,paraloc1);
a_param_ref(list,OS_ADDR,ref,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
a_call_name(list,incrfunc);
@ -1327,13 +1328,11 @@ implementation
else
begin
reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
paramanager.allocparaloc(list,paraloc2);
a_paramaddr_ref(list,href,paraloc2);
paramanager.allocparaloc(list,paraloc1);
a_paramaddr_ref(list,href,paraloc2,false);
if loadref then
a_param_ref(list,OS_ADDR,ref,paraloc1)
a_param_ref(list,OS_ADDR,ref,paraloc1,false)
else
a_paramaddr_ref(list,ref,paraloc1);
a_paramaddr_ref(list,ref,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
paramanager.freeparaloc(list,paraloc2);
allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@ -1372,14 +1371,12 @@ implementation
if needrtti then
begin
reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
paramanager.allocparaloc(list,paraloc2);
a_paramaddr_ref(list,href,paraloc2);
a_paramaddr_ref(list,href,paraloc2,false);
end;
paramanager.allocparaloc(list,paraloc1);
if loadref then
a_param_ref(list,OS_ADDR,ref,paraloc1)
a_param_ref(list,OS_ADDR,ref,paraloc1,false)
else
a_paramaddr_ref(list,ref,paraloc1);
a_paramaddr_ref(list,ref,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
if needrtti then
paramanager.freeparaloc(list,paraloc2);
@ -1390,13 +1387,11 @@ implementation
else
begin
reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
paramanager.allocparaloc(list,paraloc2);
a_paramaddr_ref(list,href,paraloc2);
paramanager.allocparaloc(list,paraloc1);
a_paramaddr_ref(list,href,paraloc2,false);
if loadref then
a_param_ref(list,OS_ADDR,ref,paraloc1)
a_param_ref(list,OS_ADDR,ref,paraloc1,false)
else
a_paramaddr_ref(list,ref,paraloc1);
a_paramaddr_ref(list,ref,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
paramanager.freeparaloc(list,paraloc2);
allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@ -1420,13 +1415,11 @@ implementation
else
begin
reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
paramanager.allocparaloc(list,paraloc2);
a_paramaddr_ref(list,href,paraloc2);
paramanager.allocparaloc(list,paraloc1);
a_paramaddr_ref(list,href,paraloc2,false);
if loadref then
a_param_ref(list,OS_ADDR,ref,paraloc1)
a_param_ref(list,OS_ADDR,ref,paraloc1,false)
else
a_paramaddr_ref(list,ref,paraloc1);
a_paramaddr_ref(list,ref,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
paramanager.freeparaloc(list,paraloc2);
allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@ -1450,13 +1443,11 @@ implementation
else
begin
reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
paramanager.allocparaloc(list,paraloc2);
a_paramaddr_ref(list,href,paraloc2);
paramanager.allocparaloc(list,paraloc1);
a_paramaddr_ref(list,href,paraloc2,false);
if loadref then
a_param_ref(list,OS_ADDR,ref,paraloc1)
a_param_ref(list,OS_ADDR,ref,paraloc1,false)
else
a_paramaddr_ref(list,ref,paraloc1);
a_paramaddr_ref(list,ref,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
paramanager.freeparaloc(list,paraloc2);
allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@ -1581,8 +1572,7 @@ implementation
paraloc1 : tparalocation;
begin
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paramanager.allocparaloc(list,paraloc1);
a_param_const(list,OS_32,stackframesize,paraloc1);
a_param_const(list,OS_32,stackframesize,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
{ No register saving needed, saveregisters is used }
a_call_name(list,'FPC_STACKCHECK');
@ -1612,8 +1602,7 @@ implementation
objectlibrary.getlabel(oklabel);
a_cmp_const_reg_label(list,OS_ADDR,OC_NE,0,reg,oklabel);
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paramanager.allocparaloc(list,paraloc1);
a_param_const(list,OS_INT,210,paraloc1);
a_param_const(list,OS_INT,210,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
a_call_name(list,'FPC_HANDLEERROR');
a_label(list,oklabel);
@ -1631,10 +1620,8 @@ implementation
if (cs_check_object in aktlocalswitches) then
begin
reference_reset_symbol(hrefvmt,objectlibrary.newasmsymboldata(objdef.vmt_mangledname),0);
paramanager.allocparaloc(list,paraloc2);
a_paramaddr_ref(list,hrefvmt,paraloc2);
paramanager.allocparaloc(list,paraloc1);
a_param_reg(list,OS_ADDR,reg,paraloc1);
a_paramaddr_ref(list,hrefvmt,paraloc2,false);
a_param_reg(list,OS_ADDR,reg,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
paramanager.freeparaloc(list,paraloc2);
{ No register saving needed, saveregisters is used }
@ -1643,8 +1630,7 @@ implementation
else
if (cs_check_range in aktlocalswitches) then
begin
paramanager.allocparaloc(list,paraloc1);
a_param_reg(list,OS_ADDR,reg,paraloc1);
a_param_reg(list,OS_ADDR,reg,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
{ No register saving needed, saveregisters is used }
a_call_name(list,'FPC_CHECK_OBJECT');
@ -1817,7 +1803,12 @@ finalization
end.
{
$Log$
Revision 1.134 2003-11-05 23:05:13 florian
Revision 1.135 2003-12-03 23:13:19 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.134 2003/11/05 23:05:13 florian
* elesize of g_copyvaluepara_openarray changed
+ g_releaesvaluepara_openarray added

View File

@ -129,16 +129,6 @@ unit cpupara;
end;
end;
end;
if calloption=pocall_register then
begin
case def.deftype of
floatdef :
begin
result:=true;
exit;
end;
end;
end;
result:=inherited push_addr_param(varspez,def,calloption);
end;
@ -419,7 +409,6 @@ unit cpupara;
if (parareg<=high(parasupregs)) and
not(
is_64bit or
(hp.paratype.def.deftype=floatdef) or
((hp.paratype.def.deftype in [floatdef,recorddef,arraydef]) and
(not pushaddr))
) then
@ -462,7 +451,7 @@ unit cpupara;
hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
if side=calleeside then
inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
end;
end;
hp:=tparaitem(hp.next);
end;
{ We need to return the size allocated }
@ -498,7 +487,12 @@ begin
end.
{
$Log$
Revision 1.46 2003-12-01 18:44:15 peter
Revision 1.47 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.46 2003/12/01 18:44:15 peter
* fixed some crashes
* fixed varargs and register calling probs

View File

@ -356,8 +356,7 @@ interface
end
else
begin
paramanager.allocparaloc(exprasmlist,paraloc2);
cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraloc2);
cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraloc2,false);
end;
secondpass(right);
location_release(exprasmlist,right.location);
@ -368,21 +367,18 @@ interface
end
else
begin
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_paramaddr_ref(exprasmlist,right.location.reference,paraloc1);
cg.a_paramaddr_ref(exprasmlist,right.location.reference,paraloc1,false);
end;
{ push parameters }
if paraloc1.loc=LOC_REGISTER then
begin
cg.ungetregister(exprasmlist,hregister2);
paramanager.allocparaloc(exprasmlist,paraloc2);
cg.a_param_reg(exprasmlist,OS_ADDR,hregister2,paraloc2);
cg.a_param_reg(exprasmlist,OS_ADDR,hregister2,paraloc2,false);
end;
if paraloc2.loc=LOC_REGISTER then
begin
cg.ungetregister(exprasmlist,hregister1);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_reg(exprasmlist,OS_ADDR,hregister1,paraloc1);
cg.a_param_reg(exprasmlist,OS_ADDR,hregister1,paraloc1,false);
end;
paramanager.freeparaloc(exprasmlist,paraloc1);
paramanager.freeparaloc(exprasmlist,paraloc2);
@ -1495,7 +1491,12 @@ begin
end.
{
$Log$
Revision 1.86 2003-10-17 14:38:32 peter
Revision 1.87 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.86 2003/10/17 14:38:32 peter
* 64k registers supported
* fixed some memory leaks

View File

@ -65,8 +65,8 @@ implementation
symconst,symdef,aasmbase,aasmtai,aasmcpu,
cgbase,
ncon,ncal,ncnv,
cpubase,
cgobj,cga,cgx86;
cpubase,tgobj,
cgobj,cga,cgx86,ncgutil;
function ti386typeconvnode.first_int_to_real : tnode;
@ -85,92 +85,45 @@ implementation
href : treference;
hregister : tregister;
l1,l2 : tasmlabel;
freereg : boolean;
begin
location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
hregister:=NR_NO;
freereg:=false;
{ for u32bit a solution is to push $0 and to load a comp }
{ does this first, it destroys maybe EDI }
if torddef(left.resulttype.def).typ=u32bit then
exprasmlist.concat(taicpu.op_const(A_PUSH,S_L,0));
{ We need to load from a reference }
location_force_mem(exprasmlist,left.location);
case left.location.loc of
LOC_REGISTER,
LOC_CREGISTER :
begin
case left.location.size of
OS_64,OS_S64 :
begin
exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,left.location.registerhigh));
hregister:=left.location.registerlow;
end;
OS_32,OS_S32 :
hregister:=left.location.register;
else
begin
hregister:=cg.getintregister(exprasmlist,OS_32);
freereg:=true;
cg.a_load_reg_reg(exprasmlist,left.location.size,OS_32,left.location.register,hregister);
end;
end;
end;
LOC_REFERENCE,
LOC_CREFERENCE :
begin
hregister:=cg.getintregister(exprasmlist,OS_INT);
freereg:=true;
if left.location.size in [OS_64,OS_S64] then
begin
href:=left.location.reference;
inc(href.offset,4);
cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,href,hregister);
exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,hregister));
cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,left.location.reference,hregister);
end
else
cg.a_load_ref_reg(exprasmlist,left.location.size,OS_INT,left.location.reference,hregister);
end;
else
internalerror(2002032218);
end;
{ For u32bit we need to load it as comp and need to
make it 64bits }
if (torddef(left.resulttype.def).typ=u32bit) then
begin
tg.GetTemp(exprasmlist,8,tt_normal,href);
cg.g_concatcopy(exprasmlist,left.location.reference,href,4,true,false);
inc(href.offset,4);
cg.a_load_const_ref(exprasmlist,OS_32,0,href);
dec(href.offset,4);
left.location.reference:=href;
end;
{ Load from reference to fpu reg }
location_release(exprasmlist,left.location);
location_freetemp(exprasmlist,left.location);
{ for 64 bit integers, the high dword is already pushed }
exprasmlist.concat(taicpu.op_reg(A_PUSH,S_L,hregister));
if freereg then
cg.ungetregister(exprasmlist,hregister);
reference_reset_base(href,NR_ESP,0);
case torddef(left.resulttype.def).typ of
u32bit:
begin
emit_ref(A_FILD,S_IQ,href);
emit_const_reg(A_ADD,S_L,8,NR_ESP);
end;
u32bit,
scurrency,
s64bit:
begin
emit_ref(A_FILD,S_IQ,href);
emit_const_reg(A_ADD,S_L,8,NR_ESP);
end;
exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
u64bit:
begin
{ unsigned 64 bit ints are harder to handle: }
{ we load bits 0..62 and then check bit 63: }
{ if it is 1 then we add $80000000 000000000 }
{ as double }
inc(href.offset,4);
inc(left.location.reference.offset,4);
hregister:=cg.getintregister(exprasmlist,OS_32);
cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,href,hregister);
reference_reset_base(href,NR_ESP,4);
emit_const_ref(A_AND,S_L,$7fffffff,href);
cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,left.location.reference,hregister);
emit_const_ref(A_AND,S_L,$7fffffff,left.location.reference);
emit_const_reg(A_TEST,S_L,longint($80000000),hregister);
cg.ungetregister(exprasmlist,hregister);
reference_reset_base(href,NR_ESP,0);
emit_ref(A_FILD,S_IQ,href);
dec(left.location.reference.offset,4);
exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
objectlibrary.getdatalabel(l1);
objectlibrary.getlabel(l2);
cg.a_jmp_flags(exprasmlist,F_E,l2);
@ -181,16 +134,11 @@ implementation
reference_reset_symbol(href,l1,0);
emit_ref(A_FADD,S_FL,href);
cg.a_label(exprasmlist,l2);
emit_const_reg(A_ADD,S_L,8,NR_ESP);
end
else
begin
emit_ref(A_FILD,S_IL,href);
hregister:=cg.getintregister(exprasmlist,OS_32);
emit_reg(A_POP,S_L,hregister);
cg.ungetregister(exprasmlist,hregister);
end;
exprasmlist.concat(taicpu.op_ref(A_FILD,S_IL,left.location.reference));
end;
location_freetemp(exprasmlist,left.location);
tcgx86(cg).inc_fpu_stack;
location.register:=NR_ST;
end;
@ -236,7 +184,12 @@ begin
end.
{
$Log$
Revision 1.68 2003-11-04 22:30:15 florian
Revision 1.69 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.68 2003/11/04 22:30:15 florian
+ type cast variant<->enum
* cnv. node second pass uses now as well helper wrappers

View File

@ -35,7 +35,6 @@ interface
tcgcallparanode = class(tcallparanode)
private
tempparaloc : tparalocation;
procedure allocate_tempparaloc;
procedure push_addr_para;
procedure push_value_para;
public
@ -99,22 +98,12 @@ implementation
TCGCALLPARANODE
*****************************************************************************}
procedure tcgcallparanode.allocate_tempparaloc;
begin
{ Allocate (temporary) paralocation }
tempparaloc:=paraitem.paraloc[callerside];
if (tempparaloc.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) then
paramanager.alloctempregs(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);
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc,true);
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
end;
@ -137,7 +126,6 @@ implementation
if left.resulttype.def.deftype=floatdef then
begin
location_release(exprasmlist,left.location);
allocate_tempparaloc;
{$ifdef i386}
if tempparaloc.loc<>LOC_REFERENCE then
internalerror(200309291);
@ -180,7 +168,7 @@ implementation
dec(href.offset,2);
dec(size,2);
end;
cg.a_param_ref(exprasmlist,cgsize,href,tempparaloc);
cg.a_param_ref(exprasmlist,cgsize,href,tempparaloc,true);
end;
end
else
@ -215,7 +203,6 @@ implementation
aktcallnode.procdefinition.proccalloption) then
begin
location_release(exprasmlist,left.location);
allocate_tempparaloc;
{$ifdef i386}
if tempparaloc.loc<>LOC_REFERENCE then
internalerror(200309292);
@ -249,16 +236,14 @@ implementation
if cgsize in [OS_64,OS_S64] then
begin
inc(tcgcallnode(aktcallnode).pushedparasize,8);
allocate_tempparaloc;
cg64.a_param64_loc(exprasmlist,left.location,tempparaloc);
cg64.a_param64_loc(exprasmlist,left.location,tempparaloc,true);
location_release(exprasmlist,left.location);
end
else
begin
location_release(exprasmlist,left.location);
allocate_tempparaloc;
inc(tcgcallnode(aktcallnode).pushedparasize,align(tcgsize2size[tempparaloc.size],tempparaloc.alignment));
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
cg.a_param_loc(exprasmlist,left.location,tempparaloc,true);
end;
end;
{$ifdef SUPPORT_MMX}
@ -266,7 +251,6 @@ implementation
LOC_CMMXREGISTER:
begin
location_release(exprasmlist,left.location);
allocate_tempparaloc;
inc(tcgcallnode(aktcallnode).pushedparasize,8);
cg.a_parammm_reg(exprasmlist,left.location.register);
end;
@ -291,6 +275,12 @@ implementation
(nf_varargs_para in flags)) then
internalerror(200304242);
{ Initialize temporary paralocation, only reset register
value for register parameters }
tempparaloc:=paraitem.paraloc[callerside];
if (tempparaloc.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) then
tempparaloc.register:=NR_NO;
{ Skip nothingn nodes which are used after disabling
a parameter }
if (left.nodetype<>nothingn) then
@ -337,8 +327,7 @@ implementation
begin
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
location_release(exprasmlist,left.location);
allocate_tempparaloc;
cg.a_param_loc(exprasmlist,left.location,tempparaloc);
cg.a_param_loc(exprasmlist,left.location,tempparaloc,true);
end
else
push_addr_para;
@ -762,8 +751,10 @@ implementation
cg.ungetregister(exprasmlist,pvreg);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
cg.allocexplicitregisters(exprasmlist,R_SSEREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
if cg.uses_registers(R_FPUREGISTER) then
cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
if cg.uses_registers(R_MMREGISTER) then
cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
{ call method }
cg.a_call_reg(exprasmlist,pvreg);
@ -779,8 +770,10 @@ implementation
freeparas;
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
cg.allocexplicitregisters(exprasmlist,R_SSEREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
if cg.uses_registers(R_FPUREGISTER) then
cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
if cg.uses_registers(R_MMREGISTER) then
cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
{ Calling interrupt from the same code requires some
extra code }
@ -815,8 +808,10 @@ implementation
cg.ungetregister(exprasmlist,pvreg);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_alloc);
cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
if cg.uses_registers(R_FPUREGISTER) then
cg.allocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
if cg.uses_registers(R_MMREGISTER) then
cg.allocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
{ Calling interrupt from the same code requires some
extra code }
@ -872,8 +867,10 @@ implementation
end;
end;
end;
cg.deallocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
cg.deallocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
if cg.uses_registers(R_MMREGISTER) then
cg.deallocexplicitregisters(exprasmlist,R_MMREGISTER,paramanager.get_volatile_registers_mm(procdefinition.proccalloption));
if cg.uses_registers(R_FPUREGISTER) then
cg.deallocexplicitregisters(exprasmlist,R_FPUREGISTER,regs_to_push_fpu);
cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,regs_to_free);
{ handle function results }
@ -1119,7 +1116,12 @@ begin
end.
{
$Log$
Revision 1.142 2003-12-02 21:23:34 peter
Revision 1.143 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.142 2003/12/02 21:23:34 peter
* exitlabel for inline procs
Revision 1.141 2003/11/23 17:39:33 peter

View File

@ -825,18 +825,16 @@ implementation
{ Push parameters }
if assigned(right) then
begin
paramanager.allocparaloc(exprasmlist,paraloc3);
if assigned(frametree) then
begin
location_release(exprasmlist,frametree.location);
cg.a_param_loc(exprasmlist,frametree.location,paraloc3)
cg.a_param_loc(exprasmlist,frametree.location,paraloc3,false)
end
else
cg.a_param_const(exprasmlist,OS_INT,0,paraloc3);
cg.a_param_const(exprasmlist,OS_INT,0,paraloc3,false);
{ push address }
location_release(exprasmlist,right.location);
paramanager.allocparaloc(exprasmlist,paraloc2);
cg.a_param_loc(exprasmlist,right.location,paraloc2);
cg.a_param_loc(exprasmlist,right.location,paraloc2,false);
end
else
begin
@ -845,18 +843,15 @@ implementation
cg.a_label(exprasmlist,a);
reference_reset_symbol(href2,a,0);
{ push current frame }
paramanager.allocparaloc(exprasmlist,paraloc3);
cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3);
cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3,false);
{ push current address }
paramanager.allocparaloc(exprasmlist,paraloc2);
if target_info.system <> system_powerpc_macos then
cg.a_paramaddr_ref(exprasmlist,href2,paraloc2)
cg.a_paramaddr_ref(exprasmlist,href2,paraloc2,false)
else
cg.a_param_const(exprasmlist,OS_INT,0,paraloc2);
cg.a_param_const(exprasmlist,OS_INT,0,paraloc2,false);
end;
location_release(exprasmlist,left.location);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_loc(exprasmlist,left.location,paraloc1);
cg.a_param_loc(exprasmlist,left.location,paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
paramanager.freeparaloc(exprasmlist,paraloc2);
paramanager.freeparaloc(exprasmlist,paraloc3);
@ -912,8 +907,7 @@ implementation
cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_reg(exprasmlist,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
cg.a_param_reg(exprasmlist,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
@ -1021,8 +1015,7 @@ implementation
'default handler' flag (=-1)
}
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paraloc1);
cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_call_name(exprasmlist,'FPC_CATCHES');
@ -1049,8 +1042,7 @@ implementation
cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
@ -1186,8 +1178,7 @@ implementation
{ send the vmt parameter }
reference_reset_symbol(href2,objectlibrary.newasmsymboldata(excepttype.vmt_mangledname),0);
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_paramaddr_ref(exprasmlist,href2,paraloc1);
cg.a_paramaddr_ref(exprasmlist,href2,paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_call_name(exprasmlist,'FPC_CATCHES');
@ -1245,8 +1236,7 @@ implementation
cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
cg.deallocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
@ -1479,7 +1469,12 @@ begin
end.
{
$Log$
Revision 1.85 2003-10-17 14:38:32 peter
Revision 1.86 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.85 2003/10/17 14:38:32 peter
* 64k registers supported
* fixed some memory leaks

View File

@ -188,24 +188,20 @@ implementation
maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
cg.a_label(exprasmlist,falselabel);
{ erroraddr }
paramanager.allocparaloc(exprasmlist,paraloc4);
cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc4);
cg.a_param_reg(exprasmlist,OS_ADDR,NR_FRAME_POINTER_REG,paraloc4,false);
{ lineno }
paramanager.allocparaloc(exprasmlist,paraloc3);
cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,paraloc3);
cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,paraloc3,false);
{ filename string }
hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
firstpass(tnode(hp2));
secondpass(tnode(hp2));
if codegenerror then
exit;
paramanager.allocparaloc(exprasmlist,paraloc2);
cg.a_paramaddr_ref(exprasmlist,hp2.location.reference,paraloc2);
cg.a_paramaddr_ref(exprasmlist,hp2.location.reference,paraloc2,false);
hp2.free;
{ push msg }
secondpass(tcallparanode(tcallparanode(left).right).left);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_paramaddr_ref(exprasmlist,tcallparanode(tcallparanode(left).right).left.location.reference,paraloc1);
cg.a_paramaddr_ref(exprasmlist,tcallparanode(tcallparanode(left).right).left.location.reference,paraloc1,false);
{ call }
paramanager.freeparaloc(exprasmlist,paraloc1);
paramanager.freeparaloc(exprasmlist,paraloc2);
@ -656,7 +652,12 @@ end.
{
$Log$
Revision 1.47 2003-10-10 17:48:13 peter
Revision 1.48 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.47 2003/10/10 17:48:13 peter
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
* tregisteralloctor renamed to trgobj
* removed rgobj from a lot of units

View File

@ -154,8 +154,7 @@ implementation
cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,hregister,norelocatelab);
{ don't save the allocated register else the result will be destroyed later }
reference_reset_symbol(href,objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname),0);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_ref(exprasmlist,OS_ADDR,href,paraloc1);
cg.a_param_ref(exprasmlist,OS_ADDR,href,paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_call_reg(exprasmlist,hregister);
@ -892,7 +891,12 @@ begin
end.
{
$Log$
Revision 1.100 2003-12-01 18:44:15 peter
Revision 1.101 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.100 2003/12/01 18:44:15 peter
* fixed some crashes
* fixed varargs and register calling probs

View File

@ -331,8 +331,7 @@ implementation
objectlibrary.getlabel(hl);
cg.a_cmp_const_reg_label(exprasmlist,OS_INT,OC_NE,0,hdenom,hl);
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_const(exprasmlist,OS_S32,200,paraloc1);
cg.a_param_const(exprasmlist,OS_S32,200,paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
cg.a_call_name(exprasmlist,'FPC_HANDLERROR');
cg.a_label(exprasmlist,hl);
@ -502,7 +501,12 @@ begin
end.
{
$Log$
Revision 1.21 2003-10-10 17:48:13 peter
Revision 1.22 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.21 2003/10/10 17:48:13 peter
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu
* tregisteralloctor renamed to trgobj
* removed rgobj from a lot of units

View File

@ -292,8 +292,7 @@ implementation
(not tpointerdef(left.resulttype.def).is_far) then
begin
paraloc1:=paramanager.getintparaloc(pocall_default,1);
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,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
{ FPC_CHECKPOINTER uses saveregisters }
cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
@ -346,8 +345,7 @@ implementation
not(cs_compilesystem in aktmoduleswitches) then
begin
paraloc1:=paramanager.getintparaloc(pocall_default,1);
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,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
{ FPC_CHECKPOINTER uses saveregisters }
cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
@ -363,8 +361,7 @@ implementation
not(cs_compilesystem in aktmoduleswitches) then
begin
paraloc1:=paramanager.getintparaloc(pocall_default,1);
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,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
{ FPC_CHECKPOINTER uses saveregisters }
cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER');
@ -557,10 +554,8 @@ implementation
begin
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paraloc2:=paramanager.getintparaloc(pocall_default,2);
paramanager.allocparaloc(exprasmlist,paraloc2);
cg.a_param_loc(exprasmlist,right.location,paraloc2);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_loc(exprasmlist,left.location,paraloc1);
cg.a_param_loc(exprasmlist,right.location,paraloc2,false);
cg.a_param_loc(exprasmlist,left.location,paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
paramanager.freeparaloc(exprasmlist,paraloc2);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@ -620,8 +615,7 @@ implementation
if (cs_check_range in aktlocalswitches) then
begin
paraloc1:=paramanager.getintparaloc(pocall_default,1);
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,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
@ -700,12 +694,10 @@ implementation
begin
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paraloc2:=paramanager.getintparaloc(pocall_default,2);
paramanager.allocparaloc(exprasmlist,paraloc2);
cg.a_param_const(exprasmlist,OS_INT,tordconstnode(right).value,paraloc2);
cg.a_param_const(exprasmlist,OS_INT,tordconstnode(right).value,paraloc2,false);
href:=location.reference;
dec(href.offset,7);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1);
cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
paramanager.freeparaloc(exprasmlist,paraloc2);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@ -834,12 +826,10 @@ implementation
begin
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paraloc2:=paramanager.getintparaloc(pocall_default,2);
paramanager.allocparaloc(exprasmlist,paraloc2);
cg.a_param_reg(exprasmlist,OS_INT,right.location.register,paraloc2);
cg.a_param_reg(exprasmlist,OS_INT,right.location.register,paraloc2,false);
href:=location.reference;
dec(href.offset,7);
paramanager.allocparaloc(exprasmlist,paraloc1);
cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1);
cg.a_param_ref(exprasmlist,OS_INT,href,paraloc1,false);
paramanager.freeparaloc(exprasmlist,paraloc1);
paramanager.freeparaloc(exprasmlist,paraloc2);
cg.allocexplicitregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
@ -878,7 +868,12 @@ begin
end.
{
$Log$
Revision 1.81 2003-11-23 17:03:35 peter
Revision 1.82 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.81 2003/11/23 17:03:35 peter
* fixed parentfp loading, it was using the offset of the current
nested proc instead of the parent

View File

@ -278,13 +278,10 @@ implementation
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paraloc2:=paramanager.getintparaloc(pocall_default,2);
paraloc3:=paramanager.getintparaloc(pocall_default,3);
paramanager.allocparaloc(list,paraloc3);
cg.a_paramaddr_ref(list,envbuf,paraloc3);
paramanager.allocparaloc(list,paraloc2);
cg.a_paramaddr_ref(list,jmpbuf,paraloc2);
cg.a_paramaddr_ref(list,envbuf,paraloc3,false);
cg.a_paramaddr_ref(list,jmpbuf,paraloc2,false);
{ push type of exceptionframe }
paramanager.allocparaloc(list,paraloc1);
cg.a_param_const(list,OS_S32,1,paraloc1);
cg.a_param_const(list,OS_S32,1,paraloc1,false);
paramanager.freeparaloc(list,paraloc3);
paramanager.freeparaloc(list,paraloc2);
paramanager.freeparaloc(list,paraloc1);
@ -293,8 +290,7 @@ implementation
cg.deallocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paramanager.allocparaloc(list,paraloc1);
cg.a_param_reg(list,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
cg.a_param_reg(list,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1,false);
paramanager.freeparaloc(list,paraloc1);
cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_call_name(list,'FPC_SETJMP');
@ -1286,11 +1282,9 @@ implementation
reference_reset_symbol(href,objectlibrary.newasmsymboldata('etext'),0);
paraloc1:=paramanager.getintparaloc(pocall_default,1);
paraloc2:=paramanager.getintparaloc(pocall_default,2);
paramanager.allocparaloc(list,paraloc2);
cg.a_paramaddr_ref(list,href,paraloc2);
cg.a_paramaddr_ref(list,href,paraloc2,false);
reference_reset_symbol(href,objectlibrary.newasmsymboldata('__image_base__'),0);
paramanager.allocparaloc(list,paraloc1);
cg.a_paramaddr_ref(list,href,paraloc1);
cg.a_paramaddr_ref(list,href,paraloc1,false);
paramanager.freeparaloc(list,paraloc2);
paramanager.freeparaloc(list,paraloc1);
cg.allocexplicitregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_cdecl));
@ -1452,11 +1446,30 @@ implementation
procedure gen_stackalloc_code(list:Taasmoutput);
var
hitemp,
lotemp,
stackframe : longint;
begin
{ Calculate size of stackframe }
stackframe:=current_procinfo.calc_stackframe_size;
{ All temps are know, write offsets used for information }
if (cs_asm_source in aktglobalswitches) then
begin
if tg.direction>0 then
begin
lotemp:=current_procinfo.tempstart;
hitemp:=tg.lasttemp;
end
else
begin
lotemp:=tg.lasttemp;
hitemp:=current_procinfo.tempstart;
end;
list.concat(Tai_comment.Create(strpnew('Temps allocated between '+std_regname(current_procinfo.framepointer)+
tostr_with_plus(lotemp)+' and '+std_regname(current_procinfo.framepointer)+tostr_with_plus(hitemp))));
end;
{$ifndef powerpc}
{ at least for the ppc this applies always, so this code isn't usable (FK) }
{ omit stack frame ? }
@ -1982,7 +1995,12 @@ implementation
end.
{
$Log$
Revision 1.171 2003-11-30 19:35:29 florian
Revision 1.172 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.171 2003/11/30 19:35:29 florian
* fixed several arm related problems
Revision 1.170 2003/11/29 20:13:25 florian

View File

@ -83,6 +83,7 @@ unit paramgr;
@param(loc Parameter location)
}
procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
procedure alloctempparaloc(list: taasmoutput;var locpara:tparalocation);virtual;
{# free a parameter location allocated with allocparaloc
@ -112,7 +113,6 @@ unit paramgr;
{ Return the location of the low and high part of a 64bit parameter }
procedure splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);virtual;
procedure alloctempregs(list: taasmoutput;var locpara:tparalocation);virtual;
end;
@ -320,6 +320,39 @@ implementation
end;
procedure tparamanager.alloctempparaloc(list: taasmoutput;var locpara:tparalocation);
begin
case locpara.loc of
LOC_REFERENCE:
begin
{ no temp needed by default }
end;
LOC_REGISTER:
begin
{$ifndef cpu64bit}
if locpara.size in [OS_64,OS_S64] then
begin
locpara.registerlow:=cg.getintregister(list,OS_32);
locpara.registerhigh:=cg.getintregister(list,OS_32);
end
else
{$endif cpu64bit}
locpara.register:=cg.getintregister(list,locpara.size);
end;
LOC_FPUREGISTER:
begin
locpara.register:=cg.getfpuregister(list,locpara.size);
end;
LOC_MMREGISTER:
begin
locpara.register:=cg.getfpuregister(list,locpara.size);
end;
else
internalerror(200308123);
end;
end;
procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
begin
case loc.loc of
@ -375,35 +408,6 @@ implementation
end;
procedure tparamanager.alloctempregs(list: taasmoutput;var locpara:tparalocation);
begin
case locpara.loc of
LOC_REGISTER:
begin
{$ifndef cpu64bit}
if locpara.size in [OS_64,OS_S64] then
begin
locpara.registerlow:=cg.getintregister(list,OS_32);
locpara.registerhigh:=cg.getintregister(list,OS_32);
end
else
{$endif cpu64bit}
locpara.register:=cg.getintregister(list,locpara.size);
end;
LOC_FPUREGISTER:
begin
locpara.register:=cg.getfpuregister(list,locpara.size);
end;
LOC_MMREGISTER:
begin
locpara.register:=cg.getfpuregister(list,locpara.size);
end;
else
internalerror(200308123);
end;
end;
function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint;
var
hp : tparaitem;
@ -450,7 +454,12 @@ end.
{
$Log$
Revision 1.65 2003-10-29 21:24:14 jonas
Revision 1.66 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.65 2003/10/29 21:24:14 jonas
+ support for fpu temp parameters
+ saving/restoring of fpu register before/after a procedure call

View File

@ -78,6 +78,9 @@ unit procinfo;
{ Size of the parameters on the stack }
para_stack_size : longint;
{ Offset of temp after para/local are allocated }
tempstart : longint;
{# some collected informations about the procedure
see pi_xxxx constants above
}
@ -208,7 +211,12 @@ implementation
end.
{
$Log$
Revision 1.8 2003-11-10 22:02:52 peter
Revision 1.9 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.8 2003/11/10 22:02:52 peter
* cross unit inlining fixed
Revision 1.7 2003/10/17 14:38:32 peter

View File

@ -529,9 +529,9 @@ implementation
depending on the implicit finally we need to add
an try...finally...end wrapper }
newblock:=internalstatements(newstatement);
if (pi_needs_implicit_finally in current_procinfo.flags) and
if (pi_needs_implicit_finally in flags) and
{ but it's useless in init/final code of units }
not(current_procinfo.procdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
not(procdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
begin
{ Generate special exception block only needed when
implicit finaly is used }
@ -642,17 +642,17 @@ implementation
{ Create register allocator }
cg.init_register_allocators;
current_procinfo.set_first_temp_offset;
current_procinfo.generate_parameter_info;
set_first_temp_offset;
generate_parameter_info;
{ Allocate space in temp/registers for parast and localst }
aktfilepos:=entrypos;
gen_alloc_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
if current_procinfo.procdef.localst.symtabletype=localsymtable then
gen_alloc_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
if (cs_asm_source in aktglobalswitches) then
aktproccode.concat(Tai_comment.Create(strpnew('Temps start at '+std_regname(current_procinfo.framepointer)+
tostr_with_plus(tg.lasttemp))));
gen_alloc_parast(aktproccode,tparasymtable(procdef.parast));
if procdef.localst.symtabletype=localsymtable then
gen_alloc_localst(aktproccode,tlocalsymtable(procdef.localst));
{ Store temp offset for information about 'real' temps }
tempstart:=tg.lasttemp;
{ Generate code to load register parameters in temps and insert local
copies for values parameters. This must be done before the code for the
@ -672,7 +672,7 @@ implementation
{ generate code for the node tree }
do_secondpass(code);
current_procinfo.aktproccode.concatlist(exprasmlist);
aktproccode.concatlist(exprasmlist);
{$ifdef i386}
procdef.fpu_used:=code.registersfpu;
{$endif i386}
@ -702,7 +702,7 @@ implementation
else
aktproccode.concatlist(templist);
{ insert exit label at the correct position }
cg.a_label(templist,current_procinfo.aktexitlabel);
cg.a_label(templist,aktexitlabel);
if assigned(exitlabel_asmnode.currenttai) then
aktproccode.insertlistafter(exitlabel_asmnode.currenttai,templist)
else
@ -743,9 +743,9 @@ implementation
{ Free space in temp/registers for parast and localst, must be
done after gen_entry_code }
aktfilepos:=exitpos;
if current_procinfo.procdef.localst.symtabletype=localsymtable then
gen_free_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
gen_free_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
if procdef.localst.symtabletype=localsymtable then
gen_free_localst(aktproccode,tlocalsymtable(procdef.localst));
gen_free_parast(aktproccode,tparasymtable(procdef.parast));
{ The procedure body is finished, we can now
allocate the registers }
@ -773,9 +773,9 @@ implementation
if not(cs_no_regalloc in aktglobalswitches) then
begin
if (cs_optimize in aktglobalswitches) and
{ do not optimize pure assembler procedures }
not(pi_is_assembler in current_procinfo.flags) then
optimize(aktproccode);
{ do not optimize pure assembler procedures }
not(pi_is_assembler in flags) then
optimize(aktproccode);
end;
{$endif NoOpt}
@ -1004,7 +1004,7 @@ implementation
{$endif state_tracking}
{ reset to normal non static function }
if (current_procinfo.procdef.parast.symtablelevel=normal_function_level) then
if (procdef.parast.symtablelevel=normal_function_level) then
allow_only_static:=false;
current_procinfo:=oldprocinfo;
@ -1318,7 +1318,12 @@ implementation
end.
{
$Log$
Revision 1.174 2003-11-27 09:08:01 florian
Revision 1.175 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.174 2003/11/27 09:08:01 florian
* resourcestring is allowed in the interface
Revision 1.173 2003/11/23 17:05:16 peter

View File

@ -62,10 +62,10 @@ unit cgx86;
{ left to right), this allows to move the parameter to }
{ register, if the cpu supports register calling }
{ conventions }
procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);override;
procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);override;
procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);override;
procedure a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);override;
procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;var locpara : tparalocation;alloctemp:boolean);override;
procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;var locpara : tparalocation;alloctemp:boolean);override;
procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;var locpara : tparalocation;alloctemp:boolean);override;
procedure a_paramaddr_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);override;
procedure a_call_name(list : taasmoutput;const s : string);override;
procedure a_call_reg(list : taasmoutput;reg : tregister);override;
@ -282,6 +282,8 @@ unit cgx86;
result:=rgint.uses_registers;
R_SSEREGISTER :
result:=rgmm.uses_registers;
R_FPUREGISTER :
result:=false;
else
internalerror(200310094);
end;
@ -486,7 +488,7 @@ unit cgx86;
{ we implement the following routines because otherwise we can't }
{ instantiate the class since it's abstract }
procedure tcgx86.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const locpara : tparalocation);
procedure tcgx86.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;var locpara : tparalocation;alloctemp:boolean);
begin
check_register_size(size,r);
if (locpara.loc=LOC_REFERENCE) and
@ -512,11 +514,11 @@ unit cgx86;
end;
end
else
inherited a_param_reg(list,size,r,locpara);
inherited a_param_reg(list,size,r,locpara,alloctemp);
end;
procedure tcgx86.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
procedure tcgx86.a_param_const(list : taasmoutput;size : tcgsize;a : aword;var locpara : tparalocation;alloctemp:boolean);
begin
if (locpara.loc=LOC_REFERENCE) and
@ -537,11 +539,11 @@ unit cgx86;
end;
end
else
inherited a_param_const(list,size,a,locpara);
inherited a_param_const(list,size,a,locpara,alloctemp);
end;
procedure tcgx86.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;const locpara : tparalocation);
procedure tcgx86.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;var locpara : tparalocation;alloctemp:boolean);
var
pushsize : tcgsize;
@ -575,11 +577,11 @@ unit cgx86;
end;
end
else
inherited a_param_ref(list,size,r,locpara);
inherited a_param_ref(list,size,r,locpara,alloctemp);
end;
procedure tcgx86.a_paramaddr_ref(list : taasmoutput;const r : treference;const locpara : tparalocation);
procedure tcgx86.a_paramaddr_ref(list : taasmoutput;const r : treference;var locpara : tparalocation;alloctemp:boolean);
var
tmpreg : tregister;
begin
@ -610,7 +612,7 @@ unit cgx86;
end;
end
else
inherited a_paramaddr_ref(list,r,locpara);
inherited a_paramaddr_ref(list,r,locpara,alloctemp);
end;
@ -1749,7 +1751,12 @@ unit cgx86;
end.
{
$Log$
Revision 1.87 2003-11-05 23:06:03 florian
Revision 1.88 2003-12-03 23:13:20 peter
* delayed paraloc allocation, a_param_*() gets extra parameter
if it needs to allocate temp or real paralocation
* optimized/simplified int-real loading
Revision 1.87 2003/11/05 23:06:03 florian
* elesize of g_copyvaluepara_openarray changed
Revision 1.86 2003/10/30 18:53:53 marco