41 #define DEBUG_TYPE "asm-printer"
44 struct SrcMgrDiagInfo {
55 SrcMgrDiagInfo *DiagInfo =
static_cast<SrcMgrDiagInfo *
>(diagInfo);
56 assert(DiagInfo &&
"Diagnostic context not passed down?");
60 unsigned LocCookie = 0;
61 if (
const MDNode *LocInfo = DiagInfo->LocInfo) {
63 if (ErrorLine >= LocInfo->getNumOperands())
66 if (LocInfo->getNumOperands() != 0)
68 mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine)))
69 LocCookie = CI->getZExtValue();
72 DiagInfo->DiagHandler(Diag, DiagInfo->DiagContext, LocCookie);
80 assert(!Str.
empty() &&
"Can't emit empty inline asm block");
83 bool isNullTerminated = Str.
back() == 0;
93 assert(MCAI &&
"No MCAsmInfo");
103 SrcMgrDiagInfo DiagInfo;
107 bool HasDiagHandler =
false;
111 DiagInfo.LocInfo = LocMDNode;
115 HasDiagHandler =
true;
118 std::unique_ptr<MemoryBuffer> Buffer;
119 if (isNullTerminated)
127 std::unique_ptr<MCAsmParser> Parser(
142 TmpSTI, *Parser, *MII, MCOptions));
145 " we don't have an asm parser for this target\n");
146 Parser->setAssemblerDialect(Dialect);
147 Parser->setTargetParser(*TAP.get());
155 int Res = Parser->Run(
true,
158 if (Res && !HasDiagHandler)
167 OS <<
"\t.intel_syntax\n\t";
169 const char *LastEmitted = AsmStr;
172 while (*LastEmitted) {
173 switch (*LastEmitted) {
176 const char *LiteralEnd = LastEmitted+1;
177 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
178 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
181 OS.
write(LastEmitted, LiteralEnd-LastEmitted);
182 LastEmitted = LiteralEnd;
194 switch (*LastEmitted) {
195 default: Done =
false;
break;
202 const char *IDStart = LastEmitted;
203 const char *IDEnd = IDStart;
204 while (*IDEnd >=
'0' && *IDEnd <=
'9') ++IDEnd;
207 if (
StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
209 Twine(AsmStr) +
"'");
212 if (Val >= NumOperands-1)
214 Twine(AsmStr) +
"'");
250 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
257 OS <<
"\n\t.att_syntax\n" << (char)0;
265 const char *LastEmitted = AsmStr;
270 while (*LastEmitted) {
271 switch (*LastEmitted) {
274 const char *LiteralEnd = LastEmitted+1;
275 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
276 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
278 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
279 OS.
write(LastEmitted, LiteralEnd-LastEmitted);
280 LastEmitted = LiteralEnd;
292 switch (*LastEmitted) {
293 default: Done =
false;
break;
295 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
301 if (CurVariant != -1)
303 Twine(AsmStr) +
"'");
308 if (CurVariant == -1)
315 if (CurVariant == -1)
323 bool HasCurlyBraces =
false;
324 if (*LastEmitted ==
'{') {
326 HasCurlyBraces =
true;
332 if (HasCurlyBraces && *LastEmitted ==
':') {
334 const char *StrStart = LastEmitted;
335 const char *StrEnd = strchr(StrStart,
'}');
338 " string: '" +
Twine(AsmStr) +
"'");
340 std::string Val(StrStart, StrEnd);
342 LastEmitted = StrEnd+1;
346 const char *IDStart = LastEmitted;
347 const char *IDEnd = IDStart;
348 while (*IDEnd >=
'0' && *IDEnd <=
'9') ++IDEnd;
353 Twine(AsmStr) +
"'");
356 char Modifier[2] = { 0, 0 };
358 if (HasCurlyBraces) {
361 if (*LastEmitted ==
':') {
363 if (*LastEmitted == 0)
365 Twine(AsmStr) +
"'");
367 Modifier[0] = *LastEmitted;
371 if (*LastEmitted !=
'}')
373 Twine(AsmStr) +
"'");
377 if (Val >= NumOperands-1)
379 Twine(AsmStr) +
"'");
383 if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
405 if (Modifier[0] ==
'l') {
412 Modifier[0] ? Modifier :
nullptr,
416 Modifier[0] ? Modifier :
nullptr, OS);
423 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
431 OS <<
'\n' << (char)0;
437 assert(MI->
isInlineAsm() &&
"printInlineAsm only works on inline asms");
440 unsigned NumDefs = 0;
452 if (AsmStr[0] == 0) {
464 unsigned LocCookie = 0;
465 const MDNode *LocMD =
nullptr;
471 mdconst::dyn_extract<ConstantInt>(LocMD->
getOperand(0))) {
472 LocCookie = CI->getZExtValue();
514 const char *Code)
const {
516 if (!strcmp(Code,
"private")) {
518 }
else if (!strcmp(Code,
"comment")) {
520 }
else if (!strcmp(Code,
"uid")) {
534 Msg <<
"Unknown special formatter '" << Code
535 <<
"' for machine instr: " << *
MI;
544 unsigned AsmVariant,
const char *ExtraCode,
547 if (ExtraCode && ExtraCode[0]) {
548 if (ExtraCode[1] != 0)
return true;
551 switch (ExtraCode[0]) {
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
A parsed version of the target data layout string in and methods for querying it. ...
unsigned getAssemblerDialect() const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
MCTargetOptions MCOptions
Machine level options.
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
size_t size() const
size - Get the string size.
MachineBasicBlock * getMBB() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const
getInlineAsmDiagnosticHandler - Return the diagnostic handler set by setInlineAsmDiagnosticHandler.
MCContext & OutContext
This is the context for the output file that we are streaming.
unsigned getNumOperands() const
Return number of MDNode operands.
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
bool SanitizeAddress
Enables AddressSanitizer instrumentation at machine level.
const MachineFunction * MF
The current machine function.
const char * getPrivateGlobalPrefix() const
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
A raw_ostream that writes to an SmallVector or SmallString.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
const char * getSymbolName() const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
virtual void emitInlineAsmStart() const
Let the target do anything it needs to do before emitting inlineasm.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
const MDNode * getMetadata() const
bool isMetadata() const
isMetadata - Tests if this is a MO_Metadata operand.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const Module * getModule() const
virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS, const char *Code) const
Print information related to the specified machine instr that is independent of the operand...
const char * getInlineAsmEnd() const
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
void emitError(unsigned LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
MCTargetAsmParser * createMCAsmParser(MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) const
createMCAsmParser - Create a target specific assembly parser.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)
Specify a diagnostic handler to be invoked every time PrintMessage is called.
const MCAsmInfo * MAI
Target Asm Printer information.
This is an important class for using LLVM in a threaded context.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MachineOperand & getOperand(unsigned i) const
char back() const
back - Get the last character in the string.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant...
TargetMachine & TM
Target machine description.
This class is intended to be used as a driving class for all asm writers.
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag...
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &)
Create an MCAsmParser instance.
static void srcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo)
srcMgrDiagHandler - This callback is invoked when the SourceMgr for an inline asm has an error in it...
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling...
static bool isMemKind(unsigned Flag)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MCSymbol * getSymbol() const
getSymbol - Return the MCSymbol for this basic block.
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo) const
Let the target do anything it needs to do after emitting inlineasm.
raw_ostream & write(unsigned char C)
const MDOperand & getOperand(unsigned I) const
This is the shared class of boolean and integer constants.
const DataLayout * getDataLayout() const
Deprecated in 3.7, will be removed in 3.8.
MachineOperand class - Representation of each machine instruction operand.
Module.h This file contains the declarations for the Module class.
void(* InlineAsmDiagHandlerTy)(const SMDiagnostic &, void *Context, unsigned LocCookie)
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it...
void * getInlineAsmDiagnosticContext() const
getInlineAsmDiagnosticContext - Return the diagnostic context set by setInlineAsmDiagnosticHandler.
Representation of each machine instruction.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
MCSubtargetInfo - Generic base class for all target subtargets.
A raw_ostream that writes to an std::string.
static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI, MachineModuleInfo *MMI, int InlineAsmVariant, int AsmPrinterVariant, AsmPrinter *AP, unsigned LocCookie, raw_ostream &OS)
bool useIntegratedAssembler() const
Return true if assembly (inline or otherwise) should be parsed.
This class implements an extremely fast bulk output stream that can only output to a stream...
const Target & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
StringRef - Represent a constant reference to a string, i.e.
static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI, MachineModuleInfo *MMI, int InlineAsmVariant, AsmPrinter *AP, unsigned LocCookie, raw_ostream &OS)
const char * getInlineAsmStart() const
Represents a location in source code.
const char * getCommentString() const
InlineAsm::AsmDialect getInlineAsmDialect() const
MachineModuleInfo - This class contains meta information specific to a module.
LLVMContext & getContext() const
Get the global data context.
bool empty() const
empty - Check if the string is empty.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...