* 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; function taicpu.is_same_reg_move(regtype: Tregistertype):boolean;
begin begin
{ allow the register allocator to remove unnecessary moves } { allow the register allocator to remove unnecessary moves }
result:=((opcode=A_MOV) and (regtype = R_INTREGISTER)) or result:=(((opcode=A_MOV) and (regtype = R_INTREGISTER)) or
((opcode=A_MVF) and (regtype = R_FPUREGISTER)) and ((opcode=A_MVF) and (regtype = R_FPUREGISTER))
) and
(condition=C_None) and (condition=C_None) and
(ops=2) and (ops=2) and
(oper[0]^.typ=top_reg) and (oper[0]^.typ=top_reg) and
@ -422,7 +423,10 @@ implementation
end. end.
{ {
$Log$ $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 * taicpu.is_same_reg_move() now gets a regtype parameter so it only
removes moves of that particular register type. This is necessary so removes moves of that particular register type. This is necessary so
we don't remove the live_start instruction of a register before it 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 push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override; function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override;
// procedure freeintparaloc(list: taasmoutput; nr : longint); 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; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
end; end;
@ -230,12 +230,12 @@ unit cpupara;
begin begin
if (hp.paratyp in [vs_var,vs_out]) then if (hp.paratyp in [vs_var,vs_out]) then
begin begin
paradef := voidpointertype.def; paradef:=voidpointertype.def;
loc := LOC_REGISTER; loc:=LOC_REGISTER;
end end
else else
begin begin
paradef := hp.paratype.def; paradef:=hp.paratype.def;
loc:=getparaloc(p.proccalloption,paradef); loc:=getparaloc(p.proccalloption,paradef);
end; end;
{ make sure all alignment bytes are 0 as well } { make sure all alignment bytes are 0 as well }
@ -248,28 +248,28 @@ unit cpupara;
if paraloc.size = OS_NO then if paraloc.size = OS_NO then
paraloc.size := OS_ADDR; paraloc.size := OS_ADDR;
is_64bit := paraloc.size in [OS_64,OS_S64,OS_F64]; is_64bit := paraloc.size in [OS_64,OS_S64,OS_F64];
{ this is not abi compliant }
if nextintreg<=(RS_R3-ord(is_64bit)) then if nextintreg<=(RS_R3-ord(is_64bit)) then
begin begin
paraloc.loc:=LOC_REGISTER; paraloc.loc:=LOC_REGISTER;
{ big endian } paraloc.registerlow:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
if is_64bit then inc(nextintreg);
begin if is_64bit then
paraloc.registerhigh:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); begin
inc(nextintreg); paraloc.registerhigh:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
end; inc(nextintreg);
paraloc.registerlow:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); end;
inc(nextintreg);
end end
else else
begin begin
nextintreg:=RS_R4; nextintreg:=RS_R4;
paraloc.loc:=LOC_REFERENCE; paraloc.loc:=LOC_REFERENCE;
paraloc.reference.index:=NR_STACK_POINTER_REG; paraloc.reference.index:=NR_STACK_POINTER_REG;
paraloc.reference.offset:=stack_offset; paraloc.reference.offset:=stack_offset;
if not is_64bit then if not is_64bit then
inc(stack_offset,4) inc(stack_offset,4)
else else
inc(stack_offset,8); inc(stack_offset,8);
end; end;
end; end;
LOC_FPUREGISTER: LOC_FPUREGISTER:
@ -346,12 +346,32 @@ unit cpupara;
p.funcret_paraloc[side]:=paraloc; p.funcret_paraloc[side]:=paraloc;
end; 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 begin
paramanager:=tarmparamanager.create; paramanager:=tarmparamanager.create;
end. end.
{ {
$Log$ $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 * genintparaloc fixed
Revision 1.12 2004/01/20 23:18:00 florian Revision 1.12 2004/01/20 23:18:00 florian

View File

@ -81,6 +81,7 @@
{$ifdef arm} {$ifdef arm}
{$define cpuneedsdiv32helper} {$define cpuneedsdiv32helper}
{$define cputargethasfixedstack}
{$define noopt} {$define noopt}
{$define oldset} {$define oldset}
{$endif arm} {$endif arm}
@ -93,7 +94,10 @@
{ {
$Log$ $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 Stacksize force to 1mb
Revision 1.30 2003/12/14 22:41:46 peter Revision 1.30 2003/12/14 22:41:46 peter

View File

@ -104,8 +104,18 @@ implementation
begin begin
{ Allocate (temporary) paralocation } { Allocate (temporary) paralocation }
tempparaloc:=paraitem.paraloc[callerside]; tempparaloc:=paraitem.paraloc[callerside];
if (tempparaloc.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) then case tempparaloc.loc of
paramanager.alloctempregs(exprasmlist,tempparaloc) 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; end;
@ -288,7 +298,6 @@ implementation
end; end;
procedure tcgcallparanode.secondcallparan; procedure tcgcallparanode.secondcallparan;
var var
otlabel, otlabel,
@ -602,7 +611,7 @@ implementation
oldpushedparasize : longint; oldpushedparasize : longint;
{ adress returned from an I/O-error } { adress returned from an I/O-error }
{ help reference pointer } { help reference pointer }
href : treference; href,href2 : treference;
pop_size : longint; pop_size : longint;
pvreg, pvreg,
vmtreg : tregister; vmtreg : tregister;
@ -616,52 +625,94 @@ implementation
ppn:=tcgcallparanode(left); ppn:=tcgcallparanode(left);
while assigned(ppn) do while assigned(ppn) do
begin begin
case ppn.tempparaloc.loc of if (ppn.left.nodetype<>nothingn) then
LOC_REGISTER: begin
begin { better check for the real location of the parameter here, when stack passed parameters
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc); are saved temporary in registers, checking for the tempparaloc.loc is wrong
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]); }
case ppn.paraitem.paraloc[callerside].loc of
LOC_REGISTER:
begin
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
{$ifdef sparc} {$ifdef sparc}
case ppn.tempparaloc.size of case ppn.tempparaloc.size of
OS_F32 : OS_F32 :
ppn.tempparaloc.size:=OS_32; ppn.tempparaloc.size:=OS_32;
OS_F64 : OS_F64 :
ppn.tempparaloc.size:=OS_64; ppn.tempparaloc.size:=OS_64;
end; end;
{$endif sparc} {$endif sparc}
{$ifndef cpu64bit} {$ifndef cpu64bit}
if ppn.tempparaloc.size in [OS_64,OS_S64] then if ppn.tempparaloc.size in [OS_64,OS_S64] then
begin begin
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerlow, cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerlow,
ppn.paraitem.paraloc[callerside].registerlow); ppn.paraitem.paraloc[callerside].registerlow);
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerhigh, cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,ppn.tempparaloc.registerhigh,
ppn.paraitem.paraloc[callerside].registerhigh); ppn.paraitem.paraloc[callerside].registerhigh);
end end
else else
{$endif cpu64bit} {$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); ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register);
end; end;
LOC_FPUREGISTER: LOC_MMREGISTER:
begin 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
{ {
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc); paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]); paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
paramanager.freeparaloc(exprasmlist,ppn.tempparaloc); paramanager.freeparaloc(exprasmlist,ppn.tempparaloc);
paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]); paramanager.allocparaloc(exprasmlist,ppn.paraitem.paraloc[callerside]);
cg.a_loadmm_reg_reg(exprasmlist,ppn.tempparaloc.size, cg.a_loadmm_reg_reg(exprasmlist,ppn.tempparaloc.size,
ppn.tempparaloc.size,ppn.tempparaloc.register,ppn.paraitem.paraloc[callerside].register, shuffle???); 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; end;
ppn:=tcgcallparanode(ppn.right); ppn:=tcgcallparanode(ppn.right);
end; end;
end; end;
@ -1157,7 +1208,10 @@ begin
end. end.
{ {
$Log$ $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 $ifdef i386 to x86
* Change several OS_32 to OS_INT/OS_ADDR * 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 splitparaloc64(const locpara:tparalocation;var loclopara,lochipara:tparalocation);virtual;
procedure alloctempregs(list: taasmoutput;var locpara:tparalocation);virtual; procedure alloctempregs(list: taasmoutput;var locpara:tparalocation);virtual;
procedure alloctempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var locpara:tparalocation);virtual;
end; end;
@ -132,7 +133,7 @@ implementation
uses uses
cpuinfo,systems, cpuinfo,systems,
cgobj, cgobj,tgobj,
defutil,verbose; defutil,verbose;
{ true if uses a parameter as return value } { true if uses a parameter as return value }
@ -339,17 +340,32 @@ implementation
procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation); procedure tparamanager.freeparaloc(list: taasmoutput; const loc: tparalocation);
var
href : treference;
begin begin
case loc.loc of case loc.loc of
LOC_REGISTER, LOC_REGISTER, LOC_CREGISTER:
LOC_CREGISTER, begin
LOC_FPUREGISTER, {$ifndef cpu64bit}
LOC_CFPUREGISTER, if (loc.size in [OS_64,OS_S64,OS_F64]) then
LOC_MMREGISTER, begin
LOC_CMMREGISTER : 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); cg.ungetregister(list,loc.register);
LOC_REFERENCE,LOC_CREFERENCE: 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 else
internalerror(200306091); internalerror(200306091);
end; end;
@ -458,6 +474,17 @@ implementation
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.reference.index:=href.base;
locpara.reference.offset:=href.offset;
end;
function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint; function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint;
var var
hp : tparaitem; hp : tparaitem;
@ -504,7 +531,10 @@ end.
{ {
$Log$ $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 * more x86_64 parameter fixes
* tparalocation.lochigh is now used to indicate if registerhigh * tparalocation.lochigh is now used to indicate if registerhigh
is used and what the type is is used and what the type is