mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 22:39:36 +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,11 +510,19 @@ uses
|
|||||||
end;
|
end;
|
||||||
la_invoke, la_call:
|
la_invoke, la_call:
|
||||||
begin
|
begin
|
||||||
if opnr=1 then
|
case opnr of
|
||||||
|
1: result:=oper[0]^.def;
|
||||||
|
3:
|
||||||
|
begin
|
||||||
|
if oper[3]^.typ=top_reg then
|
||||||
result:=oper[2]^.def
|
result:=oper[2]^.def
|
||||||
|
else
|
||||||
|
internalerror(2015112001)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
internalerror(2013110102);
|
internalerror(2013110102);
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
la_br,
|
la_br,
|
||||||
la_unreachable:
|
la_unreachable:
|
||||||
internalerror(2013110103);
|
internalerror(2013110103);
|
||||||
@ -963,9 +971,9 @@ uses
|
|||||||
have to insert a type conversion later from the alias def to the
|
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
|
call def here; we can't always do that at the point the call itself
|
||||||
is generated, because the alias declaration may occur anywhere }
|
is generated, because the alias declaration may occur anywhere }
|
||||||
loaddef(0,callpd);
|
loaddef(0,retsize);
|
||||||
loadreg(1,dst);
|
loadreg(1,dst);
|
||||||
loaddef(2,retsize);
|
loaddef(2,callpd);
|
||||||
loadsymbol(3,name,0);
|
loadsymbol(3,name,0);
|
||||||
loadparas(4,paras);
|
loadparas(4,paras);
|
||||||
end;
|
end;
|
||||||
@ -975,9 +983,9 @@ uses
|
|||||||
begin
|
begin
|
||||||
create_llvm(la_call);
|
create_llvm(la_call);
|
||||||
ops:=5;
|
ops:=5;
|
||||||
loaddef(0,callpd);
|
loaddef(0,retsize);
|
||||||
loadreg(1,dst);
|
loadreg(1,dst);
|
||||||
loaddef(2,retsize);
|
loaddef(2,callpd);
|
||||||
loadreg(3,reg);
|
loadreg(3,reg);
|
||||||
loadparas(4,paras);
|
loadparas(4,paras);
|
||||||
end;
|
end;
|
||||||
|
@ -51,7 +51,7 @@ uses
|
|||||||
procedure deallocallcpuregisters(list: TAsmList); override;
|
procedure deallocallcpuregisters(list: TAsmList); override;
|
||||||
|
|
||||||
protected
|
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
|
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_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;
|
function a_call_reg(list: TAsmList; pd: tabstractprocdef; reg: tregister; const paras: array of pcgpara): tcgpara; override;
|
||||||
@ -336,7 +336,7 @@ implementation
|
|||||||
end;
|
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);
|
procedure load_ref_anyreg(def: tdef; const ref: treference; reg: tregister; var callpara: pllvmcallpara);
|
||||||
begin
|
begin
|
||||||
@ -432,16 +432,6 @@ implementation
|
|||||||
if (pd.typ=procvardef) and
|
if (pd.typ=procvardef) and
|
||||||
not pd.is_addressonly then
|
not pd.is_addressonly then
|
||||||
pd:=tprocvardef(cprocvardef.getreusableprocaddr(pd));
|
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;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -449,12 +439,11 @@ implementation
|
|||||||
var
|
var
|
||||||
callparas: tfplist;
|
callparas: tfplist;
|
||||||
llvmretdef,
|
llvmretdef,
|
||||||
hlretdef,
|
hlretdef: tdef;
|
||||||
calldef: tdef;
|
|
||||||
res: tregister;
|
res: tregister;
|
||||||
begin
|
begin
|
||||||
a_call_common(list,pd,paras,forceresdef,res,calldef,hlretdef,llvmretdef,callparas);
|
a_call_common(list,pd,paras,forceresdef,res,hlretdef,llvmretdef,callparas);
|
||||||
list.concat(taillvm.call_size_name_paras(get_call_pd(pd),res,calldef,current_asmdata.RefAsmSymbol(pd.mangledname),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);
|
result:=get_call_result_cgpara(pd,forceresdef);
|
||||||
set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
|
set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
|
||||||
end;
|
end;
|
||||||
@ -464,12 +453,11 @@ implementation
|
|||||||
var
|
var
|
||||||
callparas: tfplist;
|
callparas: tfplist;
|
||||||
llvmretdef,
|
llvmretdef,
|
||||||
hlretdef,
|
hlretdef: tdef;
|
||||||
calldef: tdef;
|
|
||||||
res: tregister;
|
res: tregister;
|
||||||
begin
|
begin
|
||||||
a_call_common(list,pd,paras,nil,res,calldef,hlretdef,llvmretdef,callparas);
|
a_call_common(list,pd,paras,nil,res,hlretdef,llvmretdef,callparas);
|
||||||
list.concat(taillvm.call_size_reg_paras(get_call_pd(pd),res,calldef,reg,callparas));
|
list.concat(taillvm.call_size_reg_paras(get_call_pd(pd),res,llvmretdef,reg,callparas));
|
||||||
result:=get_call_result_cgpara(pd,nil);
|
result:=get_call_result_cgpara(pd,nil);
|
||||||
set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
|
set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
|
||||||
end;
|
end;
|
||||||
|
@ -192,7 +192,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if (opidx=3) and
|
if (opidx=3) and
|
||||||
(p.llvmopcode=la_call) then
|
(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 }
|
{ not a named register }
|
||||||
else if (p.oper[opidx]^.ref^.refaddr<>addr_full) then
|
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);
|
record_asmsym_def(p.oper[opidx]^.ref^.symbol,p.spilling_get_reg_type(opidx),false);
|
||||||
@ -277,11 +277,11 @@ implementation
|
|||||||
la_call:
|
la_call:
|
||||||
if p.oper[3]^.typ=top_ref then
|
if p.oper[3]^.typ=top_ref then
|
||||||
begin
|
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);
|
symdef:=get_asmsym_def(p.oper[3]^.ref^.symbol);
|
||||||
{ the type used in the call is different from the type used to
|
{ the type used in the call is different from the type used to
|
||||||
declare the symbol -> insert a typecast }
|
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
|
begin
|
||||||
if symdef.typ=procdef then
|
if symdef.typ=procdef then
|
||||||
{ ugly, but can't use getcopyas(procvardef) due to the
|
{ ugly, but can't use getcopyas(procvardef) due to the
|
||||||
@ -290,7 +290,7 @@ implementation
|
|||||||
symtable) and "pointer to procedure" results in the
|
symtable) and "pointer to procedure" results in the
|
||||||
correct llvm type }
|
correct llvm type }
|
||||||
symdef:=cpointerdef.getreusable(tprocdef(symdef));
|
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);
|
p.loadtai(3,cnv);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user