summaryrefslogtreecommitdiff
path: root/compiler/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/llvm')
-rw-r--r--compiler/llvm/aasmllvm.pas12
-rw-r--r--compiler/llvm/agllvm.pas19
-rw-r--r--compiler/llvm/hlcgllvm.pas19
-rw-r--r--compiler/llvm/llvmdef.pas24
-rw-r--r--compiler/llvm/nllvmadd.pas20
-rw-r--r--compiler/llvm/nllvmcnv.pas35
-rw-r--r--compiler/llvm/nllvmmat.pas8
-rw-r--r--compiler/llvm/nllvmutil.pas14
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;