+ LLVM 3.7 support in the LLVM IR writer

git-svn-id: trunk@34550 -
This commit is contained in:
Jonas Maebe 2016-09-20 21:44:06 +00:00
parent eb9d4b71b3
commit 999cb7de6d
3 changed files with 98 additions and 9 deletions

View File

@ -200,7 +200,7 @@ implementation
uses
cutils, strings,
symconst,
aasmcpu;
aasmcnst,aasmcpu;
{ taillvmprocdecl }
@ -553,8 +553,7 @@ uses
internalerror(2013110104);
end;
end;
la_load,
la_getelementptr:
la_load:
begin
{ dst = load ptrdef srcref }
case opnr of
@ -564,6 +563,36 @@ uses
internalerror(2013110105);
end;
end;
la_getelementptr:
begin
{ dst = getelementptr ref ... }
case opnr of
0:
begin
case oper[1]^.typ of
top_def:
result:=oper[1]^.def;
top_tai:
begin
case oper[1]^.ai.typ of
ait_llvmins:
result:=taillvm(oper[1]^.ai).spilling_get_reg_type(0);
ait_typedconst:
result:=tai_abstracttypedconst(oper[1]^.ai).def
else
internalerror(2016071202);
end
end
else
internalerror(2016071201);
end
end;
2:
result:=oper[1]^.def;
else
internalerror(2013110105);
end;
end;
la_fence,
la_cmpxchg,
la_atomicrmw:

View File

@ -390,9 +390,11 @@ implementation
procedure TLLVMInstrWriter.WriteInstruction(hp: tai);
var
op: tllvmop;
tmpstr,
sep: TSymStr;
i, opstart: byte;
nested: boolean;
opdone,
done: boolean;
begin
op:=taillvm(hp).llvmopcode;
@ -403,6 +405,7 @@ implementation
if owner.fdecllevel=0 then
owner.writer.AsmWrite(#9);
sep:=' ';
opdone:=false;
done:=false;
opstart:=0;
nested:=false;
@ -414,6 +417,41 @@ implementation
owner.writer.AsmWrite(llvmencodetypedecl(taillvm(hp).oper[0]^.def));
done:=true;
end;
la_load,
la_getelementptr:
begin
if (taillvm(hp).oper[0]^.typ<>top_reg) or
(taillvm(hp).oper[0]^.reg<>NR_NO) then
owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,false)+' = ')
else
nested:=true;
opstart:=1;
if llvmflag_load_getelptr_type in llvmversion_properties[current_settings.llvmversion] then
begin
owner.writer.AsmWrite(llvm_op2str[op]);
opdone:=true;
if nested then
owner.writer.AsmWrite(' (')
else
owner.writer.AsmWrite(' ');
{ can't just dereference the type, because it may be an
implicit pointer type such as a class -> resort to string
manipulation... Not very clean :( }
tmpstr:=llvmencodetypename(taillvm(hp).spilling_get_reg_type(0));
if op=la_getelementptr then
begin
if tmpstr[length(tmpstr)]<>'*' then
begin
writeln(tmpstr);
internalerror(2016071101);
end
else
setlength(tmpstr,length(tmpstr)-1);
end;
owner.writer.AsmWrite(tmpstr);
owner.writer.AsmWrite(',');
end
end;
la_ret, la_br, la_switch, la_indirectbr,
la_invoke, la_resume,
la_unreachable,
@ -428,8 +466,22 @@ implementation
begin
if taillvm(hp).oper[1]^.reg<>NR_NO then
owner.writer.AsmWrite(getregisterstring(taillvm(hp).oper[1]^.reg)+' = ');
sep:=' ';
opstart:=2;
if llvmflag_call_no_ptr in llvmversion_properties[current_settings.llvmversion] then
begin
owner.writer.AsmWrite(llvm_op2str[op]);
opdone:=true;
tmpstr:=llvmencodetypename(taillvm(hp).oper[2]^.def);
if tmpstr[length(tmpstr)]<>'*' then
begin
writeln(tmpstr);
internalerror(2016071102);
end
else
setlength(tmpstr,length(tmpstr)-1);
owner.writer.AsmWrite(tmpstr);
opstart:=3;
end;
end;
la_blockaddress:
begin
@ -495,9 +547,12 @@ implementation
{ process operands }
if not done then
begin
owner.writer.AsmWrite(llvm_op2str[op]);
if nested then
owner.writer.AsmWrite(' (');
if not opdone then
begin
owner.writer.AsmWrite(llvm_op2str[op]);
if nested then
owner.writer.AsmWrite(' (');
end;
if taillvm(hp).ops<>0 then
begin
for i:=opstart to taillvm(hp).ops-1 do

View File

@ -33,6 +33,7 @@ Type
llvmver_3_6_0,
llvmver_3_6_1,
llvmver_3_6_2,
llvmver_3_7_0,
{ Xcode versions use snapshots of LLVM and don't correspond to released
versions of llvm (they don't ship with the llvm utilities either, but
they do come with Clang, which can also be used to some extent instead
@ -43,7 +44,9 @@ Type
type
tllvmversionflag = (
llvmflag_metadata_keyword, { use "metadata" keyword (others leave it away, except when metadata is an argument to call instructions) }
llvmflag_linker_private { have linker_private linkage type (later versions use global in combination with hidden visibility) }
llvmflag_linker_private, { have linker_private linkage type (later versions use global in combination with hidden visibility) }
llvmflag_load_getelptr_type, { the return type of loads and the base type of getelementptr must be specified }
llvmflag_call_no_ptr { with direct calls, the function type is not a function pointer }
);
tllvmversionflags = set of tllvmversionflag;
@ -59,7 +62,8 @@ Const
'LLVM-3.6.0',
'LLVM-3.6.1',
'LLVM-3.6.2',
'LLVM-Xcode-6.4'
'LLVM-3.7.0',
'LLVM-Xcode-6.4' { somewhere around LLVM 3.6.0 }
);
llvmversion_properties: array[tllvmversion] of tllvmversionflags =
@ -74,6 +78,7 @@ Const
{ llvmver_3_6_0 } [],
{ llvmver_3_6_1 } [],
{ llvmver_3_6_2 } [],
{ llvmver_3_7_0 } [llvmflag_load_getelptr_type,llvmflag_call_no_ptr],
{ llvmver_xc_6_4 } [llvmflag_metadata_keyword]
);