1f4a2713aSLionel Sambuc //===-- lib/MC/Disassembler.cpp - Disassembler Public C Interface ---------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc
10f4a2713aSLionel Sambuc #include "Disassembler.h"
11f4a2713aSLionel Sambuc #include "llvm-c/Disassembler.h"
12f4a2713aSLionel Sambuc #include "llvm/MC/MCAsmInfo.h"
13f4a2713aSLionel Sambuc #include "llvm/MC/MCContext.h"
14f4a2713aSLionel Sambuc #include "llvm/MC/MCDisassembler.h"
15f4a2713aSLionel Sambuc #include "llvm/MC/MCInst.h"
16f4a2713aSLionel Sambuc #include "llvm/MC/MCInstPrinter.h"
17f4a2713aSLionel Sambuc #include "llvm/MC/MCInstrInfo.h"
18f4a2713aSLionel Sambuc #include "llvm/MC/MCRegisterInfo.h"
19f4a2713aSLionel Sambuc #include "llvm/MC/MCRelocationInfo.h"
20f4a2713aSLionel Sambuc #include "llvm/MC/MCSubtargetInfo.h"
21f4a2713aSLionel Sambuc #include "llvm/MC/MCSymbolizer.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/FormattedStream.h"
24f4a2713aSLionel Sambuc #include "llvm/Support/TargetRegistry.h"
25f4a2713aSLionel Sambuc
26f4a2713aSLionel Sambuc using namespace llvm;
27f4a2713aSLionel Sambuc
28f4a2713aSLionel Sambuc // LLVMCreateDisasm() creates a disassembler for the TripleName. Symbolic
29f4a2713aSLionel Sambuc // disassembly is supported by passing a block of information in the DisInfo
30f4a2713aSLionel Sambuc // parameter and specifying the TagType and callback functions as described in
31f4a2713aSLionel Sambuc // the header llvm-c/Disassembler.h . The pointer to the block and the
32f4a2713aSLionel Sambuc // functions can all be passed as NULL. If successful, this returns a
33f4a2713aSLionel Sambuc // disassembler context. If not, it returns NULL.
34f4a2713aSLionel Sambuc //
35*0a6a1f1dSLionel Sambuc LLVMDisasmContextRef
LLVMCreateDisasmCPUFeatures(const char * Triple,const char * CPU,const char * Features,void * DisInfo,int TagType,LLVMOpInfoCallback GetOpInfo,LLVMSymbolLookupCallback SymbolLookUp)36*0a6a1f1dSLionel Sambuc LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU,
37*0a6a1f1dSLionel Sambuc const char *Features, void *DisInfo, int TagType,
38f4a2713aSLionel Sambuc LLVMOpInfoCallback GetOpInfo,
39f4a2713aSLionel Sambuc LLVMSymbolLookupCallback SymbolLookUp) {
40f4a2713aSLionel Sambuc // Get the target.
41f4a2713aSLionel Sambuc std::string Error;
42f4a2713aSLionel Sambuc const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
43f4a2713aSLionel Sambuc if (!TheTarget)
44*0a6a1f1dSLionel Sambuc return nullptr;
45f4a2713aSLionel Sambuc
46f4a2713aSLionel Sambuc const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(Triple);
47f4a2713aSLionel Sambuc if (!MRI)
48*0a6a1f1dSLionel Sambuc return nullptr;
49f4a2713aSLionel Sambuc
50f4a2713aSLionel Sambuc // Get the assembler info needed to setup the MCContext.
51f4a2713aSLionel Sambuc const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, Triple);
52f4a2713aSLionel Sambuc if (!MAI)
53*0a6a1f1dSLionel Sambuc return nullptr;
54f4a2713aSLionel Sambuc
55f4a2713aSLionel Sambuc const MCInstrInfo *MII = TheTarget->createMCInstrInfo();
56f4a2713aSLionel Sambuc if (!MII)
57*0a6a1f1dSLionel Sambuc return nullptr;
58f4a2713aSLionel Sambuc
59f4a2713aSLionel Sambuc const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU,
60*0a6a1f1dSLionel Sambuc Features);
61f4a2713aSLionel Sambuc if (!STI)
62*0a6a1f1dSLionel Sambuc return nullptr;
63f4a2713aSLionel Sambuc
64f4a2713aSLionel Sambuc // Set up the MCContext for creating symbols and MCExpr's.
65*0a6a1f1dSLionel Sambuc MCContext *Ctx = new MCContext(MAI, MRI, nullptr);
66f4a2713aSLionel Sambuc if (!Ctx)
67*0a6a1f1dSLionel Sambuc return nullptr;
68f4a2713aSLionel Sambuc
69f4a2713aSLionel Sambuc // Set up disassembler.
70*0a6a1f1dSLionel Sambuc MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI, *Ctx);
71f4a2713aSLionel Sambuc if (!DisAsm)
72*0a6a1f1dSLionel Sambuc return nullptr;
73f4a2713aSLionel Sambuc
74*0a6a1f1dSLionel Sambuc std::unique_ptr<MCRelocationInfo> RelInfo(
75f4a2713aSLionel Sambuc TheTarget->createMCRelocationInfo(Triple, *Ctx));
76f4a2713aSLionel Sambuc if (!RelInfo)
77*0a6a1f1dSLionel Sambuc return nullptr;
78f4a2713aSLionel Sambuc
79*0a6a1f1dSLionel Sambuc std::unique_ptr<MCSymbolizer> Symbolizer(TheTarget->createMCSymbolizer(
80*0a6a1f1dSLionel Sambuc Triple, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo.release()));
81*0a6a1f1dSLionel Sambuc DisAsm->setSymbolizer(std::move(Symbolizer));
82*0a6a1f1dSLionel Sambuc
83f4a2713aSLionel Sambuc // Set up the instruction printer.
84f4a2713aSLionel Sambuc int AsmPrinterVariant = MAI->getAssemblerDialect();
85f4a2713aSLionel Sambuc MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant,
86f4a2713aSLionel Sambuc *MAI, *MII, *MRI, *STI);
87f4a2713aSLionel Sambuc if (!IP)
88*0a6a1f1dSLionel Sambuc return nullptr;
89f4a2713aSLionel Sambuc
90f4a2713aSLionel Sambuc LLVMDisasmContext *DC = new LLVMDisasmContext(Triple, DisInfo, TagType,
91f4a2713aSLionel Sambuc GetOpInfo, SymbolLookUp,
92f4a2713aSLionel Sambuc TheTarget, MAI, MRI,
93f4a2713aSLionel Sambuc STI, MII, Ctx, DisAsm, IP);
94f4a2713aSLionel Sambuc if (!DC)
95*0a6a1f1dSLionel Sambuc return nullptr;
96f4a2713aSLionel Sambuc
97f4a2713aSLionel Sambuc DC->setCPU(CPU);
98f4a2713aSLionel Sambuc return DC;
99f4a2713aSLionel Sambuc }
100f4a2713aSLionel Sambuc
LLVMCreateDisasmCPU(const char * Triple,const char * CPU,void * DisInfo,int TagType,LLVMOpInfoCallback GetOpInfo,LLVMSymbolLookupCallback SymbolLookUp)101*0a6a1f1dSLionel Sambuc LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
102*0a6a1f1dSLionel Sambuc void *DisInfo, int TagType,
103*0a6a1f1dSLionel Sambuc LLVMOpInfoCallback GetOpInfo,
104*0a6a1f1dSLionel Sambuc LLVMSymbolLookupCallback SymbolLookUp){
105*0a6a1f1dSLionel Sambuc return LLVMCreateDisasmCPUFeatures(Triple, CPU, "", DisInfo, TagType,
106*0a6a1f1dSLionel Sambuc GetOpInfo, SymbolLookUp);
107*0a6a1f1dSLionel Sambuc }
108*0a6a1f1dSLionel Sambuc
LLVMCreateDisasm(const char * Triple,void * DisInfo,int TagType,LLVMOpInfoCallback GetOpInfo,LLVMSymbolLookupCallback SymbolLookUp)109f4a2713aSLionel Sambuc LLVMDisasmContextRef LLVMCreateDisasm(const char *Triple, void *DisInfo,
110f4a2713aSLionel Sambuc int TagType, LLVMOpInfoCallback GetOpInfo,
111f4a2713aSLionel Sambuc LLVMSymbolLookupCallback SymbolLookUp) {
112*0a6a1f1dSLionel Sambuc return LLVMCreateDisasmCPUFeatures(Triple, "", "", DisInfo, TagType,
113*0a6a1f1dSLionel Sambuc GetOpInfo, SymbolLookUp);
114f4a2713aSLionel Sambuc }
115f4a2713aSLionel Sambuc
116f4a2713aSLionel Sambuc //
117f4a2713aSLionel Sambuc // LLVMDisasmDispose() disposes of the disassembler specified by the context.
118f4a2713aSLionel Sambuc //
LLVMDisasmDispose(LLVMDisasmContextRef DCR)119f4a2713aSLionel Sambuc void LLVMDisasmDispose(LLVMDisasmContextRef DCR){
120f4a2713aSLionel Sambuc LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
121f4a2713aSLionel Sambuc delete DC;
122f4a2713aSLionel Sambuc }
123f4a2713aSLionel Sambuc
124f4a2713aSLionel Sambuc /// \brief Emits the comments that are stored in \p DC comment stream.
125f4a2713aSLionel Sambuc /// Each comment in the comment stream must end with a newline.
emitComments(LLVMDisasmContext * DC,formatted_raw_ostream & FormattedOS)126f4a2713aSLionel Sambuc static void emitComments(LLVMDisasmContext *DC,
127f4a2713aSLionel Sambuc formatted_raw_ostream &FormattedOS) {
128f4a2713aSLionel Sambuc // Flush the stream before taking its content.
129f4a2713aSLionel Sambuc DC->CommentStream.flush();
130f4a2713aSLionel Sambuc StringRef Comments = DC->CommentsToEmit.str();
131f4a2713aSLionel Sambuc // Get the default information for printing a comment.
132f4a2713aSLionel Sambuc const MCAsmInfo *MAI = DC->getAsmInfo();
133f4a2713aSLionel Sambuc const char *CommentBegin = MAI->getCommentString();
134f4a2713aSLionel Sambuc unsigned CommentColumn = MAI->getCommentColumn();
135f4a2713aSLionel Sambuc bool IsFirst = true;
136f4a2713aSLionel Sambuc while (!Comments.empty()) {
137f4a2713aSLionel Sambuc if (!IsFirst)
138f4a2713aSLionel Sambuc FormattedOS << '\n';
139f4a2713aSLionel Sambuc // Emit a line of comments.
140f4a2713aSLionel Sambuc FormattedOS.PadToColumn(CommentColumn);
141f4a2713aSLionel Sambuc size_t Position = Comments.find('\n');
142f4a2713aSLionel Sambuc FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
143f4a2713aSLionel Sambuc // Move after the newline character.
144f4a2713aSLionel Sambuc Comments = Comments.substr(Position+1);
145f4a2713aSLionel Sambuc IsFirst = false;
146f4a2713aSLionel Sambuc }
147f4a2713aSLionel Sambuc FormattedOS.flush();
148f4a2713aSLionel Sambuc
149f4a2713aSLionel Sambuc // Tell the comment stream that the vector changed underneath it.
150f4a2713aSLionel Sambuc DC->CommentsToEmit.clear();
151f4a2713aSLionel Sambuc DC->CommentStream.resync();
152f4a2713aSLionel Sambuc }
153f4a2713aSLionel Sambuc
154*0a6a1f1dSLionel Sambuc /// \brief Gets latency information for \p Inst from the itinerary
155f4a2713aSLionel Sambuc /// scheduling model, based on \p DC information.
156f4a2713aSLionel Sambuc /// \return The maximum expected latency over all the operands or -1
157*0a6a1f1dSLionel Sambuc /// if no information is available.
getItineraryLatency(LLVMDisasmContext * DC,const MCInst & Inst)158f4a2713aSLionel Sambuc static int getItineraryLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
159f4a2713aSLionel Sambuc const int NoInformationAvailable = -1;
160f4a2713aSLionel Sambuc
161f4a2713aSLionel Sambuc // Check if we have a CPU to get the itinerary information.
162f4a2713aSLionel Sambuc if (DC->getCPU().empty())
163f4a2713aSLionel Sambuc return NoInformationAvailable;
164f4a2713aSLionel Sambuc
165f4a2713aSLionel Sambuc // Get itinerary information.
166f4a2713aSLionel Sambuc const MCSubtargetInfo *STI = DC->getSubtargetInfo();
167f4a2713aSLionel Sambuc InstrItineraryData IID = STI->getInstrItineraryForCPU(DC->getCPU());
168f4a2713aSLionel Sambuc // Get the scheduling class of the requested instruction.
169f4a2713aSLionel Sambuc const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
170f4a2713aSLionel Sambuc unsigned SCClass = Desc.getSchedClass();
171f4a2713aSLionel Sambuc
172f4a2713aSLionel Sambuc int Latency = 0;
173f4a2713aSLionel Sambuc for (unsigned OpIdx = 0, OpIdxEnd = Inst.getNumOperands(); OpIdx != OpIdxEnd;
174f4a2713aSLionel Sambuc ++OpIdx)
175f4a2713aSLionel Sambuc Latency = std::max(Latency, IID.getOperandCycle(SCClass, OpIdx));
176f4a2713aSLionel Sambuc
177f4a2713aSLionel Sambuc return Latency;
178f4a2713aSLionel Sambuc }
179f4a2713aSLionel Sambuc
180f4a2713aSLionel Sambuc /// \brief Gets latency information for \p Inst, based on \p DC information.
181f4a2713aSLionel Sambuc /// \return The maximum expected latency over all the definitions or -1
182*0a6a1f1dSLionel Sambuc /// if no information is available.
getLatency(LLVMDisasmContext * DC,const MCInst & Inst)183f4a2713aSLionel Sambuc static int getLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
184f4a2713aSLionel Sambuc // Try to compute scheduling information.
185f4a2713aSLionel Sambuc const MCSubtargetInfo *STI = DC->getSubtargetInfo();
186*0a6a1f1dSLionel Sambuc const MCSchedModel SCModel = STI->getSchedModel();
187f4a2713aSLionel Sambuc const int NoInformationAvailable = -1;
188f4a2713aSLionel Sambuc
189f4a2713aSLionel Sambuc // Check if we have a scheduling model for instructions.
190*0a6a1f1dSLionel Sambuc if (!SCModel.hasInstrSchedModel())
191*0a6a1f1dSLionel Sambuc // Try to fall back to the itinerary model if the scheduling model doesn't
192*0a6a1f1dSLionel Sambuc // have a scheduling table. Note the default does not have a table.
193f4a2713aSLionel Sambuc return getItineraryLatency(DC, Inst);
194f4a2713aSLionel Sambuc
195f4a2713aSLionel Sambuc // Get the scheduling class of the requested instruction.
196f4a2713aSLionel Sambuc const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
197f4a2713aSLionel Sambuc unsigned SCClass = Desc.getSchedClass();
198*0a6a1f1dSLionel Sambuc const MCSchedClassDesc *SCDesc = SCModel.getSchedClassDesc(SCClass);
199f4a2713aSLionel Sambuc // Resolving the variant SchedClass requires an MI to pass to
200f4a2713aSLionel Sambuc // SubTargetInfo::resolveSchedClass.
201f4a2713aSLionel Sambuc if (!SCDesc || !SCDesc->isValid() || SCDesc->isVariant())
202f4a2713aSLionel Sambuc return NoInformationAvailable;
203f4a2713aSLionel Sambuc
204f4a2713aSLionel Sambuc // Compute output latency.
205f4a2713aSLionel Sambuc int Latency = 0;
206f4a2713aSLionel Sambuc for (unsigned DefIdx = 0, DefEnd = SCDesc->NumWriteLatencyEntries;
207f4a2713aSLionel Sambuc DefIdx != DefEnd; ++DefIdx) {
208f4a2713aSLionel Sambuc // Lookup the definition's write latency in SubtargetInfo.
209f4a2713aSLionel Sambuc const MCWriteLatencyEntry *WLEntry = STI->getWriteLatencyEntry(SCDesc,
210f4a2713aSLionel Sambuc DefIdx);
211f4a2713aSLionel Sambuc Latency = std::max(Latency, WLEntry->Cycles);
212f4a2713aSLionel Sambuc }
213f4a2713aSLionel Sambuc
214f4a2713aSLionel Sambuc return Latency;
215f4a2713aSLionel Sambuc }
216f4a2713aSLionel Sambuc
217f4a2713aSLionel Sambuc
218f4a2713aSLionel Sambuc /// \brief Emits latency information in DC->CommentStream for \p Inst, based
219f4a2713aSLionel Sambuc /// on the information available in \p DC.
emitLatency(LLVMDisasmContext * DC,const MCInst & Inst)220f4a2713aSLionel Sambuc static void emitLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
221f4a2713aSLionel Sambuc int Latency = getLatency(DC, Inst);
222f4a2713aSLionel Sambuc
223*0a6a1f1dSLionel Sambuc // Report only interesting latencies.
224f4a2713aSLionel Sambuc if (Latency < 2)
225f4a2713aSLionel Sambuc return;
226f4a2713aSLionel Sambuc
227f4a2713aSLionel Sambuc DC->CommentStream << "Latency: " << Latency << '\n';
228f4a2713aSLionel Sambuc }
229f4a2713aSLionel Sambuc
230f4a2713aSLionel Sambuc //
231f4a2713aSLionel Sambuc // LLVMDisasmInstruction() disassembles a single instruction using the
232f4a2713aSLionel Sambuc // disassembler context specified in the parameter DC. The bytes of the
233f4a2713aSLionel Sambuc // instruction are specified in the parameter Bytes, and contains at least
234f4a2713aSLionel Sambuc // BytesSize number of bytes. The instruction is at the address specified by
235f4a2713aSLionel Sambuc // the PC parameter. If a valid instruction can be disassembled its string is
236f4a2713aSLionel Sambuc // returned indirectly in OutString which whos size is specified in the
237f4a2713aSLionel Sambuc // parameter OutStringSize. This function returns the number of bytes in the
238f4a2713aSLionel Sambuc // instruction or zero if there was no valid instruction. If this function
239f4a2713aSLionel Sambuc // returns zero the caller will have to pick how many bytes they want to step
240f4a2713aSLionel Sambuc // over by printing a .byte, .long etc. to continue.
241f4a2713aSLionel Sambuc //
LLVMDisasmInstruction(LLVMDisasmContextRef DCR,uint8_t * Bytes,uint64_t BytesSize,uint64_t PC,char * OutString,size_t OutStringSize)242f4a2713aSLionel Sambuc size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
243f4a2713aSLionel Sambuc uint64_t BytesSize, uint64_t PC, char *OutString,
244f4a2713aSLionel Sambuc size_t OutStringSize){
245f4a2713aSLionel Sambuc LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
246f4a2713aSLionel Sambuc // Wrap the pointer to the Bytes, BytesSize and PC in a MemoryObject.
247*0a6a1f1dSLionel Sambuc ArrayRef<uint8_t> Data(Bytes, BytesSize);
248f4a2713aSLionel Sambuc
249f4a2713aSLionel Sambuc uint64_t Size;
250f4a2713aSLionel Sambuc MCInst Inst;
251f4a2713aSLionel Sambuc const MCDisassembler *DisAsm = DC->getDisAsm();
252f4a2713aSLionel Sambuc MCInstPrinter *IP = DC->getIP();
253f4a2713aSLionel Sambuc MCDisassembler::DecodeStatus S;
254f4a2713aSLionel Sambuc SmallVector<char, 64> InsnStr;
255f4a2713aSLionel Sambuc raw_svector_ostream Annotations(InsnStr);
256*0a6a1f1dSLionel Sambuc S = DisAsm->getInstruction(Inst, Size, Data, PC,
257f4a2713aSLionel Sambuc /*REMOVE*/ nulls(), Annotations);
258f4a2713aSLionel Sambuc switch (S) {
259f4a2713aSLionel Sambuc case MCDisassembler::Fail:
260f4a2713aSLionel Sambuc case MCDisassembler::SoftFail:
261f4a2713aSLionel Sambuc // FIXME: Do something different for soft failure modes?
262f4a2713aSLionel Sambuc return 0;
263f4a2713aSLionel Sambuc
264f4a2713aSLionel Sambuc case MCDisassembler::Success: {
265f4a2713aSLionel Sambuc Annotations.flush();
266f4a2713aSLionel Sambuc StringRef AnnotationsStr = Annotations.str();
267f4a2713aSLionel Sambuc
268f4a2713aSLionel Sambuc SmallVector<char, 64> InsnStr;
269f4a2713aSLionel Sambuc raw_svector_ostream OS(InsnStr);
270f4a2713aSLionel Sambuc formatted_raw_ostream FormattedOS(OS);
271f4a2713aSLionel Sambuc IP->printInst(&Inst, FormattedOS, AnnotationsStr);
272f4a2713aSLionel Sambuc
273f4a2713aSLionel Sambuc if (DC->getOptions() & LLVMDisassembler_Option_PrintLatency)
274f4a2713aSLionel Sambuc emitLatency(DC, Inst);
275f4a2713aSLionel Sambuc
276f4a2713aSLionel Sambuc emitComments(DC, FormattedOS);
277*0a6a1f1dSLionel Sambuc OS.flush();
278f4a2713aSLionel Sambuc
279f4a2713aSLionel Sambuc assert(OutStringSize != 0 && "Output buffer cannot be zero size");
280f4a2713aSLionel Sambuc size_t OutputSize = std::min(OutStringSize-1, InsnStr.size());
281f4a2713aSLionel Sambuc std::memcpy(OutString, InsnStr.data(), OutputSize);
282f4a2713aSLionel Sambuc OutString[OutputSize] = '\0'; // Terminate string.
283f4a2713aSLionel Sambuc
284f4a2713aSLionel Sambuc return Size;
285f4a2713aSLionel Sambuc }
286f4a2713aSLionel Sambuc }
287f4a2713aSLionel Sambuc llvm_unreachable("Invalid DecodeStatus!");
288f4a2713aSLionel Sambuc }
289f4a2713aSLionel Sambuc
290f4a2713aSLionel Sambuc //
291f4a2713aSLionel Sambuc // LLVMSetDisasmOptions() sets the disassembler's options. It returns 1 if it
292f4a2713aSLionel Sambuc // can set all the Options and 0 otherwise.
293f4a2713aSLionel Sambuc //
LLVMSetDisasmOptions(LLVMDisasmContextRef DCR,uint64_t Options)294f4a2713aSLionel Sambuc int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){
295f4a2713aSLionel Sambuc if (Options & LLVMDisassembler_Option_UseMarkup){
296f4a2713aSLionel Sambuc LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
297f4a2713aSLionel Sambuc MCInstPrinter *IP = DC->getIP();
298f4a2713aSLionel Sambuc IP->setUseMarkup(1);
299f4a2713aSLionel Sambuc DC->addOptions(LLVMDisassembler_Option_UseMarkup);
300f4a2713aSLionel Sambuc Options &= ~LLVMDisassembler_Option_UseMarkup;
301f4a2713aSLionel Sambuc }
302f4a2713aSLionel Sambuc if (Options & LLVMDisassembler_Option_PrintImmHex){
303f4a2713aSLionel Sambuc LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
304f4a2713aSLionel Sambuc MCInstPrinter *IP = DC->getIP();
305f4a2713aSLionel Sambuc IP->setPrintImmHex(1);
306f4a2713aSLionel Sambuc DC->addOptions(LLVMDisassembler_Option_PrintImmHex);
307f4a2713aSLionel Sambuc Options &= ~LLVMDisassembler_Option_PrintImmHex;
308f4a2713aSLionel Sambuc }
309f4a2713aSLionel Sambuc if (Options & LLVMDisassembler_Option_AsmPrinterVariant){
310f4a2713aSLionel Sambuc LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
311f4a2713aSLionel Sambuc // Try to set up the new instruction printer.
312f4a2713aSLionel Sambuc const MCAsmInfo *MAI = DC->getAsmInfo();
313f4a2713aSLionel Sambuc const MCInstrInfo *MII = DC->getInstrInfo();
314f4a2713aSLionel Sambuc const MCRegisterInfo *MRI = DC->getRegisterInfo();
315f4a2713aSLionel Sambuc const MCSubtargetInfo *STI = DC->getSubtargetInfo();
316f4a2713aSLionel Sambuc int AsmPrinterVariant = MAI->getAssemblerDialect();
317f4a2713aSLionel Sambuc AsmPrinterVariant = AsmPrinterVariant == 0 ? 1 : 0;
318f4a2713aSLionel Sambuc MCInstPrinter *IP = DC->getTarget()->createMCInstPrinter(
319f4a2713aSLionel Sambuc AsmPrinterVariant, *MAI, *MII, *MRI, *STI);
320f4a2713aSLionel Sambuc if (IP) {
321f4a2713aSLionel Sambuc DC->setIP(IP);
322f4a2713aSLionel Sambuc DC->addOptions(LLVMDisassembler_Option_AsmPrinterVariant);
323f4a2713aSLionel Sambuc Options &= ~LLVMDisassembler_Option_AsmPrinterVariant;
324f4a2713aSLionel Sambuc }
325f4a2713aSLionel Sambuc }
326f4a2713aSLionel Sambuc if (Options & LLVMDisassembler_Option_SetInstrComments) {
327f4a2713aSLionel Sambuc LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
328f4a2713aSLionel Sambuc MCInstPrinter *IP = DC->getIP();
329f4a2713aSLionel Sambuc IP->setCommentStream(DC->CommentStream);
330f4a2713aSLionel Sambuc DC->addOptions(LLVMDisassembler_Option_SetInstrComments);
331f4a2713aSLionel Sambuc Options &= ~LLVMDisassembler_Option_SetInstrComments;
332f4a2713aSLionel Sambuc }
333f4a2713aSLionel Sambuc if (Options & LLVMDisassembler_Option_PrintLatency) {
334f4a2713aSLionel Sambuc LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
335f4a2713aSLionel Sambuc DC->addOptions(LLVMDisassembler_Option_PrintLatency);
336f4a2713aSLionel Sambuc Options &= ~LLVMDisassembler_Option_PrintLatency;
337f4a2713aSLionel Sambuc }
338f4a2713aSLionel Sambuc return (Options == 0);
339f4a2713aSLionel Sambuc }
340