mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 19:48:49 +02:00
* 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:
parent
fed94f56c8
commit
abd79d275f
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user