mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 23:19:29 +02:00
+ basic support infrastructure in the llvm assembler writer to write out
typed constant data o llvm declarations now get an extra "initdata" list that contains the typed constant data associated with this declaration (if any) git-svn-id: branches/hlcgllvm@28111 -
This commit is contained in:
parent
1fdb16b615
commit
7ebb1b813f
@ -120,7 +120,7 @@ interface
|
||||
Procedure AsmWriteLn(const s:ansistring);
|
||||
|
||||
{# Write a new line to the assembler file }
|
||||
Procedure AsmLn;
|
||||
Procedure AsmLn; virtual;
|
||||
|
||||
procedure AsmCreate(Aplace:tcutplace);
|
||||
procedure AsmClose;
|
||||
|
@ -141,9 +141,12 @@ interface
|
||||
{ declarations/definitions of symbols (procedures, variables), both defined
|
||||
here and external }
|
||||
taillvmdecl = class(tai)
|
||||
{ initialisation data, if any }
|
||||
initdata: tasmlist;
|
||||
namesym: tasmsymbol;
|
||||
def: tdef;
|
||||
constructor create(_namesym: tasmsymbol; _def: tdef);
|
||||
constructor create(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist);
|
||||
destructor destroy; override;
|
||||
end;
|
||||
|
||||
{ parameter to an llvm call instruction }
|
||||
@ -168,12 +171,19 @@ uses
|
||||
|
||||
{ taillvmprocdecl }
|
||||
|
||||
constructor taillvmdecl.create(_namesym: tasmsymbol; _def: tdef);
|
||||
constructor taillvmdecl.create(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist);
|
||||
begin
|
||||
inherited create;
|
||||
typ:=ait_llvmdecl;
|
||||
namesym:=_namesym;
|
||||
def:=_def;
|
||||
initdata:=_initdata;
|
||||
end;
|
||||
|
||||
destructor taillvmdecl.destroy;
|
||||
begin
|
||||
initdata.free;
|
||||
inherited destroy;
|
||||
end;
|
||||
|
||||
{ taillvmalias }
|
||||
@ -209,7 +219,7 @@ uses
|
||||
internalerror(2014020701);
|
||||
def:=tpointerdef(def).pointeddef;
|
||||
end;
|
||||
current_asmdata.AsmLists[al_imports].concat(taillvmdecl.create(ref.symbol,def));
|
||||
current_asmdata.AsmLists[al_imports].concat(taillvmdecl.create(ref.symbol,def,nil));
|
||||
ref.symbol.declared:=true;
|
||||
end;
|
||||
|
||||
|
@ -36,6 +36,8 @@ interface
|
||||
|
||||
TLLVMAssember=class(texternalassembler)
|
||||
protected
|
||||
fdecllevel: longint;
|
||||
|
||||
procedure WriteExtraHeader;virtual;
|
||||
procedure WriteExtraFooter;virtual;
|
||||
procedure WriteInstruction(hp: tai);
|
||||
@ -48,6 +50,7 @@ interface
|
||||
procedure WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var hp: tai);
|
||||
public
|
||||
constructor create(smart: boolean); override;
|
||||
procedure AsmLn; override;
|
||||
function MakeCmdLine: TCmdStr; override;
|
||||
procedure WriteTree(p:TAsmList);override;
|
||||
procedure WriteAsmList;override;
|
||||
@ -576,6 +579,86 @@ implementation
|
||||
|
||||
|
||||
procedure TLLVMAssember.WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var hp: tai);
|
||||
|
||||
procedure WriteTypedConstData(hp: tai_abstracttypedconst);
|
||||
var
|
||||
p: tai_abstracttypedconst;
|
||||
pval: tai;
|
||||
defstr: TSymStr;
|
||||
first, gotstring: boolean;
|
||||
begin
|
||||
{ special case: tck_simple_procvar2proc; this means that we want the
|
||||
procdef of the procvardef, rather than both the procdef and the
|
||||
method/nestedfp/... pointers }
|
||||
if hp.adetyp<>tck_simple_procvar2proc then
|
||||
defstr:=llvmencodetype(hp.def)
|
||||
else
|
||||
defstr:=llvmencodeproctype(tabstractprocdef(hp.def),'',lpd_procvar);
|
||||
{ write the struct, array or simple type }
|
||||
case hp.adetyp of
|
||||
tck_record:
|
||||
begin
|
||||
AsmWrite(defstr);
|
||||
AsmWrite(' ');
|
||||
AsmWrite('<{');
|
||||
first:=true;
|
||||
for p in tai_aggregatetypedconst(hp) do
|
||||
begin
|
||||
if not first then
|
||||
AsmWrite(', ')
|
||||
else
|
||||
first:=false;
|
||||
WriteTypedConstData(p);
|
||||
end;
|
||||
AsmWrite('}>');
|
||||
end;
|
||||
tck_array:
|
||||
begin
|
||||
AsmWrite(defstr);
|
||||
first:=true;
|
||||
gotstring:=false;
|
||||
for p in tai_aggregatetypedconst(hp) do
|
||||
begin
|
||||
if not first then
|
||||
AsmWrite(',')
|
||||
else
|
||||
begin
|
||||
AsmWrite(' ');
|
||||
if (tai_abstracttypedconst(p).adetyp=tck_simple) and
|
||||
(tai_simpletypedconst(p).val.typ=ait_string) then
|
||||
begin
|
||||
gotstring:=true;
|
||||
end
|
||||
else
|
||||
begin
|
||||
AsmWrite('[');
|
||||
end;
|
||||
first:=false;
|
||||
end;
|
||||
{ cannot concat strings and other things }
|
||||
if gotstring and
|
||||
((tai_abstracttypedconst(p).adetyp<>tck_simple) or
|
||||
(tai_simpletypedconst(p).val.typ<>ait_string)) then
|
||||
internalerror(2014062701);
|
||||
WriteTypedConstData(p);
|
||||
end;
|
||||
if not gotstring then
|
||||
AsmWrite(']');
|
||||
end;
|
||||
tck_simple,
|
||||
tck_simple_procvar2proc:
|
||||
begin
|
||||
pval:=tai_simpletypedconst(hp).val;
|
||||
if pval.typ<>ait_string then
|
||||
begin
|
||||
AsmWrite(defstr);
|
||||
AsmWrite(' ');
|
||||
end;
|
||||
WriteTai(replaceforbidden,do_line,InlineLevel,pval);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
hp2: tai;
|
||||
s: string;
|
||||
@ -713,9 +796,28 @@ implementation
|
||||
else
|
||||
internalerror(2014020104);
|
||||
end;
|
||||
asmwrite(llvmencodetype(taillvmdecl(hp).def));
|
||||
if not(taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL]) then
|
||||
asmwrite(' zeroinitializer');
|
||||
if not assigned(taillvmdecl(hp).initdata) then
|
||||
begin
|
||||
asmwrite(llvmencodetype(taillvmdecl(hp).def));
|
||||
if not(taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL]) then
|
||||
asmwrite(' zeroinitializer');
|
||||
end
|
||||
else
|
||||
begin
|
||||
inc(fdecllevel);
|
||||
{ can't have an external symbol with initialisation data }
|
||||
if taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL] then
|
||||
internalerror(2014052905);
|
||||
{ bitcast initialisation data to the type of the constant }
|
||||
{ write initialisation data }
|
||||
hp2:=tai(taillvmdecl(hp).initdata.first);
|
||||
while assigned(hp2) do
|
||||
begin
|
||||
WriteTai(replaceforbidden,do_line,InlineLevel,hp2);
|
||||
hp2:=tai(hp2.next);
|
||||
end;
|
||||
dec(fdecllevel);
|
||||
end;
|
||||
{ alignment }
|
||||
asmwrite(', align ');
|
||||
asmwriteln(tostr(taillvmdecl(hp).def.alignment));
|
||||
@ -827,6 +929,10 @@ implementation
|
||||
std_regname(tai_varloc(hp).newlocation)));
|
||||
AsmLn;
|
||||
end;
|
||||
ait_typedconst:
|
||||
begin
|
||||
WriteTypedConstData(tai_abstracttypedconst(hp));
|
||||
end
|
||||
else
|
||||
internalerror(2006012201);
|
||||
end;
|
||||
@ -840,6 +946,14 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure TLLVMAssember.AsmLn;
|
||||
begin
|
||||
{ don't write newlines in the middle of declarations }
|
||||
if fdecllevel=0 then
|
||||
inherited AsmLn;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure TLLVMAssember.WriteDirectiveName(dir: TAsmDirective);
|
||||
begin
|
||||
|
@ -307,7 +307,7 @@ implementation
|
||||
begin
|
||||
asmsym:=current_asmdata.RefAsmSymbol(pd.mangledname);
|
||||
if not asmsym.declared then
|
||||
current_asmdata.AsmLists[al_imports].Concat(taillvmdecl.create(asmsym,pd));
|
||||
current_asmdata.AsmLists[al_imports].Concat(taillvmdecl.create(asmsym,pd,nil));
|
||||
end;
|
||||
callparas:=tfplist.Create;
|
||||
for i:=0 to high(paras) do
|
||||
@ -937,7 +937,7 @@ implementation
|
||||
list.concat(taillvmalias.create(asmsym,item.str,current_procinfo.procdef,llv_default,lll_default));
|
||||
item:=TCmdStrListItem(item.next);
|
||||
end;
|
||||
list.concat(taillvmdecl.create(asmsym,current_procinfo.procdef));
|
||||
list.concat(taillvmdecl.create(asmsym,current_procinfo.procdef,nil));
|
||||
end;
|
||||
|
||||
|
||||
|
@ -62,7 +62,7 @@ implementation
|
||||
asmsym:=current_asmdata.DefineAsmSymbol(sym.mangledname,AB_GLOBAL,AT_DATA)
|
||||
else
|
||||
asmsym:=current_asmdata.DefineAsmSymbol(sym.mangledname,AB_LOCAL,AT_DATA);
|
||||
list.concat(taillvmdecl.Create(asmsym,sym.vardef));
|
||||
list.concat(taillvmdecl.Create(asmsym,sym.vardef,nil));
|
||||
end;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user