summaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2013-10-01 22:14:56 +0000
committerQuentin Colombet <qcolombet@apple.com>2013-10-01 22:14:56 +0000
commit76502a756da8fbc3cf6f2f26bc09cce598a9fc03 (patch)
treee2bf8a5ff9a3322590cbcd857b9269210bcac0ed /lib/MC
parent9432820cafe49c8716a5c0f6033d866cf9c244cb (diff)
downloadllvm-76502a756da8fbc3cf6f2f26bc09cce598a9fc03.tar.gz
llvm-76502a756da8fbc3cf6f2f26bc09cce598a9fc03.tar.bz2
llvm-76502a756da8fbc3cf6f2f26bc09cce598a9fc03.tar.xz
[llvm-c][Disassembler] Add an option to reproduce in disassembled output the
comments issued with verbose assembly. E.g., on a vector shuffle operation, disassembled output are: * Without the option: vpshufd $-0x79, (%rsp), %xmm0 * With the option: vpshufd $-0x79, (%rsp), %xmm0 ## xmm0 = mem[3,1,0,2] This part of <rdar://problem/14687488>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191799 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCDisassembler/Disassembler.cpp53
1 files changed, 45 insertions, 8 deletions
diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp
index ecc7aff382..86b1cf170a 100644
--- a/lib/MC/MCDisassembler/Disassembler.cpp
+++ b/lib/MC/MCDisassembler/Disassembler.cpp
@@ -20,6 +20,7 @@
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbolizer.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/TargetRegistry.h"
@@ -143,6 +144,36 @@ public:
};
} // end anonymous namespace
+/// \brief Emits the comments that are stored in \p DC comment stream.
+/// Each comment in the comment stream must end with a newline.
+static void emitComments(LLVMDisasmContext *DC,
+ formatted_raw_ostream &FormattedOS) {
+ // Flush the stream before taking its content.
+ DC->CommentStream.flush();
+ StringRef Comments = DC->CommentsToEmit.str();
+ // Get the default information for printing a comment.
+ const MCAsmInfo *MAI = DC->getAsmInfo();
+ const char *CommentBegin = MAI->getCommentString();
+ unsigned CommentColumn = MAI->getCommentColumn();
+ bool IsFirst = true;
+ while (!Comments.empty()) {
+ if (!IsFirst)
+ FormattedOS << '\n';
+ // Emit a line of comments.
+ FormattedOS.PadToColumn(CommentColumn);
+ size_t Position = Comments.find('\n');
+ FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
+ // Move after the newline character.
+ Comments = Comments.substr(Position+1);
+ IsFirst = false;
+ }
+ FormattedOS.flush();
+
+ // Tell the comment stream that the vector changed underneath it.
+ DC->CommentsToEmit.clear();
+ DC->CommentStream.resync();
+}
+
//
// LLVMDisasmInstruction() disassembles a single instruction using the
// disassembler context specified in the parameter DC. The bytes of the
@@ -167,8 +198,10 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
const MCDisassembler *DisAsm = DC->getDisAsm();
MCInstPrinter *IP = DC->getIP();
MCDisassembler::DecodeStatus S;
+ SmallVector<char, 64> InsnStr;
+ raw_svector_ostream Annotations(InsnStr);
S = DisAsm->getInstruction(Inst, Size, MemoryObject, PC,
- /*REMOVE*/ nulls(), DC->CommentStream);
+ /*REMOVE*/ nulls(), Annotations);
switch (S) {
case MCDisassembler::Fail:
case MCDisassembler::SoftFail:
@@ -176,17 +209,15 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
return 0;
case MCDisassembler::Success: {
- DC->CommentStream.flush();
- StringRef Comments = DC->CommentsToEmit.str();
+ Annotations.flush();
+ StringRef AnnotationsStr = Annotations.str();
SmallVector<char, 64> InsnStr;
raw_svector_ostream OS(InsnStr);
- IP->printInst(&Inst, OS, Comments);
- OS.flush();
+ formatted_raw_ostream FormattedOS(OS);
+ IP->printInst(&Inst, FormattedOS, AnnotationsStr);
- // Tell the comment stream that the vector changed underneath it.
- DC->CommentsToEmit.clear();
- DC->CommentStream.resync();
+ emitComments(DC, FormattedOS);
assert(OutStringSize != 0 && "Output buffer cannot be zero size");
size_t OutputSize = std::min(OutStringSize-1, InsnStr.size());
@@ -232,5 +263,11 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){
Options &= ~LLVMDisassembler_Option_AsmPrinterVariant;
}
}
+ if (Options & LLVMDisassembler_Option_SetInstrComments) {
+ LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
+ MCInstPrinter *IP = DC->getIP();
+ IP->setCommentStream(DC->CommentStream);
+ Options &= ~LLVMDisassembler_Option_SetInstrComments;
+ }
return (Options == 0);
}