mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-28 09:43:42 +02:00
834 lines
29 KiB
ObjectPascal
834 lines
29 KiB
ObjectPascal
{
|
|
$Id$
|
|
Copyright (c) 2002 by Florian Klaempfl
|
|
|
|
Generic calling convention handling
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
****************************************************************************
|
|
}
|
|
{# Parameter passing manager. Used to manage how
|
|
parameters are passed to routines.
|
|
}
|
|
unit paramgr;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
cclasses,globtype,
|
|
cpubase,cgbase,
|
|
aasmtai,
|
|
symconst,symtype,symdef;
|
|
|
|
type
|
|
tvarargsinfo = (
|
|
va_uses_float_reg
|
|
);
|
|
|
|
tvarargspara = class(tlinkedlist)
|
|
varargsinfo : set of tvarargsinfo;
|
|
end;
|
|
|
|
{# This class defines some methods to take care of routine
|
|
parameters. It should be overriden for each new processor
|
|
}
|
|
tparamanager = class
|
|
{# Returns true if the return value is actually a parameter
|
|
pointer.
|
|
}
|
|
function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;virtual;
|
|
|
|
function push_high_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;
|
|
|
|
{ Returns true if a parameter is too large to copy and only
|
|
the address is pushed
|
|
}
|
|
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;
|
|
{ return the size of a push }
|
|
function push_size(varspez:tvarspez;def : tdef;calloption : tproccalloption) : longint;
|
|
{ Returns true if a parameter needs to be copied on the stack, this
|
|
is required for cdecl procedures
|
|
}
|
|
function copy_value_on_stack(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;
|
|
{# Returns a structure giving the information on
|
|
the storage of the parameter (which must be
|
|
an integer parameter). This is only used when calling
|
|
internal routines directly, where all parameters must
|
|
be 4-byte values.
|
|
|
|
In case the location is a register, this register is allocated.
|
|
Call freeintparaloc() after the call to free the locations again.
|
|
Default implementation: don't do anything at all (in case you don't
|
|
use register parameter passing)
|
|
|
|
@param(list Current assembler list)
|
|
@param(nr Parameter number of routine, starting from 1)
|
|
}
|
|
function get_para_align(calloption : tproccalloption):byte;virtual;
|
|
function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;virtual;
|
|
function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;virtual;
|
|
function get_volatile_registers_flags(calloption : tproccalloption):tcpuregisterset;virtual;
|
|
function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;virtual;
|
|
function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;virtual;abstract;
|
|
|
|
{# allocate a parameter location created with create_paraloc_info
|
|
|
|
@param(list Current assembler list)
|
|
@param(loc Parameter location)
|
|
}
|
|
procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
|
|
|
|
{# free a parameter location allocated with allocparaloc
|
|
|
|
@param(list Current assembler list)
|
|
@param(loc Parameter location)
|
|
}
|
|
procedure freeparaloc(list: taasmoutput; const loc: tparalocation); virtual;
|
|
|
|
{ This is used to populate the location information on all parameters
|
|
for the routine as seen in either the caller or the callee. It returns
|
|
the size allocated on the stack
|
|
}
|
|
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;virtual;abstract;
|
|
|
|
{ This is used to populate the location information on all parameters
|
|
for the routine when it is being inlined. It returns
|
|
the size allocated on the stack
|
|
}
|
|
function create_inline_paraloc_info(p : tabstractprocdef):longint;virtual;
|
|
|
|
{ This is used to populate the location information on all parameters
|
|
for the routine that are passed as varargs. It returns
|
|
the size allocated on the stack (including the normal parameters)
|
|
}
|
|
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;virtual;abstract;
|
|
|
|
{ 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;
|
|
procedure alloctempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var locpara:tparalocation);virtual;
|
|
end;
|
|
|
|
|
|
var
|
|
paramanager : tparamanager;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
cpuinfo,systems,
|
|
cgutils,cgobj,tgobj,
|
|
defutil,verbose;
|
|
|
|
{ true if uses a parameter as return value }
|
|
function tparamanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
|
|
begin
|
|
ret_in_param:=(def.deftype in [arraydef,recorddef]) or
|
|
((def.deftype=stringdef) and (tstringdef(def).string_typ in [st_shortstring,st_longstring])) or
|
|
((def.deftype=procvardef) and (po_methodpointer in tprocvardef(def).procoptions)) or
|
|
((def.deftype=objectdef) and is_object(def)) or
|
|
(def.deftype=variantdef) or
|
|
((def.deftype=setdef) and (tsetdef(def).settype<>smallset));
|
|
end;
|
|
|
|
|
|
function tparamanager.push_high_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
|
|
begin
|
|
push_high_param:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and
|
|
(
|
|
is_open_array(def) or
|
|
is_open_string(def) or
|
|
is_array_of_const(def)
|
|
);
|
|
end;
|
|
|
|
|
|
{ true if a parameter is too large to copy and only the address is pushed }
|
|
function tparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
|
|
begin
|
|
result:=false;
|
|
{ var,out always require address }
|
|
if varspez in [vs_var,vs_out] then
|
|
begin
|
|
result:=true;
|
|
exit;
|
|
end;
|
|
{ Only vs_const, vs_value here }
|
|
case def.deftype of
|
|
variantdef,
|
|
formaldef :
|
|
result:=true;
|
|
recorddef :
|
|
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (def.size>pointer_size);
|
|
arraydef :
|
|
begin
|
|
if (calloption in [pocall_cdecl,pocall_cppdecl]) then
|
|
begin
|
|
{ array of const values are pushed on the stack }
|
|
result:=not is_array_of_const(def);
|
|
end
|
|
else
|
|
begin
|
|
result:=(
|
|
(tarraydef(def).highrange>=tarraydef(def).lowrange) and
|
|
(def.size>pointer_size)
|
|
) or
|
|
is_open_array(def) or
|
|
is_array_of_const(def) or
|
|
is_array_constructor(def);
|
|
end;
|
|
end;
|
|
objectdef :
|
|
result:=is_object(def);
|
|
stringdef :
|
|
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tstringdef(def).string_typ in [st_shortstring,st_longstring]);
|
|
procvardef :
|
|
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (po_methodpointer in tprocvardef(def).procoptions);
|
|
setdef :
|
|
result:=not(calloption in [pocall_cdecl,pocall_cppdecl]) and (tsetdef(def).settype<>smallset);
|
|
end;
|
|
end;
|
|
|
|
|
|
{ true if a parameter is too large to push and needs a concatcopy to get the value on the stack }
|
|
function tparamanager.copy_value_on_stack(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
|
|
begin
|
|
copy_value_on_stack:=false;
|
|
{ this is only for cdecl procedures with vs_const,vs_value }
|
|
if not(
|
|
(calloption in [pocall_cdecl,pocall_cppdecl]) and
|
|
(varspez in [vs_value,vs_const])
|
|
) then
|
|
exit;
|
|
case def.deftype of
|
|
variantdef,
|
|
formaldef :
|
|
copy_value_on_stack:=true;
|
|
recorddef :
|
|
copy_value_on_stack:=(def.size>pointer_size);
|
|
arraydef :
|
|
copy_value_on_stack:=(tarraydef(def).highrange>=tarraydef(def).lowrange) and
|
|
(def.size>pointer_size);
|
|
objectdef :
|
|
copy_value_on_stack:=is_object(def);
|
|
stringdef :
|
|
copy_value_on_stack:=tstringdef(def).string_typ in [st_shortstring,st_longstring];
|
|
procvardef :
|
|
copy_value_on_stack:=(po_methodpointer in tprocvardef(def).procoptions);
|
|
setdef :
|
|
copy_value_on_stack:=(tsetdef(def).settype<>smallset);
|
|
end;
|
|
end;
|
|
|
|
|
|
{ return the size of a push }
|
|
function tparamanager.push_size(varspez:tvarspez;def : tdef;calloption : tproccalloption) : longint;
|
|
begin
|
|
push_size:=-1;
|
|
case varspez of
|
|
vs_out,
|
|
vs_var :
|
|
push_size:=pointer_size;
|
|
vs_value,
|
|
vs_const :
|
|
begin
|
|
if push_addr_param(varspez,def,calloption) then
|
|
push_size:=pointer_size
|
|
else
|
|
begin
|
|
{ special array are normally pushed by addr, only for
|
|
cdecl array of const it comes here and the pushsize
|
|
is unknown }
|
|
if is_array_of_const(def) then
|
|
push_size:=0
|
|
else
|
|
push_size:=def.size;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
function tparamanager.get_para_align(calloption : tproccalloption):byte;
|
|
begin
|
|
result:=std_param_align;
|
|
end;
|
|
|
|
|
|
function tparamanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
|
|
begin
|
|
result:=[];
|
|
end;
|
|
|
|
|
|
function tparamanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;
|
|
begin
|
|
result:=[];
|
|
end;
|
|
|
|
|
|
function tparamanager.get_volatile_registers_flags(calloption : tproccalloption):tcpuregisterset;
|
|
begin
|
|
result:=[];
|
|
end;
|
|
|
|
|
|
function tparamanager.get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;
|
|
begin
|
|
result:=[];
|
|
end;
|
|
|
|
|
|
procedure tparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
|
|
begin
|
|
case loc.loc of
|
|
LOC_REGISTER,
|
|
LOC_CREGISTER,
|
|
LOC_FPUREGISTER,
|
|
LOC_CFPUREGISTER,
|
|
LOC_MMREGISTER,
|
|
LOC_CMMREGISTER :
|
|
begin
|
|
{ NR_NO means we don't need to allocate the parameter.
|
|
This is used for inlining parameters which allocates
|
|
the parameters in gen_alloc_parast (PFV) }
|
|
if loc.register<>NR_NO then
|
|
cg.getexplicitregister(list,loc.register);
|
|
end;
|
|
LOC_REFERENCE,
|
|
LOC_CREFERENCE :
|
|
{ do nothing by default, most of the time it's the framepointer }
|
|
else
|
|
internalerror(200306091);
|
|
end;
|
|
case loc.lochigh of
|
|
LOC_INVALID :
|
|
;
|
|
LOC_REGISTER,
|
|
LOC_CREGISTER,
|
|
LOC_FPUREGISTER,
|
|
LOC_CFPUREGISTER,
|
|
LOC_MMREGISTER,
|
|
LOC_CMMREGISTER :
|
|
begin
|
|
{ NR_NO means we don't need to allocate the parameter.
|
|
This is used for inlining parameters which allocates
|
|
the parameters in gen_alloc_parast (PFV) }
|
|
if loc.registerhigh<>NR_NO then
|
|
cg.getexplicitregister(list,loc.registerhigh);
|
|
end;
|
|
else
|
|
internalerror(200306091);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
|
|
var
|
|
href : treference;
|
|
begin
|
|
case loc.loc of
|
|
LOC_REGISTER, LOC_CREGISTER:
|
|
begin
|
|
{$ifndef cpu64bit}
|
|
if (loc.size in [OS_64,OS_S64,OS_F64]) then
|
|
begin
|
|
cg.ungetregister(list,loc.registerhigh);
|
|
cg.ungetregister(list,loc.registerlow);
|
|
end
|
|
else
|
|
{$endif cpu64bit}
|
|
cg.ungetregister(list,loc.register);
|
|
end;
|
|
LOC_MMREGISTER, LOC_CMMREGISTER,
|
|
LOC_FPUREGISTER, LOC_CFPUREGISTER:
|
|
cg.ungetregister(list,loc.register);
|
|
LOC_REFERENCE,LOC_CREFERENCE:
|
|
begin
|
|
{$ifdef cputargethasfixedstack}
|
|
reference_reset_base(href,loc.reference.index,loc.reference.offset);
|
|
tg.ungettemp(list,href);
|
|
{$endif cputargethasfixedstack}
|
|
end;
|
|
else
|
|
internalerror(200306091);
|
|
end;
|
|
case loc.lochigh of
|
|
LOC_INVALID :
|
|
;
|
|
LOC_REGISTER,
|
|
LOC_CREGISTER,
|
|
LOC_FPUREGISTER,
|
|
LOC_CFPUREGISTER,
|
|
LOC_MMREGISTER,
|
|
LOC_CMMREGISTER :
|
|
cg.ungetregister(list,loc.register);
|
|
else
|
|
internalerror(200306091);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure tparamanager.splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);
|
|
begin
|
|
lochipara:=locpara;
|
|
loclopara:=locpara;
|
|
case locpara.size of
|
|
OS_S128 :
|
|
begin
|
|
lochipara.size:=OS_S64;
|
|
loclopara.size:=OS_64;
|
|
end;
|
|
OS_128 :
|
|
begin
|
|
lochipara.size:=OS_64;
|
|
loclopara.size:=OS_64;
|
|
end;
|
|
OS_S64 :
|
|
begin
|
|
lochipara.size:=OS_S32;
|
|
loclopara.size:=OS_32;
|
|
end;
|
|
OS_64 :
|
|
begin
|
|
lochipara.size:=OS_32;
|
|
loclopara.size:=OS_32;
|
|
end;
|
|
else
|
|
internalerror(200307023);
|
|
end;
|
|
loclopara.lochigh:=LOC_INVALID;
|
|
lochipara.lochigh:=LOC_INVALID;
|
|
case locpara.loc of
|
|
LOC_REGISTER,
|
|
LOC_CREGISTER,
|
|
LOC_FPUREGISTER,
|
|
LOC_CFPUREGISTER,
|
|
LOC_MMREGISTER,
|
|
LOC_CMMREGISTER :
|
|
begin
|
|
if locpara.lochigh=LOC_INVALID then
|
|
internalerror(200402061);
|
|
loclopara.register:=locpara.registerlow;
|
|
lochipara.register:=locpara.registerhigh;
|
|
end;
|
|
LOC_REFERENCE:
|
|
begin
|
|
if target_info.endian=endian_big then
|
|
inc(loclopara.reference.offset,tcgsize2size[loclopara.size])
|
|
else
|
|
inc(lochipara.reference.offset,tcgsize2size[loclopara.size]);
|
|
end;
|
|
else
|
|
internalerror(200307024);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure tparamanager.alloctempregs(list: taasmoutput;var locpara:tparalocation);
|
|
var
|
|
cgsize : tcgsize;
|
|
begin
|
|
if locpara.lochigh<>LOC_INVALID then
|
|
cgsize:=OS_INT
|
|
else
|
|
cgsize:=locpara.size;
|
|
case locpara.loc of
|
|
LOC_REGISTER:
|
|
locpara.register:=cg.getintregister(list,cgsize);
|
|
LOC_FPUREGISTER:
|
|
locpara.register:=cg.getfpuregister(list,cgsize);
|
|
LOC_MMREGISTER:
|
|
locpara.register:=cg.getmmregister(list,cgsize);
|
|
else
|
|
internalerror(200308123);
|
|
end;
|
|
case locpara.lochigh of
|
|
LOC_INVALID:
|
|
;
|
|
LOC_REGISTER:
|
|
locpara.registerhigh:=cg.getintregister(list,cgsize);
|
|
LOC_FPUREGISTER:
|
|
locpara.registerhigh:=cg.getfpuregister(list,cgsize);
|
|
LOC_MMREGISTER:
|
|
locpara.registerhigh:=cg.getmmregister(list,cgsize);
|
|
else
|
|
internalerror(200308123);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure tparamanager.alloctempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var locpara:tparalocation);
|
|
var
|
|
href : treference;
|
|
begin
|
|
tg.gettemp(list,paraitem.paratype.def.size,tt_persistent,href);
|
|
locpara.loc:=LOC_REFERENCE;
|
|
locpara.lochigh:=LOC_INVALID;
|
|
locpara.reference.index:=href.base;
|
|
locpara.reference.offset:=href.offset;
|
|
end;
|
|
|
|
|
|
function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint;
|
|
var
|
|
hp : tparaitem;
|
|
paraloc : tparalocation;
|
|
parasize : longint;
|
|
begin
|
|
parasize:=0;
|
|
hp:=tparaitem(p.para.first);
|
|
while assigned(hp) do
|
|
begin
|
|
if push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption) then
|
|
paraloc.size:=OS_ADDR
|
|
else
|
|
paraloc.size:=def_cgsize(hp.paratype.def);
|
|
if paraloc.size=OS_NO then
|
|
internalerror(200309301);
|
|
{ Indicate parameter is loaded in register, the register
|
|
will be allocated when the allocpara is called }
|
|
paraloc.loc:=LOC_REGISTER;
|
|
paraloc.register:=NR_NO;
|
|
(*
|
|
paraloc.loc:=LOC_REFERENCE;
|
|
paraloc.reference.index:=NR_FRAME_POINTER_REG;
|
|
l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
|
|
varalign:=size_2_align(l);
|
|
paraloc.reference.offset:=parasize+target_info.first_parm_offset;
|
|
varalign:=used_align(varalign,p.paraalign,p.paraalign);
|
|
parasize:=align(parasize+l,varalign);
|
|
*)
|
|
hp.paraloc[callerside]:=paraloc;
|
|
hp.paraloc[calleeside]:=paraloc;
|
|
hp:=tparaitem(hp.next);
|
|
end;
|
|
{ We need to return the size allocated }
|
|
result:=parasize;
|
|
end;
|
|
|
|
|
|
initialization
|
|
;
|
|
finalization
|
|
paramanager.free;
|
|
end.
|
|
|
|
{
|
|
$Log$
|
|
Revision 1.72 2004-03-06 20:35:19 florian
|
|
* fixed arm compilation
|
|
* cleaned up code generation for exported linux procedures
|
|
|
|
Revision 1.71 2004/02/17 19:14:09 florian
|
|
* temp. fix for lochigh para
|
|
|
|
Revision 1.70 2004/02/09 22:48:45 florian
|
|
* several fixes to parameter handling on arm
|
|
|
|
Revision 1.69 2004/02/09 22:14:17 peter
|
|
* more x86_64 parameter fixes
|
|
* tparalocation.lochigh is now used to indicate if registerhigh
|
|
is used and what the type is
|
|
|
|
Revision 1.68 2003/12/28 22:09:12 florian
|
|
+ setting of bit 6 of cr for c var args on ppc implemented
|
|
|
|
Revision 1.67 2003/12/06 01:15:22 florian
|
|
* reverted Peter's alloctemp patch; hopefully properly
|
|
|
|
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
|
|
|
|
Revision 1.64 2003/10/17 14:38:32 peter
|
|
* 64k registers supported
|
|
* fixed some memory leaks
|
|
|
|
Revision 1.63 2003/10/11 16:06:42 florian
|
|
* fixed some MMX<->SSE
|
|
* started to fix ppc, needs an overhaul
|
|
+ stabs info improve for spilling, not sure if it works correctly/completly
|
|
- MMX_SUPPORT removed from Makefile.fpc
|
|
|
|
Revision 1.62 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
|
|
* moved location_* and reference_* to cgobj
|
|
* first things for mmx register allocation
|
|
|
|
Revision 1.61 2003/10/09 21:31:37 daniel
|
|
* Register allocator splitted, ans abstract now
|
|
|
|
Revision 1.60 2003/10/05 21:21:52 peter
|
|
* c style array of const generates callparanodes
|
|
* varargs paraloc fixes
|
|
|
|
Revision 1.59 2003/10/03 22:00:33 peter
|
|
* parameter alignment fixes
|
|
|
|
Revision 1.58 2003/10/01 20:34:49 peter
|
|
* procinfo unit contains tprocinfo
|
|
* cginfo renamed to cgbase
|
|
* moved cgmessage to verbose
|
|
* fixed ppc and sparc compiles
|
|
|
|
Revision 1.57 2003/09/30 21:02:37 peter
|
|
* updates for inlining
|
|
|
|
Revision 1.56 2003/09/23 17:56:05 peter
|
|
* locals and paras are allocated in the code generation
|
|
* tvarsym.localloc contains the location of para/local when
|
|
generating code for the current procedure
|
|
|
|
Revision 1.55 2003/09/16 16:17:01 peter
|
|
* varspez in calls to push_addr_param
|
|
|
|
Revision 1.54 2003/09/10 08:31:47 marco
|
|
* Patch from Peter for paraloc
|
|
|
|
Revision 1.53 2003/09/07 22:09:35 peter
|
|
* preparations for different default calling conventions
|
|
* various RA fixes
|
|
|
|
Revision 1.52 2003/09/04 15:39:58 peter
|
|
* released useparatemp
|
|
|
|
Revision 1.51 2003/09/03 15:55:01 peter
|
|
* NEWRA branch merged
|
|
|
|
Revision 1.50.2.1 2003/08/29 17:28:59 peter
|
|
* next batch of updates
|
|
|
|
Revision 1.50 2003/08/11 21:18:20 peter
|
|
* start of sparc support for newra
|
|
|
|
Revision 1.49 2003/07/08 21:24:59 peter
|
|
* sparc fixes
|
|
|
|
Revision 1.48 2003/07/05 20:11:41 jonas
|
|
* create_paraloc_info() is now called separately for the caller and
|
|
callee info
|
|
* fixed ppc cycle
|
|
|
|
Revision 1.47 2003/07/02 22:18:04 peter
|
|
* paraloc splitted in callerparaloc,calleeparaloc
|
|
* sparc calling convention updates
|
|
|
|
Revision 1.46 2003/06/17 16:32:03 peter
|
|
* allocpara/freepara 64bit support
|
|
|
|
Revision 1.45 2003/06/13 21:19:30 peter
|
|
* current_procdef removed, use current_procinfo.procdef instead
|
|
|
|
Revision 1.44 2003/06/12 21:11:10 peter
|
|
* ungetregisterfpu gets size parameter
|
|
|
|
Revision 1.43 2003/06/09 14:54:26 jonas
|
|
* (de)allocation of registers for parameters is now performed properly
|
|
(and checked on the ppc)
|
|
- removed obsolete allocation of all parameter registers at the start
|
|
of a procedure (and deallocation at the end)
|
|
|
|
Revision 1.42 2003/06/08 10:54:41 jonas
|
|
- disabled changing of LOC_*REGISTER to LOC_C*REGISTER in setparalocs,
|
|
this is not necessary anymore (doesn't do anything anymore actually,
|
|
except making sure the interface crc changes)
|
|
|
|
Revision 1.41 2003/06/07 18:57:04 jonas
|
|
+ added freeintparaloc
|
|
* ppc get/freeintparaloc now check whether the parameter regs are
|
|
properly allocated/deallocated (and get an extra list para)
|
|
* ppc a_call_* now internalerrors if pi_do_call is not yet set
|
|
* fixed lot of missing pi_do_call's
|
|
|
|
Revision 1.40 2003/05/31 15:05:28 peter
|
|
* FUNCTION_RESULT64_LOW/HIGH_REG added for int64 results
|
|
|
|
Revision 1.39 2003/05/30 23:57:08 peter
|
|
* more sparc cleanup
|
|
* accumulator removed, splitted in function_return_reg (called) and
|
|
function_result_reg (caller)
|
|
|
|
Revision 1.38 2003/05/13 15:16:13 peter
|
|
* removed ret_in_acc, it's the reverse of ret_in_param
|
|
* fixed ret_in_param for win32 cdecl array
|
|
|
|
Revision 1.37 2003/04/30 22:15:59 florian
|
|
* some 64 bit adaptions in ncgadd
|
|
* x86-64 now uses ncgadd
|
|
* tparamanager.ret_in_acc doesn't return true anymore for a void-def
|
|
|
|
Revision 1.36 2003/04/27 11:21:33 peter
|
|
* aktprocdef renamed to current_procinfo.procdef
|
|
* procinfo renamed to current_procinfo
|
|
* procinfo will now be stored in current_module so it can be
|
|
cleaned up properly
|
|
* gen_main_procsym changed to create_main_proc and release_main_proc
|
|
to also generate a tprocinfo structure
|
|
* fixed unit implicit initfinal
|
|
|
|
Revision 1.35 2003/04/27 07:29:50 peter
|
|
* current_procinfo.procdef cleanup, current_procdef is now always nil when parsing
|
|
a new procdef declaration
|
|
* aktprocsym removed
|
|
* lexlevel removed, use symtable.symtablelevel instead
|
|
* implicit init/final code uses the normal genentry/genexit
|
|
* funcret state checking updated for new funcret handling
|
|
|
|
Revision 1.34 2003/04/23 13:15:04 peter
|
|
* fix push_high_param for cdecl
|
|
|
|
Revision 1.33 2003/04/23 10:14:30 peter
|
|
* cdecl array of const has no addr push
|
|
|
|
Revision 1.32 2003/04/22 13:47:08 peter
|
|
* fixed C style array of const
|
|
* fixed C array passing
|
|
* fixed left to right with high parameters
|
|
|
|
Revision 1.31 2003/02/02 19:25:54 carl
|
|
* Several bugfixes for m68k target (register alloc., opcode emission)
|
|
+ VIS target
|
|
+ Generic add more complete (still not verified)
|
|
|
|
Revision 1.30 2003/01/08 18:43:56 daniel
|
|
* Tregister changed into a record
|
|
|
|
Revision 1.29 2002/12/23 20:58:03 peter
|
|
* remove unused global var
|
|
|
|
Revision 1.28 2002/12/17 22:19:33 peter
|
|
* fixed pushing of records>8 bytes with stdcall
|
|
* simplified hightree loading
|
|
|
|
Revision 1.27 2002/12/06 16:56:58 peter
|
|
* only compile cs_fp_emulation support when cpufpuemu is defined
|
|
* define cpufpuemu for m68k only
|
|
|
|
Revision 1.26 2002/11/27 20:04:09 peter
|
|
* tvarsym.get_push_size replaced by paramanager.push_size
|
|
|
|
Revision 1.25 2002/11/27 02:33:19 peter
|
|
* copy_value_on_stack method added for cdecl record passing
|
|
|
|
Revision 1.24 2002/11/25 17:43:21 peter
|
|
* splitted defbase in defutil,symutil,defcmp
|
|
* merged isconvertable and is_equal into compare_defs(_ext)
|
|
* made operator search faster by walking the list only once
|
|
|
|
Revision 1.23 2002/11/18 17:31:58 peter
|
|
* pass proccalloption to ret_in_xxx and push_xxx functions
|
|
|
|
Revision 1.22 2002/11/16 18:00:04 peter
|
|
* only push small arrays on the stack for win32
|
|
|
|
Revision 1.21 2002/10/05 12:43:25 carl
|
|
* fixes for Delphi 6 compilation
|
|
(warning : Some features do not work under Delphi)
|
|
|
|
Revision 1.20 2002/09/30 07:07:25 florian
|
|
* fixes to common code to get the alpha compiler compiled applied
|
|
|
|
Revision 1.19 2002/09/30 07:00:47 florian
|
|
* fixes to common code to get the alpha compiler compiled applied
|
|
|
|
Revision 1.18 2002/09/09 09:10:51 florian
|
|
+ added generic tparamanager.getframepointerloc
|
|
|
|
Revision 1.17 2002/09/07 19:40:39 florian
|
|
* tvarsym.paraitem is set now
|
|
|
|
Revision 1.16 2002/09/01 21:04:48 florian
|
|
* several powerpc related stuff fixed
|
|
|
|
Revision 1.15 2002/08/25 19:25:19 peter
|
|
* sym.insert_in_data removed
|
|
* symtable.insertvardata/insertconstdata added
|
|
* removed insert_in_data call from symtable.insert, it needs to be
|
|
called separatly. This allows to deref the address calculation
|
|
* procedures now calculate the parast addresses after the procedure
|
|
directives are parsed. This fixes the cdecl parast problem
|
|
* push_addr_param has an extra argument that specifies if cdecl is used
|
|
or not
|
|
|
|
Revision 1.14 2002/08/17 22:09:47 florian
|
|
* result type handling in tcgcal.pass_2 overhauled
|
|
* better tnode.dowrite
|
|
* some ppc stuff fixed
|
|
|
|
Revision 1.13 2002/08/17 09:23:38 florian
|
|
* first part of procinfo rewrite
|
|
|
|
Revision 1.12 2002/08/16 14:24:58 carl
|
|
* issameref() to test if two references are the same (then emit no opcodes)
|
|
+ ret_in_reg to replace ret_in_acc
|
|
(fix some register allocation bugs at the same time)
|
|
+ save_std_register now has an extra parameter which is the
|
|
usedinproc registers
|
|
|
|
Revision 1.11 2002/08/12 15:08:40 carl
|
|
+ stab register indexes for powerpc (moved from gdb to cpubase)
|
|
+ tprocessor enumeration moved to cpuinfo
|
|
+ linker in target_info is now a class
|
|
* many many updates for m68k (will soon start to compile)
|
|
- removed some ifdef or correct them for correct cpu
|
|
|
|
Revision 1.10 2002/08/10 17:15:20 jonas
|
|
* register parameters are now LOC_CREGISTER instead of LOC_REGISTER
|
|
|
|
Revision 1.9 2002/08/09 07:33:02 florian
|
|
* a couple of interface related fixes
|
|
|
|
Revision 1.8 2002/08/06 20:55:21 florian
|
|
* first part of ppc calling conventions fix
|
|
|
|
Revision 1.7 2002/08/05 18:27:48 carl
|
|
+ more more more documentation
|
|
+ first version include/exclude (can't test though, not enough scratch for i386 :()...
|
|
|
|
Revision 1.6 2002/07/30 20:50:43 florian
|
|
* the code generator knows now if parameters are in registers
|
|
|
|
Revision 1.5 2002/07/26 21:15:39 florian
|
|
* rewrote the system handling
|
|
|
|
Revision 1.4 2002/07/20 11:57:55 florian
|
|
* types.pas renamed to defbase.pas because D6 contains a types
|
|
unit so this would conflicts if D6 programms are compiled
|
|
+ Willamette/SSE2 instructions to assembler added
|
|
|
|
Revision 1.3 2002/07/13 19:38:43 florian
|
|
* some more generic calling stuff fixed
|
|
|
|
Revision 1.2 2002/07/13 07:17:15 jonas
|
|
* fixed memory leak reported by Sergey Korshunoff
|
|
|
|
Revision 1.1 2002/07/11 14:41:28 florian
|
|
* start of the new generic parameter handling
|
|
}
|
|
|
|
|