mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-22 06:09:14 +02:00
* update x86_64 with new cpupara
This commit is contained in:
parent
3dcc711558
commit
cd01e600b9
@ -350,43 +350,51 @@ unit cpupara;
|
||||
hp.paraloc[side].size:=paracgsize;
|
||||
hp.paraloc[side].intsize:=paralen;
|
||||
hp.paraloc[side].Alignment:=paraalign;
|
||||
{ Copy to stack? }
|
||||
if paracgsize=OS_NO then
|
||||
if paralen>0 then
|
||||
begin
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.size:=paracgsize;
|
||||
if side=callerside then
|
||||
paraloc^.reference.index:=NR_STACK_POINTER_REG
|
||||
else
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(paralen),paraalign,paraalign);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
parasize:=align(parasize+paralen,varalign);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if paralen=0 then
|
||||
internalerror(200501163);
|
||||
while (paralen>0) do
|
||||
{ Copy to stack? }
|
||||
if paracgsize=OS_NO then
|
||||
begin
|
||||
{ We can allocate at maximum 32 bits per location }
|
||||
if paralen>sizeof(aint) then
|
||||
l:=sizeof(aint)
|
||||
else
|
||||
l:=paralen;
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.size:=int_cgsize(l);
|
||||
paraloc^.size:=paracgsize;
|
||||
if side=callerside then
|
||||
paraloc^.reference.index:=NR_STACK_POINTER_REG
|
||||
else
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(l),paraalign,paraalign);
|
||||
varalign:=used_align(size_2_align(paralen),paraalign,paraalign);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
parasize:=align(parasize+l,varalign);
|
||||
dec(paralen,l);
|
||||
parasize:=align(parasize+paralen,varalign);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if paralen=0 then
|
||||
internalerror(200501163);
|
||||
while (paralen>0) do
|
||||
begin
|
||||
{ We can allocate at maximum 32 bits per location }
|
||||
if paralen>sizeof(aint) then
|
||||
l:=sizeof(aint)
|
||||
else
|
||||
l:=paralen;
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.size:=int_cgsize(l);
|
||||
if side=callerside then
|
||||
paraloc^.reference.index:=NR_STACK_POINTER_REG
|
||||
else
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(l),paraalign,paraalign);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
parasize:=align(parasize+l,varalign);
|
||||
dec(paralen,l);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_VOID;
|
||||
end;
|
||||
end;
|
||||
{ Adapt offsets for left-to-right calling }
|
||||
@ -602,7 +610,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.62 2005-01-18 22:19:20 peter
|
||||
Revision 1.63 2005-01-29 11:36:52 peter
|
||||
* update x86_64 with new cpupara
|
||||
|
||||
Revision 1.62 2005/01/18 22:19:20 peter
|
||||
* multiple location support for i386 a_param_ref
|
||||
* remove a_param_copy_ref for i386
|
||||
|
||||
|
@ -701,6 +701,10 @@ implementation
|
||||
{$endif PASS2INLINE}
|
||||
begin
|
||||
{$ifdef cputargethasfixedstack}
|
||||
{ Can't have a data copied to the stack, every location
|
||||
must contain a valid size field }
|
||||
if ppn.tempcgpara.size=OS_NO then
|
||||
internalerror(200501281);
|
||||
reference_reset_base(href,callerparaloc^.reference.index,callerparaloc^.reference.offset);
|
||||
{ copy parameters in case they were moved to a temp. location because we've a fixed stack }
|
||||
case tmpparaloc^.loc of
|
||||
@ -709,7 +713,7 @@ implementation
|
||||
reference_reset_base(htempref,tmpparaloc^.reference.index,tmpparaloc^.reference.offset);
|
||||
{ use concatcopy, because it can also be a float which fails when
|
||||
load_ref_ref is used }
|
||||
cg.g_concatcopy(exprasmlist,htempref,href,sizeleft);
|
||||
cg.g_concatcopy(exprasmlist,htempref,href,tcgsize2size[tmpparaloc^.size]);
|
||||
end;
|
||||
LOC_REGISTER:
|
||||
cg.a_load_reg_ref(exprasmlist,tmpparaloc^.size,tmpparaloc^.size,tmpparaloc^.register,href);
|
||||
@ -742,12 +746,15 @@ implementation
|
||||
ppn:=tcgcallparanode(left);
|
||||
while assigned(ppn) do
|
||||
begin
|
||||
if
|
||||
if (ppn.left.nodetype<>nothingn) then
|
||||
begin
|
||||
if
|
||||
{$ifdef PASS2INLINE}
|
||||
not assigned(inlinecode) or
|
||||
not assigned(inlinecode) or
|
||||
{$endif PASS2INLINE}
|
||||
(ppn.parasym.paraloc[callerside].location^.loc <> LOC_REFERENCE) then
|
||||
paramanager.freeparaloc(exprasmlist,ppn.parasym.paraloc[callerside]);
|
||||
(ppn.parasym.paraloc[callerside].location^.loc <> LOC_REFERENCE) then
|
||||
paramanager.freeparaloc(exprasmlist,ppn.parasym.paraloc[callerside]);
|
||||
end;
|
||||
ppn:=tcgcallparanode(ppn.right);
|
||||
end;
|
||||
end;
|
||||
@ -1213,7 +1220,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.197 2005-01-20 17:47:01 peter
|
||||
Revision 1.198 2005-01-29 11:36:52 peter
|
||||
* update x86_64 with new cpupara
|
||||
|
||||
Revision 1.197 2005/01/20 17:47:01 peter
|
||||
* remove copy_value_on_stack and a_param_copy_ref
|
||||
|
||||
Revision 1.196 2005/01/18 22:19:20 peter
|
||||
|
@ -651,6 +651,7 @@ implementation
|
||||
|
||||
dec(compile_level);
|
||||
compiled_module:=olddata^.old_compiled_module;
|
||||
SetCompileModule(compiled_module);
|
||||
|
||||
dispose(olddata);
|
||||
end;
|
||||
@ -659,7 +660,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.71 2005-01-26 16:23:28 peter
|
||||
Revision 1.72 2005-01-29 11:36:52 peter
|
||||
* update x86_64 with new cpupara
|
||||
|
||||
Revision 1.71 2005/01/26 16:23:28 peter
|
||||
* detect arithmetic overflows for constants at compile time
|
||||
* use try..except instead of setjmp
|
||||
|
||||
|
@ -29,7 +29,7 @@ unit cpupara;
|
||||
uses
|
||||
globtype,
|
||||
cpubase,cgbase,
|
||||
symconst,symbase,symtype,symsym,symdef,
|
||||
symconst,symtype,symsym,symdef,
|
||||
aasmtai,
|
||||
parabase,paramgr;
|
||||
|
||||
@ -164,6 +164,7 @@ unit cpupara;
|
||||
begin
|
||||
cgpara.reset;
|
||||
cgpara.size:=OS_INT;
|
||||
cgpara.intsize:=tcgsize2size[OS_INT];
|
||||
cgpara.alignment:=get_para_align(calloption);
|
||||
paraloc:=cgpara.add_location;
|
||||
with paraloc^ do
|
||||
@ -188,7 +189,6 @@ unit cpupara;
|
||||
|
||||
procedure tx86_64paramanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
|
||||
var
|
||||
paraloc : pcgparalocation;
|
||||
retcgsize : tcgsize;
|
||||
begin
|
||||
{ Constructors return self instead of a boolean }
|
||||
@ -248,16 +248,17 @@ unit cpupara;
|
||||
procedure tx86_64paramanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
|
||||
var intparareg,mmparareg,parasize:longint);
|
||||
var
|
||||
hp : tparavarsym;
|
||||
paraloc,
|
||||
paraloc2 : pcgparalocation;
|
||||
subreg : tsubregister;
|
||||
pushaddr : boolean;
|
||||
hp : tparavarsym;
|
||||
paraloc : pcgparalocation;
|
||||
subreg : tsubregister;
|
||||
pushaddr : boolean;
|
||||
paracgsize : tcgsize;
|
||||
loc1,loc2 : tcgloc;
|
||||
loc : array[1..2] of tcgloc;
|
||||
paralen,
|
||||
locidx,
|
||||
l,i,
|
||||
varalign,
|
||||
paraalign : longint;
|
||||
paraalign : longint;
|
||||
begin
|
||||
paraalign:=get_para_align(p.proccalloption);
|
||||
{ Register parameters are assigned from left to right }
|
||||
@ -267,111 +268,106 @@ unit cpupara;
|
||||
pushaddr:=push_addr_param(hp.varspez,hp.vartype.def,p.proccalloption);
|
||||
if pushaddr then
|
||||
begin
|
||||
loc1:=LOC_REGISTER;
|
||||
loc2:=LOC_INVALID;
|
||||
loc[1]:=LOC_REGISTER;
|
||||
loc[2]:=LOC_INVALID;
|
||||
paracgsize:=OS_ADDR;
|
||||
paralen:=sizeof(aint);
|
||||
end
|
||||
else
|
||||
begin
|
||||
getvalueparaloc(hp.vartype.def,loc1,loc2);
|
||||
getvalueparaloc(hp.vartype.def,loc[1],loc[2]);
|
||||
paralen:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
|
||||
paracgsize:=def_cgsize(hp.vartype.def);
|
||||
end;
|
||||
hp.paraloc[side].reset;
|
||||
hp.paraloc[side].size:=paracgsize;
|
||||
hp.paraloc[side].intsize:=paralen;
|
||||
hp.paraloc[side].Alignment:=paraalign;
|
||||
{ First location }
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
if (loc1=LOC_REGISTER) and
|
||||
(intparareg<=high(paraintsupregs)) then
|
||||
if paralen>0 then
|
||||
begin
|
||||
if (paracgsize=OS_NO) or (loc2<>LOC_INVALID) then
|
||||
locidx:=1;
|
||||
while (paralen>0) do
|
||||
begin
|
||||
paraloc^.size:=OS_INT;
|
||||
subreg:=R_SUBWHOLE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
paraloc^.size:=paracgsize;
|
||||
{ s64comp is pushed in an int register }
|
||||
if paraloc^.size=OS_C64 then
|
||||
paraloc^.size:=OS_64;
|
||||
subreg:=cgsize2subreg(paraloc^.size);
|
||||
if locidx>2 then
|
||||
internalerror(200501283);
|
||||
{ Enough registers free? }
|
||||
case loc[locidx] of
|
||||
LOC_REGISTER :
|
||||
begin
|
||||
if (intparareg>high(paraintsupregs)) then
|
||||
loc[locidx]:=LOC_REFERENCE;
|
||||
end;
|
||||
LOC_MMREGISTER :
|
||||
begin
|
||||
if (mmparareg>high(parammsupregs)) then
|
||||
loc[locidx]:=LOC_REFERENCE;
|
||||
end;
|
||||
end;
|
||||
{ Allocate }
|
||||
case loc[locidx] of
|
||||
LOC_REGISTER :
|
||||
begin
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
if (paracgsize=OS_NO) or (loc[2]<>LOC_INVALID) then
|
||||
begin
|
||||
paraloc^.size:=OS_INT;
|
||||
subreg:=R_SUBWHOLE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
paraloc^.size:=paracgsize;
|
||||
{ s64comp is pushed in an int register }
|
||||
if paraloc^.size=OS_C64 then
|
||||
paraloc^.size:=OS_64;
|
||||
subreg:=cgsize2subreg(paraloc^.size);
|
||||
end;
|
||||
paraloc^.register:=newreg(R_INTREGISTER,paraintsupregs[intparareg],subreg);
|
||||
inc(intparareg);
|
||||
dec(paralen,tcgsize2size[paraloc^.size]);
|
||||
end;
|
||||
LOC_MMREGISTER :
|
||||
begin
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_MMREGISTER;
|
||||
paraloc^.register:=newreg(R_MMREGISTER,parammsupregs[mmparareg],R_SUBNONE);
|
||||
if paracgsize=OS_F128 then
|
||||
paraloc^.size:=OS_F64
|
||||
else
|
||||
paraloc^.size:=paracgsize;
|
||||
inc(mmparareg);
|
||||
dec(paralen,tcgsize2size[paraloc^.size]);
|
||||
end;
|
||||
LOC_REFERENCE :
|
||||
begin
|
||||
{ Extended needs a single location }
|
||||
if (paracgsize=OS_F80) or
|
||||
(paralen<=sizeof(aint)) then
|
||||
l:=paralen
|
||||
else
|
||||
l:=sizeof(aint);
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.size:=int_cgsize(l);
|
||||
if side=callerside then
|
||||
paraloc^.reference.index:=NR_STACK_POINTER_REG
|
||||
else
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
varalign:=used_align(size_2_align(l),paraalign,paraalign);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
parasize:=align(parasize+l,varalign);
|
||||
dec(paralen,l);
|
||||
end;
|
||||
end;
|
||||
if (locidx<2) and
|
||||
(loc[locidx+1]<>LOC_INVALID) then
|
||||
inc(locidx);
|
||||
end;
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
paraloc^.register:=newreg(R_INTREGISTER,paraintsupregs[intparareg],subreg);
|
||||
inc(intparareg);
|
||||
end
|
||||
else if (loc1=LOC_MMREGISTER) and
|
||||
(mmparareg<=high(parammsupregs)) then
|
||||
begin
|
||||
paraloc^.loc:=LOC_MMREGISTER;
|
||||
paraloc^.register:=newreg(R_MMREGISTER,parammsupregs[mmparareg],R_SUBNONE);
|
||||
if paracgsize=OS_F128 then
|
||||
paraloc^.size:=OS_F64
|
||||
else
|
||||
paraloc^.size:=paracgsize;
|
||||
inc(mmparareg);
|
||||
end
|
||||
else
|
||||
begin
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.size:=paracgsize;
|
||||
if side=callerside then
|
||||
paraloc^.reference.index:=NR_STACK_POINTER_REG
|
||||
else
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
l:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
|
||||
varalign:=size_2_align(l);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
varalign:=used_align(varalign,paraalign,paraalign);
|
||||
parasize:=align(parasize+l,varalign);
|
||||
end;
|
||||
{ Second location }
|
||||
if (loc2<>LOC_INVALID) then
|
||||
begin
|
||||
if (loc2=LOC_REGISTER) and
|
||||
(intparareg<=high(paraintsupregs)) then
|
||||
begin
|
||||
paraloc2:=hp.paraloc[side].add_location;
|
||||
paraloc2^.loc:=LOC_REGISTER;
|
||||
paraloc2^.register:=newreg(R_INTREGISTER,paraintsupregs[intparareg],R_SUBWHOLE);
|
||||
paraloc2^.size:=OS_INT;
|
||||
inc(intparareg);
|
||||
end
|
||||
else
|
||||
if (loc2=LOC_MMREGISTER) and
|
||||
(mmparareg<=high(parammsupregs)) then
|
||||
begin
|
||||
paraloc2:=hp.paraloc[side].add_location;
|
||||
paraloc2^.loc:=LOC_REGISTER;
|
||||
paraloc2^.register:=newreg(R_MMREGISTER,parammsupregs[mmparareg],R_SUBNONE);
|
||||
if paracgsize=OS_F128 then
|
||||
paraloc2^.size:=OS_F64
|
||||
else
|
||||
paraloc2^.size:=paracgsize;
|
||||
inc(mmparareg);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ Release when location low has already registers
|
||||
assigned }
|
||||
if paraloc^.loc=LOC_REGISTER then
|
||||
dec(intparareg);
|
||||
if paraloc^.loc=LOC_MMREGISTER then
|
||||
dec(mmparareg);
|
||||
{ Overwrite with LOC_REFERENCE }
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.size:=paracgsize;
|
||||
if side=callerside then
|
||||
paraloc^.reference.index:=NR_STACK_POINTER_REG
|
||||
else
|
||||
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
|
||||
l:=push_size(hp.varspez,hp.vartype.def,p.proccalloption);
|
||||
varalign:=size_2_align(l);
|
||||
paraloc^.reference.offset:=parasize;
|
||||
varalign:=used_align(varalign,paraalign,paraalign);
|
||||
parasize:=align(parasize+l,varalign);
|
||||
end;
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_VOID;
|
||||
end;
|
||||
end;
|
||||
{ Register parameters are assigned from left-to-right, but the
|
||||
@ -430,7 +426,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.13 2004-12-12 12:56:18 peter
|
||||
Revision 1.14 2005-01-29 11:36:52 peter
|
||||
* update x86_64 with new cpupara
|
||||
|
||||
Revision 1.13 2004/12/12 12:56:18 peter
|
||||
* compile fixes for x86_64
|
||||
|
||||
Revision 1.12 2004/11/21 17:54:59 peter
|
||||
|
Loading…
Reference in New Issue
Block a user