[ARM] Allow "-march=foo+fp" to vary with foo

This is the LLVM part of this change, the Clang part contains the full
description in its commit message.

Differential Revision: https://reviews.llvm.org/D60697

llvm-svn: 362600
This commit is contained in:
Sjoerd Meijer 2019-06-05 13:11:51 +00:00
parent 886a55eaa0
commit a1bb4fb79d
2 changed files with 73 additions and 8 deletions

View File

@ -240,6 +240,8 @@ StringRef getCPUAttr(ArchKind AK);
StringRef getSubArch(ArchKind AK);
StringRef getArchExtName(unsigned ArchExtKind);
StringRef getArchExtFeature(StringRef ArchExt);
bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, StringRef ArchExt,
std::vector<StringRef> &Features);
StringRef getHWDivName(unsigned HWDivKind);
// Information by Name

View File

@ -485,22 +485,85 @@ StringRef ARM::getArchExtName(unsigned ArchExtKind) {
return StringRef();
}
StringRef ARM::getArchExtFeature(StringRef ArchExt) {
if (ArchExt.startswith("no")) {
StringRef ArchExtBase(ArchExt.substr(2));
for (const auto AE : ARCHExtNames) {
if (AE.NegFeature && ArchExtBase == AE.getName())
return StringRef(AE.NegFeature);
}
static bool stripNegationPrefix(StringRef &Name) {
if (Name.startswith("no")) {
Name = Name.substr(2);
return true;
}
return false;
}
StringRef ARM::getArchExtFeature(StringRef ArchExt) {
bool Negated = stripNegationPrefix(ArchExt);
for (const auto AE : ARCHExtNames) {
if (AE.Feature && ArchExt == AE.getName())
return StringRef(AE.Feature);
return StringRef(Negated ? AE.NegFeature : AE.Feature);
}
return StringRef();
}
static unsigned findDoublePrecisionFPU(unsigned InputFPUKind) {
const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
// If the input FPU already supports double-precision, then there
// isn't any different FPU we can return here.
//
// The current available FPURestriction values are None (no
// restriction), D16 (only 16 d-regs) and SP_D16 (16 d-regs
// and single precision only); there's no value representing
// SP restriction without D16. So this test just means 'is it
// SP only?'.
if (InputFPU.Restriction != ARM::FPURestriction::SP_D16)
return ARM::FK_INVALID;
// Otherwise, look for an FPU entry with all the same fields, except
// that SP_D16 has been replaced with just D16, representing adding
// double precision and not changing anything else.
for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
CandidateFPU.Restriction == ARM::FPURestriction::D16) {
return CandidateFPU.ID;
}
}
// nothing found
return ARM::FK_INVALID;
}
bool ARM::appendArchExtFeatures(
StringRef CPU, ARM::ArchKind AK, StringRef ArchExt,
std::vector<StringRef> &Features) {
StringRef StandardFeature = getArchExtFeature(ArchExt);
if (!StandardFeature.empty()) {
Features.push_back(StandardFeature);
return true;
}
const bool Negated = stripNegationPrefix(ArchExt);
if (CPU == "")
CPU = "generic";
if (ArchExt == "fp" || ArchExt == "fp.dp") {
unsigned FPUKind;
if (ArchExt == "fp.dp") {
if (Negated) {
Features.push_back("-fp64");
return true;
}
FPUKind = findDoublePrecisionFPU(getDefaultFPU(CPU, AK));
} else if (Negated) {
FPUKind = ARM::FK_NONE;
} else {
FPUKind = getDefaultFPU(CPU, AK);
}
return ARM::getFPUFeatures(FPUKind, Features);
}
return false;
}
StringRef ARM::getHWDivName(unsigned HWDivKind) {
for (const auto D : HWDivNames) {
if (HWDivKind == D.ID)