summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2014-04-23 10:26:19 +0000
committerJames Molloy <james.molloy@arm.com>2014-04-23 10:26:19 +0000
commit8bdd24b1a9723d0c09a0f8d6179e29fa45276645 (patch)
treef7a61aa0992c62e9e0f6163f2a28a18d44d64244
parenta7a23c1cce4ad8f9f50fc1c0d55515365d40ab38 (diff)
downloadbcm5719-llvm-8bdd24b1a9723d0c09a0f8d6179e29fa45276645.tar.gz
bcm5719-llvm-8bdd24b1a9723d0c09a0f8d6179e29fa45276645.zip
[ARM64] Change inline assembly constraints to be more lax, to match the behaviour of Clang/AArch64 and GCC.
GCC allows sub-64bit values to use the 'r' register constraint. llvm-svn: 206963
-rw-r--r--clang/lib/Basic/Targets.cpp51
-rw-r--r--clang/test/CodeGen/aarch64-inline-asm.c1
-rw-r--r--clang/test/Sema/arm64-inline-asm.c3
-rw-r--r--clang/test/Sema/inline-asm-validate.c3
4 files changed, 26 insertions, 32 deletions
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 7d20f045c49..108b197daef 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -4643,46 +4643,37 @@ public:
case 'w': // Floating point and SIMD registers (V0-V31)
Info.setAllowsRegister();
return true;
+ case 'I': // Constant that can be used with an ADD instruction
+ case 'J': // Constant that can be used with a SUB instruction
+ case 'K': // Constant that can be used with a 32-bit logical instruction
+ case 'L': // Constant that can be used with a 64-bit logical instruction
+ case 'M': // Constant that can be used as a 32-bit MOV immediate
+ case 'N': // Constant that can be used as a 64-bit MOV immediate
+ case 'Y': // Floating point constant zero
+ case 'Z': // Integer constant zero
+ return true;
+ case 'Q': // A memory reference with base register and no offset
+ Info.setAllowsMemory();
+ return true;
+ case 'S': // A symbolic address
+ Info.setAllowsRegister();
+ return true;
+ case 'U':
+ // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes, whatever they may be
+ // Utf: A memory address suitable for ldp/stp in TF mode, whatever it may be
+ // Usa: An absolute symbolic address
+ // Ush: The high part (bits 32:12) of a pc-relative symbolic address
+ llvm_unreachable("FIXME: Unimplemented support for bizarre constraints");
case 'z': // Zero register, wzr or xzr
Info.setAllowsRegister();
return true;
case 'x': // Floating point and SIMD registers (V0-V15)
Info.setAllowsRegister();
return true;
- case 'Q': // A memory address that is a single base register.
- Info.setAllowsMemory();
- return true;
}
return false;
}
- virtual bool validateConstraintModifier(StringRef Constraint,
- const char Modifier,
- unsigned Size) const {
- // Strip off constraint modifiers.
- while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
- Constraint = Constraint.substr(1);
-
- switch (Constraint[0]) {
- default:
- return true;
- case 'z':
- case 'r': {
- switch (Modifier) {
- case 'x':
- case 'w':
- // For now assume that the person knows what they're
- // doing with the modifier.
- return true;
- default:
- // By default an 'r' constraint will be in the 'x'
- // registers.
- return (Size == 64);
- }
- }
- }
- }
-
virtual const char *getClobbers() const { return ""; }
int getEHDataRegisterNumber(unsigned RegNo) const {
diff --git a/clang/test/CodeGen/aarch64-inline-asm.c b/clang/test/CodeGen/aarch64-inline-asm.c
index ca39c6e7ff2..8dd2e34f594 100644
--- a/clang/test/CodeGen/aarch64-inline-asm.c
+++ b/clang/test/CodeGen/aarch64-inline-asm.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
// The only part clang really deals with is the lvalue/rvalue
// distinction on constraints. It's sufficient to emit llvm and make
diff --git a/clang/test/Sema/arm64-inline-asm.c b/clang/test/Sema/arm64-inline-asm.c
index 2d936214be6..08eb669265f 100644
--- a/clang/test/Sema/arm64-inline-asm.c
+++ b/clang/test/Sema/arm64-inline-asm.c
@@ -1,8 +1,9 @@
// RUN: %clang_cc1 -triple arm64-apple-ios7.1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
void foo() {
asm volatile("USE(%0)" :: "z"(0LL));
asm volatile("USE(%x0)" :: "z"(0LL));
asm volatile("USE(%w0)" :: "z"(0));
- asm volatile("USE(%0)" :: "z"(0)); // expected-warning {{value size does not match register size specified by the constraint and modifier}}
}
diff --git a/clang/test/Sema/inline-asm-validate.c b/clang/test/Sema/inline-asm-validate.c
index cfe4972d5af..c32dedb65e8 100644
--- a/clang/test/Sema/inline-asm-validate.c
+++ b/clang/test/Sema/inline-asm-validate.c
@@ -1,8 +1,9 @@
// RUN: %clang_cc1 -triple arm64-apple-macosx10.8.0 -fsyntax-only -verify %s
+// expected-no-diagnostics
unsigned t, r, *p;
int foo (void) {
- __asm__ __volatile__( "stxr %w[_t], %[_r], [%[_p]]" : [_t] "=&r" (t) : [_p] "p" (p), [_r] "r" (r) : "memory"); // expected-warning {{value size does not match register size specified by the constraint and modifier}}
+ __asm__ __volatile__( "stxr %w[_t], %[_r], [%[_p]]" : [_t] "=&r" (t) : [_p] "p" (p), [_r] "r" (r) : "memory");
return 1;
}
OpenPOWER on IntegriCloud