43#define DEBUG_TYPE "asm-printer"
45unsigned AsmPrinter::addInlineAsmDiagBuffer(
StringRef AsmStr,
46 const MDNode *LocMDNode)
const {
48 Context.initInlineSourceManager();
50 std::vector<const MDNode *> &LocInfos =
Context.getLocInfos();
52 std::unique_ptr<MemoryBuffer> Buffer;
62 LocInfos.resize(BufNum);
63 LocInfos[BufNum - 1] = LocMDNode;
75 assert(!Str.empty() &&
"Can't emit empty inline asm block");
78 bool isNullTerminated = Str.back() == 0;
80 Str = Str.substr(0, Str.size()-1);
88 assert(MCAI &&
"No MCAsmInfo");
98 unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode);
102 std::unique_ptr<MCAsmParser> Parser(
113 assert(MII &&
"Failed to create instruction info");
115 STI, *Parser, *MII, MCOptions));
118 " we don't have an asm parser for this target\n");
119 Parser->setAssemblerDialect(Dialect);
120 Parser->setTargetParser(*TAP);
124 Parser->getLexer().setLexMasmIntegers(
true);
128 (void)Parser->Run(
true,
139 if (InputIsIntelDialect) {
141 OS <<
"\t.intel_syntax\n\t";
145 const char *LastEmitted = AsmStr;
146 unsigned NumOperands =
MI->getNumOperands();
148 int AsmPrinterVariant;
149 if (InputIsIntelDialect)
150 AsmPrinterVariant = 1;
158 while (*LastEmitted) {
159 switch (*LastEmitted) {
162 const char *LiteralEnd = LastEmitted+1;
163 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
164 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
166 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
167 OS.
write(LastEmitted, LiteralEnd - LastEmitted);
168 LastEmitted = LiteralEnd;
180 switch (*LastEmitted) {
181 default:
Done =
false;
break;
183 if (!InputIsIntelDialect)
184 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
190 if (CurVariant != -1)
192 Twine(AsmStr) +
"'");
197 if (CurVariant == -1)
204 if (CurVariant == -1)
212 bool HasCurlyBraces =
false;
213 if (*LastEmitted ==
'{') {
215 HasCurlyBraces =
true;
221 if (HasCurlyBraces && *LastEmitted ==
':') {
223 const char *StrStart = LastEmitted;
224 const char *StrEnd = strchr(StrStart,
'}');
227 " string: '" +
Twine(AsmStr) +
"'");
228 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
230 LastEmitted = StrEnd+1;
234 const char *IDStart = LastEmitted;
235 const char *IDEnd = IDStart;
240 if (
StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
242 Twine(AsmStr) +
"'");
245 if (Val >= NumOperands - 1)
247 Twine(AsmStr) +
"'");
249 char Modifier[2] = { 0, 0 };
251 if (HasCurlyBraces) {
254 if (*LastEmitted ==
':') {
256 if (*LastEmitted == 0)
258 Twine(AsmStr) +
"'");
260 Modifier[0] = *LastEmitted;
264 if (*LastEmitted !=
'}')
266 Twine(AsmStr) +
"'");
272 if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
279 if (OpNo >=
MI->getNumOperands())
282 OpNo +=
F.getNumOperandRegisters() + 1;
288 if (OpNo >=
MI->getNumOperands() ||
MI->getOperand(OpNo).isMetadata()) {
297 if (
MI->getOperand(OpNo).isBlockAddress()) {
302 }
else if (
MI->getOperand(OpNo).isMBB()) {
305 }
else if (
F.isMemKind()) {
307 MI, OpNo, Modifier[0] ? Modifier :
nullptr,
OS);
310 Modifier[0] ? Modifier :
nullptr,
OS);
316 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
324 if (InputIsIntelDialect)
325 OS <<
"\n\t.att_syntax";
332 assert(
MI->isInlineAsm() &&
"printInlineAsm only works on inline asms");
335 const char *AsmStr =
MI->getOperand(0).getSymbolName();
339 if (AsmStr[0] == 0) {
352 const MDNode *LocMD =
nullptr;
354 if (MO.isMetadata() && (LocMD = MO.getMetadata()) &&
357 mdconst::dyn_extract<ConstantInt>(LocMD->
getOperand(0))) {
358 LocCookie = CI->getZExtValue();
383 if (
F.isClobberKind()) {
385 if (!
TRI->isAsmClobberable(*
MF, Reg))
389 I +=
F.getNumOperandRegisters();
392 if (!RestrRegs.
empty()) {
393 std::string
Msg =
"inline asm clobber list contains reserved registers: ";
395 for (
const Register RR : RestrRegs) {
397 Msg +=
TRI->getRegAsmName(RR);
400 "Reserved registers on the clobber list may not be "
401 "preserved across the asm statement, and clobbering them may "
402 "lead to undefined behaviour.";
408 for (
const Register RR : RestrRegs) {
409 if (std::optional<std::string> reason =
410 TRI->explainReservedReg(*
MF, RR)) {
418 MI->getInlineAsmDialect());
433 if (Code ==
"private") {
435 OS <<
DL.getPrivateGlobalPrefix();
436 }
else if (Code ==
"comment") {
438 }
else if (Code ==
"uid") {
452 Msg <<
"Unknown special formatter '" << Code
453 <<
"' for machine instr: " << *
MI;
471 if (ExtraCode && ExtraCode[0]) {
472 if (ExtraCode[1] != 0)
return true;
476 switch (ExtraCode[0]) {
503 O << ((32 - MO.
getImm()) & 31);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void EmitInlineAsmStr(const char *AsmStr, const MachineInstr *MI, MachineModuleInfo *MMI, const MCAsmInfo *MAI, AsmPrinter *AP, uint64_t LocCookie, raw_ostream &OS)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This file defines the SmallVector class.
This class is intended to be used as a driving class for all asm writers.
virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo) const
Let the target do anything it needs to do after emitting inlineasm.
TargetMachine & TM
Target machine description.
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS, StringRef Code) const
Print information related to the specified machine instr that is independent of the operand,...
unsigned getFunctionNumber() const
Return a unique ID for the current function.
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
MCContext & OutContext
This is the context for the output file that we are streaming.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
virtual void emitInlineAsmStart() const
Let the target do anything it needs to do before emitting inlineasm.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
The address of a basic block.
This is the shared class of boolean and integer constants.
A parsed version of the target data layout string in and methods for querying it.
Diagnostic information for inline asm reporting.
Lightweight error class with error context and mandatory checking.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
void emitError(uint64_t LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
virtual int unqualifiedInlineAsmVariant() const
The default variant to use in unqualified asm instructions.
This class is intended to be used as a base class for asm properties and features specific to the tar...
const char * getInlineAsmStart() const
bool useIntegratedAssembler() const
Return true if assembly (inline or otherwise) should be parsed.
const char * getInlineAsmEnd() const
StringRef getCommentString() const
bool getEmitGNUAsmStartIndentationMarker() const
bool parseInlineAsmUsingAsmParser() const
Return true if target want to use AsmParser to parse inlineasm.
Context object for machine code objects.
void registerInlineAsmLabel(MCSymbol *Sym)
registerInlineAsmLabel - Records that the name is a label referenced in inline assembly.
SourceMgr * getInlineSourceManager()
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
std::vector< std::string > IASSearchPaths
Additional paths to search for .include directives when using the integrated assembler.
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Representation of each machine instruction.
This class contains meta information specific to a module.
const MCContext & getContext() const
const Module * getModule() const
const LLVMTargetMachine & getTarget() const
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
int64_t getOffset() const
Return the offset from the symbol in this operand.
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.
LLVMContext & getContext() const
Get the global data context.
Wrapper class representing virtual and physical registers.
Represents a location in source code.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
void setIncludeDirs(const std::vector< std::string > &Dirs)
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
StringRef - Represent a constant reference to a string, i.e.
const Target & getTarget() const
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
MCTargetOptions MCOptions
Machine level options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
MCTargetAsmParser * createMCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) const
createMCAsmParser - Create a target specific assembly parser.
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
const CustomOperand< const MCSubtargetInfo & > Msg[]
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
auto reverse(ContainerTy &&C)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, unsigned CB=0)
Create an MCAsmParser instance for parsing assembly similar to gas syntax.