2
0
Эх сурвалжийг харах

* when generating code for a pure assembler routine with LLVM, instantiate
a code and temp generator for the architectural target instead of for LLVM
* write the code for pure assembler routines using a GNU-style external
assembler writer for the target, with a decorator to wrap it in
LLVM module-level assembly statements

git-svn-id: trunk@31633 -

Jonas Maebe 10 жил өмнө
parent
commit
839482751d

+ 1 - 1
compiler/assemble.pas

@@ -2165,7 +2165,7 @@ Implementation
       end;
 
 
-    function GetExternalAssemblerWithAsmInfoWriter(info: pasminfo; wr: TExternalAssemblerOutputFile): TExternalAssembler;
+    function GetExternalGnuAssemblerWithAsmInfoWriter(info: pasminfo; wr: TExternalAssemblerOutputFile): TExternalAssembler;
       var
         asmkind: tasm;
       begin

+ 21 - 3
compiler/llvm/agllvm.pas

@@ -1115,14 +1115,32 @@ implementation
       var
         hal : tasmlisttype;
         i: longint;
+        a: TExternalAssembler;
+        decorator: TLLVMModuleInlineAssemblyDecorator;
       begin
         WriteExtraHeader;
 
         for hal:=low(TasmlistType) to high(TasmlistType) do
           begin
-            writer.AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
-            writetree(current_asmdata.asmlists[hal]);
-            writer.AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
+            if not assigned(current_asmdata.asmlists[hal]) or
+               current_asmdata.asmlists[hal].Empty then
+              continue;
+            writer.AsmWriteLn(asminfo^.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
+            if hal<>al_pure_assembler then
+              writetree(current_asmdata.asmlists[hal])
+            else
+              begin
+                { write routines using the target-specific external assembler
+                  writer, filtered using the LLVM module-level assembly
+                  decorator }
+                decorator:=TLLVMModuleInlineAssemblyDecorator.Create;
+                writer.decorator:=decorator;
+                a:=GetExternalGnuAssemblerWithAsmInfoWriter(asminfo,writer);
+                a.WriteTree(current_asmdata.asmlists[hal]);
+                writer.decorator:=nil;
+                decorator.free;
+              end;
+            writer.AsmWriteLn(asminfo^.comment+'End asmlist '+AsmlistTypeStr[hal]);
           end;
 
         writer.AsmLn;

+ 15 - 3
compiler/llvm/hlcgllvm.pas

@@ -151,7 +151,8 @@ implementation
     aasmllvm,llvmbase,tgllvm,
     symtable,symllvm,
     paramgr,llvmpara,
-    procinfo,cpuinfo,cgobj,cgllvm,cghlcpu;
+    procinfo,cpuinfo,cgobj,cgllvm,cghlcpu,
+    cgcpu,hlcgcpu;
 
   const
     topcg2llvmop: array[topcg] of tllvmop =
@@ -1719,8 +1720,19 @@ implementation
 
   procedure create_hlcodegen;
     begin
-      hlcg:=thlcgllvm.create;
-      cgllvm.create_codegen
+      if not assigned(current_procinfo) or
+         not(po_assembler in current_procinfo.procdef.procoptions) then
+        begin
+          tgobjclass:=ttgllvm;
+          hlcg:=thlcgllvm.create;
+          cgllvm.create_codegen
+        end
+      else
+        begin
+          tgobjclass:=orgtgclass;
+          hlcgcpu.create_hlcodegen;
+          { todo: handle/remove chlcgobj }
+        end;
     end;
 
 begin

+ 5 - 0
compiler/llvm/tgllvm.pas

@@ -68,6 +68,10 @@ unit tgllvm;
         procedure ungetiftemp(list: TAsmList; const ref: treference); override;
       end;
 
+
+  var
+    orgtgclass: ttgobjclass;
+
 implementation
 
     uses
@@ -166,5 +170,6 @@ implementation
       end;
 
 begin
+  orgtgclass:=tgobjclass;
   tgobjclass:=ttgllvm;
 end.