]> granicus.if.org Git - clang/commitdiff
[ms-inline asm] If we have a single asm operand that maps to multiple
authorChad Rosier <mcrosier@apple.com>
Wed, 12 Sep 2012 18:14:25 +0000 (18:14 +0000)
committerChad Rosier <mcrosier@apple.com>
Wed, 12 Sep 2012 18:14:25 +0000 (18:14 +0000)
MCOperands then iterate over all of then when computing clobbers, inputs and
outputs.

On x86 the 1-to-many mapping is a memory operand that includes a BaseReg(reg),
MemScale(imm), MemIndexReg(reg), an Expr(MCExpr or imm) and a MemSegReg(reg).
Invalid register (Op.getReg() == 0) are not considered when computing clobber.

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

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

index 3f57a6ec035b45eeb2ba85443a07741998668346..9109bcb854ae5c6f20bd9c0bee839a680ae78247 100644 (file)
@@ -581,62 +581,60 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
       unsigned MCIdx = TargetParser->getMCInstOperandNum(Kind, Inst, Operands,
                                                          i, NumMCOperands);
       assert (NumMCOperands && "Expected at least 1 MCOperand!");
-      // If we have a one-to-many mapping, then search for the MCExpr.
-      if (NumMCOperands > 1) {
-        bool foundExpr = false;
-        for (unsigned j = MCIdx, e = MCIdx + NumMCOperands; j != e; ++j) {
-          if (Inst.getOperand(j).isExpr()) {
-            foundExpr = true;
-            MCIdx = j;
-            break;
-          }
-        }
-        assert (foundExpr && "Expected for find an expression!");
-      }
-
-      const llvm::MCOperand &Op = Inst.getOperand(MCIdx);
 
-      // Register/Clobber.
-      if (Op.isReg() && NumDefs && (MCIdx < NumDefs)) {
-        std::string Reg;
-        llvm::raw_string_ostream OS(Reg);
-        IP->printRegName(OS, Op.getReg());
-
-        StringRef Clobber(OS.str());
-        if (!Context.getTargetInfo().isValidClobber(Clobber))
-          return StmtError(Diag(AsmLoc, diag::err_asm_unknown_register_name) <<
-                           Clobber);
-        ClobberRegs.insert(Reg);
-        continue;
-      }
-      // Expr/Input or Output.
-      if (Op.isExpr()) {
-        const llvm::MCExpr *Expr = Op.getExpr();
-        const llvm::MCSymbolRefExpr *SymRef;
-        if ((SymRef = dyn_cast<llvm::MCSymbolRefExpr>(Expr))) {
-          StringRef Name = SymRef->getSymbol().getName();
-          IdentifierInfo *II = getIdentifierInfo(Name, AsmToks,
-                                                 AsmTokRanges[StrIdx].first,
-                                                 AsmTokRanges[StrIdx].second);
-          if (II) {
-            CXXScopeSpec SS;
-            UnqualifiedId Id;
-            SourceLocation Loc;
-            Id.setIdentifier(II, AsmLoc);
-            ExprResult Result = ActOnIdExpression(getCurScope(), SS, Loc, Id,
-                                                  false, false);
-            if (!Result.isInvalid()) {
-              bool isMemDef = (i == 1) && Desc.mayStore();
-              if (isMemDef) {
-                Outputs.push_back(II);
-                OutputExprs.push_back(Result.take());
-                OutputExprNames.push_back(Name.str());
-                OutputConstraints.push_back("=r");
-              } else {
-                Inputs.push_back(II);
-                InputExprs.push_back(Result.take());
-                InputExprNames.push_back(Name.str());
-                InputConstraints.push_back("r");
+      for (unsigned j = MCIdx, e = MCIdx + NumMCOperands; j != e; ++j) {
+        const llvm::MCOperand &Op = Inst.getOperand(j);
+
+        // Skip immediates.
+        if (Op.isImm() || Op.isFPImm())
+          continue;
+
+        // Skip invalid register operands.
+        if (Op.isReg() && Op.getReg() == 0)
+          continue;
+
+        // Register/Clobber.
+        if (Op.isReg() && NumDefs && (j < NumDefs)) {
+          std::string Reg;
+          llvm::raw_string_ostream OS(Reg);
+          IP->printRegName(OS, Op.getReg());
+
+          StringRef Clobber(OS.str());
+          if (!Context.getTargetInfo().isValidClobber(Clobber))
+            return StmtError(
+              Diag(AsmLoc, diag::err_asm_unknown_register_name) << Clobber);
+          ClobberRegs.insert(Reg);
+          continue;
+        }
+        // Expr/Input or Output.
+        if (Op.isExpr()) {
+          const llvm::MCExpr *Expr = Op.getExpr();
+          const llvm::MCSymbolRefExpr *SymRef;
+          if ((SymRef = dyn_cast<llvm::MCSymbolRefExpr>(Expr))) {
+            StringRef Name = SymRef->getSymbol().getName();
+            IdentifierInfo *II = getIdentifierInfo(Name, AsmToks,
+                                                   AsmTokRanges[StrIdx].first,
+                                                   AsmTokRanges[StrIdx].second);
+            if (II) {
+              CXXScopeSpec SS;
+              UnqualifiedId Id;
+              SourceLocation Loc;
+              Id.setIdentifier(II, AsmLoc);
+              ExprResult Result = ActOnIdExpression(getCurScope(), SS, Loc, Id,
+                                                    false, false);
+              if (!Result.isInvalid()) {
+                bool isMemDef = (i == 1) && Desc.mayStore();
+                if (isMemDef) {
+                  Outputs.push_back(II);
+                  OutputExprs.push_back(Result.take());
+                  OutputExprNames.push_back(Name.str());
+                  OutputConstraints.push_back("=r");
+                } else {
+                  Inputs.push_back(II);
+                  InputExprs.push_back(Result.take());
+                  InputExprNames.push_back(Name.str());
+                  InputConstraints.push_back("r");
+                }
               }
             }
           }
index 8f8d687902da18111181228851ef29307dfe1d7d..67e0eb46b601563bd6481a5f8d116735efb5c2ff 100644 (file)
@@ -127,3 +127,15 @@ void t14(void) {
 // CHECK: t14
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
 }
+
+void t15(void) {
+  __asm mov eax, DWORD PTR [eax]
+// CHECK: t15
+// CHECK: call void asm sideeffect inteldialect "mov eax, DWORD PTR [eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+}
+
+void t16(unsigned long long V) {
+  __asm mov eax, DWORD PTR [V]
+// CHECK: t16
+// CHECK:   call void asm sideeffect inteldialect "mov eax, DWORD PTR [$0]", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i64 %0) nounwind
+}