* several fixes to parameter handling on arm

This commit is contained in:
florian 2004-02-09 22:48:45 +00:00
parent 302d2d1442
commit abc41f1c3c
5 changed files with 190 additions and 78 deletions

View File

@ -296,8 +296,9 @@ implementation
function taicpu.is_same_reg_move(regtype: Tregistertype):boolean;
begin
{ allow the register allocator to remove unnecessary moves }
result:=((opcode=A_MOV) and (regtype = R_INTREGISTER)) or
((opcode=A_MVF) and (regtype = R_FPUREGISTER)) and
result:=(((opcode=A_MOV) and (regtype = R_INTREGISTER)) or
((opcode=A_MVF) and (regtype = R_FPUREGISTER))
) and
(condition=C_None) and
(ops=2) and
(oper[0]^.typ=top_reg) and
@ -422,7 +423,10 @@ implementation
end.
{
$Log$
Revision 1.27 2004-02-08 23:10:21 jonas
Revision 1.28 2004-02-09 22:48:45 florian
* several fixes to parameter handling on arm
Revision 1.27 2004/02/08 23:10:21 jonas
* taicpu.is_same_reg_move() now gets a regtype parameter so it only
removes moves of that particular register type. This is necessary so
we don't remove the live_start instruction of a register before it

View File

@ -40,7 +40,7 @@ unit cpupara;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
// procedure freeintparaloc(list: taasmoutput; nr : longint); override;
procedure alloctempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var locpara:tparalocation);override;
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
end;
@ -230,12 +230,12 @@ unit cpupara;
begin
if (hp.paratyp in [vs_var,vs_out]) then
begin
paradef := voidpointertype.def;
loc := LOC_REGISTER;
paradef:=voidpointertype.def;
loc:=LOC_REGISTER;
end
else
begin
paradef := hp.paratype.def;
paradef:=hp.paratype.def;
loc:=getparaloc(p.proccalloption,paradef);
end;
{ make sure all alignment bytes are 0 as well }
@ -248,28 +248,28 @@ unit cpupara;
if paraloc.size = OS_NO then
paraloc.size := OS_ADDR;
is_64bit := paraloc.size in [OS_64,OS_S64,OS_F64];
{ this is not abi compliant }
if nextintreg<=(RS_R3-ord(is_64bit)) then
begin
paraloc.loc:=LOC_REGISTER;
{ big endian }
if is_64bit then
begin
paraloc.registerhigh:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
inc(nextintreg);
end;
paraloc.registerlow:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
inc(nextintreg);
paraloc.loc:=LOC_REGISTER;
paraloc.registerlow:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
inc(nextintreg);
if is_64bit then
begin
paraloc.registerhigh:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
inc(nextintreg);
end;
end
else
begin
nextintreg:=RS_R4;
paraloc.loc:=LOC_REFERENCE;
paraloc.reference.index:=NR_STACK_POINTER_REG;
paraloc.reference.offset:=stack_offset;
if not is_64bit then
inc(stack_offset,4)
else
inc(stack_offset,8);
nextintreg:=RS_R4;
paraloc.loc:=LOC_REFERENCE;
paraloc.reference.index:=NR_STACK_POINTER_REG;
paraloc.reference.offset:=stack_offset;
if not is_64bit then
inc(stack_offset,4)
else
inc(stack_offset,8);
end;
end;
LOC_FPUREGISTER:
@ -346,12 +346,32 @@ unit cpupara;
p.funcret_paraloc[side]:=paraloc;
end;
procedure tarmparamanager.alloctempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var locpara:tparalocation);
var
href : treference;
begin
if (paraitem.paratyp in [vs_var,vs_out]) then
locpara.loc:=LOC_REGISTER
else
locpara.loc:=getparaloc(calloption,paraitem.paratype.def);
if locpara.loc=LOC_REFERENCE then
inherited alloctempparaloc(list,calloption,paraitem,locpara)
else
alloctempregs(list,locpara);
end;
begin
paramanager:=tarmparamanager.create;
end.
{
$Log$
Revision 1.13 2004-01-24 01:32:49 florian
Revision 1.14 2004-02-09 22:48:45 florian
* several fixes to parameter handling on arm
Revision 1.13 2004/01/24 01:32:49 florian
* genintparaloc fixed
Revision 1.12 2004/01/20 23:18:00 florian

View File

@ -81,6 +81,7 @@
{$ifdef arm}
{$define cpuneedsdiv32helper}
{$define cputargethasfixedstack}
{$define noopt}
{$define oldset}
{$endif arm}
@ -93,7 +94,10 @@
{
$Log$
Revision 1.31 2004-01-28 16:47:45 peter
Revision 1.32 2004-02-09 22:48:45 florian
* several fixes to parameter handling on arm
Revision 1.31 2004/01/28 16:47:45 peter
Stacksize force to 1mb
Revision 1.30 2003/12/14 22:41:46 peter

View File

@ -104,8 +104,18 @@ implementation
begin
{ Allocate (temporary) paralocation }
tempparaloc:=paraitem.paraloc[callerside];
if (tempparaloc.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) then
paramanager.alloctempregs(exprasmlist,tempparaloc)
case tempparaloc.loc of
LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER:
paramanager.alloctempregs(exprasmlist,tempparaloc);
{$ifdef cputargethasfixedstack}
LOC_REFERENCE:
begin
{ currently, we copy the value always to a secure location }
if true then
paramanager.alloctempparaloc(exprasmlist,aktcallnode.procdefinition.proccalloption,paraitem,tempparaloc);
end;
{$endif cputargethasfixedstack}
end;
end;
@ -288,7 +298,6 @@ implementation
end;
procedure tcgcallparanode.secondcallparan;
var
otlabel,
@ -602,7 +611,7 @@ implementation
oldpushedparasize : longint;
{ adress returned from an I/O-error }
{ help reference pointer }
href : treference;
href,href2 : treference;
pop_size : longint;
pvreg,
vmtreg : tregister;
@ -616,52 +625,94 @@ implementation
ppn:=tcgcallparanode(left);
while assigned(ppn) do
begin
case ppn.tempparaloc.loc of
LOC_REGISTER:
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
if (ppn.left.nodetype<>nothingn) then
begin
{ better check for the real location of the parameter here, when stack passed parameters
are saved temporary in registers, checking for the tempparaloc.loc is wrong
}
case ppn.paraitem.paraloc[callerside].loc of
LOC_REGISTER:
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
{$ifdef sparc}
case ppn.tempparaloc.size of
OS_F32 :
ppn.tempparaloc.size:=OS_32;
OS_F64 :
ppn.tempparaloc.size:=OS_64;
end;
case ppn.tempparaloc.size of
OS_F32 :
ppn.tempparaloc.size:=OS_32;
OS_F64 :
ppn.tempparaloc.size:=OS_64;
end;
{$endif sparc}
{$ifndef cpu64bit}
if ppn.tempparaloc.size in [OS_64,OS_S64] then
begin
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerlow,
ppn.paraitem.paraloc[callerside].registerlow);
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerhigh,
ppn.paraitem.paraloc[callerside].registerhigh);
end
else
if ppn.tempparaloc.size in [OS_64,OS_S64] then
begin
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerlow,
ppn.paraitem.paraloc[callerside].registerlow);
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerhigh,
ppn.paraitem.paraloc[callerside].registerhigh);
end
else
{$endif cpu64bit}
cg.a_load_reg_reg(exprasmlist,ppn.tempparaloc.size,ppn.tempparaloc.size,
cg.a_load_reg_reg(exprasmlist,ppn.tempparaloc.size,ppn.tempparaloc.size,
ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
end;
LOC_FPUREGISTER:
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
cg.a_loadfpu_reg_reg(exprasmlist,ppn.tempparaloc.size,
ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
end;
LOC_FPUREGISTER:
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
cg.a_loadfpu_reg_reg(exprasmlist,ppn.tempparaloc.size,
ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
end;
LOC_MMREGISTER:
begin
end;
LOC_MMREGISTER:
begin
{
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
cg.a_loadmm_reg_reg(exprasmlist,ppn.tempparaloc.size,
ppn.tempparaloc.size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register, shuffle???);
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
cg.a_loadmm_reg_reg(exprasmlist,ppn.tempparaloc.size,
ppn.tempparaloc.size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register, shuffle???);
}
internalerror(2003102910);
internalerror(2003102910);
end;
LOC_REFERENCE:
begin
{$ifdef cputargethasfixedstack}
{ copy parameters in case they were moved to a temp. location because we've a fixed stack }
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
case ppn.tempparaloc.loc of
LOC_REFERENCE:
begin
reference_reset_base(href,ppn.tempparaloc.reference.index,ppn.tempparaloc.reference.offset);
reference_reset_base(href2,ppn.paraitem.paraloc[callerside].reference.index,ppn.paraitem.paraloc[callerside].reference.offset);
cg.g_concatcopy(exprasmlist,href,href2,ppn.paraitem.paratype.def.size,false,false);
end;
LOC_REGISTER:
if ppn.tempparaloc.size in [OS_64,OS_S64] then
begin
reference_reset_base(href,ppn.paraitem.paraloc[callerside].reference.index,ppn.paraitem.paraloc[callerside].reference.offset);
cg.a_load_reg_ref(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerlow,
href);
{ we don't use a c64.load here because later (when fixed ;)) one dword could be on the stack and the
other in a cpu register }
reference_reset_base(href,ppn.paraitem.paraloc[callerside].reference.index,ppn.paraitem.paraloc[callerside].reference.offset+4);
cg.a_load_reg_ref(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerhigh,
href);
end
else
cg.a_param_reg(exprasmlist,ppn.paraitem.paraloc[callerside].size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside]);
LOC_FPUREGISTER:
cg.a_paramfpu_reg(exprasmlist,ppn.paraitem.paraloc[callerside].size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside]);
else
internalerror(200402081);
end;
{$endif cputargethasfixedstack}
end;
else
internalerror(200402091);
end;
end;
end;
ppn:=tcgcallparanode(ppn.right);
end;
end;
@ -1157,7 +1208,10 @@ begin
end.
{
$Log$
Revision 1.152 2004-01-31 17:45:17 peter
Revision 1.153 2004-02-09 22:48:45 florian
* several fixes to parameter handling on arm
Revision 1.152 2004/01/31 17:45:17 peter
* Change several $ifdef i386 to x86
* Change several OS_32 to OS_INT/OS_ADDR

View File

@ -121,6 +121,7 @@ unit paramgr;
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;
@ -132,7 +133,7 @@ implementation
uses
cpuinfo,systems,
cgobj,
cgobj,tgobj,
defutil,verbose;
{ true if uses a parameter as return value }
@ -339,17 +340,32 @@ implementation
procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
var
href : treference;
begin
case loc.loc of
LOC_REGISTER,
LOC_CREGISTER,
LOC_FPUREGISTER,
LOC_CFPUREGISTER,
LOC_MMREGISTER,
LOC_CMMREGISTER :
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:
{ do nothing by default, most of the time it's the framepointer }
begin
{$ifdef cputargethasfixedstack}
reference_reset_base(href,loc.reference.index,loc.reference.offset);
tg.ungettemp(list,href);
{$endif cputargethasfixedstack}
end;
else
internalerror(200306091);
end;
@ -458,6 +474,17 @@ implementation
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.reference.index:=href.base;
locpara.reference.offset:=href.offset;
end;
function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint;
var
hp : tparaitem;
@ -504,7 +531,10 @@ end.
{
$Log$
Revision 1.69 2004-02-09 22:14:17 peter
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