Add -disassemble support for -show-inst and -show-encode capability llvm-mc. Also refactor so all MC paraphernalia are created once for all uses as much as possible.
The test change is to account for the fact that the default disassembler behaviour has changed with regards to specifying the assembly syntax to use.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154809 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/MC/Disassembler/X86/intel-syntax.txt b/test/MC/Disassembler/X86/intel-syntax.txt
index 3391e45..a5dbcf2 100644
--- a/test/MC/Disassembler/X86/intel-syntax.txt
+++ b/test/MC/Disassembler/X86/intel-syntax.txt
@@ -1,4 +1,4 @@
-# RUN: llvm-mc --disassemble %s -triple=x86_64-apple-darwin9 -x86-asm-syntax=intel | FileCheck %s
+# RUN: llvm-mc --disassemble %s -triple=x86_64-apple-darwin9 --output-asm-variant=1 | FileCheck %s
# CHECK: movsb
0xa4
diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp
index a8cd7c1..5f2fdb8 100644
--- a/tools/llvm-mc/Disassembler.cpp
+++ b/tools/llvm-mc/Disassembler.cpp
@@ -17,21 +17,18 @@
#include "../../lib/MC/MCDisassembler/EDInst.h"
#include "../../lib/MC/MCDisassembler/EDOperand.h"
#include "../../lib/MC/MCDisassembler/EDToken.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+
using namespace llvm;
typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy;
@@ -56,8 +53,9 @@
}
static bool PrintInsts(const MCDisassembler &DisAsm,
- MCInstPrinter &Printer, const ByteArrayTy &Bytes,
- SourceMgr &SM, raw_ostream &Out) {
+ const ByteArrayTy &Bytes,
+ SourceMgr &SM, raw_ostream &Out,
+ MCStreamer &Streamer) {
// Wrap the vector in a MemoryObject.
VectorMemoryObject memoryObject(Bytes);
@@ -87,8 +85,7 @@
// Fall through
case MCDisassembler::Success:
- Printer.printInst(&Inst, Out, "");
- Out << "\n";
+ Streamer.EmitInstruction(Inst);
break;
}
}
@@ -145,56 +142,22 @@
int Disassembler::disassemble(const Target &T,
const std::string &Triple,
- const std::string &Cpu,
- const std::string &FeaturesStr,
+ MCSubtargetInfo &STI,
+ MCStreamer &Streamer,
MemoryBuffer &Buffer,
+ SourceMgr &SM,
raw_ostream &Out) {
- // Set up disassembler.
- OwningPtr<const MCAsmInfo> AsmInfo(T.createMCAsmInfo(Triple));
-
- if (!AsmInfo) {
- errs() << "error: no assembly info for target " << Triple << "\n";
- return -1;
- }
-
- OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu,
- FeaturesStr));
- if (!STI) {
- errs() << "error: no subtarget info for target " << Triple << "\n";
- return -1;
- }
-
- OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(*STI));
+ OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(STI));
if (!DisAsm) {
errs() << "error: no disassembler for target " << Triple << "\n";
return -1;
}
- OwningPtr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple));
- if (!MRI) {
- errs() << "error: no register info for target " << Triple << "\n";
- return -1;
- }
-
- OwningPtr<const MCInstrInfo> MII(T.createMCInstrInfo());
- if (!MII) {
- errs() << "error: no instruction info for target " << Triple << "\n";
- return -1;
- }
-
- int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
- OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant, *AsmInfo,
- *MII, *MRI, *STI));
- if (!IP) {
- errs() << "error: no instruction printer for target " << Triple << '\n';
- return -1;
- }
+ // Set up initial section manually here
+ Streamer.InitSections();
bool ErrorOccurred = false;
- SourceMgr SM;
- SM.AddNewSourceBuffer(&Buffer, SMLoc());
-
// Convert the input to a vector for disassembly.
ByteArrayTy ByteArray;
StringRef Str = Buffer.getBuffer();
@@ -202,7 +165,7 @@
ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM);
if (!ByteArray.empty())
- ErrorOccurred |= PrintInsts(*DisAsm, *IP, ByteArray, SM, Out);
+ ErrorOccurred |= PrintInsts(*DisAsm, ByteArray, SM, Out, Streamer);
return ErrorOccurred;
}
@@ -236,12 +199,10 @@
int Disassembler::disassembleEnhanced(const std::string &TS,
MemoryBuffer &Buffer,
+ SourceMgr &SM,
raw_ostream &Out) {
ByteArrayTy ByteArray;
StringRef Str = Buffer.getBuffer();
- SourceMgr SM;
-
- SM.AddNewSourceBuffer(&Buffer, SMLoc());
if (ByteArrayFromString(ByteArray, Str, SM)) {
return -1;
diff --git a/tools/llvm-mc/Disassembler.h b/tools/llvm-mc/Disassembler.h
index e8cd92d..17d622f 100644
--- a/tools/llvm-mc/Disassembler.h
+++ b/tools/llvm-mc/Disassembler.h
@@ -22,18 +22,23 @@
class MemoryBuffer;
class Target;
class raw_ostream;
+class SourceMgr;
+class MCSubtargetInfo;
+class MCStreamer;
class Disassembler {
public:
- static int disassemble(const Target &target,
- const std::string &tripleString,
- const std::string &Cpu,
- const std::string &FeaturesStr,
- MemoryBuffer &buffer,
+ static int disassemble(const Target &T,
+ const std::string &Triple,
+ MCSubtargetInfo &STI,
+ MCStreamer &Streamer,
+ MemoryBuffer &Buffer,
+ SourceMgr &SM,
raw_ostream &Out);
static int disassembleEnhanced(const std::string &tripleString,
MemoryBuffer &buffer,
+ SourceMgr &SM,
raw_ostream &Out);
};
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index 89d72b2..36a482e 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -243,37 +243,11 @@
}
}
-static int AsLexInput(const char *ProgName) {
- OwningPtr<MemoryBuffer> BufferPtr;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) {
- errs() << ProgName << ": " << ec.message() << '\n';
- return 1;
- }
- MemoryBuffer *Buffer = BufferPtr.take();
+static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out) {
- SourceMgr SrcMgr;
-
- // Tell SrcMgr about this buffer, which is what TGParser will pick up.
- SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
-
- // Record the location of the include directories so that the lexer can find
- // it later.
- SrcMgr.setIncludeDirs(IncludeDirs);
-
- const Target *TheTarget = GetTarget(ProgName);
- if (!TheTarget)
- return 1;
-
- llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TripleName));
- assert(MAI && "Unable to create target asm info!");
-
- AsmLexer Lexer(*MAI);
+ 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)) {
AsmToken Tok = Lexer.getTok();
@@ -347,13 +321,49 @@
Out->os() << "\")\n";
}
- // Keep output if no errors.
- if (Error == 0) Out->keep();
-
return Error;
}
-static int AssembleInput(const char *ProgName) {
+static int AssembleInput(const char *ProgName, const Target *TheTarget,
+ SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str,
+ MCAsmInfo &MAI, MCSubtargetInfo &STI) {
+ OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
+ Str, MAI));
+ OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(STI, *Parser));
+ if (!TAP) {
+ errs() << ProgName
+ << ": error: this target does not support assembly parsing.\n";
+ return 1;
+ }
+
+ Parser->setShowParsedOperands(ShowInstOperands);
+ Parser->setTargetParser(*TAP.get());
+
+ int Res = Parser->Run(NoInitialTextSection);
+
+ return Res;
+}
+
+int main(int argc, char **argv) {
+ // Print a stack trace if we signal out.
+ sys::PrintStackTraceOnErrorSignal();
+ PrettyStackTraceProgram X(argc, argv);
+ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+
+ // Initialize targets and assembly printers/parsers.
+ llvm::InitializeAllTargetInfos();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmParsers();
+ llvm::InitializeAllDisassemblers();
+
+ // Register the target printer for --version.
+ cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
+
+ cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
+ TripleName = Triple::normalize(TripleName);
+ setDwarfDebugFlags(argc, argv);
+
+ const char *ProgName = argv[0];
const Target *TheTarget = GetTarget(ProgName);
if (!TheTarget)
return 1;
@@ -414,7 +424,6 @@
OwningPtr<MCSubtargetInfo>
STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
- // FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (FileType == OFT_AssemblyFile) {
MCInstPrinter *IP =
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
@@ -441,93 +450,24 @@
NoExecStack));
}
- OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
- *Str.get(), *MAI));
- OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser));
- if (!TAP) {
- errs() << ProgName
- << ": error: this target does not support assembly parsing.\n";
- return 1;
- }
-
- Parser->setShowParsedOperands(ShowInstOperands);
- Parser->setTargetParser(*TAP.get());
-
- int Res = Parser->Run(NoInitialTextSection);
-
- // Keep output if no errors.
- if (Res == 0) Out->keep();
-
- return Res;
-}
-
-static int DisassembleInput(const char *ProgName, bool Enhanced) {
- const Target *TheTarget = GetTarget(ProgName);
- if (!TheTarget)
- return 0;
-
- OwningPtr<MemoryBuffer> Buffer;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, Buffer)) {
- errs() << ProgName << ": " << ec.message() << '\n';
- return 1;
- }
-
- OwningPtr<tool_output_file> Out(GetOutputStream());
- if (!Out)
- return 1;
-
- int Res;
- if (Enhanced) {
- Res =
- Disassembler::disassembleEnhanced(TripleName, *Buffer.take(), Out->os());
- } else {
- // Package up features to be passed to target/subtarget
- std::string FeaturesStr;
- if (MAttrs.size()) {
- SubtargetFeatures Features;
- for (unsigned i = 0; i != MAttrs.size(); ++i)
- Features.AddFeature(MAttrs[i]);
- FeaturesStr = Features.getString();
- }
-
- Res = Disassembler::disassemble(*TheTarget, TripleName, MCPU, FeaturesStr,
- *Buffer.take(), Out->os());
- }
-
- // Keep output if no errors.
- if (Res == 0) Out->keep();
-
- return Res;
-}
-
-
-int main(int argc, char **argv) {
- // Print a stack trace if we signal out.
- sys::PrintStackTraceOnErrorSignal();
- PrettyStackTraceProgram X(argc, argv);
- llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
-
- // Initialize targets and assembly printers/parsers.
- llvm::InitializeAllTargetInfos();
- llvm::InitializeAllTargetMCs();
- llvm::InitializeAllAsmParsers();
- llvm::InitializeAllDisassemblers();
-
- // Register the target printer for --version.
- cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
-
- cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
- TripleName = Triple::normalize(TripleName);
- setDwarfDebugFlags(argc, argv);
-
+ int Res = 1;
switch (Action) {
case AC_AsLex:
- return AsLexInput(argv[0]);
+ Res = AsLexInput(SrcMgr, *MAI, Out.get());
+ break;
case AC_Assemble:
- return AssembleInput(argv[0]);
+ Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI);
+ break;
case AC_Disassemble:
- return DisassembleInput(argv[0], false);
+ Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
+ *Buffer, SrcMgr, Out->os());
+ break;
case AC_EDisassemble:
- return DisassembleInput(argv[0], true);
+ Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, SrcMgr, Out->os());
+ break;
}
+
+ // Keep output if no errors.
+ if (Res == 0) Out->keep();
+ return Res;
}