diff options
author | Quentin Colombet <qcolombet@apple.com> | 2013-10-01 22:14:56 +0000 |
---|---|---|
committer | Quentin Colombet <qcolombet@apple.com> | 2013-10-01 22:14:56 +0000 |
commit | 76502a756da8fbc3cf6f2f26bc09cce598a9fc03 (patch) | |
tree | e2bf8a5ff9a3322590cbcd857b9269210bcac0ed /lib/MC/MCDisassembler | |
parent | 9432820cafe49c8716a5c0f6033d866cf9c244cb (diff) | |
download | external_llvm-76502a756da8fbc3cf6f2f26bc09cce598a9fc03.zip external_llvm-76502a756da8fbc3cf6f2f26bc09cce598a9fc03.tar.gz external_llvm-76502a756da8fbc3cf6f2f26bc09cce598a9fc03.tar.bz2 |
[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/MCDisassembler')
-rw-r--r-- | lib/MC/MCDisassembler/Disassembler.cpp | 53 |
1 files changed, 45 insertions, 8 deletions
diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp index ecc7aff..86b1cf1 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); } |