diff options
-rw-r--r-- | include/llvm/CodeGen/AsmPrinter.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 21 | ||||
-rw-r--r-- | test/CodeGen/Generic/inline-asm-special-strings.ll | 6 |
3 files changed, 27 insertions, 2 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index c619655e7a..c0ef133103 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -176,7 +176,7 @@ namespace llvm { /// or other bits of target-specific knowledge into the asmstrings. The /// syntax used is ${:comment}. Targets can override this to add support /// for their own strange codes. - virtual void PrintSpecial(const MachineInstr *MI, const char *Code); + virtual void PrintSpecial(const MachineInstr *MI, const char *Code) const; /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM /// instruction, using the specified assembler variant. Targets should diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 0e04a16c86..2a3a8bb32d 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1185,7 +1185,7 @@ void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { /// or other bits of target-specific knowledge into the asmstrings. The /// syntax used is ${:comment}. Targets can override this to add support /// for their own strange codes. -void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) { +void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) const { if (!strcmp(Code, "private")) { O << TAI->getPrivateGlobalPrefix(); } else if (!strcmp(Code, "comment")) { @@ -1307,6 +1307,25 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { HasCurlyBraces = true; } + // If we have ${:foo}, then this is not a real operand reference, it is a + // "magic" string reference, just like in .td files. Arrange to call + // PrintSpecial. + if (HasCurlyBraces && *LastEmitted == ':') { + ++LastEmitted; + const char *StrStart = LastEmitted; + const char *StrEnd = strchr(StrStart, '}'); + if (StrEnd == 0) { + cerr << "Unterminated ${:foo} operand in inline asm string: '" + << AsmStr << "'\n"; + exit(1); + } + + std::string Val(StrStart, StrEnd); + PrintSpecial(MI, Val.c_str()); + LastEmitted = StrEnd+1; + break; + } + const char *IDStart = LastEmitted; char *IDEnd; errno = 0; diff --git a/test/CodeGen/Generic/inline-asm-special-strings.ll b/test/CodeGen/Generic/inline-asm-special-strings.ll new file mode 100644 index 0000000000..e52e0be74b --- /dev/null +++ b/test/CodeGen/Generic/inline-asm-special-strings.ll @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s | llc | grep "foo 0 0" + +define void @bar() nounwind { + tail call void asm sideeffect "foo ${:uid} ${:uid}", ""() nounwind + ret void +} |