Пример #1
0
// 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;
}
Пример #2
0
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;
}