41 #define DEBUG_TYPE "asm-printer" 49 assert(DiagInfo &&
"Diagnostic context not passed down?");
53 const MDNode *LocInfo =
nullptr;
54 if (BufNum > 0 && BufNum <= DiagInfo->LocInfos.size())
55 LocInfo = DiagInfo->
LocInfos[BufNum-1];
59 unsigned LocCookie = 0;
67 mdconst::dyn_extract<ConstantInt>(LocInfo->
getOperand(ErrorLine)))
68 LocCookie = CI->getZExtValue();
74 unsigned AsmPrinter::addInlineAsmDiagBuffer(
StringRef AsmStr,
75 const MDNode *LocMDNode)
const {
77 DiagInfo = make_unique<SrcMgrDiagInfo>();
92 std::unique_ptr<MemoryBuffer> Buffer;
102 DiagInfo->LocInfos.resize(BufNum);
103 DiagInfo->LocInfos[BufNum - 1] = LocMDNode;
115 assert(!Str.
empty() &&
"Can't emit empty inline asm block");
118 bool isNullTerminated = Str.
back() == 0;
119 if (isNullTerminated)
128 assert(MCAI &&
"No MCAsmInfo");
137 unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode);
152 STI, *Parser, *MII, MCOptions));
155 " we don't have an asm parser for this target\n");
156 Parser->setAssemblerDialect(Dialect);
157 Parser->setTargetParser(*TAP.get());
162 Parser->getLexer().setLexMasmIntegers(
true);
170 int Res = Parser->Run(
true,
174 if (Res && !DiagInfo->DiagHandler)
183 OS <<
"\t.intel_syntax\n\t";
185 const char *LastEmitted = AsmStr;
188 while (*LastEmitted) {
189 switch (*LastEmitted) {
192 const char *LiteralEnd = LastEmitted+1;
193 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
194 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
197 OS.
write(LastEmitted, LiteralEnd-LastEmitted);
198 LastEmitted = LiteralEnd;
210 switch (*LastEmitted) {
211 default: Done =
false;
break;
221 if (LastEmitted[0] ==
'{' && LastEmitted[1] ==
':') {
223 const char *StrStart = LastEmitted;
224 const char *StrEnd = strchr(StrStart,
'}');
227 " string: '" +
Twine(AsmStr) +
"'");
229 std::string Val(StrStart, StrEnd);
231 LastEmitted = StrEnd+1;
235 const char *IDStart = LastEmitted;
236 const char *IDEnd = IDStart;
237 while (*IDEnd >=
'0' && *IDEnd <=
'9') ++IDEnd;
242 Twine(AsmStr) +
"'");
245 if (Val >= NumOperands-1)
247 Twine(AsmStr) +
"'");
283 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
290 OS <<
"\n\t.att_syntax\n" << (
char)0;
298 const char *LastEmitted = AsmStr;
303 while (*LastEmitted) {
304 switch (*LastEmitted) {
307 const char *LiteralEnd = LastEmitted+1;
308 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
309 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
311 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
312 OS.
write(LastEmitted, LiteralEnd-LastEmitted);
313 LastEmitted = LiteralEnd;
325 switch (*LastEmitted) {
326 default: Done =
false;
break;
328 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
334 if (CurVariant != -1)
336 Twine(AsmStr) +
"'");
341 if (CurVariant == -1)
348 if (CurVariant == -1)
356 bool HasCurlyBraces =
false;
357 if (*LastEmitted ==
'{') {
359 HasCurlyBraces =
true;
365 if (HasCurlyBraces && *LastEmitted ==
':') {
367 const char *StrStart = LastEmitted;
368 const char *StrEnd = strchr(StrStart,
'}');
371 " string: '" +
Twine(AsmStr) +
"'");
373 std::string Val(StrStart, StrEnd);
375 LastEmitted = StrEnd+1;
379 const char *IDStart = LastEmitted;
380 const char *IDEnd = IDStart;
381 while (*IDEnd >=
'0' && *IDEnd <=
'9') ++IDEnd;
386 Twine(AsmStr) +
"'");
389 char Modifier[2] = { 0, 0 };
391 if (HasCurlyBraces) {
394 if (*LastEmitted ==
':') {
396 if (*LastEmitted == 0)
398 Twine(AsmStr) +
"'");
400 Modifier[0] = *LastEmitted;
404 if (*LastEmitted !=
'}')
406 Twine(AsmStr) +
"'");
410 if (Val >= NumOperands-1)
412 Twine(AsmStr) +
"'");
416 if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
438 if (Modifier[0] ==
'l') {
445 Modifier[0] ? Modifier :
nullptr,
449 Modifier[0] ? Modifier :
nullptr, OS);
456 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
464 OS <<
'\n' << (
char)0;
473 unsigned NumDefs = 0;
485 if (AsmStr[0] == 0) {
497 unsigned LocCookie = 0;
498 const MDNode *LocMD =
nullptr;
504 mdconst::dyn_extract<ConstantInt>(LocMD->
getOperand(0))) {
505 LocCookie = CI->getZExtValue();
533 std::vector<std::string> RestrRegs;
539 unsigned Flags = MO.
getImm();
550 if (!RestrRegs.empty()) {
551 unsigned BufNum = addInlineAsmDiagBuffer(OS.
str(), LocMD);
552 auto &
SrcMgr = DiagInfo->SrcMgr;
554 SrcMgr.getMemoryBuffer(BufNum)->getBuffer().begin());
556 std::string Msg =
"inline asm clobber list contains reserved registers: ";
557 for (
auto I = RestrRegs.begin(),
E = RestrRegs.end();
I !=
E;
I++) {
558 if(
I != RestrRegs.begin())
562 std::string
Note =
"Reserved registers on the clobber list may not be " 563 "preserved across the asm statement, and clobbering them may " 564 "lead to undefined behaviour.";
585 const char *Code)
const {
586 if (!strcmp(Code,
"private")) {
589 }
else if (!strcmp(Code,
"comment")) {
591 }
else if (!strcmp(Code,
"uid")) {
605 Msg <<
"Unknown special formatter '" << Code
606 <<
"' for machine instr: " << *
MI;
615 unsigned AsmVariant,
const char *ExtraCode,
618 if (ExtraCode && ExtraCode[0]) {
619 if (ExtraCode[1] != 0)
return true;
622 switch (ExtraCode[0]) {
638 O << ((32 - MO.
getImm()) & 31);
virtual void emitInlineAsmStart() const
Let the target do anything it needs to do before emitting inlineasm.
A parsed version of the target data layout string in and methods for querying it. ...
const char * getInlineAsmStart() const
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
MachineBasicBlock * getMBB() const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
MCTargetOptions MCOptions
Machine level options.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
StringRef getPrivateGlobalPrefix() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool EnablePrintSchedInfo
Enable print [latency:throughput] in output.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
unsigned getReg() const
getReg - Returns the register number.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
bool SanitizeAddress
Enables AddressSanitizer instrumentation at machine level.
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
void * getInlineAsmDiagnosticContext() const
getInlineAsmDiagnosticContext - Return the diagnostic context set by setInlineAsmDiagnosticHandler.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
A raw_ostream that writes to an SmallVector or SmallString.
bool isMetadata() const
isMetadata - Tests if this is a MO_Metadata operand.
unsigned const TargetRegisterInfo * TRI
MachineFunction * MF
The current machine function.
const MDOperand & getOperand(unsigned I) const
const char * getInlineAsmEnd() const
LLVMContext::InlineAsmDiagHandlerTy DiagHandler
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, unsigned CB=0)
Create an MCAsmParser instance.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
unsigned getNumOperands() const
Retuns the total number of operands.
LLVMContext & getContext() const
Get the global data context.
const char * getSymbolName() const
virtual unsigned getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
Context object for machine code objects.
void emitError(unsigned LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
const MCContext & getContext() const
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
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...
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).
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
const char * getName(unsigned RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register...
This class is intended to be used as a base class for asm properties and features specific to the tar...
void setInlineSourceManager(SourceMgr *SM)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
const MCAsmInfo * MAI
Target Asm Printer information.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This is an important class for using LLVM in a threaded context.
unsigned getAssemblerDialect() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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...
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
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...
StringRef getCommentString() const
static unsigned getKind(unsigned Flags)
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...
const Target & getTarget() const
static bool isMemKind(unsigned Flag)
MCTargetAsmParser * createMCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) const
createMCAsmParser - Create a target specific assembly parser.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM_NODISCARD char back() const
back - Get the last character in the string.
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
raw_ostream & write(unsigned char C)
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.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
InlineAsm::AsmDialect getInlineAsmDialect() 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.
virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo) const
Let the target do anything it needs to do after emitting inlineasm.
StringRef str()
Return a StringRef for the vector contents.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
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...
bool useIntegratedAssembler() const
Return true if assembly (inline or otherwise) should be parsed.
static SMLoc getFromPointer(const char *Ptr)
Representation of each machine instruction.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Generic base class for all target subtargets.
InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const
getInlineAsmDiagnosticHandler - Return the diagnostic handler set by setInlineAsmDiagnosticHandler.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
const Module * getModule() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
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.
This class implements an extremely fast bulk output stream that can only output to a stream...
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)
virtual bool isAsmClobberable(const MachineFunction &MF, unsigned PhysReg) const
Returns false if we can't guarantee that Physreg, specified as an IR asm clobber constraint, will be preserved across the statement.
std::vector< const MDNode * > LocInfos
Represents a location in source code.
unsigned getNumOperands() const
Return number of MDNode operands.
const MachineOperand & getOperand(unsigned i) const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
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 MDNode * getMetadata() const
This class contains meta information specific to a module.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.