diff --git a/compiler/llvm/aasmllvm.pas b/compiler/llvm/aasmllvm.pas index ef041e7381..4ac9bfff0c 100644 --- a/compiler/llvm/aasmllvm.pas +++ b/compiler/llvm/aasmllvm.pas @@ -107,7 +107,7 @@ interface constructor getelementptr_reg_size_ref_size_const(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:ptrint;indirect:boolean); constructor getelementptr_reg_tai_size_const(dst:tregister;const ai:tai;indextype:tdef;index1:ptrint;indirect:boolean); - constructor blockaddress(fun, lab: tasmsymbol); + constructor blockaddress(size: tdef; fun, lab: tasmsymbol); constructor landingpad(dst:tregister;def:tdef;firstclause:taillvm); constructor exceptclause(op:tllvmop;def:tdef;kind:TAsmSymbol;nextclause:taillvm); @@ -514,7 +514,7 @@ uses end; la_blockaddress: case opnr of - 0: result:=operand_write + 1: result:=operand_write else result:=operand_read; end @@ -673,7 +673,7 @@ uses end; la_blockaddress: case opnr of - 0: result:=voidcodepointertype + 1: result:=voidcodepointertype else internalerror(2015111904); end @@ -1037,12 +1037,13 @@ uses loadconst(index+1,index1); end; - constructor taillvm.blockaddress(fun, lab: tasmsymbol); + constructor taillvm.blockaddress(size: tdef; fun, lab: tasmsymbol); begin create_llvm(la_blockaddress); - ops:=2; - loadsymbol(0,fun,0); - loadsymbol(1,lab,0); + ops:=3; + loaddef(0,size); + loadsymbol(1,fun,0); + loadsymbol(2,lab,0); end; diff --git a/compiler/llvm/agllvm.pas b/compiler/llvm/agllvm.pas index c89a7fcf8a..28a7d50629 100644 --- a/compiler/llvm/agllvm.pas +++ b/compiler/llvm/agllvm.pas @@ -604,12 +604,18 @@ implementation end; la_blockaddress: begin - owner.writer.AsmWrite('i8* blockaddress('); - owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,false)); + { nested -> no type } + if owner.fdecllevel = 0 then + begin + owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,false)); + owner.writer.AsmWrite(' '); + end; + owner.writer.AsmWrite('blockaddress('); + owner.writer.AsmWrite(getopstr(taillvm(hp).oper[1]^,false)); { getopstr would add a "label" qualifier, which blockaddress does not want } owner.writer.AsmWrite(',%'); - with taillvm(hp).oper[1]^ do + with taillvm(hp).oper[2]^ do begin if (typ<>top_ref) or (ref^.refaddr<>addr_full) then diff --git a/compiler/llvm/nllvmld.pas b/compiler/llvm/nllvmld.pas index 007f53af7c..6f7455301c 100644 --- a/compiler/llvm/nllvmld.pas +++ b/compiler/llvm/nllvmld.pas @@ -124,7 +124,7 @@ procedure tllvmloadnode.pass_generate_code; labelsym: begin selfreg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidcodepointertype); - ai:=taillvm.blockaddress( + ai:=taillvm.blockaddress(voidcodepointertype, current_asmdata.RefAsmSymbol(current_procinfo.procdef.mangledname,AT_FUNCTION), location.reference.symbol ); diff --git a/compiler/llvm/nllvmtcon.pas b/compiler/llvm/nllvmtcon.pas index 5354f91b52..e24645e415 100644 --- a/compiler/llvm/nllvmtcon.pas +++ b/compiler/llvm/nllvmtcon.pas @@ -109,6 +109,7 @@ interface procedure queue_subscriptn(def: tabstractrecorddef; vs: tfieldvarsym); override; procedure queue_typeconvn(fromdef, todef: tdef); override; procedure queue_emit_staticvar(vs: tstaticvarsym); override; + procedure queue_emit_label(l: tlabelsym); override; procedure queue_emit_asmsym(sym: tasmsymbol; def: tdef); override; procedure queue_emit_ordconst(value: int64; def: tdef); override; @@ -128,6 +129,7 @@ implementation uses verbose,systems,fmodule, aasmdata, + procinfo, cpubase,cpuinfo,llvmbase, symtable,llvmdef,defutil,defcmp; @@ -782,6 +784,24 @@ implementation end; + procedure tllvmtai_typedconstbuilder.queue_emit_label(l: tlabelsym); + var + ai: taillvm; + typedai: tai; + tmpintdef: tdef; + op, + firstop, + secondop: tllvmop; + begin + ai:=taillvm.blockaddress(voidcodepointertype, + current_asmdata.RefAsmSymbol(current_procinfo.procdef.mangledname,AT_FUNCTION), + current_asmdata.RefAsmSymbol(l.mangledname,AT_LABEL) + ); + emit_tai(ai,voidcodepointertype); + fqueue_offset:=low(fqueue_offset); + end; + + procedure tllvmtai_typedconstbuilder.queue_emit_asmsym(sym: tasmsymbol; def: tdef); begin { we've already incorporated the offset via the inserted operations above,