Quellcode durchsuchen

+ 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 -

Jonas Maebe vor 11 Jahren
Ursprung
Commit
7ebb1b813f

+ 1 - 1
compiler/assemble.pas

@@ -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;

+ 13 - 3
compiler/llvm/aasmllvm.pas

@@ -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;
 

+ 117 - 3
compiler/llvm/agllvm.pas

@@ -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

+ 2 - 2
compiler/llvm/hlcgllvm.pas

@@ -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;
 
 

+ 1 - 1
compiler/llvm/nllvmutil.pas

@@ -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;