mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 18:09:27 +02:00
* several fixes to parameter handling on arm
This commit is contained in:
parent
302d2d1442
commit
abc41f1c3c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user