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");
105 SrcMgrDiagInfo DiagInfo;
109 bool HasDiagHandler =
false;
113 DiagInfo.LocInfo = LocMDNode;
117 HasDiagHandler =
true;
120 std::unique_ptr<MemoryBuffer> Buffer;
121 if (isNullTerminated)
129 std::unique_ptr<MCAsmParser> Parser(
138 STI, *Parser, *MII, MCOptions));
141 " we don't have an asm parser for this target\n");
142 Parser->setAssemblerDialect(Dialect);
143 Parser->setTargetParser(*TAP.get());
151 int Res = Parser->Run(
true,
154 if (Res && !HasDiagHandler)
163 OS <<
"\t.intel_syntax\n\t";
165 const char *LastEmitted = AsmStr;
168 while (*LastEmitted) {
169 switch (*LastEmitted) {
172 const char *LiteralEnd = LastEmitted+1;
173 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
174 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
177 OS.
write(LastEmitted, LiteralEnd-LastEmitted);
178 LastEmitted = LiteralEnd;
190 switch (*LastEmitted) {
191 default: Done =
false;
break;
201 if (LastEmitted[0] ==
'{' && LastEmitted[1] ==
':') {
203 const char *StrStart = LastEmitted;
204 const char *StrEnd = strchr(StrStart,
'}');
207 " string: '" +
Twine(AsmStr) +
"'");
209 std::string Val(StrStart, StrEnd);
211 LastEmitted = StrEnd+1;
215 const char *IDStart = LastEmitted;
216 const char *IDEnd = IDStart;
217 while (*IDEnd >=
'0' && *IDEnd <=
'9') ++IDEnd;
222 Twine(AsmStr) +
"'");
225 if (Val >= NumOperands-1)
227 Twine(AsmStr) +
"'");
263 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
270 OS <<
"\n\t.att_syntax\n" << (char)0;
278 const char *LastEmitted = AsmStr;
283 while (*LastEmitted) {
284 switch (*LastEmitted) {
287 const char *LiteralEnd = LastEmitted+1;
288 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
289 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
291 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
292 OS.
write(LastEmitted, LiteralEnd-LastEmitted);
293 LastEmitted = LiteralEnd;
305 switch (*LastEmitted) {
306 default: Done =
false;
break;
308 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
314 if (CurVariant != -1)
316 Twine(AsmStr) +
"'");
321 if (CurVariant == -1)
328 if (CurVariant == -1)
336 bool HasCurlyBraces =
false;
337 if (*LastEmitted ==
'{') {
339 HasCurlyBraces =
true;
345 if (HasCurlyBraces && *LastEmitted ==
':') {
347 const char *StrStart = LastEmitted;
348 const char *StrEnd = strchr(StrStart,
'}');
351 " string: '" +
Twine(AsmStr) +
"'");
353 std::string Val(StrStart, StrEnd);
355 LastEmitted = StrEnd+1;
359 const char *IDStart = LastEmitted;
360 const char *IDEnd = IDStart;
361 while (*IDEnd >=
'0' && *IDEnd <=
'9') ++IDEnd;
366 Twine(AsmStr) +
"'");
369 char Modifier[2] = { 0, 0 };
371 if (HasCurlyBraces) {
374 if (*LastEmitted ==
':') {
376 if (*LastEmitted == 0)
378 Twine(AsmStr) +
"'");
380 Modifier[0] = *LastEmitted;
384 if (*LastEmitted !=
'}')
386 Twine(AsmStr) +
"'");
390 if (Val >= NumOperands-1)
392 Twine(AsmStr) +
"'");
396 if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
418 if (Modifier[0] ==
'l') {
425 Modifier[0] ? Modifier :
nullptr,
429 Modifier[0] ? Modifier :
nullptr, OS);
436 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
444 OS <<
'\n' << (char)0;
453 unsigned NumDefs = 0;
465 if (AsmStr[0] == 0) {
477 unsigned LocCookie = 0;
478 const MDNode *LocMD =
nullptr;
484 mdconst::dyn_extract<ConstantInt>(LocMD->
getOperand(0))) {
485 LocCookie = CI->getZExtValue();
527 const char *Code)
const {
528 if (!
strcmp(Code,
"private")) {
531 }
else if (!
strcmp(Code,
"comment")) {
533 }
else if (!
strcmp(Code,
"uid")) {
547 Msg <<
"Unknown special formatter '" << Code
548 <<
"' for machine instr: " << *
MI;
557 unsigned AsmVariant,
const char *ExtraCode,
560 if (ExtraCode && ExtraCode[0]) {
561 if (ExtraCode[1] != 0)
return true;
564 switch (ExtraCode[0]) {
580 O << ((32 - MO.
getImm()) & 31);
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
StringRef getPrivateGlobalPrefix() 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.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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.
std::vector< std::string > IASSearchPaths
Additional paths to search for .include directives when using the integrated assembler.
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.
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
LLVM_NODISCARD char back() const
back - Get the last character in the string.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with strcmp
bool isMetadata() const
isMetadata - Tests if this is a MO_Metadata operand.
StringRef getCommentString() const
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...
MCTargetAsmParser * createMCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) const
createMCAsmParser - Create a target specific assembly parser.
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...
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
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
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...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
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
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.
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...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
Lightweight error class with error context and mandatory checking.
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
void setIncludeDirs(const std::vector< std::string > &Dirs)
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.
InlineAsm::AsmDialect getInlineAsmDialect() const
This class contains meta information specific to a module.
LLVMContext & getContext() const
Get the global data context.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...