]> granicus.if.org Git - clang/commitdiff
david conrad points out that {|} in inline assembly on arm are not asm
authorChris Lattner <sabre@nondot.org>
Fri, 23 Apr 2010 16:29:58 +0000 (16:29 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 23 Apr 2010 16:29:58 +0000 (16:29 +0000)
variants.  This fixes neon inline asm which my patch for PR6780 broke.

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

include/clang/Basic/TargetInfo.h
lib/AST/Stmt.cpp
lib/Basic/TargetInfo.cpp
lib/Basic/Targets.cpp
test/CodeGen/arm_asm_clobber.c

index f89d5649e7d61645c3efd5b5acdafcd0ecd556de..5bb0079dc1fcdba47a170802630fbb5772b70727 100644 (file)
@@ -45,6 +45,7 @@ protected:
   // Target values set by the ctor of the actual target implementation.  Default
   // values are specified by the TargetInfo constructor.
   bool TLSSupported;
+  bool NoAsmVariants;  // True if {|} are normal characters.
   unsigned char PointerWidth, PointerAlign;
   unsigned char IntWidth, IntAlign;
   unsigned char FloatWidth, FloatAlign;
@@ -414,6 +415,15 @@ public:
     return TLSSupported;
   }
   
+  /// hasNoAsmVariants - Return true if {|} are normal characters in the
+  /// asm string.  If this returns false (the default), then {abc|xyz} is syntax
+  /// that says that when compmiling for asm variant #0, "abc" should be
+  /// generated, but when compiling for asm variant #1, "xyz" should be
+  /// generated.
+  bool hasNoAsmVariants() const {
+    return NoAsmVariants;
+  }
+  
   /// getEHDataRegisterNumber - Return the register number that
   /// __builtin_eh_return_regno would return with the specified argument.
   virtual int getEHDataRegisterNumber(unsigned RegNo) const {
index 97023820e247538abe4bd00051f73b767c8d722c..ee4a74a6125dea21f758422c89452aac3b95b379 100644 (file)
@@ -19,6 +19,7 @@
 #include "clang/AST/Type.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
+#include "clang/Basic/TargetInfo.h"
 #include <cstdio>
 using namespace clang;
 
@@ -240,6 +241,8 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
   // asm string.
   std::string CurStringPiece;
 
+  bool HasVariants = !C.Target.hasNoAsmVariants();
+  
   while (1) {
     // Done with the string?
     if (CurPtr == StrEnd) {
@@ -251,9 +254,9 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
     char CurChar = *CurPtr++;
     switch (CurChar) {
     case '$': CurStringPiece += "$$"; continue;
-    case '{': CurStringPiece += "$("; continue;
-    case '|': CurStringPiece += "$|"; continue;
-    case '}': CurStringPiece += "$)"; continue;
+    case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue;
+    case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue;
+    case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue;
     case '%':
       break;
     default:
index b259facbb7c28df3f49efae0138ce9560d15905c..4c0c59a109e74e505e6f0acae90685375fb1ce2f 100644 (file)
@@ -23,6 +23,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
   // Set defaults.  Defaults are set for a 32-bit RISC platform, like PPC or
   // SPARC.  These should be overridden by concrete targets as needed.
   TLSSupported = true;
+  NoAsmVariants = false;
   PointerWidth = PointerAlign = 32;
   IntWidth = IntAlign = 32;
   LongWidth = LongAlign = 32;
index 832c91cfb61b8a5264bf04a2b24f1211c6239c28..3d5048ccb9bf7ac697512a23acbb7c12ba4989b9 100644 (file)
@@ -1396,6 +1396,10 @@ public:
     SizeType = UnsignedInt;
     PtrDiffType = SignedInt;
 
+    // {} in inline assembly are neon specifiers, not assembly variant
+    // specifiers.
+    NoAsmVariants = true;
+    
     // FIXME: Should we just treat this as a feature?
     IsThumb = getTriple().getArchName().startswith("thumb");
     if (IsThumb) {
index a7ca0b5332b02e49a5f37dd4d8962e609c43f177..aac47d57dc5abdb280bccfb933291a6610274c6f 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple armv6-unknown-unknown -emit-llvm -o %t %s
+// RUN: %clang_cc1 -triple armv6-unknown-unknown -emit-llvm -o - %s | FileCheck %s
 
 void test0(void) {
        asm volatile("mov r0, r0" :: );
@@ -19,3 +19,14 @@ void test3(void) {
        asm volatile("mov r0, r0" :::
                                 "v1", "v2", "v3", "v5");
 }
+
+
+// {} should not be treated as asm variants.
+void test4(float *a, float *b) {
+  // CHECK: @test4
+  // CHECK: call void asm sideeffect "vld1.32 {d8[],d9[]}, 
+  __asm__ volatile (
+                    "vld1.32 {d8[],d9[]}, [%1,:32] \n\t"
+                    "vst1.32 {q4},        [%0,:128] \n\t"
+                    :: "r"(a), "r"(b));
+}