From 9bffb0701d02a10e77e1ac0f196074eed6466ed0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 23 Apr 2010 16:29:58 +0000 Subject: [PATCH] david conrad points out that {|} in inline assembly on arm are not asm 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 | 10 ++++++++++ lib/AST/Stmt.cpp | 9 ++++++--- lib/Basic/TargetInfo.cpp | 1 + lib/Basic/Targets.cpp | 4 ++++ test/CodeGen/arm_asm_clobber.c | 13 ++++++++++++- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index f89d5649e7..5bb0079dc1 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -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 { diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 97023820e2..ee4a74a612 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -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 using namespace clang; @@ -240,6 +241,8 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl&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&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: diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index b259facbb7..4c0c59a109 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -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; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 832c91cfb6..3d5048ccb9 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -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) { diff --git a/test/CodeGen/arm_asm_clobber.c b/test/CodeGen/arm_asm_clobber.c index a7ca0b5332..aac47d57dc 100644 --- a/test/CodeGen/arm_asm_clobber.c +++ b/test/CodeGen/arm_asm_clobber.c @@ -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)); +} -- 2.40.0