changeset 673:37a7688a7494

Add basics for direct assembly output.
author Christian Kamm <kamm incasoftware de>
date Sat, 11 Oct 2008 11:07:53 +0200
parents 22b6947fd30c
children db6a7e574cbd
files gen/toobj.cpp premake.lua
diffstat 2 files changed, 68 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/gen/toobj.cpp	Wed Oct 08 22:43:38 2008 +0200
+++ b/gen/toobj.cpp	Sat Oct 11 11:07:53 2008 +0200
@@ -14,9 +14,14 @@
 #include "gen/llvm.h"
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Target/SubtargetFeature.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/PassManager.h"
 #include "llvm/System/Path.h"
+#include "llvm/Support/raw_ostream.h"
 
 #include "mars.h"
 #include "module.h"
@@ -190,6 +195,68 @@
         ir.module->print(aos, NULL);
     }
 
+
+    //TODO: Move all of this into a helper function?
+    if(false)
+    {
+        using namespace llvm;
+
+    //FIXME: Proper out file name.
+        std::string Err;
+        raw_fd_ostream Out("test.s", Err);
+        if(!Err.empty()) {}
+
+        const TargetMachineRegistry::entry* MArch;
+        MArch = TargetMachineRegistry::getClosestStaticTargetForModule(*ir.module, Err);
+        if (MArch == 0) {
+            error("error auto-selecting target for module '%s'", Err.c_str());
+            fatal();
+        }
+ 
+        SubtargetFeatures Features;
+    //TODO: Features?
+    //    Features.setCPU(MCPU);
+    //    for (unsigned i = 0; i != MAttrs.size(); ++i)
+    //      Features.AddFeature(MAttrs[i]);
+
+    //TODO: Set PIC if shared (or just do it always?)
+    //  TargetMachine::setRelocationModel(...);
+
+        std::auto_ptr<TargetMachine> target(MArch->CtorFn(*ir.module, Features.getString()));
+        assert(target.get() && "Could not allocate target machine!");
+        TargetMachine &Target = *target.get();
+
+        // Build up all of the passes that we want to do to the module.
+        ExistingModuleProvider Provider(ir.module);
+        FunctionPassManager Passes(&Provider);
+    //FIXME does this TargetData match gTargetData?
+        Passes.add(new TargetData(*Target.getTargetData()));
+
+        // Ask the target to add backend passes as necessary.
+        MachineCodeEmitter *MCE = 0;
+
+    //TODO: May want to switch it on for -O0?
+        bool Fast = false;
+        FileModel::Model mod = Target.addPassesToEmitFile(Passes, Out, TargetMachine::AssemblyFile, Fast);
+        assert(mod == FileModel::AsmFile);
+
+        bool err = Target.addPassesToEmitFileFinish(Passes, MCE, Fast);
+        assert(!err);
+
+        Passes.doInitialization();
+
+        // Run our queue of passes all at once now, efficiently.
+        for (llvm::Module::iterator I = ir.module->begin(), E = ir.module->end(); I != E; ++I)
+        if (!I->isDeclaration())
+            Passes.run(*I);
+
+        Passes.doFinalization();
+
+        // release module from module provider so we can delete it ourselves
+        llvm::Module* rmod = Provider.releaseModule(&Err);
+        assert(rmod);
+    }
+
     delete ir.module;
     gTargetData = 0;
     gIR = NULL;
--- a/premake.lua	Wed Oct 08 22:43:38 2008 +0200
+++ b/premake.lua	Sat Oct 11 11:07:53 2008 +0200
@@ -55,7 +55,7 @@
 package.buildoptions = { "-x c++", "`llvm-config --cxxflags`" }
 package.linkoptions = {
     -- long but it's faster than just 'all'
-    "`llvm-config --libs bitwriter linker ipo instrumentation`",
+    "`llvm-config --libs bitwriter linker ipo instrumentation backend`",
     "`llvm-config --ldflags`",
 }
 package.defines = {