* function results can now also be regvars

- removed tprocinfo.return_offset, never use it again since it's invalid
    if the result is a regvar
This commit is contained in:
Jonas Maebe 2003-06-02 21:42:05 +00:00
parent 230a14ff68
commit 6f3e16298a
8 changed files with 124 additions and 80 deletions

View File

@ -78,8 +78,6 @@ unit cgbase;
frame pointer from the outer procedure is stored.
}
framepointer_offset : longint;
{# result value offset in stack (functions only) }
return_offset : longint;
{# firsttemp position }
firsttemp_offset : longint;
@ -347,7 +345,6 @@ implementation
parent:=aparent;
procdef:=nil;
framepointer_offset:=0;
return_offset:=0;
firsttemp_offset:=0;
flags:=[];
framepointer.enum:=R_INTREGISTER;
@ -414,9 +411,6 @@ implementation
var
srsym : tvarsym;
begin
{ Retrieve function result offset }
if assigned(procdef.funcretsym) then
current_procinfo.return_offset:=tvarsym(procdef.funcretsym).adjusted_address;
end;
@ -579,7 +573,12 @@ implementation
end.
{
$Log$
Revision 1.52 2003-05-26 21:17:17 peter
Revision 1.53 2003-06-02 21:42:05 jonas
* function results can now also be regvars
- removed tprocinfo.return_offset, never use it again since it's invalid
if the result is a regvar
Revision 1.52 2003/05/26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added

View File

@ -38,6 +38,7 @@ Implementation
Uses
globtype,systems,
globals,cgbase,
symsym,symdef,
{$ifdef finaldestdebug}
cobjects,
{$endif finaldestdebug}
@ -76,7 +77,7 @@ begin
((Taicpu(hp2).opcode = A_LEAVE) or
(Taicpu(hp2).opcode = A_RET)) and
(Taicpu(p).oper[0].ref^.Base.enum = current_procinfo.FramePointer.enum) and
(Taicpu(p).oper[0].ref^.Offset >= current_procinfo.Return_Offset) and
(Taicpu(p).oper[0].ref^.Offset >= tvarsym(current_procinfo.procdef.funcretsym).adjusted_address) and
(Taicpu(p).oper[0].ref^.Index.enum = R_NO) then
begin
asml.remove(p);
@ -995,7 +996,7 @@ Begin
(Taicpu(hp1).opcode = A_RET)) And
(Taicpu(p).oper[1].typ = top_ref) And
(Taicpu(p).oper[1].ref^.base.enum = current_procinfo.FramePointer.enum) And
(Taicpu(p).oper[1].ref^.offset >= current_procinfo.Return_Offset) And
(Taicpu(p).oper[1].ref^.offset >= tvarsym(current_procinfo.procdef.funcretsym).adjusted_address) And
(Taicpu(p).oper[1].ref^.index.enum = R_NO) And
(Taicpu(p).oper[0].typ = top_reg)
Then
@ -1565,7 +1566,7 @@ Begin
(Taicpu(hp2).opcode = A_RET)) And
(Taicpu(p).oper[0].ref^.Base.enum = current_procinfo.FramePointer.enum) And
(Taicpu(p).oper[0].ref^.Index.enum = R_NO) And
(Taicpu(p).oper[0].ref^.Offset >= current_procinfo.Return_Offset) And
(Taicpu(p).oper[0].ref^.Offset >= tvarsym(current_procinfo.procdef.funcretsym).adjusted_address) And
(hp1.typ = ait_instruction) And
(Taicpu(hp1).opcode = A_MOV) And
(Taicpu(hp1).opsize = S_B) And
@ -2060,7 +2061,12 @@ End.
{
$Log$
Revision 1.44 2003-05-30 23:57:08 peter
Revision 1.45 2003-06-02 21:42:05 jonas
* function results can now also be regvars
- removed tprocinfo.return_offset, never use it again since it's invalid
if the result is a regvar
Revision 1.44 2003/05/30 23:57:08 peter
* more sparc cleanup
* accumulator removed, splitted in function_return_reg (called) and
function_result_reg (caller)

View File

@ -1224,33 +1224,6 @@ implementation
begin
if not is_void(current_procdef.rettype.def) then
begin
{ for now the pointer to the result can't be a register }
if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
begin
{$ifdef powerpc}
{ no stack space is allocated in this case -> can't save the result reg on the stack }
if not(po_assembler in current_procdef.procoptions) then
{$endif powerpc}
begin
paraloc:=paramanager.getfuncretparaloc(current_procdef);
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
case paraloc.loc of
LOC_CREGISTER,
LOC_REGISTER:
if not(paraloc.size in [OS_64,OS_S64]) then
cg.a_load_reg_ref(list,paraloc.size,paraloc.register,href)
else
cg64.a_load64_reg_ref(list,paraloc.register64,href);
LOC_CFPUREGISTER,
LOC_FPUREGISTER:
cg.a_load_reg_ref(list,paraloc.size,paraloc.register,href);
LOC_CMMREGISTER,
LOC_MMREGISTER:
cg.a_loadmm_reg_ref(list,paraloc.register,href);
end;
end;
end;
{ initialize return value }
if (current_procdef.rettype.def.needs_inittable) then
begin
@ -1260,8 +1233,11 @@ implementation
{$endif powerpc}
if (cs_implicit_exceptions in aktmoduleswitches) then
include(current_procinfo.flags,pi_needs_implicit_finally);
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
reference_reset_base(href,current_procinfo.framepointer,tvarsym(current_procdef.funcretsym).adjusted_address);
cg.g_initialize(list,current_procdef.rettype.def,href,paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption));
{ load the pointer to the initialized retvalue in te register }
if (tvarsym(current_procdef.funcretsym).reg.enum <> R_NO) then
cg.a_load_ref_reg(list,OS_ADDR,href,tvarsym(current_procdef.funcretsym).reg);
end;
end;
end;
@ -1269,14 +1245,29 @@ implementation
procedure load_return_value(list:TAAsmoutput; var uses_acc,uses_acchi,uses_fpu : boolean);
var
href : treference;
ressym: tvarsym;
resloc: tlocation;
hreg,r,r2 : tregister;
cgsize : TCGSize;
begin
if not is_void(current_procdef.rettype.def) then
begin
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
cgsize:=def_cgsize(current_procdef.rettype.def);
ressym := tvarsym(current_procdef.funcretsym);
if ressym.reg.enum <> R_NO then
begin
if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
location_reset(resloc,LOC_CREGISTER,OS_ADDR)
else
if ressym.vartype.def.deftype = floatdef then
location_reset(resloc,LOC_CFPUREGISTER,def_cgsize(current_procdef.rettype.def))
else
location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procdef.rettype.def));
resloc.register := ressym.reg;
end
else
begin
location_reset(resloc,LOC_REFERENCE,def_cgsize(current_procdef.rettype.def));
reference_reset_base(resloc.reference,current_procinfo.framepointer,tvarsym(current_procdef.funcretsym).adjusted_address);
end;
{ Here, we return the function result. In most architectures, the value is
passed into the FUNCTION_RETURN_REG, but in a windowed architecure like sparc a
function returns in a register and the caller receives it in an other one }
@ -1286,7 +1277,7 @@ implementation
begin
uses_acc:=true;
{$ifndef cpu64bit}
if cgsize in [OS_64,OS_S64] then
if resloc.size in [OS_64,OS_S64] then
begin
uses_acchi:=true;
r.enum:=R_INTREGISTER;
@ -1295,14 +1286,14 @@ implementation
r2.enum:=R_INTREGISTER;
r2.number:=NR_FUNCTION_RETURN64_HIGH_REG;
cg.a_reg_alloc(list,r2);
cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
end
else
{$endif cpu64bit}
begin
hreg.enum:=R_INTREGISTER;
hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(cgsize);
cg.a_load_ref_reg(list,cgsize,href,hreg);
hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(resloc.size);
cg.a_load_loc_reg(list,resloc.size,resloc,hreg);
end;
end;
floatdef :
@ -1314,7 +1305,7 @@ implementation
else
{$endif cpufpemu}
r.enum:=FPU_RESULT_REG;
cg.a_loadfpu_ref_reg(list,cgsize,href,r);
cg.a_loadfpu_loc_reg(list,resloc,r);
end;
else
begin
@ -1323,7 +1314,7 @@ implementation
uses_acc:=true;
{$ifndef cpu64bit}
{ Win32 can return records in EAX:EDX }
if cgsize in [OS_64,OS_S64] then
if resloc.size in [OS_64,OS_S64] then
begin
uses_acchi:=true;
r.enum:=R_INTREGISTER;
@ -1332,14 +1323,14 @@ implementation
r2.enum:=R_INTREGISTER;
r2.number:=NR_FUNCTION_RETURN64_HIGH_REG;
cg.a_reg_alloc(list,r2);
cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
end
else
{$endif cpu64bit}
begin
hreg.enum:=R_INTREGISTER;
hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(cgsize);
cg.a_load_ref_reg(list,cgsize,href,hreg);
hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(resloc.size);
cg.a_load_loc_reg(list,resloc.size,resloc,hreg);
end;
end
end;
@ -1768,20 +1759,20 @@ implementation
if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
list.concat(Tai_stabs.Create(strpnew(
'"'+current_procdef.procsym.name+':X*'+tstoreddef(current_procdef.rettype.def).numberstring+'",'+
tostr(N_tsym)+',0,0,'+tostr(current_procinfo.return_offset))))
tostr(N_tsym)+',0,0,'+tostr(tvarsym(current_procdef.funcretsym).adjusted_address))))
else
list.concat(Tai_stabs.Create(strpnew(
'"'+current_procdef.procsym.name+':X'+tstoreddef(current_procdef.rettype.def).numberstring+'",'+
tostr(N_tsym)+',0,0,'+tostr(current_procinfo.return_offset))));
tostr(N_tsym)+',0,0,'+tostr(tvarsym(current_procdef.funcretsym).adjusted_address))));
if (m_result in aktmodeswitches) then
if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
list.concat(Tai_stabs.Create(strpnew(
'"RESULT:X*'+tstoreddef(current_procdef.rettype.def).numberstring+'",'+
tostr(N_tsym)+',0,0,'+tostr(current_procinfo.return_offset))))
tostr(N_tsym)+',0,0,'+tostr(tvarsym(current_procdef.funcretsym).adjusted_address))))
else
list.concat(Tai_stabs.Create(strpnew(
'"RESULT:X'+tstoreddef(current_procdef.rettype.def).numberstring+'",'+
tostr(N_tsym)+',0,0,'+tostr(current_procinfo.return_offset))));
tostr(N_tsym)+',0,0,'+tostr(tvarsym(current_procdef.funcretsym).adjusted_address))));
end;
mangled_length:=length(current_procdef.mangledname);
getmem(p,2*mangled_length+50);
@ -1822,14 +1813,29 @@ implementation
procedure load_inlined_return_value(list:TAAsmoutput);
var
href : treference;
ressym: tvarsym;
resloc: tlocation;
r,r2 : tregister;
cgsize : TCGSize;
begin
if not is_void(current_procdef.rettype.def) then
begin
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
cgsize:=def_cgsize(current_procdef.rettype.def);
ressym := tvarsym(current_procdef.funcretsym);
if ressym.reg.enum <> R_NO then
begin
if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
location_reset(resloc,LOC_CREGISTER,OS_ADDR)
else
if ressym.vartype.def.deftype = floatdef then
location_reset(resloc,LOC_CFPUREGISTER,def_cgsize(current_procdef.rettype.def))
else
location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procdef.rettype.def));
resloc.register := ressym.reg;
end
else
begin
location_reset(resloc,LOC_CREGISTER,def_cgsize(current_procdef.rettype.def));
reference_reset_base(resloc.reference,current_procinfo.framepointer,tvarsym(current_procdef.funcretsym).adjusted_address);
end;
{ Here, we return the function result. In most architectures, the value is
passed into the FUNCTION_RETURN_REG, but in a windowed architecure like sparc a
function returns in a register and the caller receives it in an other one }
@ -1838,17 +1844,17 @@ implementation
enumdef :
begin
{$ifndef cpu64bit}
if cgsize in [OS_64,OS_S64] then
if resloc.size in [OS_64,OS_S64] then
begin
r:=rg.getregisterint(list,OS_INT);
r2:=rg.getregisterint(list,OS_INT);
cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
end
else
{$endif cpu64bit}
begin
r:=rg.getregisterint(list,cgsize);
cg.a_load_ref_reg(list,cgsize,href,r);
r:=rg.getregisterint(list,resloc.size);
cg.a_load_loc_reg(list,resloc.size,resloc,r);
end;
end;
floatdef :
@ -1859,7 +1865,7 @@ implementation
else
{$endif cpufpemu}
r.enum:=FPU_RESULT_REG;
cg.a_loadfpu_ref_reg(list,cgsize,href,r);
cg.a_loadfpu_loc_reg(list,resloc,r);
end;
else
begin
@ -1867,17 +1873,17 @@ implementation
begin
{$ifndef cpu64bit}
{ Win32 can return records in EAX:EDX }
if cgsize in [OS_64,OS_S64] then
if resloc.size in [OS_64,OS_S64] then
begin
r:=rg.getregisterint(list,OS_INT);
r2:=rg.getregisterint(list,OS_INT);
cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
cg64.a_load64_loc_reg(list,resloc,joinreg64(r,r2));
end
else
{$endif cpu64bit}
begin
r:=rg.getregisterint(list,cgsize);
cg.a_load_ref_reg(list,cgsize,href,r);
r:=rg.getregisterint(list,resloc.size);
cg.a_load_loc_reg(list,resloc.size,resloc,r);
end;
end
end;
@ -1946,7 +1952,12 @@ implementation
end.
{
$Log$
Revision 1.116 2003-06-01 21:38:06 peter
Revision 1.117 2003-06-02 21:42:05 jonas
* function results can now also be regvars
- removed tprocinfo.return_offset, never use it again since it's invalid
if the result is a regvar
Revision 1.116 2003/06/01 21:38:06 peter
* getregisterfpu size parameter added
* op_const_reg size parameter added
* sparc updates

View File

@ -111,6 +111,7 @@ implementation
{ Generate result variable accessing function result }
vs:=tvarsym.create('$result',vs_var,pd.rettype);
include(vs.varoptions,vo_is_funcret);
include(vs.varoptions,vo_regable);
pd.parast.insert(vs);
pd.insertpara(vs.vartype,vs,nil,true);
{ Store the this symbol as funcretsym for procedures }
@ -210,6 +211,10 @@ implementation
begin
vs:=tvarsym.create('$result',vs_value,pd.rettype);
include(vs.varoptions,vo_is_funcret);
if tstoreddef(pd.rettype.def).is_intregable then
include(vs.varoptions,vo_regable);
if tstoreddef(pd.rettype.def).is_fpuregable then
include(vs.varoptions,vo_fpuregable);
pd.localst.insert(vs);
pd.localst.insertvardata(vs);
pd.funcretsym:=vs;
@ -2163,7 +2168,12 @@ const
end.
{
$Log$
Revision 1.125 2003-05-22 21:31:35 peter
Revision 1.126 2003-06-02 21:42:05 jonas
* function results can now also be regvars
- removed tprocinfo.return_offset, never use it again since it's invalid
if the result is a regvar
Revision 1.125 2003/05/22 21:31:35 peter
* defer codegeneration for nested procedures
Revision 1.124 2003/05/15 18:58:53 peter

View File

@ -78,8 +78,6 @@ unit cpupi;
aktproccode.insert(Tai_comment.Create(strpnew('Parameter copies start at: r1+'+tostr(procdef.parast.address_fixup))));
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;
if cs_asm_source in aktglobalswitches then
aktproccode.insert(Tai_comment.Create(strpnew('Locals start at: r1+'+tostr(procdef.localst.address_fixup))));
@ -100,7 +98,12 @@ begin
end.
{
$Log$
Revision 1.21 2003-05-24 11:47:27 jonas
Revision 1.22 2003-06-02 21:42:05 jonas
* function results can now also be regvars
- removed tprocinfo.return_offset, never use it again since it's invalid
if the result is a regvar
Revision 1.21 2003/05/24 11:47:27 jonas
* fixed framepointer storage: it's now always stored at r1+12, which is
a place in the link area reserved for compiler use.

View File

@ -114,7 +114,7 @@ interface
tvarsym(current_procdef.funcretsym).varstate:=vs_assigned;
{ !!!!!
if (not is_void(current_procdef.rettype.def)) then
retstr:=upper(tostr(procinfo^.return_offset)+'('+gas_reg2str[procinfo^.framepointer]+')')
retstr:=upper(tostr(tvarsym(current_procdef.funcretsym).adjusted_address)+'('+gas_reg2str[procinfo^.framepointer]+')')
else
}
retstr:='';
@ -351,7 +351,12 @@ initialization
end.
{
$Log$
Revision 1.14 2003-05-30 23:57:08 peter
Revision 1.15 2003-06-02 21:42:05 jonas
* function results can now also be regvars
- removed tprocinfo.return_offset, never use it again since it's invalid
if the result is a regvar
Revision 1.14 2003/05/30 23:57:08 peter
* more sparc cleanup
* accumulator removed, splitted in function_return_reg (called) and
function_result_reg (caller)

View File

@ -99,7 +99,7 @@ interface
framereg:=current_procinfo.framepointer;
convert_register_to_enum(framereg);
if (not is_void(current_procdef.rettype.def)) then
retstr:=upper(tostr(current_procinfo.return_offset)+'('+std_reg2str[framereg.enum]+')')
retstr:=upper(tostr(tvarsym(current_procdef.funcretsym).adjusted_address)+'('+std_reg2str[framereg.enum]+')')
else
retstr:='';
@ -349,7 +349,12 @@ initialization
end.
{
$Log$
Revision 1.10 2003-05-23 22:33:48 florian
Revision 1.11 2003-06-02 21:42:05 jonas
* function results can now also be regvars
- removed tprocinfo.return_offset, never use it again since it's invalid
if the result is a regvar
Revision 1.10 2003/05/23 22:33:48 florian
* fix some small flaws which prevent sparc linux system unit from compiling
* some reformatting done

View File

@ -94,7 +94,7 @@ interface
framereg:=current_procinfo.framepointer;
convert_register_to_enum(framereg);
if (not is_void(current_procdef.rettype.def)) then
retstr:=upper(tostr(current_procinfo.return_offset)+'('+gas_reg2str[framereg.enum]+')')
retstr:=upper(tostr(tvarsym(current_procdef.funcretsym).adjusted_address)+'('+gas_reg2str[framereg.enum]+')')
else
retstr:='';
c:=current_scanner.asmgetchar;
@ -361,7 +361,12 @@ initialization
end.
{
$Log$
Revision 1.5 2003-05-22 21:33:31 peter
Revision 1.6 2003-06-02 21:42:05 jonas
* function results can now also be regvars
- removed tprocinfo.return_offset, never use it again since it's invalid
if the result is a regvar
Revision 1.5 2003/05/22 21:33:31 peter
* removed some unit dependencies
Revision 1.4 2003/05/15 18:58:54 peter