diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-mc/llvm-mc.cpp')
-rw-r--r-- | contrib/llvm/tools/llvm-mc/llvm-mc.cpp | 177 |
1 files changed, 98 insertions, 79 deletions
diff --git a/contrib/llvm/tools/llvm-mc/llvm-mc.cpp b/contrib/llvm/tools/llvm-mc/llvm-mc.cpp index fc8a1c5..aef0a3d 100644 --- a/contrib/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/contrib/llvm/tools/llvm-mc/llvm-mc.cpp @@ -12,13 +12,13 @@ // //===----------------------------------------------------------------------===// +#include "llvm/MC/MCParser/AsmLexer.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCParser/AsmParser.h" #include "llvm/Target/TargetAsmBackend.h" #include "llvm/Target/TargetAsmParser.h" #include "llvm/Target/TargetData.h" @@ -27,6 +27,7 @@ #include "llvm/Target/TargetSelect.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileUtilities.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -51,6 +52,10 @@ ShowEncoding("show-encoding", cl::desc("Show instruction encodings")); static cl::opt<bool> ShowInst("show-inst", cl::desc("Show internal instruction representation")); +static cl::opt<bool> +ShowInstOperands("show-inst-operands", + cl::desc("Show instructions operands as parsed")); + static cl::opt<unsigned> OutputAsmVariant("output-asm-variant", cl::desc("Syntax variant to use for output printing")); @@ -135,6 +140,22 @@ static const Target *GetTarget(const char *ProgName) { return 0; } +static tool_output_file *GetOutputStream() { + if (OutputFilename == "") + OutputFilename = "-"; + + std::string Err; + tool_output_file *Out = new tool_output_file(OutputFilename.c_str(), Err, + raw_fd_ostream::F_Binary); + if (!Err.empty()) { + errs() << Err << '\n'; + delete Out; + return 0; + } + + return Out; +} + static int AsLexInput(const char *ProgName) { std::string ErrorMessage; MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, @@ -165,9 +186,13 @@ static int AsLexInput(const char *ProgName) { assert(MAI && "Unable to create target asm info!"); AsmLexer Lexer(*MAI); - + Lexer.setBuffer(SrcMgr.getMemoryBuffer(0)); + + OwningPtr<tool_output_file> Out(GetOutputStream()); + if (!Out) + return 1; + bool Error = false; - while (Lexer.Lex().isNot(AsmToken::Eof)) { switch (Lexer.getKind()) { default: @@ -178,69 +203,51 @@ static int AsLexInput(const char *ProgName) { Error = true; // error already printed. break; case AsmToken::Identifier: - outs() << "identifier: " << Lexer.getTok().getString() << '\n'; + Out->os() << "identifier: " << Lexer.getTok().getString() << '\n'; break; case AsmToken::String: - outs() << "string: " << Lexer.getTok().getString() << '\n'; + Out->os() << "string: " << Lexer.getTok().getString() << '\n'; break; case AsmToken::Integer: - outs() << "int: " << Lexer.getTok().getString() << '\n'; + Out->os() << "int: " << Lexer.getTok().getString() << '\n'; break; - case AsmToken::Amp: outs() << "Amp\n"; break; - case AsmToken::AmpAmp: outs() << "AmpAmp\n"; break; - case AsmToken::Caret: outs() << "Caret\n"; break; - case AsmToken::Colon: outs() << "Colon\n"; break; - case AsmToken::Comma: outs() << "Comma\n"; break; - case AsmToken::Dollar: outs() << "Dollar\n"; break; - case AsmToken::EndOfStatement: outs() << "EndOfStatement\n"; break; - case AsmToken::Eof: outs() << "Eof\n"; break; - case AsmToken::Equal: outs() << "Equal\n"; break; - case AsmToken::EqualEqual: outs() << "EqualEqual\n"; break; - case AsmToken::Exclaim: outs() << "Exclaim\n"; break; - case AsmToken::ExclaimEqual: outs() << "ExclaimEqual\n"; break; - case AsmToken::Greater: outs() << "Greater\n"; break; - case AsmToken::GreaterEqual: outs() << "GreaterEqual\n"; break; - case AsmToken::GreaterGreater: outs() << "GreaterGreater\n"; break; - case AsmToken::LParen: outs() << "LParen\n"; break; - case AsmToken::Less: outs() << "Less\n"; break; - case AsmToken::LessEqual: outs() << "LessEqual\n"; break; - case AsmToken::LessGreater: outs() << "LessGreater\n"; break; - case AsmToken::LessLess: outs() << "LessLess\n"; break; - case AsmToken::Minus: outs() << "Minus\n"; break; - case AsmToken::Percent: outs() << "Percent\n"; break; - case AsmToken::Pipe: outs() << "Pipe\n"; break; - case AsmToken::PipePipe: outs() << "PipePipe\n"; break; - case AsmToken::Plus: outs() << "Plus\n"; break; - case AsmToken::RParen: outs() << "RParen\n"; break; - case AsmToken::Slash: outs() << "Slash\n"; break; - case AsmToken::Star: outs() << "Star\n"; break; - case AsmToken::Tilde: outs() << "Tilde\n"; 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; } } - - return Error; -} -static formatted_raw_ostream *GetOutputStream() { - if (OutputFilename == "") - OutputFilename = "-"; - - // Make sure that the Out file gets unlinked from the disk if we get a - // SIGINT. - if (OutputFilename != "-") - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); - - std::string Err; - raw_fd_ostream *Out = new raw_fd_ostream(OutputFilename.c_str(), Err, - raw_fd_ostream::F_Binary); - if (!Err.empty()) { - errs() << Err << '\n'; - delete Out; - return 0; - } - - return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM); + // Keep output if no errors. + if (Error == 0) Out->keep(); + + return Error; } static int AssembleInput(const char *ProgName) { @@ -273,10 +280,6 @@ static int AssembleInput(const char *ProgName) { assert(MAI && "Unable to create target asm info!"); MCContext Ctx(*MAI); - formatted_raw_ostream *Out = GetOutputStream(); - if (!Out) - return 1; - // FIXME: We shouldn't need to do this (and link in codegen). OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, "")); @@ -287,47 +290,52 @@ static int AssembleInput(const char *ProgName) { return 1; } - OwningPtr<MCCodeEmitter> CE; + OwningPtr<tool_output_file> Out(GetOutputStream()); + if (!Out) + return 1; + + formatted_raw_ostream FOS(Out->os()); OwningPtr<MCStreamer> Str; - OwningPtr<TargetAsmBackend> TAB; if (FileType == OFT_AssemblyFile) { MCInstPrinter *IP = TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI); + MCCodeEmitter *CE = 0; if (ShowEncoding) - CE.reset(TheTarget->createCodeEmitter(*TM, Ctx)); - Str.reset(createAsmStreamer(Ctx, *Out,TM->getTargetData()->isLittleEndian(), - /*asmverbose*/true, IP, CE.get(), ShowInst)); + CE = TheTarget->createCodeEmitter(*TM, Ctx); + Str.reset(createAsmStreamer(Ctx, FOS, + TM->getTargetData()->isLittleEndian(), + /*asmverbose*/true, IP, CE, ShowInst)); } else if (FileType == OFT_Null) { Str.reset(createNullStreamer(Ctx)); } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); - CE.reset(TheTarget->createCodeEmitter(*TM, Ctx)); - TAB.reset(TheTarget->createAsmBackend(TripleName)); + MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx); + TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName); Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB, - *Out, CE.get(), RelaxAll)); + FOS, CE, RelaxAll)); } if (EnableLogging) { Str.reset(createLoggingStreamer(Str.take(), errs())); } - AsmParser Parser(*TheTarget, SrcMgr, Ctx, *Str.get(), *MAI); - OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(Parser)); + OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx, + *Str.get(), *MAI)); + OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*Parser, *TM)); if (!TAP) { errs() << ProgName << ": error: this target does not support assembly parsing.\n"; return 1; } - Parser.setTargetParser(*TAP.get()); + Parser->setShowParsedOperands(ShowInstOperands); + Parser->setTargetParser(*TAP.get()); - int Res = Parser.Run(NoInitialTextSection); - delete Out; + int Res = Parser->Run(NoInitialTextSection); - // Delete output on errors. - if (Res && OutputFilename != "-") - sys::Path(OutputFilename).eraseFromDisk(); + // Keep output if no errors. + if (Res == 0) Out->keep(); return Res; } @@ -351,10 +359,20 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) { return 1; } + OwningPtr<tool_output_file> Out(GetOutputStream()); + if (!Out) + return 1; + + int Res; if (Enhanced) - return Disassembler::disassembleEnhanced(TripleName, *Buffer); + Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, Out->os()); else - return Disassembler::disassemble(*TheTarget, TripleName, *Buffer); + Res = Disassembler::disassemble(*TheTarget, TripleName, *Buffer, Out->os()); + + // Keep output if no errors. + if (Res == 0) Out->keep(); + + return Res; } @@ -373,6 +391,7 @@ int main(int argc, char **argv) { llvm::InitializeAllDisassemblers(); cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); + TripleName = Triple::normalize(TripleName); switch (Action) { default: |