* always emit the procdef when calling a routine in llvm; this is

only required when calling a routine that returns a procvardef or
    if it's a C-style varargs routine, but it's always allowed and
    always doing it simplifies procvar handling

git-svn-id: trunk@32416 -
This commit is contained in:
Jonas Maebe 2015-11-21 12:37:17 +00:00
parent fed94f56c8
commit abd79d275f
3 changed files with 28 additions and 32 deletions

View File

@ -510,10 +510,18 @@ uses
end;
la_invoke, la_call:
begin
if opnr=1 then
result:=oper[2]^.def
else
internalerror(2013110102);
case opnr of
1: result:=oper[0]^.def;
3:
begin
if oper[3]^.typ=top_reg then
result:=oper[2]^.def
else
internalerror(2015112001)
end
else
internalerror(2013110102);
end;
end;
la_br,
la_unreachable:
@ -963,9 +971,9 @@ uses
have to insert a type conversion later from the alias def to the
call def here; we can't always do that at the point the call itself
is generated, because the alias declaration may occur anywhere }
loaddef(0,callpd);
loaddef(0,retsize);
loadreg(1,dst);
loaddef(2,retsize);
loaddef(2,callpd);
loadsymbol(3,name,0);
loadparas(4,paras);
end;
@ -975,9 +983,9 @@ uses
begin
create_llvm(la_call);
ops:=5;
loaddef(0,callpd);
loaddef(0,retsize);
loadreg(1,dst);
loaddef(2,retsize);
loaddef(2,callpd);
loadreg(3,reg);
loadparas(4,paras);
end;

View File

@ -51,7 +51,7 @@ uses
procedure deallocallcpuregisters(list: TAsmList); override;
protected
procedure a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out calldef: tdef; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
procedure a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
public
function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara;override;
function a_call_reg(list: TAsmList; pd: tabstractprocdef; reg: tregister; const paras: array of pcgpara): tcgpara; override;
@ -336,7 +336,7 @@ implementation
end;
procedure thlcgllvm.a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out calldef: tdef; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
procedure thlcgllvm.a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
procedure load_ref_anyreg(def: tdef; const ref: treference; reg: tregister; var callpara: pllvmcallpara);
begin
@ -432,16 +432,6 @@ implementation
if (pd.typ=procvardef) and
not pd.is_addressonly then
pd:=tprocvardef(cprocvardef.getreusableprocaddr(pd));
{ if the function returns a function pointer type or is varargs, we
must specify the full function signature, otherwise we can only
specify the return type }
if (po_varargs in pd.procoptions) or
((pd.proccalloption in cdecl_pocalls) and
(pd.paras.count>0) and
is_array_of_const(tparavarsym(pd.paras[pd.paras.count-1]).vardef)) then
calldef:=get_call_pd(pd)
else
calldef:=llvmretdef;
end;
@ -449,12 +439,11 @@ implementation
var
callparas: tfplist;
llvmretdef,
hlretdef,
calldef: tdef;
hlretdef: tdef;
res: tregister;
begin
a_call_common(list,pd,paras,forceresdef,res,calldef,hlretdef,llvmretdef,callparas);
list.concat(taillvm.call_size_name_paras(get_call_pd(pd),res,calldef,current_asmdata.RefAsmSymbol(pd.mangledname),callparas));
a_call_common(list,pd,paras,forceresdef,res,hlretdef,llvmretdef,callparas);
list.concat(taillvm.call_size_name_paras(get_call_pd(pd),res,llvmretdef,current_asmdata.RefAsmSymbol(pd.mangledname),callparas));
result:=get_call_result_cgpara(pd,forceresdef);
set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
end;
@ -464,12 +453,11 @@ implementation
var
callparas: tfplist;
llvmretdef,
hlretdef,
calldef: tdef;
hlretdef: tdef;
res: tregister;
begin
a_call_common(list,pd,paras,nil,res,calldef,hlretdef,llvmretdef,callparas);
list.concat(taillvm.call_size_reg_paras(get_call_pd(pd),res,calldef,reg,callparas));
a_call_common(list,pd,paras,nil,res,hlretdef,llvmretdef,callparas);
list.concat(taillvm.call_size_reg_paras(get_call_pd(pd),res,llvmretdef,reg,callparas));
result:=get_call_result_cgpara(pd,nil);
set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
end;

View File

@ -192,7 +192,7 @@ implementation
begin
if (opidx=3) and
(p.llvmopcode=la_call) then
record_asmsym_def(p.oper[opidx]^.ref^.symbol,tpointerdef(p.oper[0]^.def).pointeddef,false)
record_asmsym_def(p.oper[opidx]^.ref^.symbol,tpointerdef(p.oper[2]^.def).pointeddef,false)
{ not a named register }
else if (p.oper[opidx]^.ref^.refaddr<>addr_full) then
record_asmsym_def(p.oper[opidx]^.ref^.symbol,p.spilling_get_reg_type(opidx),false);
@ -277,11 +277,11 @@ implementation
la_call:
if p.oper[3]^.typ=top_ref then
begin
maybe_insert_extern_sym_decl(toplevellist,p.oper[3]^.ref^.symbol,tpointerdef(p.oper[0]^.def).pointeddef);
maybe_insert_extern_sym_decl(toplevellist,p.oper[3]^.ref^.symbol,tpointerdef(p.oper[2]^.def).pointeddef);
symdef:=get_asmsym_def(p.oper[3]^.ref^.symbol);
{ the type used in the call is different from the type used to
declare the symbol -> insert a typecast }
if not equal_llvm_defs(symdef,p.oper[0]^.def) then
if not equal_llvm_defs(symdef,p.oper[2]^.def) then
begin
if symdef.typ=procdef then
{ ugly, but can't use getcopyas(procvardef) due to the
@ -290,7 +290,7 @@ implementation
symtable) and "pointer to procedure" results in the
correct llvm type }
symdef:=cpointerdef.getreusable(tprocdef(symdef));
cnv:=taillvm.op_reg_size_sym_size(la_bitcast,NR_NO,symdef,p.oper[3]^.ref^.symbol,p.oper[0]^.def);
cnv:=taillvm.op_reg_size_sym_size(la_bitcast,NR_NO,symdef,p.oper[3]^.ref^.symbol,p.oper[2]^.def);
p.loadtai(3,cnv);
end;
end;