mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 16:06:22 +02:00
* varargs calculation fixed, it's now the same as the other
targets
This commit is contained in:
parent
783f8068a5
commit
b6ed8c482b
@ -53,8 +53,10 @@ unit cpupara;
|
||||
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;override;
|
||||
private
|
||||
procedure create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||
function create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
|
||||
function create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
|
||||
procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
|
||||
var parasize:longint);
|
||||
procedure create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
|
||||
var parareg,parasize:longint);
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -261,53 +263,15 @@ unit cpupara;
|
||||
end;
|
||||
|
||||
|
||||
function ti386paramanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;
|
||||
procedure ti386paramanager.create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
|
||||
var parasize:longint);
|
||||
var
|
||||
hp : tparaitem;
|
||||
paraloc : tparalocation;
|
||||
l,
|
||||
varalign,
|
||||
paraalign,
|
||||
parasize : longint;
|
||||
paraalign : longint;
|
||||
begin
|
||||
parasize:=0;
|
||||
paraalign:=get_para_align(p.proccalloption);
|
||||
{ Retrieve last know info from normal parameters }
|
||||
hp:=tparaitem(p.para.last);
|
||||
if assigned(hp) then
|
||||
parasize:=hp.paraloc[callerside].reference.offset;
|
||||
{ Assign varargs }
|
||||
hp:=tparaitem(varargspara.first);
|
||||
while assigned(hp) do
|
||||
begin
|
||||
paraloc.size:=def_cgsize(hp.paratype.def);
|
||||
paraloc.loc:=LOC_REFERENCE;
|
||||
paraloc.lochigh:=LOC_INVALID;
|
||||
paraloc.alignment:=paraalign;
|
||||
paraloc.reference.index:=NR_STACK_POINTER_REG;
|
||||
l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
|
||||
varalign:=size_2_align(l);
|
||||
paraloc.reference.offset:=parasize;
|
||||
varalign:=used_align(varalign,paraalign,paraalign);
|
||||
parasize:=align(parasize+l,varalign);
|
||||
hp.paraloc[callerside]:=paraloc;
|
||||
hp:=tparaitem(hp.next);
|
||||
end;
|
||||
{ We need to return the size allocated }
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
||||
function ti386paramanager.create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
|
||||
var
|
||||
hp : tparaitem;
|
||||
paraloc : tparalocation;
|
||||
l,
|
||||
varalign,
|
||||
paraalign,
|
||||
parasize : longint;
|
||||
begin
|
||||
parasize:=0;
|
||||
paraalign:=get_para_align(p.proccalloption);
|
||||
{ we push Flags and CS as long
|
||||
to cope with the IRETD
|
||||
@ -323,7 +287,7 @@ unit cpupara;
|
||||
That means the for pushes the para with the
|
||||
highest offset (see para3) needs to be pushed first
|
||||
}
|
||||
hp:=tparaitem(p.para.first);
|
||||
hp:=firstpara;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
if hp.paratyp in [vs_var,vs_out] then
|
||||
@ -373,28 +337,24 @@ unit cpupara;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{ We need to return the size allocated }
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
||||
function ti386paramanager.create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
|
||||
procedure ti386paramanager.create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;firstpara:tparaitem;
|
||||
var parareg,parasize:longint);
|
||||
var
|
||||
hp : tparaitem;
|
||||
paraloc : tparalocation;
|
||||
subreg : tsubregister;
|
||||
pushaddr,
|
||||
is_64bit : boolean;
|
||||
l,parareg,
|
||||
l,
|
||||
varalign,
|
||||
paraalign,
|
||||
parasize : longint;
|
||||
paraalign : longint;
|
||||
begin
|
||||
parareg:=0;
|
||||
parasize:=0;
|
||||
paraalign:=get_para_align(p.proccalloption);
|
||||
{ Register parameters are assigned from left to right }
|
||||
hp:=tparaitem(p.para.first);
|
||||
hp:=firstpara;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
pushaddr:=push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption);
|
||||
@ -464,40 +424,61 @@ unit cpupara;
|
||||
end;
|
||||
hp:=tparaitem(hp.next);
|
||||
end;
|
||||
{ We need to return the size allocated }
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
||||
function ti386paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
|
||||
var
|
||||
parasize,
|
||||
parareg : longint;
|
||||
begin
|
||||
result:=0;
|
||||
parasize:=0;
|
||||
parareg:=0;
|
||||
case p.proccalloption of
|
||||
pocall_register :
|
||||
result:=create_register_paraloc_info(p,side);
|
||||
create_register_paraloc_info(p,side,tparaitem(p.para.first),parareg,parasize);
|
||||
pocall_inline,
|
||||
pocall_compilerproc,
|
||||
pocall_internproc :
|
||||
begin
|
||||
{ Use default calling }
|
||||
if (pocall_default=pocall_register) then
|
||||
result:=create_register_paraloc_info(p,side)
|
||||
create_register_paraloc_info(p,side,tparaitem(p.para.first),parareg,parasize)
|
||||
else
|
||||
result:=create_stdcall_paraloc_info(p,side);
|
||||
create_stdcall_paraloc_info(p,side,tparaitem(p.para.first),parasize);
|
||||
end;
|
||||
else
|
||||
result:=create_stdcall_paraloc_info(p,side);
|
||||
create_stdcall_paraloc_info(p,side,tparaitem(p.para.first),parasize);
|
||||
end;
|
||||
create_funcret_paraloc_info(p,side);
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
||||
function ti386paramanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;
|
||||
var
|
||||
parasize : longint;
|
||||
begin
|
||||
parasize:=0;
|
||||
{ calculate the registers for the normal parameters }
|
||||
create_stdcall_paraloc_info(p,callerside,tparaitem(p.para.first),parasize);
|
||||
{ append the varargs }
|
||||
create_stdcall_paraloc_info(p,callerside,tparaitem(varargspara.first),parasize);
|
||||
result:=parasize;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
begin
|
||||
paramanager:=ti386paramanager.create;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.52 2004-06-20 08:55:31 florian
|
||||
Revision 1.53 2004-07-09 23:09:02 peter
|
||||
* varargs calculation fixed, it's now the same as the other
|
||||
targets
|
||||
|
||||
Revision 1.52 2004/06/20 08:55:31 florian
|
||||
* logs truncated
|
||||
|
||||
Revision 1.51 2004/06/16 20:07:10 florian
|
||||
|
Loading…
Reference in New Issue
Block a user