diff options
Diffstat (limited to 'compiler/llvm')
-rw-r--r-- | compiler/llvm/aasmllvm.pas | 12 | ||||
-rw-r--r-- | compiler/llvm/agllvm.pas | 19 | ||||
-rw-r--r-- | compiler/llvm/hlcgllvm.pas | 19 | ||||
-rw-r--r-- | compiler/llvm/llvmdef.pas | 24 | ||||
-rw-r--r-- | compiler/llvm/nllvmadd.pas | 20 | ||||
-rw-r--r-- | compiler/llvm/nllvmcnv.pas | 35 | ||||
-rw-r--r-- | compiler/llvm/nllvmmat.pas | 8 | ||||
-rw-r--r-- | compiler/llvm/nllvmutil.pas | 14 |
8 files changed, 70 insertions, 81 deletions
diff --git a/compiler/llvm/aasmllvm.pas b/compiler/llvm/aasmllvm.pas index 430754e101..af1ab28c03 100644 --- a/compiler/llvm/aasmllvm.pas +++ b/compiler/llvm/aasmllvm.pas @@ -142,11 +142,10 @@ interface ); taillvmalias = class(tailineinfo) - vis: tllvmvisibility; - linkage: tllvmlinkage; + bind: tasmsymbind; oldsym, newsym: TAsmSymbol; def: tdef; - constructor create(_oldsym: tasmsymbol; const newname: TSymStr; _def: tdef; _vis: tllvmvisibility; _linkage: tllvmlinkage); + constructor create(_oldsym: tasmsymbol; const newname: TSymStr; _def: tdef; _bind: tasmsymbind); end; taillvmdeclflag = @@ -244,7 +243,7 @@ uses { taillvmalias } - constructor taillvmalias.create(_oldsym: tasmsymbol; const newname: TSymStr; _def: tdef; _vis: tllvmvisibility; _linkage: tllvmlinkage); + constructor taillvmalias.create(_oldsym: tasmsymbol; const newname: TSymStr; _def: tdef; _bind: tasmsymbind); begin inherited Create; typ:=ait_llvmalias; @@ -252,8 +251,7 @@ uses newsym:=current_asmdata.DefineAsmSymbol(newname,AB_GLOBAL,AT_FUNCTION); newsym.declared:=true; def:=_def; - vis:=_vis; - linkage:=_linkage; + bind:=_bind; end; @@ -584,7 +582,7 @@ uses la_icmp, la_fcmp: begin case opnr of - 0: result:=pasbool8type; + 0: result:=llvmbool1type; 3,4: result:=oper[2]^.def; else internalerror(2013110801); diff --git a/compiler/llvm/agllvm.pas b/compiler/llvm/agllvm.pas index 8921708e9b..f0c7a1a19d 100644 --- a/compiler/llvm/agllvm.pas +++ b/compiler/llvm/agllvm.pas @@ -731,13 +731,15 @@ implementation procedure WriteLinkageVibilityFlags(bind: TAsmSymBind); begin case bind of - AB_EXTERNAL: + AB_EXTERNAL, + AB_EXTERNAL_INDIRECT: writer.AsmWrite(' external'); AB_COMMON: writer.AsmWrite(' common'); AB_LOCAL: writer.AsmWrite(' internal'); - AB_GLOBAL: + AB_GLOBAL, + AB_INDIRECT: writer.AsmWrite(''); AB_WEAK_EXTERNAL: writer.AsmWrite(' extern_weak'); @@ -1047,18 +1049,7 @@ implementation begin writer.AsmWrite(LlvmAsmSymName(taillvmalias(hp).newsym)); writer.AsmWrite(' = alias '); - if taillvmalias(hp).linkage<>lll_default then - begin - str(taillvmalias(hp).linkage, s); - writer.AsmWrite(copy(s, length('lll_')+1, 255)); - writer.AsmWrite(' '); - end; - if taillvmalias(hp).vis<>llv_default then - begin - str(taillvmalias(hp).vis, s); - writer.AsmWrite(copy(s, length('llv_')+1, 255)); - writer.AsmWrite(' '); - end; + WriteLinkageVibilityFlags(taillvmalias(hp).bind); if taillvmalias(hp).def.typ=procdef then writer.AsmWrite(llvmencodeproctype(tabstractprocdef(taillvmalias(hp).def), '', lpd_alias)) else diff --git a/compiler/llvm/hlcgllvm.pas b/compiler/llvm/hlcgllvm.pas index 805da16185..ac08930160 100644 --- a/compiler/llvm/hlcgllvm.pas +++ b/compiler/llvm/hlcgllvm.pas @@ -934,7 +934,7 @@ implementation tmpsrc1:=getintregister(list,calcsize); a_load_reg_reg(list,size,calcsize,dst,tmpsrc1); location_reset(ovloc,LOC_REGISTER,OS_8); - ovloc.register:=getintregister(list,pasbool8type); + ovloc.register:=getintregister(list,llvmbool1type); list.concat(taillvm.op_reg_cond_size_reg_reg(la_icmp,ovloc.register,OC_NE,calcsize,tmpsrc1,tmpdst)); end; @@ -950,6 +950,9 @@ implementation if (size=pasbool8type) and (cmp_op in [OC_EQ,OC_NE]) then begin + { convert to an llvmbool1type and use directly } + tmpreg:=getintregister(list,llvmbool1type); + a_load_reg_reg(list,size,llvmbool1type,reg,tmpreg); case cmp_op of OC_EQ: invert:=a=0; @@ -967,7 +970,7 @@ implementation l:=falselab; falselab:=tmplab; end; - list.concat(taillvm.op_size_reg_lab_lab(la_br,pasbool8type,reg,l,falselab)); + list.concat(taillvm.op_size_reg_lab_lab(la_br,llvmbool1type,tmpreg,l,falselab)); a_label(list,fallthroughlab); exit; end; @@ -984,13 +987,13 @@ implementation begin if getregtype(reg1)<>getregtype(reg2) then internalerror(2012111105); - resreg:=getintregister(list,pasbool8type); + resreg:=getintregister(list,llvmbool1type); current_asmdata.getjumplabel(falselab); { invert order of registers. In FPC, cmp_reg_reg(reg1,reg2) means that e.g. OC_GT is true if "subl %reg1,%reg2" in x86 AT&T is >0. In LLVM, OC_GT is true if op1>op2 } list.concat(taillvm.op_reg_cond_size_reg_reg(la_icmp,resreg,cmp_op,size,reg2,reg1)); - list.concat(taillvm.op_size_reg_lab_lab(la_br,pasbool8type,resreg,l,falselab)); + list.concat(taillvm.op_size_reg_lab_lab(la_br,llvmbool1type,resreg,l,falselab)); a_label(list,falselab); end; @@ -1037,7 +1040,7 @@ implementation a_load_const_cgpara(list,u32inttype,maxalign,alignpara); { we don't know anything about volatility here, should become an extra parameter to g_concatcopy } - a_load_const_cgpara(list,pasbool8type,0,volatilepara); + a_load_const_cgpara(list,llvmbool1type,0,volatilepara); g_call_system_proc(list,pd,[@destpara,@sourcepara,@sizepara,@alignpara,@volatilepara],nil).resetiftemp; sourcepara.done; destpara.done; @@ -1171,7 +1174,7 @@ implementation while assigned(item) do begin if mangledname<>item.Str then - list.concat(taillvmalias.create(asmsym,item.str,current_procinfo.procdef,llv_default,lll_default)); + list.concat(taillvmalias.create(asmsym,item.str,current_procinfo.procdef,asmsym.bind)); item:=TCmdStrListItem(item.next); end; list.concat(taillvmdecl.createdef(asmsym,current_procinfo.procdef,nil,sec_code,current_procinfo.procdef.alignment)); @@ -1292,7 +1295,7 @@ implementation if ovloc.size<>OS_8 then internalerror(2015122504); current_asmdata.getjumplabel(hl); - a_cmp_const_loc_label(list,pasbool8type,OC_EQ,0,ovloc,hl); + a_cmp_const_loc_label(list,llvmbool1type,OC_EQ,0,ovloc,hl); g_call_system_proc(list,'fpc_overflow',[],nil); a_label(list,hl); end; @@ -1901,7 +1904,7 @@ implementation if po_external in procdef.procoptions then exit; asmsym:=current_asmdata.RefAsmSymbol(externalname,AT_FUNCTION); - list.concat(taillvmalias.create(asmsym,procdef.mangledname,procdef,llv_default,lll_default)); + list.concat(taillvmalias.create(asmsym,procdef.mangledname,procdef,asmsym.bind)); end; diff --git a/compiler/llvm/llvmdef.pas b/compiler/llvm/llvmdef.pas index be3c3972ca..17114cf8dd 100644 --- a/compiler/llvm/llvmdef.pas +++ b/compiler/llvm/llvmdef.pas @@ -211,17 +211,23 @@ implementation end; end; end - else if is_pasbool(fromsize) and - not is_pasbool(tosize) then + else if (fromsize=llvmbool1type) and + (tosize<>llvmbool1type) then begin if is_cbool(tosize) then result:=la_sext else result:=la_zext end - else if is_pasbool(tosize) and - not is_pasbool(fromsize) then - result:=la_trunc + else if (tosize=llvmbool1type) and + (fromsize<>llvmbool1type) then + begin + { would have to compare with 0, can't just take the lowest bit } + if is_cbool(fromsize) then + internalerror(2016052001) + else + result:=la_trunc + end else result:=la_bitcast; end; @@ -308,10 +314,10 @@ implementation if is_void(def) then encodedstr:=encodedstr+'void' { mainly required because comparison operations return i1, and - otherwise we always have to immediatel extend them to i8 for - no good reason; besides, Pascal booleans can only contain 0 - or 1 in valid code anyway (famous last words...) } - else if torddef(def).ordtype=pasbool8 then + we need a way to represent the i1 type in Pascal. We don't + reuse pasbool8type, because putting an i1 in a record or + passing it as a parameter may result in unexpected behaviour } + else if def=llvmbool1type then encodedstr:=encodedstr+'i1' else encodedstr:=encodedstr+'i'+tostr(def.size*8); diff --git a/compiler/llvm/nllvmadd.pas b/compiler/llvm/nllvmadd.pas index a348c4a6c5..d54b9c0eff 100644 --- a/compiler/llvm/nllvmadd.pas +++ b/compiler/llvm/nllvmadd.pas @@ -109,7 +109,7 @@ implementation pass_left_right; location_reset(location,LOC_REGISTER,OS_8); - location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,pasbool8type); + location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,llvmbool1type); force_reg_left_right(false,false); @@ -143,11 +143,15 @@ implementation else internalerror(2012042701); end; + tmpreg:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef); + hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,llvmbool1type,resultdef,location.register,tmpreg); + location.register:=tmpreg; end; procedure tllvmaddnode.second_cmpordinal; var + tmpreg: tregister; cmpop: topcmp; unsigned : boolean; begin @@ -189,7 +193,7 @@ implementation cmpop:=swap_opcmp(cmpop); location_reset(location,LOC_REGISTER,OS_8); - location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef); + location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,llvmbool1type); if right.location.loc=LOC_CONSTANT then current_asmdata.CurrAsmList.concat(taillvm.op_reg_cond_size_reg_const(la_icmp, @@ -197,6 +201,10 @@ implementation else current_asmdata.CurrAsmList.concat(taillvm.op_reg_cond_size_reg_reg(la_icmp, location.register,cmpop,left.resultdef,left.location.register,right.location.register)); + + tmpreg:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef); + hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,llvmbool1type,resultdef,location.register,tmpreg); + location.register:=tmpreg; end; @@ -214,6 +222,7 @@ implementation procedure tllvmaddnode.second_addfloat; var + tmpreg: tregister; op : tllvmop; llvmfpcmp : tllvmfpcmp; size : tdef; @@ -279,7 +288,7 @@ implementation else begin location_reset(location,LOC_REGISTER,OS_8); - location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef); + location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,llvmbool1type); end; { see comment in thlcgllvm.a_loadfpu_ref_reg } @@ -297,7 +306,10 @@ implementation else begin current_asmdata.CurrAsmList.concat(taillvm.op_reg_fpcond_size_reg_reg(op, - location.register,llvmfpcmp,size,left.location.register,right.location.register)) + location.register,llvmfpcmp,size,left.location.register,right.location.register)); + tmpreg:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef); + hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,llvmbool1type,resultdef,location.register,tmpreg); + location.register:=tmpreg; end; end; diff --git a/compiler/llvm/nllvmcnv.pas b/compiler/llvm/nllvmcnv.pas index 7db9df8aa0..e696f9ee09 100644 --- a/compiler/llvm/nllvmcnv.pas +++ b/compiler/llvm/nllvmcnv.pas @@ -50,7 +50,7 @@ interface { procedure second_cord_to_pointer;override; } procedure second_proc_to_procvar;override; procedure second_nil_to_methodprocvar; override; - procedure second_bool_to_int;override; + { procedure second_bool_to_int;override; } procedure second_int_to_bool;override; { procedure second_load_smallset;override; } { procedure second_ansistring_to_pchar;override; } @@ -202,39 +202,6 @@ procedure tllvmtypeconvnode.second_nil_to_methodprocvar; end; -procedure tllvmtypeconvnode.second_bool_to_int; - var - pdef: tdef; - hreg: tregister; - begin - inherited; - { all boolean/integer of the same size are represented using the same type - by FPC in LLVM, except for Pascal booleans, which are i1 -> convert - the type if necessary. This never has to be done for registers on the - assignment side, because we make everything that's explicitly typecasted - on the assignment side non regable for llvm } - if is_pasbool(left.resultdef) and - (nf_explicit in flags) and - not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and - (resultdef.size=1) then - case location.loc of - LOC_REFERENCE,LOC_CREFERENCE: - begin - pdef:=cpointerdef.getreusable(resultdef); - hreg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,pdef); - hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.resultdef,pdef,location.reference,hreg); - hlcg.reference_reset_base(location.reference,pdef,hreg,0,location.reference.alignment); - end; - LOC_REGISTER,LOC_CREGISTER: - begin - hreg:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef); - hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,left.resultdef,resultdef,location.register,hreg); - location.register:=hreg; - end; - end; - end; - - procedure tllvmtypeconvnode.second_int_to_bool; var truelabel, diff --git a/compiler/llvm/nllvmmat.pas b/compiler/llvm/nllvmmat.pas index 24c2a98948..031100feae 100644 --- a/compiler/llvm/nllvmmat.pas +++ b/compiler/llvm/nllvmmat.pas @@ -96,16 +96,16 @@ procedure tllvmmoddivnode.pass_generate_code; begin current_asmdata.getjumplabel(hl); location_reset(ovloc,LOC_REGISTER,OS_8); - ovloc.register:=hlcg.getintregister(current_asmdata.CurrAsmList,pasbool8type); + ovloc.register:=hlcg.getintregister(current_asmdata.CurrAsmList,llvmbool1type); if right.nodetype=ordconstn then current_asmdata.CurrAsmList.concat(taillvm.op_reg_cond_size_reg_const(la_icmp,ovloc.register,OC_EQ,resultdef,left.location.register,low(int64))) else begin - tmpovreg1:=hlcg.getintregister(current_asmdata.CurrAsmList,pasbool8type); - tmpovreg2:=hlcg.getintregister(current_asmdata.CurrAsmList,pasbool8type); + tmpovreg1:=hlcg.getintregister(current_asmdata.CurrAsmList,llvmbool1type); + tmpovreg2:=hlcg.getintregister(current_asmdata.CurrAsmList,llvmbool1type); current_asmdata.CurrAsmList.concat(taillvm.op_reg_cond_size_reg_const(la_icmp,tmpovreg1,OC_EQ,resultdef,left.location.register,low(int64))); current_asmdata.CurrAsmList.concat(taillvm.op_reg_cond_size_reg_const(la_icmp,tmpovreg2,OC_EQ,resultdef,right.location.register,-1)); - hlcg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,pasbool8type,tmpovreg1,tmpovreg2,ovloc.register); + hlcg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,llvmbool1type,tmpovreg1,tmpovreg2,ovloc.register); end; hlcg.g_overflowCheck_loc(current_asmdata.CurrAsmList,location,resultdef,ovloc); end; diff --git a/compiler/llvm/nllvmutil.pas b/compiler/llvm/nllvmutil.pas index f33b2b38e1..fc8d204b4a 100644 --- a/compiler/llvm/nllvmutil.pas +++ b/compiler/llvm/nllvmutil.pas @@ -45,13 +45,16 @@ implementation uses verbose,cutils,globals,fmodule,systems, aasmbase,aasmtai,cpubase,llvmbase,aasmllvm, + aasmcnst, symbase,symtable,defutil, llvmtype; class procedure tllvmnodeutils.insertbsssym(list: tasmlist; sym: tstaticvarsym; size: asizeint; varalign: shortint); var - asmsym: tasmsymbol; + asmsym, + symind: tasmsymbol; field1, field2: tsym; + tcb: ttai_typedconstbuilder; begin if sym.globalasmsym then asmsym:=current_asmdata.DefineAsmSymbol(sym.mangledname,AB_GLOBAL,AT_DATA) @@ -65,6 +68,15 @@ implementation list.concat(taillvmdecl.createdef(asmsym, get_threadvar_record(sym.vardef,field1,field2), nil,sec_data,varalign)); + symind:=current_asmdata.DefineAsmSymbol(sym.mangledname,AB_INDIRECT,AT_DATA); + tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable,tcalo_new_section]); + tcb.emit_tai(Tai_const.Create_sym_offset(asmsym,0),cpointerdef.getreusable(sym.vardef)); + list.concatlist(tcb.get_final_asmlist( + symind,cpointerdef.getreusable(sym.vardef), + sec_rodata, + lower(sym.mangledname), + const_align(sym.vardef.alignment))); + tcb.free; end; |