diff options
author | Marina Yatsina <marina.yatsina@intel.com> | 2016-12-26 12:23:42 +0000 |
---|---|---|
committer | Marina Yatsina <marina.yatsina@intel.com> | 2016-12-26 12:23:42 +0000 |
commit | c42fd03bf85486cc60a8b5171f1f21e37855bbf1 (patch) | |
tree | 8ec9372415033e0b750cd249be1d7c9875dcb9e7 /clang/lib/Basic | |
parent | 600941351e20ec9cca1617f6b28887fb7dd25252 (diff) | |
download | bcm5719-llvm-c42fd03bf85486cc60a8b5171f1f21e37855bbf1.tar.gz bcm5719-llvm-c42fd03bf85486cc60a8b5171f1f21e37855bbf1.zip |
[inline-asm]No error for conflict between inputs\outputs and clobber list
According to extended asm syntax, a case where the clobber list includes a variable from the inputs or outputs should be an error - conflict.
for example:
const long double a = 0.0;
int main()
{
char b;
double t1 = a;
__asm__ ("fucompp": "=a" (b) : "u" (t1), "t" (t1) : "cc", "st", "st(1)");
return 0;
}
This should conflict with the output - t1 which is st, and st which is st aswell.
The patch fixes it.
Commit on behald of Ziv Izhar.
Differential Revision: https://reviews.llvm.org/D15075
llvm-svn: 290539
Diffstat (limited to 'clang/lib/Basic')
-rw-r--r-- | clang/lib/Basic/TargetInfo.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 34 |
2 files changed, 37 insertions, 3 deletions
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index e37f13a05b9..b1b01e5f584 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -410,8 +410,8 @@ bool TargetInfo::isValidGCCRegisterName(StringRef Name) const { return false; } -StringRef -TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const { +StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name, + bool ReturnCanonical) const { assert(isValidGCCRegisterName(Name) && "Invalid register passed in"); // Get rid of any register prefix. @@ -436,7 +436,7 @@ TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const { // Make sure the register that the additional name is for is within // the bounds of the register names from above. if (AN == Name && ARN.RegNum < Names.size()) - return Name; + return ReturnCanonical ? Names[ARN.RegNum] : Name; } // Now check aliases. diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index dd88646b17f..85a83bca002 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -2789,6 +2789,40 @@ public: const char *getClobbers() const override { return "~{dirflag},~{fpsr},~{flags}"; } + + StringRef getConstraintRegister(const StringRef &Constraint, + const StringRef &Expression) const override { + StringRef::iterator I, E; + for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) { + if (isalpha(*I)) + break; + } + if (I == E) + return ""; + switch (*I) { + // For the register constraints, return the matching register name + case 'a': + return "ax"; + case 'b': + return "bx"; + case 'c': + return "cx"; + case 'd': + return "dx"; + case 'S': + return "si"; + case 'D': + return "di"; + // In case the constraint is 'r' we need to return Expression + case 'r': + return Expression; + default: + // Default value if there is no constraint for the register + return ""; + } + return ""; + } + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level, |