* update x86_64 with new cpupara

This commit is contained in:
peter 2005-01-29 11:36:52 +00:00
parent 3dcc711558
commit cd01e600b9
4 changed files with 159 additions and 135 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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