mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 19:29:24 +02:00
* store the used tabstractprocdef when generating an llvm call instruction,
because due to aliasing symbols a single symbol may be called using different procdefs (e.g. FPC_ANSISTR_UNIQUE in the system unit is defined as an alias for a function and called as a procedure). This means we have to insert extra type conversions for llvm, which requires both the source and destination type git-svn-id: trunk@30776 -
This commit is contained in:
parent
6662cb6dd5
commit
72277f5098
@ -105,9 +105,9 @@ interface
|
||||
constructor getelementptr_reg_tai_size_const(dst:tregister;const ai:tai;indextype:tdef;index1:ptrint;indirect:boolean);
|
||||
|
||||
{ e.g. dst = call retsize name (paras) }
|
||||
constructor call_size_name_paras(dst: tregister;retsize: tdef;name:tasmsymbol;paras: tfplist);
|
||||
constructor call_size_name_paras(callpd: tdef; dst: tregister;retsize: tdef;name:tasmsymbol;paras: tfplist);
|
||||
{ e.g. dst = call retsize reg (paras) }
|
||||
constructor call_size_reg_paras(dst: tregister;retsize: tdef;reg:tregister;paras: tfplist);
|
||||
constructor call_size_reg_paras(callpd: tdef; dst: tregister;retsize: tdef;reg:tregister;paras: tfplist);
|
||||
|
||||
procedure loadoper(opidx: longint; o: toper); override;
|
||||
procedure clearop(opidx: longint); override;
|
||||
@ -924,25 +924,32 @@ uses
|
||||
end;
|
||||
|
||||
|
||||
constructor taillvm.call_size_name_paras(dst: tregister; retsize: tdef; name:tasmsymbol; paras: tfplist);
|
||||
constructor taillvm.call_size_name_paras(callpd: tdef; dst: tregister; retsize: tdef; name:tasmsymbol; paras: tfplist);
|
||||
begin
|
||||
create_llvm(la_call);
|
||||
ops:=4;
|
||||
loadreg(0,dst);
|
||||
loaddef(1,retsize);
|
||||
loadsymbol(2,name,0);
|
||||
loadparas(3,paras);
|
||||
ops:=5;
|
||||
{ we need this in case the call symbol is an alias for a symbol with a
|
||||
different def in the same module (via "external"), because then we
|
||||
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);
|
||||
loadreg(1,dst);
|
||||
loaddef(2,retsize);
|
||||
loadsymbol(3,name,0);
|
||||
loadparas(4,paras);
|
||||
end;
|
||||
|
||||
|
||||
constructor taillvm.call_size_reg_paras(dst: tregister; retsize: tdef; reg: tregister; paras: tfplist);
|
||||
constructor taillvm.call_size_reg_paras(callpd: tdef; dst: tregister; retsize: tdef; reg: tregister; paras: tfplist);
|
||||
begin
|
||||
create_llvm(la_call);
|
||||
ops:=4;
|
||||
loadreg(0,dst);
|
||||
loaddef(1,retsize);
|
||||
loadreg(2,reg);
|
||||
loadparas(3,paras);
|
||||
ops:=5;
|
||||
loaddef(0,callpd);
|
||||
loadreg(1,dst);
|
||||
loaddef(2,retsize);
|
||||
loadreg(3,reg);
|
||||
loadparas(4,paras);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -374,10 +374,10 @@ implementation
|
||||
end;
|
||||
la_call:
|
||||
begin
|
||||
if taillvm(hp).oper[0]^.reg<>NR_NO then
|
||||
owner.AsmWrite(getregisterstring(taillvm(hp).oper[0]^.reg)+' = ');
|
||||
if taillvm(hp).oper[1]^.reg<>NR_NO then
|
||||
owner.AsmWrite(getregisterstring(taillvm(hp).oper[1]^.reg)+' = ');
|
||||
sep:=' ';
|
||||
opstart:=1;
|
||||
opstart:=2;
|
||||
end;
|
||||
la_alloca:
|
||||
begin
|
||||
|
@ -314,6 +314,16 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function get_call_pd(pd: tabstractprocdef): tdef;
|
||||
begin
|
||||
if (pd.typ=procdef) or
|
||||
not pd.is_addressonly then
|
||||
result:=pd.getcopyas(procvardef,pc_address_only)
|
||||
else
|
||||
result:=pd
|
||||
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 load_ref_anyreg(def: tdef; const ref: treference; reg: tregister; var callpara: pllvmcallpara);
|
||||
@ -417,11 +427,7 @@ implementation
|
||||
((pd.proccalloption in cdecl_pocalls) and
|
||||
(pd.paras.count>0) and
|
||||
is_array_of_const(tparavarsym(pd.paras[pd.paras.count-1]).vardef)) then
|
||||
if (pd.typ=procdef) or
|
||||
not pd.is_addressonly then
|
||||
calldef:=pd.getcopyas(procvardef,pc_address_only)
|
||||
else
|
||||
calldef:=pd
|
||||
calldef:=get_call_pd(pd)
|
||||
else
|
||||
calldef:=llvmretdef;
|
||||
end;
|
||||
@ -445,7 +451,7 @@ implementation
|
||||
current_asmdata.AsmLists[al_imports].Concat(taillvmdecl.create(asmsym,pd,nil,sec_code,pd.alignment));
|
||||
end;
|
||||
a_call_common(list,pd,paras,forceresdef,res,calldef,hlretdef,llvmretdef,callparas);
|
||||
list.concat(taillvm.call_size_name_paras(res,calldef,current_asmdata.RefAsmSymbol(pd.mangledname),callparas));
|
||||
list.concat(taillvm.call_size_name_paras(get_call_pd(pd),res,calldef,current_asmdata.RefAsmSymbol(pd.mangledname),callparas));
|
||||
result:=get_call_result_cgpara(pd,forceresdef);
|
||||
set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
|
||||
end;
|
||||
@ -460,7 +466,7 @@ implementation
|
||||
res: tregister;
|
||||
begin
|
||||
a_call_common(list,pd,paras,nil,res,calldef,hlretdef,llvmretdef,callparas);
|
||||
list.concat(taillvm.call_size_reg_paras(res,calldef,reg,callparas));
|
||||
list.concat(taillvm.call_size_reg_paras(get_call_pd(pd),res,calldef,reg,callparas));
|
||||
result:=get_call_result_cgpara(pd,nil);
|
||||
set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user