diff options
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 17 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/ms-inline-asm.ll | 31 |
2 files changed, 48 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index 2ce6c182235..20075e41977 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -193,6 +193,23 @@ static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI, } if (Done) break; + // 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 (LastEmitted[0] == '{' && LastEmitted[1] == ':') { + LastEmitted += 2; + const char *StrStart = LastEmitted; + const char *StrEnd = strchr(StrStart, '}'); + if (!StrEnd) + report_fatal_error("Unterminated ${:foo} operand in inline asm" + " string: '" + Twine(AsmStr) + "'"); + + std::string Val(StrStart, StrEnd); + AP->PrintSpecial(MI, OS, Val.c_str()); + LastEmitted = StrEnd+1; + break; + } + const char *IDStart = LastEmitted; const char *IDEnd = IDStart; while (*IDEnd >= '0' && *IDEnd <= '9') ++IDEnd; diff --git a/llvm/test/CodeGen/X86/ms-inline-asm.ll b/llvm/test/CodeGen/X86/ms-inline-asm.ll index 428eb1b7190..ec0630a4ce0 100644 --- a/llvm/test/CodeGen/X86/ms-inline-asm.ll +++ b/llvm/test/CodeGen/X86/ms-inline-asm.ll @@ -126,6 +126,37 @@ entry: ; CHECK: ret } +; Make sure ${:uid} works. Clang uses it for MS inline asm labels. +; +; C source: +; int uid() { +; int r; +; __asm { +; xor eax, eax +; wloop: +; inc eax +; cmp eax, 42 +; jne wloop +; mov r, eax +; } +; return r; +; } +define i32 @uid() { +entry: + %r = alloca i32, align 4 + %0 = bitcast i32* %r to i8* + call void asm sideeffect inteldialect "xor eax, eax\0A\09.L__MSASMLABEL_.${:uid}__wloop:\0A\09inc eax\0A\09cmp eax, $$42\0A\09jne .L__MSASMLABEL_.${:uid}__wloop\0A\09mov dword ptr $0, eax", "=*m,~{eax},~{flags},~{dirflag},~{fpsr},~{flags}"(i32* nonnull %r) + %1 = load i32, i32* %r, align 4 + ret i32 %1 +; CHECK-LABEL: uid: +; CHECK: {{## InlineAsm Start|#APP}} +; CHECK: .L__MSASMLABEL_.0__wloop: +; CHECK: jne .L__MSASMLABEL_.0__wloop +; CHECK: .att_syntax +; CHECK: {{## InlineAsm End|#NO_APP}} +; CHECK: ret +} + declare hidden void @other_func() define void @naked() #0 { |