summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorYaxun Liu <Yaxun.Liu@amd.com>2017-09-28 19:07:59 +0000
committerYaxun Liu <Yaxun.Liu@amd.com>2017-09-28 19:07:59 +0000
commit304f349770843defedf882545cdfa078cf94c20c (patch)
tree1e1a679b92d6695eb4c36599f3208b42bdb6d31c /clang/lib
parentd6218cc385920a462a99d28e0959c7300b25468a (diff)
downloadbcm5719-llvm-304f349770843defedf882545cdfa078cf94c20c.tar.gz
bcm5719-llvm-304f349770843defedf882545cdfa078cf94c20c.zip
[AMDGPU] Allow flexible register names in inline asm constraints
Currently AMDGPU inline asm only allow v and s as register names in constraints. This patch allows the following register names in constraints: (n, m is unsigned integer, n < m) v s {vn} or {v[n]} {sn} or {s[n]} {S} , where S is a special register name {v[n:m]} {s[n:m]} Differential Revision: https://reviews.llvm.org/D37568 llvm-svn: 314452
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Targets/AMDGPU.h79
1 files changed, 73 insertions, 6 deletions
diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index ae19a0dc548..0e1b102174a 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -17,6 +17,7 @@
#include "clang/AST/Type.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
@@ -115,17 +116,83 @@ public:
return None;
}
+ /// Accepted register names: (n, m is unsigned integer, n < m)
+ /// v
+ /// s
+ /// {vn}, {v[n]}
+ /// {sn}, {s[n]}
+ /// {S} , where S is a special register name
+ ////{v[n:m]}
+ /// {s[n:m]}
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const override {
- switch (*Name) {
- default:
- break;
- case 'v': // vgpr
- case 's': // sgpr
+ static const ::llvm::StringSet<> SpecialRegs({
+ "exec", "vcc", "flat_scratch", "m0", "scc", "tba", "tma",
+ "flat_scratch_lo", "flat_scratch_hi", "vcc_lo", "vcc_hi", "exec_lo",
+ "exec_hi", "tma_lo", "tma_hi", "tba_lo", "tba_hi",
+ });
+
+ StringRef S(Name);
+ bool HasLeftParen = false;
+ if (S.front() == '{') {
+ HasLeftParen = true;
+ S = S.drop_front();
+ }
+ if (S.empty())
+ return false;
+ if (S.front() != 'v' && S.front() != 's') {
+ if (!HasLeftParen)
+ return false;
+ auto E = S.find('}');
+ if (!SpecialRegs.count(S.substr(0, E)))
+ return false;
+ S = S.drop_front(E + 1);
+ if (!S.empty())
+ return false;
+ // Found {S} where S is a special register.
+ Info.setAllowsRegister();
+ Name = S.data() - 1;
+ return true;
+ }
+ S = S.drop_front();
+ if (!HasLeftParen) {
+ if (!S.empty())
+ return false;
+ // Found s or v.
Info.setAllowsRegister();
+ Name = S.data() - 1;
return true;
}
- return false;
+ bool HasLeftBracket = false;
+ if (!S.empty() && S.front() == '[') {
+ HasLeftBracket = true;
+ S = S.drop_front();
+ }
+ unsigned long long N;
+ if (S.empty() || consumeUnsignedInteger(S, 10, N))
+ return false;
+ if (!S.empty() && S.front() == ':') {
+ if (!HasLeftBracket)
+ return false;
+ S = S.drop_front();
+ unsigned long long M;
+ if (consumeUnsignedInteger(S, 10, M) || N >= M)
+ return false;
+ }
+ if (HasLeftBracket) {
+ if (S.empty() || S.front() != ']')
+ return false;
+ S = S.drop_front();
+ }
+ if (S.empty() || S.front() != '}')
+ return false;
+ S = S.drop_front();
+ if (!S.empty())
+ return false;
+ // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}.
+ Info.setAllowsRegister();
+ Name = S.data() - 1;
+ return true;
}
bool
OpenPOWER on IntegriCloud