]> granicus.if.org Git - clang/commitdiff
[ms-inline asm] Start tracking which tokens are registers and which are
authorChad Rosier <mcrosier@apple.com>
Thu, 16 Aug 2012 17:10:59 +0000 (17:10 +0000)
committerChad Rosier <mcrosier@apple.com>
Thu, 16 Aug 2012 17:10:59 +0000 (17:10 +0000)
variables, function or label references.  The former is a potential clobber.
The latter is either an input or an output.  Unfortunately, it's difficult to
test this patch at the moment, but the added test case will eventually do so.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162026 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaStmt.cpp
test/CodeGen/ms-inline-asm.c

index b14c7c411633355ab3137648a27a9a35e199b10b..5bd5c8a96b25bd113a3bc8c62e06f1169f807c61 100644 (file)
@@ -28,6 +28,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
@@ -2767,6 +2768,8 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
                               SourceLocation AsmLoc,
                               ArrayRef<Token> AsmToks,
                               const TargetInfo &TI,
+                              std::vector<llvm::BitVector> &AsmRegs,
+                              std::vector<llvm::BitVector> &AsmNames,
                               std::vector<std::string> &AsmStrings) {
   assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
 
@@ -2792,6 +2795,8 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
 
     // Start a new asm string with the opcode.
     if (isNewAsm) {
+      AsmRegs[NumAsmStrings].resize(AsmToks.size());
+      AsmNames[NumAsmStrings].resize(AsmToks.size());
       Asm = AsmToks[i].getIdentifierInfo()->getName().str();
       continue;
     }
@@ -2821,14 +2826,28 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
     case tok::identifier: {
       StringRef Name = AsmToks[i].getIdentifierInfo()->getName();
 
-      // Valid registers don't need modification.
+      // Valid register?
       if (TI.isValidGCCRegisterName(Name)) {
+        AsmRegs[NumAsmStrings].set(i);
         Asm += Name;
         break;
       }
 
-      // TODO: Lookup the identifier.
       IsSimple = false;
+
+      // FIXME: Why are we missing this segment register?
+      if (Name == "fs") {
+        Asm += Name;
+        break;
+      }
+
+      // Not a register, so this must be a variable, function or label
+      // reference.  Track these as they are either an Input or an Output.
+      // Unfortunately, we don't know which is which until after we feed
+      // the patched asms to the AsmParser.
+      AsmNames[NumAsmStrings].set(i);
+
+      // TODO: Lookup the identifier and patch appropriately.
       break;
     }
     } // AsmToks[i].getKind()
@@ -2897,12 +2916,17 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
   std::string AsmString = buildMSAsmString(*this, AsmToks, NumAsmStrings);
 
   bool IsSimple;
+  std::vector<llvm::BitVector> Regs;
+  std::vector<llvm::BitVector> Names;
   std::vector<std::string> PatchedAsmStrings;
+
+  Regs.resize(NumAsmStrings);
+  Names.resize(NumAsmStrings);
   PatchedAsmStrings.resize(NumAsmStrings);
 
   // Rewrite operands to appease the AsmParser.
-  patchMSAsmStrings(*this, IsSimple, AsmLoc, AsmToks, Context.getTargetInfo(),
-                    PatchedAsmStrings);
+  patchMSAsmStrings(*this, IsSimple, AsmLoc, AsmToks,
+                    Context.getTargetInfo(), Regs, Names, PatchedAsmStrings);
 
   // patchMSAsmStrings doesn't correctly patch non-simple asm statements.
   if (!IsSimple) {
index ee4ca019c73b048f95f01277757237daf32a6e39..43ecbe34f47a9fce87a082e28899faef4552fccf 100644 (file)
@@ -82,3 +82,20 @@ void t10() {
 // CHECK: t10
 // CHECK: call void asm sideeffect "push ebx\0Amov ebx, 0x07\0Apop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
 }
+
+unsigned t11(void) {
+  unsigned i = 1, j;
+  __asm {
+    mov eax, i
+    mov j, eax
+  }
+  return j;
+// CHECK: t11
+// CHECK: entry:
+// CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4
+// CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4
+// CHECK: store i32 1, i32* [[I]], align 4
+// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4
+// CHECK: ret i32 [[RET]]
+}