From: James Molloy Date: Wed, 23 Apr 2014 10:26:19 +0000 (+0000) Subject: [ARM64] Change inline assembly constraints to be more lax, to match the behaviour... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fa203ed5f90f65092f9424ffbcc2a7324646958b;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206963 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 7d20f045c4..108b197dae 100644 --- a/lib/Basic/Targets.cpp +++ b/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/test/CodeGen/aarch64-inline-asm.c b/test/CodeGen/aarch64-inline-asm.c index ca39c6e7ff..8dd2e34f59 100644 --- a/test/CodeGen/aarch64-inline-asm.c +++ b/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/test/Sema/arm64-inline-asm.c b/test/Sema/arm64-inline-asm.c index 2d936214be..08eb669265 100644 --- a/test/Sema/arm64-inline-asm.c +++ b/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/test/Sema/inline-asm-validate.c b/test/Sema/inline-asm-validate.c index cfe4972d5a..c32dedb65e 100644 --- a/test/Sema/inline-asm-validate.c +++ b/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; }