// stolen from LDC and modified // based on llc (from LLVM) code, University of Illinois Open Source License int LLVMWriteNativeAsmToFile(LLVMTargetMachineRef TMRef, LLVMModuleRef MRef, const char* filename, int opt, int pic) { TargetMachine* TM = unwrap(TMRef); Module* M = unwrap(MRef); TargetMachine::setRelocationModel(pic ? Reloc::PIC_ : Reloc::Default); #if 0 printf("trying to write native asm for target: %s\n", TM->getTarget().getName()); #endif std::string Err; // Build up all of the passes that we want to do to the module. FunctionPassManager Passes(M); // Add TargetData if (const TargetData *TD = TM->getTargetData()) Passes.add(new TargetData(*TD)); else assert(0); // Passes.add(new TargetData(M)); // debug info doesn't work properly with OptLevel != None! CodeGenOpt::Level OLvl = CodeGenOpt::Default; if (opt) OLvl = CodeGenOpt::Aggressive; else OLvl = CodeGenOpt::None; // open output file raw_fd_ostream out(filename, Err, raw_fd_ostream::F_Binary); assert(Err.empty()); // add codegen passes formatted_raw_ostream fout(out); bool error = TM->addPassesToEmitFile(Passes, fout, TargetMachine::CGFT_AssemblyFile, OLvl); assert(error == false); // Target does not support generation of this file type! Passes.doInitialization(); // Run our queue of passes all at once now, efficiently. for (llvm::Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (!I->isDeclaration()) Passes.run(*I); Passes.doFinalization(); fout.flush(); return 1; }
int LLVMTargetMachineAssembleToOutputStream(LLVMTargetMachineRef TM, LLVMMemoryBufferRef Mem, void *JOStream, LLVMBool RelaxAll, LLVMBool NoExecStack, char **ErrorMessage) { *ErrorMessage = NULL; #if !defined(WIN32) locale_t loc = newlocale(LC_ALL_MASK, "C", 0); locale_t oldLoc = uselocale(loc); #endif TargetMachine *TheTargetMachine = unwrap(TM); const Target *TheTarget = &(TheTargetMachine->getTarget()); std::string TripleName = TheTargetMachine->getTargetTriple().str(); std::string MCPU = TheTargetMachine->getTargetCPU().str(); std::string FeaturesStr = TheTargetMachine->getTargetFeatureString().str(); Reloc::Model RelocModel = TheTargetMachine->getRelocationModel(); CodeModel::Model CMModel = TheTargetMachine->getCodeModel(); std::unique_ptr<MemoryBuffer> Buffer(unwrap(Mem)); std::string DiagStr; raw_string_ostream DiagStream(DiagStr); SourceMgr SrcMgr; SrcMgr.setDiagHandler(assembleDiagHandler, &DiagStream); // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); // Record the location of the include directories so that the lexer can find // it later. // SrcMgr.setIncludeDirs(IncludeDirs); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr); MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx); std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); raw_java_ostream& Out = *((raw_java_ostream*) JOStream); std::unique_ptr<MCStreamer> Str; MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB, Out, CE, *STI, RelaxAll != 0)); if (NoExecStack != 0) Str->InitSections(true); MCTargetOptions MCOptions; std::unique_ptr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, *Str, *MAI)); std::unique_ptr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); if (!TAP) { *ErrorMessage = strdup("this target does not support assembly parsing"); goto done; } Parser->setTargetParser(*TAP.get()); if (Parser->Run(false)) { *ErrorMessage = strdup(DiagStream.str().c_str()); goto done; } Out.flush(); done: #if !defined(WIN32) uselocale(oldLoc); freelocale(loc); #endif return *ErrorMessage ? 1 : 0; }