* changed funcret location back to tlocation

This commit is contained in:
florian 2004-11-21 17:17:03 +00:00
parent 743ac811fb
commit 18f7aa97dd
11 changed files with 305 additions and 227 deletions

View File

@ -79,7 +79,13 @@ unit cgutils;
LOC_REGISTER,
LOC_CREGISTER : (
case longint of
1 : (register : tregister);
1 : (register : tregister;
{$ifdef m68k}
{ some m68k OSes require that the result is returned in d0 and a0
the second location must be stored here }
registeralias : tregister;
{$endif m68k}
);
{$ifndef cpu64bit}
{ overlay a 64 Bit register type }
2 : (register64 : tregister64);
@ -183,7 +189,10 @@ implementation
end.
{
$Log$
Revision 1.4 2004-11-09 22:32:59 peter
Revision 1.5 2004-11-21 17:17:03 florian
* changed funcret location back to tlocation
Revision 1.4 2004/11/09 22:32:59 peter
* small m68k updates to bring it up2date
* give better error for external local variable

View File

@ -211,19 +211,20 @@ unit cgcpu;
{ return from proc }
if (po_interrupt in current_procinfo.procdef.procoptions) then
begin
if assigned(current_procinfo.procdef.funcret_paraloc[calleeside].location) and
(current_procinfo.procdef.funcret_paraloc[calleeside].location^.loc=LOC_REGISTER) then
if (current_procinfo.procdef.funcret_paraloc[calleeside].loc<>LOC_VOID) and
(current_procinfo.procdef.funcret_paraloc[calleeside].loc=LOC_REGISTER) then
list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
else
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EAX));
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EBX));
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ECX));
if assigned(current_procinfo.procdef.funcret_paraloc[calleeside].location) and
assigned(current_procinfo.procdef.funcret_paraloc[calleeside].location^.next) and
(current_procinfo.procdef.funcret_paraloc[calleeside].location^.next^.loc=LOC_REGISTER) then
if (current_procinfo.procdef.funcret_paraloc[calleeside].loc=LOC_REGISTER) and
(current_procinfo.procdef.funcret_paraloc[calleeside].size in [OS_64,OS_S64]) then
list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
else
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDX));
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ESI));
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDI));
{ .... also the segment registers }
@ -519,7 +520,10 @@ begin
end.
{
$Log$
Revision 1.60 2004-10-31 21:45:03 peter
Revision 1.61 2004-11-21 17:17:04 florian
* changed funcret location back to tlocation
Revision 1.60 2004/10/31 21:45:03 peter
* generic tlocation
* move tlocation to cgutils

View File

@ -60,7 +60,8 @@ unit cpupara;
uses
cutils,
systems,verbose,
defutil;
defutil,
cgutils;
const
parasupregs : array[0..2] of tsuperregister = (RS_EAX,RS_EDX,RS_ECX);
@ -224,8 +225,6 @@ unit cpupara;
procedure ti386paramanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
var
hiparaloc,
paraloc : pcgparalocation;
retcgsize : tcgsize;
begin
{ Constructors return self instead of a boolean }
@ -233,19 +232,20 @@ unit cpupara;
retcgsize:=OS_ADDR
else
retcgsize:=def_cgsize(p.rettype.def);
p.funcret_paraloc[side].reset;
p.funcret_paraloc[side].Alignment:=std_param_align;
p.funcret_paraloc[side].size:=retcgsize;
location_reset(p.funcret_paraloc[side],LOC_INVALID,OS_NO);
{ void has no location }
if is_void(p.rettype.def) then
exit;
paraloc:=p.funcret_paraloc[side].add_location;
begin
location_reset(p.funcret_paraloc[side],LOC_VOID,OS_NO);
exit;
end;
{ Return in FPU register? }
if p.rettype.def.deftype=floatdef then
begin
paraloc^.loc:=LOC_FPUREGISTER;
paraloc^.register:=NR_FPU_RESULT_REG;
paraloc^.size:=retcgsize;
p.funcret_paraloc[side].loc:=LOC_FPUREGISTER;
p.funcret_paraloc[side].register:=NR_FPU_RESULT_REG;
p.funcret_paraloc[side].size:=retcgsize;
end
else
{ Return in register? }
@ -254,35 +254,32 @@ unit cpupara;
if retcgsize in [OS_64,OS_S64] then
begin
{ low 32bits }
paraloc^.loc:=LOC_REGISTER;
paraloc^.size:=OS_32;
p.funcret_paraloc[side].loc:=LOC_REGISTER;
p.funcret_paraloc[side].size:=OS_64;
if side=callerside then
paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
p.funcret_paraloc[side].register64.reglo:=NR_FUNCTION_RESULT64_LOW_REG
else
paraloc^.register:=NR_FUNCTION_RETURN64_LOW_REG;
p.funcret_paraloc[side].register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
{ high 32bits }
hiparaloc:=p.funcret_paraloc[side].add_location;
hiparaloc^.loc:=LOC_REGISTER;
hiparaloc^.size:=OS_32;
if side=callerside then
hiparaloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
p.funcret_paraloc[side].register64.reghi:=NR_FUNCTION_RESULT64_HIGH_REG
else
hiparaloc^.register:=NR_FUNCTION_RETURN64_HIGH_REG;
p.funcret_paraloc[side].register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
end
else
begin
paraloc^.loc:=LOC_REGISTER;
paraloc^.size:=retcgsize;
p.funcret_paraloc[side].loc:=LOC_REGISTER;
p.funcret_paraloc[side].size:=retcgsize;
if side=callerside then
paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
p.funcret_paraloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
else
paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
p.funcret_paraloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
end;
end
else
begin
paraloc^.loc:=LOC_REFERENCE;
paraloc^.size:=retcgsize;
p.funcret_paraloc[side].loc:=LOC_REFERENCE;
p.funcret_paraloc[side].size:=retcgsize;
end;
end;
@ -517,7 +514,10 @@ begin
end.
{
$Log$
Revision 1.57 2004-11-15 23:35:31 peter
Revision 1.58 2004-11-21 17:17:04 florian
* changed funcret location back to tlocation
Revision 1.57 2004/11/15 23:35:31 peter
* tparaitem removed, use tparavarsym instead
* parameter order is now calculated from paranr value in tparavarsym

View File

@ -495,7 +495,6 @@ implementation
tempnode : tnode;
resultparaloc : pcgparalocation;
begin
resultparaloc:=procdefinition.funcret_paraloc[callerside].location;
cgsize:=procdefinition.funcret_paraloc[callerside].size;
{ structured results are easy to handle....
@ -511,18 +510,18 @@ implementation
{ ansi/widestrings must be registered, so we can dispose them }
if resulttype.def.needs_inittable then
begin
if resultparaloc^.loc<>LOC_REGISTER then
if procdefinition.funcret_paraloc[callerside].loc<>LOC_REGISTER then
internalerror(200409261);
{ the FUNCTION_RESULT_REG is already allocated }
if getsupreg(resultparaloc^.register)<first_int_imreg then
cg.ungetcpuregister(exprasmlist,resultparaloc^.register);
if getsupreg(procdefinition.funcret_paraloc[callerside].register)<first_int_imreg then
cg.ungetcpuregister(exprasmlist,procdefinition.funcret_paraloc[callerside].register);
if not assigned(funcretnode) then
begin
{ reg_ref could generate two instrcutions and allocate a register so we've to
save the result first before releasing it }
hregister:=cg.getaddressregister(exprasmlist);
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,resultparaloc^.register,hregister);
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,procdefinition.funcret_paraloc[callerside].register,hregister);
location_reset(location,LOC_REFERENCE,OS_ADDR);
location.reference:=refcountedtemp;
@ -531,7 +530,7 @@ implementation
else
begin
hregister := cg.getaddressregister(exprasmlist);
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,resultparaloc^.register,hregister);
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,procdefinition.funcret_paraloc[callerside].register,hregister);
{ in case of a regular funcretnode with ret_in_param, the }
{ original funcretnode isn't touched -> make sure it's }
{ the same here (not sure if it's necessary) }
@ -549,12 +548,12 @@ implementation
{ we have only to handle the result if it is used }
if (cnf_return_value_used in callnodeflags) then
begin
location.loc:=resultparaloc^.loc;
case resultparaloc^.loc of
location.loc:=procdefinition.funcret_paraloc[callerside].loc;
case procdefinition.funcret_paraloc[callerside].loc of
LOC_FPUREGISTER:
begin
location_reset(location,LOC_FPUREGISTER,cgsize);
location.register:=resultparaloc^.register;
location.register:=procdefinition.funcret_paraloc[callerside].register;
{$ifdef x86}
tcgx86(cg).inc_fpu_stack;
{$else x86}
@ -574,7 +573,7 @@ implementation
{$ifndef cpu64bit}
if cgsize in [OS_64,OS_S64] then
begin
procdefinition.funcret_paraloc[callerside].get_location(retloc);
retloc:=procdefinition.funcret_paraloc[callerside];
if retloc.loc<>LOC_REGISTER then
internalerror(200409141);
{ the function result registers are already allocated }
@ -594,10 +593,10 @@ implementation
getregister was done for the full register
def_cgsize(resulttype.def) is used here because
it could be a constructor call }
if getsupreg(resultparaloc^.register)<first_int_imreg then
cg.ungetcpuregister(exprasmlist,resultparaloc^.register);
if getsupreg(procdefinition.funcret_paraloc[callerside].register)<first_int_imreg then
cg.ungetcpuregister(exprasmlist,procdefinition.funcret_paraloc[callerside].register);
location.register:=cg.getintregister(exprasmlist,def_cgsize(resulttype.def));
cg.a_load_reg_reg(exprasmlist,cgsize,def_cgsize(resulttype.def),resultparaloc^.register,location.register);
cg.a_load_reg_reg(exprasmlist,cgsize,def_cgsize(resulttype.def),procdefinition.funcret_paraloc[callerside].register,location.register);
end;
end
else
@ -610,10 +609,10 @@ implementation
LOC_MMREGISTER:
begin
location_reset(location,LOC_MMREGISTER,cgsize);
if getsupreg(resultparaloc^.register)<first_mm_imreg then
cg.ungetcpuregister(exprasmlist,resultparaloc^.register);
if getsupreg(procdefinition.funcret_paraloc[callerside].register)<first_mm_imreg then
cg.ungetcpuregister(exprasmlist,procdefinition.funcret_paraloc[callerside].register);
location.register:=cg.getmmregister(exprasmlist,cgsize);
cg.a_loadmm_reg_reg(exprasmlist,cgsize,cgsize,resultparaloc^.register,location.register,mms_movescalar);
cg.a_loadmm_reg_reg(exprasmlist,cgsize,cgsize,procdefinition.funcret_paraloc[callerside].register,location.register,mms_movescalar);
end;
else
@ -624,11 +623,11 @@ implementation
begin
{$ifdef x86}
{ release FPU stack }
if resultparaloc^.loc=LOC_FPUREGISTER then
if procdefinition.funcret_paraloc[callerside].loc=LOC_FPUREGISTER then
emit_reg(A_FSTP,S_NO,NR_FPU_RESULT_REG);
{$endif x86}
if cgsize<>OS_NO then
paramanager.freeparaloc(exprasmlist,procdefinition.funcret_paraloc[callerside]);
location_free(exprasmlist,procdefinition.funcret_paraloc[callerside]);
location_reset(location,LOC_VOID,OS_NO);
end;
end;
@ -802,7 +801,6 @@ implementation
pvreg,
vmtreg : tregister;
oldaktcallnode : tcallnode;
funcretloc : pcgparalocation;
begin
if not assigned(procdefinition) or
not procdefinition.has_paraloc_info then
@ -823,21 +821,21 @@ implementation
{ Include Function result registers }
if (not is_void(resulttype.def)) then
begin
funcretloc:=procdefinition.funcret_paraloc[callerside].location;
while assigned(funcretloc) do
begin
case funcretloc^.loc of
LOC_REGISTER,
LOC_CREGISTER:
include(regs_to_save_int,getsupreg(funcretloc^.register));
LOC_FPUREGISTER,
LOC_CFPUREGISTER:
include(regs_to_save_fpu,getsupreg(funcretloc^.register));
LOC_MMREGISTER,
LOC_CMMREGISTER:
include(regs_to_save_mm,getsupreg(funcretloc^.register));
end;
funcretloc:=funcretloc^.next;
case procdefinition.funcret_paraloc[callerside].loc of
LOC_REGISTER,
LOC_CREGISTER:
include(regs_to_save_int,getsupreg(procdefinition.funcret_paraloc[callerside].register));
LOC_FPUREGISTER,
LOC_CFPUREGISTER:
include(regs_to_save_fpu,getsupreg(procdefinition.funcret_paraloc[callerside].register));
LOC_MMREGISTER,
LOC_CMMREGISTER:
include(regs_to_save_mm,getsupreg(procdefinition.funcret_paraloc[callerside].register));
LOC_REFERENCE,
LOC_VOID:
;
else
internalerror(2004110213);
end;
end;
@ -986,21 +984,21 @@ implementation
function result }
if (not is_void(resulttype.def)) then
begin
funcretloc:=procdefinition.funcret_paraloc[callerside].location;
while assigned(funcretloc) do
begin
case funcretloc^.loc of
LOC_REGISTER,
LOC_CREGISTER:
exclude(regs_to_save_int,getsupreg(funcretloc^.register));
LOC_FPUREGISTER,
LOC_CFPUREGISTER:
exclude(regs_to_save_fpu,getsupreg(funcretloc^.register));
LOC_MMREGISTER,
LOC_CMMREGISTER:
exclude(regs_to_save_mm,getsupreg(funcretloc^.register));
end;
funcretloc:=funcretloc^.next;
case procdefinition.funcret_paraloc[callerside].loc of
LOC_REGISTER,
LOC_CREGISTER:
exclude(regs_to_save_int,getsupreg(procdefinition.funcret_paraloc[callerside].register));
LOC_FPUREGISTER,
LOC_CFPUREGISTER:
exclude(regs_to_save_fpu,getsupreg(procdefinition.funcret_paraloc[callerside].register));
LOC_MMREGISTER,
LOC_CMMREGISTER:
exclude(regs_to_save_mm,getsupreg(procdefinition.funcret_paraloc[callerside].register));
LOC_REFERENCE,
LOC_VOID:
;
else
internalerror(2004110214);
end;
end;
if cg.uses_registers(R_MMREGISTER) then
@ -1250,7 +1248,10 @@ begin
end.
{
$Log$
Revision 1.185 2004-11-15 23:35:31 peter
Revision 1.186 2004-11-21 17:17:03 florian
* changed funcret location back to tlocation
Revision 1.185 2004/11/15 23:35:31 peter
* tparaitem removed, use tparavarsym instead
* parameter order is now calculated from paranr value in tparavarsym

View File

@ -61,7 +61,7 @@ interface
procedure gen_proc_exit_code(list:Taasmoutput);
procedure gen_stack_check_code(list:Taasmoutput);
procedure gen_save_used_regs(list:TAAsmoutput);
procedure gen_restore_used_regs(list:TAAsmoutput;const funcretparaloc:tcgpara);
procedure gen_restore_used_regs(list:TAAsmoutput);
procedure gen_initialize_code(list:TAAsmoutput);
procedure gen_finalize_code(list:TAAsmoutput);
procedure gen_entry_code(list:TAAsmoutput);
@ -112,6 +112,7 @@ interface
procedure generate_rtti(p:Ttypesym);
procedure generate_inittable(p:tsym);
procedure location_free(list: taasmoutput; const location : TLocation);
implementation
@ -134,6 +135,47 @@ implementation
Misc Helpers
*****************************************************************************}
procedure location_free(list: taasmoutput; const location : TLocation);
{$ifdef cputargethasfixedstack}
var
href : treference;
{$endif cputargethasfixedstack}
begin
case location.loc of
LOC_VOID:
;
LOC_REGISTER,
LOC_CREGISTER:
begin
if getsupreg(location.register)<first_int_imreg then
cg.ungetcpuregister(list,location.register);
end;
LOC_FPUREGISTER,
LOC_CFPUREGISTER:
begin
if getsupreg(location.register)<first_fpu_imreg then
cg.ungetcpuregister(list,location.register);
end;
LOC_MMREGISTER,
LOC_CMMREGISTER :
begin
if getsupreg(location.register)<first_mm_imreg then
cg.ungetcpuregister(list,location.register);
end;
LOC_REFERENCE,
LOC_CREFERENCE :
begin
{$ifdef cputargethasfixedstack}
location_freetemp(list,location);
{$endif cputargethasfixedstack}
end;
else
internalerror(2004110211);
end;
end;
{ DO NOT RELY on the fact that the tnode is not yet swaped
because of inlining code PM }
procedure firstcomplex(p : tbinarynode);
@ -1017,10 +1059,10 @@ implementation
resloc,
restmploc : tlocation;
hreg : tregister;
funcretloc : pcgparalocation;
funcretloc : tlocation;
begin
{ Is the loading needed? }
if is_void(current_procinfo.procdef.rettype.def) or
if (current_procinfo.procdef.funcret_paraloc[calleeside].loc=LOC_VOID) or
(
(po_assembler in current_procinfo.procdef.procoptions) and
(not(assigned(current_procinfo.procdef.funcretsym)) or
@ -1028,9 +1070,7 @@ implementation
) then
exit;
funcretloc:=current_procinfo.procdef.funcret_paraloc[calleeside].location;
if not assigned(funcretloc) then
internalerror(200408202);
funcretloc:=current_procinfo.procdef.funcret_paraloc[calleeside];
{ constructors return self }
if (current_procinfo.procdef.proctypeoption=potype_constructor) then
@ -1076,13 +1116,13 @@ implementation
{ 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 }
case funcretloc^.loc of
case funcretloc.loc of
LOC_REGISTER:
begin
{$ifndef cpu64bit}
if current_procinfo.procdef.funcret_paraloc[calleeside].size in [OS_64,OS_S64] then
begin
current_procinfo.procdef.funcret_paraloc[calleeside].get_location(resloc);
resloc:=current_procinfo.procdef.funcret_paraloc[calleeside];
if resloc.loc<>LOC_REGISTER then
internalerror(200409141);
{ Load low and high register separate to generate better register
@ -1131,34 +1171,39 @@ implementation
else
{$endif cpu64bit}
begin
hreg:=cg.makeregsize(list,funcretloc^.register,restmploc.size);
if getsupreg(funcretloc^.register)<first_int_imreg then
hreg:=cg.makeregsize(list,funcretloc.register,funcretloc.size);
if getsupreg(funcretloc.register)<first_int_imreg then
begin
cg.getcpuregister(list,funcretloc^.register);
cg.getcpuregister(list,funcretloc.register);
cg.ungetcpuregister(list,hreg);
{ for the optimizer }
cg.a_reg_alloc(list,funcretloc^.register);
cg.a_reg_alloc(list,funcretloc.register);
end;
{ it could be that a structure is passed in memory but the function is expected to
return a pointer to this memory }
if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption) then
cg.a_load_loc_reg(list,OS_ADDR,restmploc,hreg)
else
cg.a_load_loc_reg(list,restmploc.size,restmploc,hreg);
end;
end;
LOC_FPUREGISTER:
begin
if getsupreg(funcretloc^.register)<first_fpu_imreg then
if getsupreg(funcretloc.register)<first_fpu_imreg then
begin
cg.getcpuregister(list,funcretloc^.register);
cg.ungetcpuregister(list,funcretloc^.register);
cg.getcpuregister(list,funcretloc.register);
cg.ungetcpuregister(list,funcretloc.register);
end;
cg.a_loadfpu_loc_reg(list,restmploc,funcretloc^.register);
cg.a_loadfpu_loc_reg(list,restmploc,funcretloc.register);
end;
LOC_MMREGISTER:
begin
if getsupreg(funcretloc^.register)<first_mm_imreg then
if getsupreg(funcretloc.register)<first_mm_imreg then
begin
cg.getcpuregister(list,funcretloc^.register);
cg.ungetcpuregister(list,funcretloc^.register);
cg.getcpuregister(list,funcretloc.register);
cg.ungetcpuregister(list,funcretloc.register);
end;
cg.a_loadmm_loc_reg(list,restmploc.size,restmploc,funcretloc^.register,mms_movescalar);
cg.a_loadmm_loc_reg(list,restmploc.size,restmploc,funcretloc.register,mms_movescalar);
end;
LOC_INVALID,
LOC_REFERENCE:
@ -1194,6 +1239,7 @@ implementation
end;
end;
procedure unget_para(const paraloc:TCGParaLocation);
begin
case paraloc.loc of
@ -1215,6 +1261,7 @@ implementation
end;
end;
procedure gen_load_ref(const paraloc:TCGParaLocation;const ref:treference);
var
href : treference;
@ -1239,6 +1286,7 @@ implementation
end;
end;
procedure gen_load_reg(const paraloc:TCGParaLocation;reg:tregister);
var
href : treference;
@ -1721,7 +1769,7 @@ implementation
cg.g_proc_exit(list,parasize,(po_nostackframe in current_procinfo.procdef.procoptions));
{ release return registers, needed for optimizer }
paramanager.freeparaloc(list,current_procinfo.procdef.funcret_paraloc[calleeside]);
location_free(list,current_procinfo.procdef.funcret_paraloc[calleeside]);
{ end of frame marker for call frame info }
dwarfcfi.end_frame(list);
@ -1756,7 +1804,7 @@ implementation
end;
procedure gen_restore_used_regs(list:TAAsmoutput;const funcretparaloc:tcgpara);
procedure gen_restore_used_regs(list:TAAsmoutput);
begin
{ Pure assembler routines need to save the registers themselves }
if (po_assembler in current_procinfo.procdef.procoptions) then
@ -2075,8 +2123,7 @@ implementation
procedure gen_alloc_inline_funcret(list:TAAsmoutput;pd:tprocdef);
var
calleeparaloc,
callerparaloc : pcgparalocation;
callerparaloc : tlocation;
begin
if not assigned(pd.funcretsym) or
(po_assembler in pd.procoptions) then
@ -2087,50 +2134,52 @@ implementation
localloc.loc:=LOC_REFERENCE;
localloc.size:=int_cgsize(paramanager.push_size(varspez,vartype.def,pocall_inline));
tg.GetLocal(list,tcgsize2size[localloc.size],vartype.def,localloc.reference);
calleeparaloc:=pd.funcret_paraloc[calleeside].location;
callerparaloc:=pd.funcret_paraloc[callerside].location;
while assigned(calleeparaloc) do
callerparaloc:=pd.funcret_paraloc[callerside];
case pd.funcret_paraloc[calleeside].loc of
LOC_FPUREGISTER:
begin
pd.funcret_paraloc[calleeside].register:=cg.getfpuregister(list,pd.funcret_paraloc[calleeside].size);
pd.funcret_paraloc[callerside].register:=pd.funcret_paraloc[calleeside].register;
end;
LOC_REGISTER:
begin
{$ifndef cpu64bit}
if callerparaloc.size in [OS_64,OS_S64] then
begin
end
else
{$endif cpu64bit}
begin
pd.funcret_paraloc[calleeside].register:=cg.getintregister(list,pd.funcret_paraloc[calleeside].size);
pd.funcret_paraloc[callerside].register:=pd.funcret_paraloc[calleeside].register;
end;
end;
LOC_MMREGISTER:
begin
pd.funcret_paraloc[calleeside].register:=cg.getmmregister(list,pd.funcret_paraloc[calleeside].size);
pd.funcret_paraloc[callerside].register:=pd.funcret_paraloc[calleeside].register;
end;
LOC_REFERENCE:
begin
pd.funcret_paraloc[calleeside].reference.offset := localloc.reference.offset;
pd.funcret_paraloc[calleeside].reference.index := localloc.reference.base;
pd.funcret_paraloc[callerside].reference.offset := localloc.reference.offset;
pd.funcret_paraloc[callerside].reference.index := localloc.reference.base;
end;
LOC_VOID:
;
else
internalerror(200411191);
end;
if cs_asm_source in aktglobalswitches then
begin
if not assigned(callerparaloc) then
internalerror(200408281);
if calleeparaloc^.loc<>callerparaloc^.loc then
internalerror(200408282);
case calleeparaloc^.loc of
LOC_FPUREGISTER:
begin
calleeparaloc^.register:=cg.getfpuregister(list,calleeparaloc^.size);
callerparaloc^.register:=calleeparaloc^.register;
end;
LOC_REGISTER:
begin
calleeparaloc^.register:=cg.getintregister(list,calleeparaloc^.size);
callerparaloc^.register:=calleeparaloc^.register;
end;
LOC_MMREGISTER:
begin
calleeparaloc^.register:=cg.getmmregister(list,calleeparaloc^.size);
callerparaloc^.register:=calleeparaloc^.register;
end;
LOC_REFERENCE:
begin
calleeparaloc^.reference.offset := localloc.reference.offset;
calleeparaloc^.reference.index := localloc.reference.base;
callerparaloc^.reference.offset := localloc.reference.offset;
callerparaloc^.reference.index := localloc.reference.base;
end;
end;
calleeparaloc:=calleeparaloc^.next;
callerparaloc:=callerparaloc^.next;
end;
if cs_asm_source in aktglobalswitches then
begin
case localloc.loc of
LOC_REFERENCE :
list.concat(Tai_comment.Create(strpnew('Funcret '+realname+' allocated at '+
std_regname(localloc.reference.base)+tostr_with_plus(localloc.reference.offset))));
end;
end;
end;
case localloc.loc of
LOC_REFERENCE :
list.concat(Tai_comment.Create(strpnew('Funcret '+realname+' allocated at '+
std_regname(localloc.reference.base)+tostr_with_plus(localloc.reference.offset))));
end;
end;
end;
end;
@ -2210,7 +2259,10 @@ implementation
end.
{
$Log$
Revision 1.242 2004-11-19 08:17:01 michael
Revision 1.243 2004-11-21 17:17:03 florian
* changed funcret location back to tlocation
Revision 1.242 2004/11/19 08:17:01 michael
* Split po_public into po_public and po_global (Peter)
Revision 1.241 2004/11/15 23:35:31 peter

View File

@ -331,6 +331,8 @@ implementation
while assigned(paraloc) do
begin
case paraloc^.loc of
LOC_VOID:
;
LOC_REGISTER,
LOC_CREGISTER:
begin
@ -360,6 +362,8 @@ implementation
tg.ungettemp(list,href);
{$endif cputargethasfixedstack}
end;
else
internalerror(2004110212);
end;
paraloc:=paraloc^.next;
end;
@ -447,7 +451,10 @@ end.
{
$Log$
Revision 1.81 2004-11-15 23:35:31 peter
Revision 1.82 2004-11-21 17:17:03 florian
* changed funcret location back to tlocation
Revision 1.81 2004/11/15 23:35:31 peter
* tparaitem removed, use tparavarsym instead
* parameter order is now calculated from paranr value in tparavarsym

View File

@ -57,7 +57,8 @@ unit cpupara;
verbose,systems,
procinfo,
rgobj,
defutil,cpupi;
defutil,
cgutils;
function tppcparamanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
@ -211,8 +212,6 @@ unit cpupara;
procedure tppcparamanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
var
hiparaloc,
paraloc : pcgparalocation;
retcgsize : tcgsize;
begin
{ Constructors return self instead of a boolean }
@ -220,19 +219,22 @@ unit cpupara;
retcgsize:=OS_ADDR
else
retcgsize:=def_cgsize(p.rettype.def);
p.funcret_paraloc[side].reset;
p.funcret_paraloc[side].Alignment:=std_param_align;
location_reset(p.funcret_paraloc[side],LOC_INVALID,OS_NO);
p.funcret_paraloc[side].size:=retcgsize;
{ void has no location }
if is_void(p.rettype.def) then
exit;
paraloc:=p.funcret_paraloc[side].add_location;
begin
p.funcret_paraloc[side].loc:=LOC_VOID;
exit;
end;
{ Return in FPU register? }
if p.rettype.def.deftype=floatdef then
begin
paraloc^.loc:=LOC_FPUREGISTER;
paraloc^.register:=NR_FPU_RESULT_REG;
paraloc^.size:=retcgsize;
p.funcret_paraloc[side].loc:=LOC_FPUREGISTER;
p.funcret_paraloc[side].register:=NR_FPU_RESULT_REG;
p.funcret_paraloc[side].size:=retcgsize;
end
else
{ Return in register? }
@ -242,36 +244,32 @@ unit cpupara;
if retcgsize in [OS_64,OS_S64] then
begin
{ low 32bits }
paraloc^.loc:=LOC_REGISTER;
paraloc^.size:=OS_32;
p.funcret_paraloc[side].loc:=LOC_REGISTER;
if side=callerside then
paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
p.funcret_paraloc[side].register64.reghi:=NR_FUNCTION_RESULT64_HIGH_REG
else
paraloc^.register:=NR_FUNCTION_RETURN64_HIGH_REG;
p.funcret_paraloc[side].register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
{ high 32bits }
hiparaloc:=p.funcret_paraloc[side].add_location;
hiparaloc^.loc:=LOC_REGISTER;
hiparaloc^.size:=OS_32;
if side=callerside then
hiparaloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
p.funcret_paraloc[side].register64.reglo:=NR_FUNCTION_RESULT64_LOW_REG
else
hiparaloc^.register:=NR_FUNCTION_RETURN64_LOW_REG;
p.funcret_paraloc[side].register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
end
else
{$endif cpu64bit}
begin
paraloc^.loc:=LOC_REGISTER;
paraloc^.size:=retcgsize;
p.funcret_paraloc[side].loc:=LOC_REGISTER;
p.funcret_paraloc[side].size:=retcgsize;
if side=callerside then
paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
p.funcret_paraloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
else
paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
p.funcret_paraloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
end;
end
else
begin
paraloc^.loc:=LOC_REFERENCE;
paraloc^.size:=retcgsize;
p.funcret_paraloc[side].loc:=LOC_REFERENCE;
p.funcret_paraloc[side].size:=retcgsize;
end;
end;
@ -589,7 +587,10 @@ begin
end.
{
$Log$
Revision 1.71 2004-11-15 23:35:31 peter
Revision 1.72 2004-11-21 17:17:04 florian
* changed funcret location back to tlocation
Revision 1.71 2004/11/15 23:35:31 peter
* tparaitem removed, use tparavarsym instead
* parameter order is now calculated from paranr value in tparavarsym

View File

@ -788,7 +788,7 @@ implementation
gen_save_used_regs(templist);
aktproccode.insertlistafter(headertai,templist);
aktfilepos:=exitpos;
gen_restore_used_regs(aktproccode,procdef.funcret_paraloc[calleeside]);
gen_restore_used_regs(aktproccode);
{ Add stack checking code }
if (cs_check_stack in entryswitches) and
not(po_assembler in procdef.procoptions) and
@ -1438,7 +1438,10 @@ implementation
end.
{
$Log$
Revision 1.218 2004-11-19 08:17:02 michael
Revision 1.219 2004-11-21 17:17:03 florian
* changed funcret location back to tlocation
Revision 1.218 2004/11/19 08:17:02 michael
* Split po_public into po_public and po_global (Peter)
Revision 1.217 2004/11/17 22:21:35 peter

View File

@ -53,7 +53,8 @@ implementation
uses
cutils,verbose,systems,
defutil,cgobj;
defutil,
cgutils,cgobj;
type
tparasupregs = array[0..5] of tsuperregister;
@ -142,7 +143,6 @@ implementation
procedure tsparcparamanager.create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
var
paraloc : pcgparalocation;
retcgsize : tcgsize;
begin
{ Constructors return self instead of a boolean }
@ -150,21 +150,24 @@ implementation
retcgsize:=OS_ADDR
else
retcgsize:=def_cgsize(p.rettype.def);
p.funcret_paraloc[side].reset;
p.funcret_paraloc[side].Alignment:=std_param_align;
location_reset(p.funcret_paraloc[side],LOC_INVALID,OS_NO);
p.funcret_paraloc[side].size:=retcgsize;
{ void has no location }
if is_void(p.rettype.def) then
exit;
paraloc:=p.funcret_paraloc[side].add_location;
begin
p.funcret_paraloc[side].loc:=LOC_VOID;
exit;
end;
{ Return in FPU register? }
if p.rettype.def.deftype=floatdef then
begin
paraloc^.loc:=LOC_FPUREGISTER;
paraloc^.register:=NR_FPU_RESULT_REG;
p.funcret_paraloc[side].register:=NR_FPU_RESULT_REG;
if retcgsize=OS_F64 then
setsubreg(paraloc^.register,R_SUBFD);
paraloc^.size:=retcgsize;
setsubreg(p.funcret_paraloc[side].register,R_SUBFD);
p.funcret_paraloc[side].size:=retcgsize;
end
else
{ Return in register? }
@ -174,36 +177,31 @@ implementation
if retcgsize in [OS_64,OS_S64] then
begin
{ high }
paraloc^.loc:=LOC_REGISTER;
paraloc^.size:=OS_32;
if (side=callerside) or (p.proccalloption=pocall_inline)then
paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
p.funcret_paraloc[side].register64.reghi:=NR_FUNCTION_RESULT64_HIGH_REG
else
paraloc^.register:=NR_FUNCTION_RETURN64_HIGH_REG;
p.funcret_paraloc[side].register64.reghi:=NR_FUNCTION_RETURN64_HIGH_REG;
{ low }
paraloc:=p.funcret_paraloc[side].add_location;
paraloc^.loc:=LOC_REGISTER;
paraloc^.size:=OS_32;
if (side=callerside) or (p.proccalloption=pocall_inline) then
paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
p.funcret_paraloc[side].register64.reglo:=NR_FUNCTION_RESULT64_LOW_REG
else
paraloc^.register:=NR_FUNCTION_RETURN64_LOW_REG;
p.funcret_paraloc[side].register64.reglo:=NR_FUNCTION_RETURN64_LOW_REG;
end
else
{$endif cpu64bit}
begin
paraloc^.loc:=LOC_REGISTER;
paraloc^.size:=retcgsize;
p.funcret_paraloc[side].loc:=LOC_REGISTER;
p.funcret_paraloc[side].size:=retcgsize;
if (side=callerside) or (p.proccalloption=pocall_inline)then
paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
p.funcret_paraloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
else
paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
p.funcret_paraloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
end;
end
else
begin
paraloc^.loc:=LOC_REFERENCE;
paraloc^.size:=retcgsize;
p.funcret_paraloc[side].loc:=LOC_REFERENCE;
p.funcret_paraloc[side].size:=retcgsize;
end;
end;
@ -318,7 +316,10 @@ begin
end.
{
$Log$
Revision 1.47 2004-11-15 23:35:31 peter
Revision 1.48 2004-11-21 17:17:04 florian
* changed funcret location back to tlocation
Revision 1.47 2004/11/15 23:35:31 peter
* tparaitem removed, use tparavarsym instead
* parameter order is now calculated from paranr value in tparavarsym

View File

@ -39,7 +39,8 @@ interface
{ aasm }
aasmbase,aasmtai,
cpubase,cpuinfo,
cgbase,parabase
cgbase,cgutils,
parabase
;
@ -442,7 +443,7 @@ interface
{$ifdef i386}
fpu_used : byte; { how many stack fpu must be empty }
{$endif i386}
funcret_paraloc : array[tcallercallee] of TCGPara;
funcret_paraloc : array[tcallercallee] of TLocation;
has_paraloc_info : boolean; { paraloc info is available }
constructor create(level:byte);
constructor ppuload(ppufile:tcompilerppufile);
@ -3269,8 +3270,9 @@ implementation
savesize:=sizeof(aint);
requiredargarea:=0;
has_paraloc_info:=false;
funcret_paraloc[callerside].init;
funcret_paraloc[calleeside].init;
location_reset(funcret_paraloc[callerside],LOC_INVALID,OS_NO);
location_reset(funcret_paraloc[calleeside],LOC_INVALID,OS_NO);
end;
@ -3296,8 +3298,6 @@ implementation
memprocparast.stop;
{$endif MEMDEBUG}
end;
funcret_paraloc[callerside].done;
funcret_paraloc[calleeside].done;
inherited destroy;
end;
@ -3422,15 +3422,14 @@ implementation
proccalloption:=tproccalloption(ppufile.getbyte);
ppufile.getsmallset(procoptions);
funcret_paraloc[callerside].init;
funcret_paraloc[calleeside].init;
location_reset(funcret_paraloc[callerside],LOC_INVALID,OS_NO);
location_reset(funcret_paraloc[calleeside],LOC_INVALID,OS_NO);
if po_explicitparaloc in procoptions then
begin
b:=ppufile.getbyte;
if b<>sizeof(funcret_paraloc[callerside].location^) then
if b<>sizeof(funcret_paraloc[callerside]) then
internalerror(200411154);
ppufile.getdata(funcret_paraloc[callerside].add_location^,sizeof(funcret_paraloc[callerside].location^));
funcret_paraloc[callerside].size:=funcret_paraloc[callerside].location^.size;
ppufile.getdata(funcret_paraloc[callerside],sizeof(funcret_paraloc[callerside]));
end;
savesize:=sizeof(aint);
@ -3463,13 +3462,9 @@ implementation
if (po_explicitparaloc in procoptions) then
begin
{$warning TODO Hack to make a valid funcret_paraloc for procedures}
{ Make a 'valid' funcret_paraloc for procedures }
if is_void(rettype.def) and not assigned(funcret_paraloc[callerside].location) then
funcret_paraloc[callerside].add_location;
funcret_paraloc[callerside].check_simple_location;
ppufile.putbyte(sizeof(funcret_paraloc[callerside].location^));
ppufile.putdata(funcret_paraloc[callerside].location^,sizeof(funcret_paraloc[callerside].location^));
ppufile.putbyte(sizeof(funcret_paraloc[callerside]));
ppufile.putdata(funcret_paraloc[callerside],sizeof(funcret_paraloc[callerside]));
end;
end;
@ -6134,7 +6129,10 @@ implementation
end.
{
$Log$
Revision 1.275 2004-11-21 16:33:19 peter
Revision 1.276 2004-11-21 17:17:04 florian
* changed funcret location back to tlocation
Revision 1.275 2004/11/21 16:33:19 peter
* fixed message methods
* fixed typo with win32 dll import from implementation
* released external check

View File

@ -149,7 +149,6 @@ implementation
end;
{*****************************************************************************
TTGOBJ
*****************************************************************************}
@ -623,7 +622,10 @@ implementation
end.
{
$Log$
Revision 1.49 2004-10-31 21:45:03 peter
Revision 1.50 2004-11-21 17:17:04 florian
* changed funcret location back to tlocation
Revision 1.49 2004/10/31 21:45:03 peter
* generic tlocation
* move tlocation to cgutils