diff options
Diffstat (limited to 'tools/llvm-mc/llvm-mc.cpp')
| -rw-r--r-- | tools/llvm-mc/llvm-mc.cpp | 193 | 
1 files changed, 117 insertions, 76 deletions
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index aef0a3dffa45..2c22bedf1c2d 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -23,6 +23,10 @@  #include "llvm/Target/TargetAsmParser.h"  #include "llvm/Target/TargetData.h"  #include "llvm/Target/TargetRegistry.h" +#include "llvm/Target/SubtargetFeature.h" // FIXME. +#include "llvm/Target/TargetAsmInfo.h"  // FIXME. +#include "llvm/Target/TargetLowering.h"  // FIXME. +#include "llvm/Target/TargetLoweringObjectFile.h"  // FIXME.  #include "llvm/Target/TargetMachine.h"  // FIXME.  #include "llvm/Target/TargetSelect.h"  #include "llvm/ADT/OwningPtr.h" @@ -33,9 +37,10 @@  #include "llvm/Support/MemoryBuffer.h"  #include "llvm/Support/PrettyStackTrace.h"  #include "llvm/Support/SourceMgr.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Host.h" -#include "llvm/System/Signals.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/system_error.h"  #include "Disassembler.h"  using namespace llvm; @@ -64,6 +69,9 @@ static cl::opt<bool>  RelaxAll("mc-relax-all", cl::desc("Relax all fixups"));  static cl::opt<bool> +NoExecStack("mc-no-exec-stack", cl::desc("File doesn't need an exec stack")); + +static cl::opt<bool>  EnableLogging("enable-api-logging", cl::desc("Enable MC API logging"));  enum OutputFileType { @@ -95,6 +103,12 @@ static cl::opt<std::string>  TripleName("triple", cl::desc("Target triple to assemble for, "                                "see -version for available targets")); +static cl::opt<std::string> +MCPU("mcpu", +     cl::desc("Target a specific cpu type (-mcpu=help for details)"), +     cl::value_desc("cpu-name"), +     cl::init("")); +  static cl::opt<bool>  NoInitialTextSection("n", cl::desc(                     "Don't assume assembly file starts in the text section")); @@ -157,17 +171,12 @@ static tool_output_file *GetOutputStream() {  }  static int AsLexInput(const char *ProgName) { -  std::string ErrorMessage; -  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, -                                                      &ErrorMessage); -  if (Buffer == 0) { -    errs() << ProgName << ": "; -    if (ErrorMessage.size()) -      errs() << ErrorMessage << "\n"; -    else -      errs() << "input file didn't read correctly.\n"; +  OwningPtr<MemoryBuffer> BufferPtr; +  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) { +    errs() << ProgName << ": " << ec.message() << '\n';      return 1;    } +  MemoryBuffer *Buffer = BufferPtr.take();    SourceMgr SrcMgr; @@ -194,7 +203,9 @@ static int AsLexInput(const char *ProgName) {    bool Error = false;    while (Lexer.Lex().isNot(AsmToken::Eof)) { -    switch (Lexer.getKind()) { +    AsmToken Tok = Lexer.getTok(); + +    switch (Tok.getKind()) {      default:        SrcMgr.PrintMessage(Lexer.getLoc(), "unknown token", "warning");        Error = true; @@ -203,45 +214,63 @@ static int AsLexInput(const char *ProgName) {        Error = true; // error already printed.        break;      case AsmToken::Identifier: -      Out->os() << "identifier: " << Lexer.getTok().getString() << '\n'; -      break; -    case AsmToken::String: -      Out->os() << "string: " << Lexer.getTok().getString() << '\n'; +      Out->os() << "identifier: " << Lexer.getTok().getString();        break;      case AsmToken::Integer: -      Out->os() << "int: " << Lexer.getTok().getString() << '\n'; +      Out->os() << "int: " << Lexer.getTok().getString(); +      break; +    case AsmToken::Real: +      Out->os() << "real: " << Lexer.getTok().getString(); +      break; +    case AsmToken::Register: +      Out->os() << "register: " << Lexer.getTok().getRegVal(); +      break; +    case AsmToken::String: +      Out->os() << "string: " << Lexer.getTok().getString();        break; -    case AsmToken::Amp:            Out->os() << "Amp\n"; break; -    case AsmToken::AmpAmp:         Out->os() << "AmpAmp\n"; break; -    case AsmToken::Caret:          Out->os() << "Caret\n"; break; -    case AsmToken::Colon:          Out->os() << "Colon\n"; break; -    case AsmToken::Comma:          Out->os() << "Comma\n"; break; -    case AsmToken::Dollar:         Out->os() << "Dollar\n"; break; -    case AsmToken::EndOfStatement: Out->os() << "EndOfStatement\n"; break; -    case AsmToken::Eof:            Out->os() << "Eof\n"; break; -    case AsmToken::Equal:          Out->os() << "Equal\n"; break; -    case AsmToken::EqualEqual:     Out->os() << "EqualEqual\n"; break; -    case AsmToken::Exclaim:        Out->os() << "Exclaim\n"; break; -    case AsmToken::ExclaimEqual:   Out->os() << "ExclaimEqual\n"; break; -    case AsmToken::Greater:        Out->os() << "Greater\n"; break; -    case AsmToken::GreaterEqual:   Out->os() << "GreaterEqual\n"; break; -    case AsmToken::GreaterGreater: Out->os() << "GreaterGreater\n"; break; -    case AsmToken::LParen:         Out->os() << "LParen\n"; break; -    case AsmToken::Less:           Out->os() << "Less\n"; break; -    case AsmToken::LessEqual:      Out->os() << "LessEqual\n"; break; -    case AsmToken::LessGreater:    Out->os() << "LessGreater\n"; break; -    case AsmToken::LessLess:       Out->os() << "LessLess\n"; break; -    case AsmToken::Minus:          Out->os() << "Minus\n"; break; -    case AsmToken::Percent:        Out->os() << "Percent\n"; break; -    case AsmToken::Pipe:           Out->os() << "Pipe\n"; break; -    case AsmToken::PipePipe:       Out->os() << "PipePipe\n"; break; -    case AsmToken::Plus:           Out->os() << "Plus\n"; break; -    case AsmToken::RParen:         Out->os() << "RParen\n"; break; -    case AsmToken::Slash:          Out->os() << "Slash\n"; break; -    case AsmToken::Star:           Out->os() << "Star\n"; break; -    case AsmToken::Tilde:          Out->os() << "Tilde\n"; break; +    case AsmToken::Amp:            Out->os() << "Amp"; break; +    case AsmToken::AmpAmp:         Out->os() << "AmpAmp"; break; +    case AsmToken::At:             Out->os() << "At"; break; +    case AsmToken::Caret:          Out->os() << "Caret"; break; +    case AsmToken::Colon:          Out->os() << "Colon"; break; +    case AsmToken::Comma:          Out->os() << "Comma"; break; +    case AsmToken::Dollar:         Out->os() << "Dollar"; break; +    case AsmToken::Dot:            Out->os() << "Dot"; break; +    case AsmToken::EndOfStatement: Out->os() << "EndOfStatement"; break; +    case AsmToken::Eof:            Out->os() << "Eof"; break; +    case AsmToken::Equal:          Out->os() << "Equal"; break; +    case AsmToken::EqualEqual:     Out->os() << "EqualEqual"; break; +    case AsmToken::Exclaim:        Out->os() << "Exclaim"; break; +    case AsmToken::ExclaimEqual:   Out->os() << "ExclaimEqual"; break; +    case AsmToken::Greater:        Out->os() << "Greater"; break; +    case AsmToken::GreaterEqual:   Out->os() << "GreaterEqual"; break; +    case AsmToken::GreaterGreater: Out->os() << "GreaterGreater"; break; +    case AsmToken::Hash:           Out->os() << "Hash"; break; +    case AsmToken::LBrac:          Out->os() << "LBrac"; break; +    case AsmToken::LCurly:         Out->os() << "LCurly"; break; +    case AsmToken::LParen:         Out->os() << "LParen"; break; +    case AsmToken::Less:           Out->os() << "Less"; break; +    case AsmToken::LessEqual:      Out->os() << "LessEqual"; break; +    case AsmToken::LessGreater:    Out->os() << "LessGreater"; break; +    case AsmToken::LessLess:       Out->os() << "LessLess"; break; +    case AsmToken::Minus:          Out->os() << "Minus"; break; +    case AsmToken::Percent:        Out->os() << "Percent"; break; +    case AsmToken::Pipe:           Out->os() << "Pipe"; break; +    case AsmToken::PipePipe:       Out->os() << "PipePipe"; break; +    case AsmToken::Plus:           Out->os() << "Plus"; break; +    case AsmToken::RBrac:          Out->os() << "RBrac"; break; +    case AsmToken::RCurly:         Out->os() << "RCurly"; break; +    case AsmToken::RParen:         Out->os() << "RParen"; break; +    case AsmToken::Slash:          Out->os() << "Slash"; break; +    case AsmToken::Star:           Out->os() << "Star"; break; +    case AsmToken::Tilde:          Out->os() << "Tilde"; break;      } + +    // Print the token string. +    Out->os() << " (\""; +    Out->os().write_escaped(Tok.getString()); +    Out->os() << "\")\n";    }    // Keep output if no errors. @@ -255,16 +284,12 @@ static int AssembleInput(const char *ProgName) {    if (!TheTarget)      return 1; -  std::string Error; -  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &Error); -  if (Buffer == 0) { -    errs() << ProgName << ": "; -    if (Error.size()) -      errs() << Error << "\n"; -    else -      errs() << "input file didn't read correctly.\n"; +  OwningPtr<MemoryBuffer> BufferPtr; +  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) { +    errs() << ProgName << ": " << ec.message() << '\n';      return 1;    } +  MemoryBuffer *Buffer = BufferPtr.take();    SourceMgr SrcMgr; @@ -279,10 +304,20 @@ static int AssembleInput(const char *ProgName) {    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(TripleName));    assert(MAI && "Unable to create target asm info!"); -  MCContext Ctx(*MAI); +  // Package up features to be passed to target/subtarget +  std::string FeaturesStr; +  if (MCPU.size()) { +    SubtargetFeatures Features; +    Features.setCPU(MCPU); +    FeaturesStr = Features.getString(); +  }    // FIXME: We shouldn't need to do this (and link in codegen). -  OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, "")); +  //        When we split this out, we should do it in a way that makes +  //        it straightforward to switch subtargets on the fly (.e.g, +  //        the .cpu and .code16 directives). +  OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, +                                                             FeaturesStr));    if (!TM) {      errs() << ProgName << ": error: could not create target for triple '" @@ -290,6 +325,9 @@ static int AssembleInput(const char *ProgName) {      return 1;    } +  const TargetAsmInfo *tai = new TargetAsmInfo(*TM); +  MCContext Ctx(*MAI, tai); +    OwningPtr<tool_output_file> Out(GetOutputStream());    if (!Out)      return 1; @@ -297,15 +335,23 @@ static int AssembleInput(const char *ProgName) {    formatted_raw_ostream FOS(Out->os());    OwningPtr<MCStreamer> Str; +  const TargetLoweringObjectFile &TLOF = +    TM->getTargetLowering()->getObjFileLowering(); +  const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM); + +  // FIXME: There is a bit of code duplication with addPassesToEmitFile.    if (FileType == OFT_AssemblyFile) {      MCInstPrinter *IP =        TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI);      MCCodeEmitter *CE = 0; -    if (ShowEncoding) +    TargetAsmBackend *TAB = 0; +    if (ShowEncoding) {        CE = TheTarget->createCodeEmitter(*TM, Ctx); -    Str.reset(createAsmStreamer(Ctx, FOS, -                                TM->getTargetData()->isLittleEndian(), -                                /*asmverbose*/true, IP, CE, ShowInst)); +      TAB = TheTarget->createAsmBackend(TripleName); +    } +    Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true, +                                           /*useLoc*/ true, IP, CE, TAB, +                                           ShowInst));    } else if (FileType == OFT_Null) {      Str.reset(createNullStreamer(Ctx));    } else { @@ -313,7 +359,8 @@ static int AssembleInput(const char *ProgName) {      MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx);      TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName);      Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB, -                                              FOS, CE, RelaxAll)); +                                              FOS, CE, RelaxAll, +                                              NoExecStack));    }    if (EnableLogging) { @@ -344,18 +391,10 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) {    const Target *TheTarget = GetTarget(ProgName);    if (!TheTarget)      return 0; -   -  std::string ErrorMessage; -   -  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, -                                                      &ErrorMessage); - -  if (Buffer == 0) { -    errs() << ProgName << ": "; -    if (ErrorMessage.size()) -      errs() << ErrorMessage << "\n"; -    else -      errs() << "input file didn't read correctly.\n"; + +  OwningPtr<MemoryBuffer> Buffer; +  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, Buffer)) { +    errs() << ProgName << ": " << ec.message() << '\n';      return 1;    } @@ -365,9 +404,11 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) {    int Res;    if (Enhanced) -    Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, Out->os()); +    Res = +      Disassembler::disassembleEnhanced(TripleName, *Buffer.take(), Out->os());    else -    Res = Disassembler::disassemble(*TheTarget, TripleName, *Buffer, Out->os()); +    Res = Disassembler::disassemble(*TheTarget, TripleName, +                                    *Buffer.take(), Out->os());    // Keep output if no errors.    if (Res == 0) Out->keep();  | 
