summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDavid Candler <david.candler@arm.com>2019-09-05 15:17:25 +0000
committerDavid Candler <david.candler@arm.com>2019-09-05 15:17:25 +0000
commita59bffb5769557499fb86c28953bb7e755bedbe9 (patch)
tree61aaea85a8ebe8b571e93ce60fb4b61f6e9dd8ad /clang/lib
parent29361c704dfaefdd0f5a1c4b2d8eaa56f012bb7d (diff)
downloadbcm5719-llvm-a59bffb5769557499fb86c28953bb7e755bedbe9.tar.gz
bcm5719-llvm-a59bffb5769557499fb86c28953bb7e755bedbe9.zip
[ARM] Add support for the s,j,x,N,O inline asm constraints
A number of inline assembly constraints are currently supported by LLVM, but rejected as invalid by Clang: Target independent constraints: s: An integer constant, but allowing only relocatable values ARM specific constraints: j: An immediate integer between 0 and 65535 (valid for MOVW) x: A 32, 64, or 128-bit floating-point/SIMD register: s0-s15, d0-d7, or q0-q3 N: An immediate integer between 0 and 31 (Thumb1 only) O: An immediate integer which is a multiple of 4 between -508 and 508. (Thumb1 only) This patch adds support to Clang for the missing constraints along with some checks to ensure that the constraints are used with the correct target and Thumb mode, and that immediates are within valid ranges (at least where possible). The constraints are already implemented in LLVM, but just a couple of minor corrections to checks (V8M Baseline includes MOVW so should work with 'j', 'N' and 'O' shouldn't be valid in Thumb2) so that Clang and LLVM are in line with each other and the documentation. Differential Revision: https://reviews.llvm.org/D65863 Change-Id: I18076619e319bac35fbb60f590c069145c9d9a0a llvm-svn: 371079
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Targets/ARM.cpp93
1 files changed, 88 insertions, 5 deletions
diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index b234f013485..2d23b050bbc 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -885,19 +885,102 @@ bool ARMTargetInfo::validateAsmConstraint(
switch (*Name) {
default:
break;
- case 'l': // r0-r7
- case 'h': // r8-r15
- case 't': // VFP Floating point register single precision
- case 'w': // VFP Floating point register double precision
+ case 'l': // r0-r7 if thumb, r0-r15 if ARM
Info.setAllowsRegister();
return true;
+ case 'h': // r8-r15, thumb only
+ if (isThumb()) {
+ Info.setAllowsRegister();
+ return true;
+ }
+ break;
+ case 's': // An integer constant, but allowing only relocatable values.
+ return true;
+ case 't': // s0-s31, d0-d31, or q0-q15
+ case 'w': // s0-s15, d0-d7, or q0-q3
+ case 'x': // s0-s31, d0-d15, or q0-q7
+ Info.setAllowsRegister();
+ return true;
+ case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
+ // only available in ARMv6T2 and above
+ if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
+ Info.setRequiresImmediate(0, 65535);
+ return true;
+ }
+ break;
case 'I':
+ if (isThumb()) {
+ if (!supportsThumb2())
+ Info.setRequiresImmediate(0, 255);
+ else
+ // FIXME: should check if immediate value would be valid for a Thumb2
+ // data-processing instruction
+ Info.setRequiresImmediate();
+ } else
+ // FIXME: should check if immediate value would be valid for an ARM
+ // data-processing instruction
+ Info.setRequiresImmediate();
+ return true;
case 'J':
+ if (isThumb() && !supportsThumb2())
+ Info.setRequiresImmediate(-255, -1);
+ else
+ Info.setRequiresImmediate(-4095, 4095);
+ return true;
case 'K':
+ if (isThumb()) {
+ if (!supportsThumb2())
+ // FIXME: should check if immediate value can be obtained from shifting
+ // a value between 0 and 255 left by any amount
+ Info.setRequiresImmediate();
+ else
+ // FIXME: should check if immediate value would be valid for a Thumb2
+ // data-processing instruction when inverted
+ Info.setRequiresImmediate();
+ } else
+ // FIXME: should check if immediate value would be valid for an ARM
+ // data-processing instruction when inverted
+ Info.setRequiresImmediate();
+ return true;
case 'L':
+ if (isThumb()) {
+ if (!supportsThumb2())
+ Info.setRequiresImmediate(-7, 7);
+ else
+ // FIXME: should check if immediate value would be valid for a Thumb2
+ // data-processing instruction when negated
+ Info.setRequiresImmediate();
+ } else
+ // FIXME: should check if immediate value would be valid for an ARM
+ // data-processing instruction when negated
+ Info.setRequiresImmediate();
+ return true;
case 'M':
- // FIXME
+ if (isThumb() && !supportsThumb2())
+ // FIXME: should check if immediate value is a multiple of 4 between 0 and
+ // 1020
+ Info.setRequiresImmediate();
+ else
+ // FIXME: should check if immediate value is a power of two or a integer
+ // between 0 and 32
+ Info.setRequiresImmediate();
return true;
+ case 'N':
+ // Thumb1 only
+ if (isThumb() && !supportsThumb2()) {
+ Info.setRequiresImmediate(0, 31);
+ return true;
+ }
+ break;
+ case 'O':
+ // Thumb1 only
+ if (isThumb() && !supportsThumb2()) {
+ // FIXME: should check if immediate value is a multiple of 4 between -508
+ // and 508
+ Info.setRequiresImmediate();
+ return true;
+ }
+ break;
case 'Q': // A memory address that is a single base register.
Info.setAllowsMemory();
return true;
OpenPOWER on IntegriCloud