Go to the documentation of this file.
42 #define DEBUG_TYPE "asm-printer"
44 unsigned AsmPrinter::addInlineAsmDiagBuffer(
StringRef AsmStr,
45 const MDNode *LocMDNode)
const {
47 Context.initInlineSourceManager();
49 std::vector<const MDNode *> &LocInfos =
Context.getLocInfos();
51 std::unique_ptr<MemoryBuffer> Buffer;
61 LocInfos.resize(BufNum);
62 LocInfos[BufNum - 1] = LocMDNode;
74 assert(!Str.empty() &&
"Can't emit empty inline asm block");
77 bool isNullTerminated = Str.back() == 0;
79 Str = Str.substr(0, Str.size()-1);
87 assert(MCAI &&
"No MCAsmInfo");
97 unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode);
101 std::unique_ptr<MCAsmParser> Parser(
112 assert(MII &&
"Failed to create instruction info");
114 STI, *Parser, *MII, MCOptions));
117 " we don't have an asm parser for this target\n");
118 Parser->setAssemblerDialect(Dialect);
119 Parser->setTargetParser(*TAP);
123 Parser->getLexer().setLexMasmIntegers(
true);
127 (void)Parser->Run(
true,
138 if (InputIsIntelDialect) {
140 OS <<
"\t.intel_syntax\n\t";
144 const char *LastEmitted = AsmStr;
145 unsigned NumOperands =
MI->getNumOperands();
147 int AsmPrinterVariant;
148 if (InputIsIntelDialect)
149 AsmPrinterVariant = 1;
157 while (*LastEmitted) {
158 switch (*LastEmitted) {
161 const char *LiteralEnd = LastEmitted+1;
162 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
163 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
165 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
166 OS.
write(LastEmitted, LiteralEnd - LastEmitted);
167 LastEmitted = LiteralEnd;
179 switch (*LastEmitted) {
180 default: Done =
false;
break;
182 if (!InputIsIntelDialect)
183 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
189 if (CurVariant != -1)
191 Twine(AsmStr) +
"'");
196 if (CurVariant == -1)
203 if (CurVariant == -1)
211 bool HasCurlyBraces =
false;
212 if (*LastEmitted ==
'{') {
214 HasCurlyBraces =
true;
220 if (HasCurlyBraces && *LastEmitted ==
':') {
222 const char *StrStart = LastEmitted;
223 const char *StrEnd = strchr(StrStart,
'}');
226 " string: '" +
Twine(AsmStr) +
"'");
227 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
229 LastEmitted = StrEnd+1;
233 const char *IDStart = LastEmitted;
234 const char *IDEnd = IDStart;
239 if (
StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
241 Twine(AsmStr) +
"'");
244 if (Val >= NumOperands - 1)
246 Twine(AsmStr) +
"'");
248 char Modifier[2] = { 0, 0 };
250 if (HasCurlyBraces) {
253 if (*LastEmitted ==
':') {
255 if (*LastEmitted == 0)
257 Twine(AsmStr) +
"'");
259 Modifier[0] = *LastEmitted;
263 if (*LastEmitted !=
'}')
265 Twine(AsmStr) +
"'");
271 if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
278 if (OpNo >=
MI->getNumOperands())
280 unsigned OpFlags =
MI->getOperand(OpNo).getImm();
287 if (OpNo >=
MI->getNumOperands() ||
MI->getOperand(OpNo).isMetadata()) {
290 unsigned OpFlags =
MI->getOperand(OpNo).getImm();
296 if (
MI->getOperand(OpNo).isBlockAddress()) {
301 }
else if (
MI->getOperand(OpNo).isMBB()) {
306 MI, OpNo, Modifier[0] ? Modifier :
nullptr, OS);
309 Modifier[0] ? Modifier :
nullptr, OS);
315 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
323 if (InputIsIntelDialect)
324 OS <<
"\n\t.att_syntax";
325 OS <<
'\n' << (char)0;
331 assert(
MI->isInlineAsm() &&
"printInlineAsm only works on inline asms");
334 unsigned NumDefs = 0;
335 for (;
MI->getOperand(NumDefs).
isReg() &&
MI->getOperand(NumDefs).isDef();
337 assert(NumDefs !=
MI->getNumOperands()-2 &&
"No asm string?");
339 assert(
MI->getOperand(NumDefs).isSymbol() &&
"No asm string?");
342 const char *AsmStr =
MI->getOperand(NumDefs).getSymbolName();
346 if (AsmStr[0] == 0) {
359 const MDNode *LocMD =
nullptr;
361 if (MO.isMetadata() && (LocMD = MO.getMetadata()) &&
364 mdconst::dyn_extract<ConstantInt>(LocMD->
getOperand(0))) {
365 LocCookie = CI->getZExtValue();
389 unsigned Flags = MO.
getImm();
393 RestrRegs.push_back(
Reg);
399 if (!RestrRegs.empty()) {
400 std::string
Msg =
"inline asm clobber list contains reserved registers: ";
402 for (
const Register RR : RestrRegs) {
407 "Reserved registers on the clobber list may not be "
408 "preserved across the asm statement, and clobbering them may "
409 "lead to undefined behaviour.";
417 MI->getInlineAsmDialect());
432 if (Code ==
"private") {
434 OS <<
DL.getPrivateGlobalPrefix();
435 }
else if (Code ==
"comment") {
437 }
else if (Code ==
"uid") {
451 Msg <<
"Unknown special formatter '" << Code
452 <<
"' for machine instr: " << *
MI;
470 if (ExtraCode && ExtraCode[0]) {
471 if (ExtraCode[1] != 0)
return true;
475 switch (ExtraCode[0]) {
502 O << ((32 - MO.
getImm()) & 31);
virtual StringRef getRegAsmName(MCRegister Reg) const
Return the assembly name for Reg.
virtual int unqualifiedInlineAsmVariant() const
The default variant to use in unqualified asm instructions.
This is an optimization pass for GlobalISel generic memory operations.
StringRef getCommentString() const
void emitError(uint64_t LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool getEmitGNUAsmStartIndentationMarker() const
A parsed version of the target data layout string in and methods for querying it.
const MCContext & getContext() const
bool useIntegratedAssembler() const
Return true if assembly (inline or otherwise) should be parsed.
const GlobalValue * getGlobal() const
Context object for machine code objects.
bool parseInlineAsmUsingAsmParser() const
Return true if target want to use AsmParser to parse inlineasm.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles Note
virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo) const
Let the target do anything it needs to do after emitting inlineasm.
A raw_ostream that writes to an std::string.
const MCAsmInfo * MAI
Target Asm Printer information.
const char * getInlineAsmStart() const
This class is intended to be used as a base class for asm properties and features specific to the tar...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Reg
All possible values of the reg field in the ModR/M byte.
virtual bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const
Returns false if we can't guarantee that Physreg, specified as an IR asm clobber constraint,...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
std::vector< std::string > IASSearchPaths
Additional paths to search for .include directives when using the integrated assembler.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
int64_t getOffset() const
Return the offset from the symbol in this operand.
unsigned const TargetRegisterInfo * TRI
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
unsigned getNumOperands() const
Return number of MDNode operands.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
This is the shared class of boolean and integer constants.
Represents a location in source code.
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...
const LLVMTargetMachine & getTarget() const
MCTargetOptions MCOptions
Machine level options.
MachineOperand class - Representation of each machine instruction operand.
This class contains meta information specific to a module.
raw_ostream & write(unsigned char C)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class implements an extremely fast bulk output stream that can only output to a stream.
void registerInlineAsmLabel(MCSymbol *Sym)
registerInlineAsmLabel - Records that the name is a label referenced in inline assembly.
const char * getInlineAsmEnd() const
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
static unsigned getKind(unsigned Flags)
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.
Diagnostic information for inline asm reporting.
const MDOperand & getOperand(unsigned I) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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,...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
SourceMgr * getInlineSourceManager()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineFunction * MF
The current machine function.
MCContext & OutContext
This is the context for the output file that we are streaming.
static bool isReg(const MCInst &MI, unsigned OpNo)
The address of a basic block.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
static bool isDigit(const char C)
StringRef - Represent a constant reference to a string, i.e.
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
void setIncludeDirs(const std::vector< std::string > &Dirs)
Wrapper class representing virtual and physical registers.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
const CustomOperand< const MCSubtargetInfo & > Msg[]
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Lightweight error class with error context and mandatory checking.
virtual void emitInlineAsmStart() const
Let the target do anything it needs to do before emitting inlineasm.
LLVMContext & getContext() const
Get the global data context.
This class is intended to be used as a driving class for all asm writers.
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
TargetMachine & TM
Target machine description.
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
static void EmitInlineAsmStr(const char *AsmStr, const MachineInstr *MI, MachineModuleInfo *MMI, const MCAsmInfo *MAI, AsmPrinter *AP, uint64_t LocCookie, raw_ostream &OS)
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
A raw_ostream that writes to an SmallVector or SmallString.
MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &, unsigned CB=0)
Create an MCAsmParser instance for parsing assembly similar to gas syntax.
const Target & getTarget() const
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.
Generic base class for all target subtargets.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
const Module * getModule() const
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.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.