mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-07 21:50:14 +02:00
* fixed support for nested procedures and more parameters than those
which fit in registers (untested/probably not working: calling a nested procedure from a deeper nested procedure)
This commit is contained in:
parent
ce0885b092
commit
74301b9544
@ -963,12 +963,13 @@ const
|
||||
{ combined size of ALL the parameters of a procedure called by the current }
|
||||
{ one }
|
||||
var regcounter,firstregfpu,firstreggpr: TRegister;
|
||||
href : treference;
|
||||
href,href2 : treference;
|
||||
usesfpr,usesgpr,gotgot : boolean;
|
||||
parastart : aword;
|
||||
offset : aword;
|
||||
r,r2,rsp:Tregister;
|
||||
regcounter2: Tsuperregister;
|
||||
hp: tparaitem;
|
||||
|
||||
begin
|
||||
{ we do our own localsize calculation }
|
||||
@ -998,6 +999,7 @@ const
|
||||
a_reg_alloc(list,r);
|
||||
end;
|
||||
|
||||
|
||||
usesfpr:=false;
|
||||
if not (po_assembler in current_procdef.procoptions) then
|
||||
for regcounter.enum:=R_F14 to R_F31 do
|
||||
@ -1035,7 +1037,9 @@ const
|
||||
a_reg_dealloc(list,r);
|
||||
end;
|
||||
|
||||
if usesfpr or usesgpr then
|
||||
{ !!! always allocate space for all registers for now !!! }
|
||||
if not (po_assembler in current_procdef.procoptions) then
|
||||
{ if usesfpr or usesgpr then }
|
||||
begin
|
||||
r.enum:=R_INTREGISTER;
|
||||
r.number:=NR_R12;
|
||||
@ -1045,10 +1049,15 @@ const
|
||||
end;
|
||||
|
||||
{ calculate the size of the locals }
|
||||
{
|
||||
if usesgpr then
|
||||
inc(localsize,((NR_R31-firstreggpr.number) shr 8+1)*4);
|
||||
if usesfpr then
|
||||
inc(localsize,(ord(R_F31)-ord(firstregfpu.enum)+1)*8);
|
||||
}
|
||||
{ !!! always allocate space for all registers for now !!! }
|
||||
if not (po_assembler in current_procdef.procoptions) then
|
||||
inc(localsize,(31-13+1)*4+(31-14+1)*8);
|
||||
|
||||
{ align to 16 bytes }
|
||||
localsize:=align(localsize,16);
|
||||
@ -1123,6 +1132,27 @@ const
|
||||
list.concat(taicpu.op_reg_ref(A_STMW,firstreggpr,href));
|
||||
end;
|
||||
|
||||
if assigned(current_procdef.parast) then
|
||||
begin
|
||||
if not (po_assembler in current_procdef.procoptions) then
|
||||
begin
|
||||
{ copy memory parameters to local parast }
|
||||
r.enum:=R_INTREGISTER;
|
||||
r.number:=NR_R12;
|
||||
hp:=tparaitem(current_procdef.para.first);
|
||||
while assigned(hp) do
|
||||
begin
|
||||
if (hp.paraloc.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
||||
begin
|
||||
reference_reset_base(href,current_procinfo.framepointer,tvarsym(hp.parasym).adjusted_address);
|
||||
reference_reset_base(href2,r,hp.paraloc.reference.offset);
|
||||
cg.a_load_ref_ref(list,hp.paraloc.size,href2,href);
|
||||
end;
|
||||
hp := tparaitem(hp.next);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
r.enum:=R_INTREGISTER;
|
||||
r.number:=NR_R12;
|
||||
if usesfpr or usesgpr then
|
||||
@ -1899,6 +1929,7 @@ const
|
||||
r,r2,rsp:Tregister;
|
||||
begin
|
||||
{$warning !!!! FIX ME !!!!}
|
||||
internalerror(200305231);
|
||||
{!!!!
|
||||
lenref:=ref;
|
||||
inc(lenref.offset,4);
|
||||
@ -2411,7 +2442,12 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.94 2003-05-20 23:54:00 florian
|
||||
Revision 1.95 2003-05-23 18:51:26 jonas
|
||||
* fixed support for nested procedures and more parameters than those
|
||||
which fit in registers (untested/probably not working: calling a
|
||||
nested procedure from a deeper nested procedure)
|
||||
|
||||
Revision 1.94 2003/05/20 23:54:00 florian
|
||||
+ basic darwin support added
|
||||
|
||||
Revision 1.93 2003/05/15 22:14:42 florian
|
||||
|
@ -41,7 +41,6 @@ unit cpupi;
|
||||
maxpushedparasize : aword;
|
||||
|
||||
constructor create(aparent:tprocinfo);override;
|
||||
procedure after_header;override;
|
||||
procedure after_pass1;override;
|
||||
end;
|
||||
|
||||
@ -63,26 +62,12 @@ unit cpupi;
|
||||
localsize:=0;
|
||||
end;
|
||||
|
||||
procedure tppcprocinfo.after_header;
|
||||
begin
|
||||
{ this value is necessary for nested procedures }
|
||||
procdef.parast.address_fixup:=0;
|
||||
inherited after_header;
|
||||
|
||||
if assigned(procdef.localst) then
|
||||
procdef.localst.address_fixup:=0;
|
||||
procdef.parast.address_fixup:= -procdef.parast.datasize;
|
||||
end;
|
||||
|
||||
procedure tppcprocinfo.after_pass1;
|
||||
var
|
||||
ofs : aword;
|
||||
begin
|
||||
if not(po_assembler in procdef.procoptions) then
|
||||
begin
|
||||
procdef.parast.address_fixup := 0;
|
||||
allocate_implicit_parameter;
|
||||
procdef.localst.address_fixup := procdef.parast.address_fixup + procdef.parast.datasize;
|
||||
ofs:=align(maxpushedparasize+LinkageAreaSize,16);
|
||||
inc(procdef.parast.address_fixup,ofs);
|
||||
inc(framepointer_offset,ofs);
|
||||
@ -91,18 +76,10 @@ unit cpupi;
|
||||
if cs_asm_source in aktglobalswitches then
|
||||
aktproccode.insert(Tai_comment.Create(strpnew('Parameter copies start at: r1+'+tostr(procdef.parast.address_fixup))));
|
||||
|
||||
// Already done with an "inc" above now, not sure if it's correct (JM)
|
||||
procdef.localst.address_fixup:=procdef.parast.address_fixup+procdef.parast.datasize;
|
||||
if assigned(procdef.funcretsym) then
|
||||
return_offset:=tvarsym(procdef.funcretsym).address+tvarsym(procdef.funcretsym).owner.address_fixup;
|
||||
|
||||
{
|
||||
Already done with an "inc" above, should be correct (JM)
|
||||
if assigned(procdef.funcretsym) and
|
||||
not(paramanager.ret_in_param(procdef.rettype.def,procdef.proccalloption)) then
|
||||
return_offset:=tg.direction*tfuncretsym(procdef.funcretsym).address+procdef.localst.address_fixup;
|
||||
}
|
||||
|
||||
if cs_asm_source in aktglobalswitches then
|
||||
aktproccode.insert(Tai_comment.Create(strpnew('Locals start at: r1+'+tostr(procdef.localst.address_fixup))));
|
||||
|
||||
@ -122,7 +99,12 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.19 2003-05-22 21:34:11 peter
|
||||
Revision 1.20 2003-05-23 18:51:26 jonas
|
||||
* fixed support for nested procedures and more parameters than those
|
||||
which fit in registers (untested/probably not working: calling a
|
||||
nested procedure from a deeper nested procedure)
|
||||
|
||||
Revision 1.19 2003/05/22 21:34:11 peter
|
||||
* inherite from tcgprocinfo
|
||||
|
||||
Revision 1.18 2003/05/17 14:05:30 jonas
|
||||
|
@ -95,8 +95,11 @@ implementation
|
||||
hregister1.number:=NR_R1;
|
||||
hregister2.enum:=R_INTREGISTER;
|
||||
hregister2.number:=NR_R11;
|
||||
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,hregister1,hregister2);
|
||||
{
|
||||
if assigned(current_procinfo.procdef.localst) then
|
||||
exprasmlist.concat(taicpu.op_reg_reg_const(A_ADDI,hregister2,hregister1,current_procinfo.procdef.localst.address_fixup));
|
||||
exprasmlist.concat(taicpu.op_reg_reg_const(A_ADDI,hregister2,hregister1,current_procinfo.procdef.parast.address_fixup));
|
||||
}
|
||||
end
|
||||
else if (current_procdef.parast.symtablelevel>(tprocdef(procdefinition).parast.symtablelevel)) then
|
||||
begin
|
||||
@ -128,7 +131,12 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.13 2003-05-18 15:15:59 florian
|
||||
Revision 1.14 2003-05-23 18:51:26 jonas
|
||||
* fixed support for nested procedures and more parameters than those
|
||||
which fit in registers (untested/probably not working: calling a
|
||||
nested procedure from a deeper nested procedure)
|
||||
|
||||
Revision 1.13 2003/05/18 15:15:59 florian
|
||||
+ added abi field to tsysteminfo
|
||||
|
||||
Revision 1.12 2003/05/16 23:15:51 jonas
|
||||
|
Loading…
Reference in New Issue
Block a user