From: Chris Lattner Date: Tue, 10 Mar 2009 06:33:24 +0000 (+0000) Subject: move matching of named operands into AsmStmt class. At the same X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=10ca96ae9aed6906c3302403ef1a146a8d4c6b74;p=clang move matching of named operands into AsmStmt class. At the same time handle + operands in operand counting, fixing asm.c:t7 to expand into $2 instead of $1. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66531 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 40420ddc4b..cb4159d61e 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -982,6 +982,15 @@ public: const Expr *getInputExpr(unsigned i) const { return const_cast(this)->getInputExpr(i); } + + //===--- Other ---===// + + /// getNamedOperand - Given a symbolic operand reference like %[foo], + /// translate this into a numeric value needed to reference the same operand. + /// This returns -1 if the operand name is invalid. + int getNamedOperand(const std::string &SymbolicName) const; + + const StringLiteral *getAsmString() const { return AsmStr; } StringLiteral *getAsmString() { return AsmStr; } diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 682a9b1ee4..b7feda9b8f 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -154,6 +154,31 @@ std::string AsmStmt::getInputConstraint(unsigned i) const { Constraints[i + NumOutputs]->getByteLength()); } + +/// getNamedOperand - Given a symbolic operand reference like %[foo], +/// translate this into a numeric value needed to reference the same operand. +/// This returns -1 if the operand name is invalid. +int AsmStmt::getNamedOperand(const std::string &SymbolicName) const { + unsigned NumPlusOperands = 0; + + // Check if this is an output operand. + for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) { + if (getOutputName(i) == SymbolicName) + return i; + + // Keep track of the number of '+' operands. + if (isOutputPlusConstraint(i)) ++NumPlusOperands; + } + + for (unsigned i = 0, e = getNumInputs(); i != e; ++i) + if (getInputName(i) == SymbolicName) + return getNumOutputs() + NumPlusOperands + i; + + // Not found. + return -1; +} + + //===----------------------------------------------------------------------===// // Constructors //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index ff1f76f4a3..93c4f5b07d 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -771,34 +771,15 @@ static std::string ConvertAsmString(const AsmStmt& S, bool &Failed) { if (EscapedChar == '[') { const char *NameEnd = (const char*)memchr(StrStart, ']', StrEnd-StrStart); // FIXME: Should be caught by sema. + // FIXME: Does sema catch multiple operands with the same name? assert(NameEnd != 0 && "Could not parse symbolic name"); - std::string SymbolicName(StrStart, NameEnd); - StrStart = NameEnd+1; - int Index = -1; - - // Check if this is an output operand. - for (unsigned i = 0; i != S.getNumOutputs(); ++i) { - if (S.getOutputName(i) == SymbolicName) { - Index = i; - break; - } - } - - if (Index == -1) { - for (unsigned i = 0; i != S.getNumInputs(); ++i) { - if (S.getInputName(i) == SymbolicName) { - Index = S.getNumOutputs() + i; - break; - } - } - } - - assert(Index != -1 && "Did not find right operand!"); - - Result += '$' + llvm::utostr(Index); + int OperandIndex = S.getNamedOperand(SymbolicName); + assert(OperandIndex != -1 && "FIXME: Catch in Sema."); + + Result += '$' + llvm::utostr(unsigned(OperandIndex)); continue; } diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c index e8088d40b1..4e6ff4da90 100644 --- a/test/CodeGen/asm.c +++ b/test/CodeGen/asm.c @@ -1,21 +1,17 @@ -// RUN: clang -emit-llvm %s -o %t -arch=i386 -void t1(int len) -{ +// RUN: clang -emit-llvm %s -o %t -arch=i386 && +void t1(int len) { __asm__ volatile("" : "=&r"(len), "+&r"(len)); } -void t2(unsigned long long t) -{ +void t2(unsigned long long t) { __asm__ volatile("" : "+m"(t)); } -void t3(unsigned char *src, unsigned long long temp) -{ +void t3(unsigned char *src, unsigned long long temp) { __asm__ volatile("" : "+m"(temp), "+r"(src)); } -void t4() -{ +void t4() { unsigned long long a; struct reg { unsigned long long a, b; } b; @@ -23,13 +19,16 @@ void t4() } // PR3417 -void t5(int i) -{ +void t5(int i) { asm("nop" : "=r"(i) : "0"(t5)); } // PR3641 -void t6(void) -{ +void t6(void) { __asm__ volatile("" : : "i" (t6)); } + +// RUN: grep "T7 NAMED: \$2" %t +void t7(int a) { + __asm__ volatile("T7 NAMED: %[input]" : "+r"(a): [input] "i" (4)); +} \ No newline at end of file