labrinea removed rL LLVM as the repository for this revision.
labrinea updated this revision to Diff 29533.
http://reviews.llvm.org/D10839
Files:
lib/Basic/Targets.cpp
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -30,6 +30,7 @@
#include "llvm/Support/TargetParser.h"
#include <algorithm>
#include <memory>
+#include <locale>
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -4043,8 +4044,13 @@
FP_Neon
} FPMath;
+ unsigned ArchKind;
+ unsigned ArchProfile;
+ unsigned ArchVersion;
+
unsigned FPU : 5;
+ unsigned ShouldUseInlineAtomic : 1;
unsigned IsAAPCS : 1;
unsigned IsThumb : 1;
unsigned HWDiv : 2;
@@ -4066,37 +4072,6 @@
static const Builtin::Info BuiltinInfo[];
- static bool shouldUseInlineAtomic(const llvm::Triple &T) {
- StringRef ArchName = T.getArchName();
- if (T.getArch() == llvm::Triple::arm ||
- T.getArch() == llvm::Triple::armeb) {
- StringRef VersionStr;
- if (ArchName.startswith("armv"))
- VersionStr = ArchName.substr(4, 1);
- else if (ArchName.startswith("armebv"))
- VersionStr = ArchName.substr(6, 1);
- else
- return false;
- unsigned Version;
- if (VersionStr.getAsInteger(10, Version))
- return false;
- return Version >= 6;
- }
- assert(T.getArch() == llvm::Triple::thumb ||
- T.getArch() == llvm::Triple::thumbeb);
- StringRef VersionStr;
- if (ArchName.startswith("thumbv"))
- VersionStr = ArchName.substr(6, 1);
- else if (ArchName.startswith("thumbebv"))
- VersionStr = ArchName.substr(8, 1);
- else
- return false;
- unsigned Version;
- if (VersionStr.getAsInteger(10, Version))
- return false;
- return Version >= 7;
- }
-
void setABIAAPCS() {
IsAAPCS = true;
@@ -4195,6 +4170,29 @@
// FIXME: Override "preferred align" for double and long long.
}
+ void setArchInfo(StringRef CPU) {
+ StringRef SubArch;
+
+ ArchKind = llvm::ARMTargetParser::parseCPUArch(CPU);
+ SubArch = llvm::ARMTargetParser::getSubArch(ArchKind);
+ ArchProfile = llvm::ARMTargetParser::parseArchProfile(SubArch);
+ ArchVersion = llvm::ARMTargetParser::parseArchVersion(SubArch);
+ }
+
+ void setAtomic() {
+ // Cortex M does not support 8 byte atomics, while general Thumb2 does.
+ if (ArchProfile == llvm::ARM::PK_M) {
+ MaxAtomicPromoteWidth = 32;
+ if (ShouldUseInlineAtomic)
+ MaxAtomicInlineWidth = 32;
+ }
+ else {
+ MaxAtomicPromoteWidth = 64;
+ if (ShouldUseInlineAtomic)
+ MaxAtomicInlineWidth = 64;
+ }
+ }
+
public:
ARMTargetInfo(const llvm::Triple &Triple, bool IsBigEndian)
: TargetInfo(Triple), CPU("arm1136j-s"), FPMath(FP_Default),
@@ -4210,12 +4208,32 @@
break;
}
+ StringRef ArchName; // ArchName defined from triple
+ unsigned ArchISA; // (aarch64, thumb, or arm)
+ const char *DefaultCPU; // default cpu for this arch
+
+ ArchName = Triple.getArchName();
+ ArchISA = llvm::ARMTargetParser::parseArchISA(ArchName);
+ DefaultCPU = llvm::ARMTargetParser::getDefaultCPU(ArchName);
+
+ // SubArch is specified by the target triple
+ if (DefaultCPU) {
+ setArchInfo(DefaultCPU);
+ ShouldUseInlineAtomic = (ArchISA == llvm::ARM::IK_ARM &&
+ ArchVersion >= 6) ||
+ (ArchISA == llvm::ARM::IK_THUMB &&
+ ArchVersion >= 7);
+ }
+ else {
+ setArchInfo(CPU);
+ ShouldUseInlineAtomic = false;
+ }
+
// {} in inline assembly are neon specifiers, not assembly variant
// specifiers.
NoAsmVariants = true;
- // FIXME: Should we just treat this as a feature?
- IsThumb = getTriple().getArchName().startswith("thumb");
+ IsThumb = (ArchISA == llvm::ARM::IK_THUMB);
// FIXME: This duplicates code from the driver that sets the -target-abi
// option - this code is used if -target-abi isn't passed and should
@@ -4261,9 +4279,7 @@
TheCXXABI.set(TargetCXXABI::GenericARM);
// ARM has atomics up to 8 bytes
- MaxAtomicPromoteWidth = 64;
- if (shouldUseInlineAtomic(getTriple()))
- MaxAtomicInlineWidth = 64;
+ setAtomic();
// Do force alignment of members that follow zero length bitfields. If
// the alignment of the zero-length bitfield is greater than the member
@@ -4294,11 +4310,6 @@
// FIXME: This should be based on Arch attributes, not CPU names.
void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
- StringRef ArchName = getTriple().getArchName();
- unsigned ArchKind = llvm::ARMTargetParser::parseArch(ArchName);
- bool IsV8 = (ArchKind == llvm::ARM::AK_ARMV8A ||
- ArchKind == llvm::ARM::AK_ARMV8_1A);
-
if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
Features["vfp2"] = true;
else if (CPU == "cortex-a8" || CPU == "cortex-a9") {
@@ -4323,7 +4334,7 @@
Features["hwdiv-arm"] = true;
Features["crc"] = true;
Features["crypto"] = true;
- } else if (CPU == "cortex-r5" || CPU == "cortex-r7" || IsV8) {
+ } else if (CPU == "cortex-r5" || CPU == "cortex-r7" || ArchVersion == 8) {
Features["hwdiv"] = true;
Features["hwdiv-arm"] = true;
} else if (CPU == "cortex-m3" || CPU == "cortex-m4" || CPU == "cortex-m7" ||
@@ -4406,32 +4417,29 @@
.Case("hwdiv-arm", HWDiv & HWDivARM)
.Default(false);
}
- const char *getCPUDefineSuffix(StringRef Name) const {
- if(Name == "generic") {
- auto subarch = getTriple().getSubArch();
- switch (subarch) {
- case llvm::Triple::SubArchType::ARMSubArch_v8_1a:
- return "8_1A";
- default:
- break;
- }
- }
-
- unsigned ArchKind = llvm::ARMTargetParser::parseCPUArch(Name);
- if (ArchKind == llvm::ARM::AK_INVALID)
- return "";
+ StringRef getCPUAttr() const {
+ const char *CPUAttr;
// For most sub-arches, the build attribute CPU name is enough.
// For Cortex variants, it's slightly different.
switch(ArchKind) {
default:
- return llvm::ARMTargetParser::getCPUAttr(ArchKind);
+ CPUAttr = llvm::ARMTargetParser::getCPUAttr(ArchKind);
+ if (CPUAttr == nullptr)
+ return "";
+ for(char c : std::string(CPUAttr))
+ assert( (std::isalnum(c) || c == '_') &&
+ "CPU attribute contains non alphanumeric characters.");
+ return CPUAttr;
case llvm::ARM::AK_ARMV6M:
case llvm::ARM::AK_ARMV6SM:
+ case llvm::ARM::AK_ARMV6HL:
return "6M";
case llvm::ARM::AK_ARMV7:
case llvm::ARM::AK_ARMV7A:
case llvm::ARM::AK_ARMV7S:
+ case llvm::ARM::AK_ARMV7L:
+ case llvm::ARM::AK_ARMV7HL:
return "7A";
case llvm::ARM::AK_ARMV7R:
return "7R";
@@ -4445,83 +4453,57 @@
return "8_1A";
}
}
- const char *getCPUProfile(StringRef Name) const {
- if(Name == "generic") {
- auto subarch = getTriple().getSubArch();
- switch (subarch) {
- case llvm::Triple::SubArchType::ARMSubArch_v8_1a:
- return "A";
- default:
- break;
- }
- }
- unsigned CPUArch = llvm::ARMTargetParser::parseCPUArch(Name);
- if (CPUArch == llvm::ARM::AK_INVALID)
+ StringRef getCPUProfile() const {
+ switch(ArchProfile) {
+ case llvm::ARM::PK_A:
+ return "A";
+ case llvm::ARM::PK_R:
+ return "R";
+ case llvm::ARM::PK_M:
+ return "M";
+ default:
return "";
-
- StringRef ArchName = llvm::ARMTargetParser::getArchName(CPUArch);
- switch(llvm::ARMTargetParser::parseArchProfile(ArchName)) {
- case llvm::ARM::PK_A:
- return "A";
- case llvm::ARM::PK_R:
- return "R";
- case llvm::ARM::PK_M:
- return "M";
- default:
- return "";
}
}
+
bool setCPU(const std::string &Name) override {
- if (!getCPUDefineSuffix(Name))
+ unsigned ArchKind = llvm::ARMTargetParser::parseCPUArch(Name);
+ if (ArchKind == llvm::ARM::AK_INVALID)
return false;
-
- // Cortex M does not support 8 byte atomics, while general Thumb2 does.
- StringRef Profile = getCPUProfile(Name);
- if (Profile == "M" && MaxAtomicInlineWidth) {
- MaxAtomicPromoteWidth = 32;
- MaxAtomicInlineWidth = 32;
- }
-
+ setArchInfo(Name);
+ setAtomic();
CPU = Name;
return true;
}
+
bool setFPMath(StringRef Name) override;
- bool supportsThumb(StringRef ArchName, StringRef CPUArch,
- unsigned CPUArchVer) const {
- return CPUArchVer >= 7 || (CPUArch.find('T') != StringRef::npos) ||
- (CPUArch.find('M') != StringRef::npos);
- }
- bool supportsThumb2(StringRef ArchName, StringRef CPUArch,
- unsigned CPUArchVer) const {
- // We check both CPUArchVer and ArchName because when only triple is
- // specified, the default CPU is arm1136j-s.
- return ArchName.endswith("v6t2") || ArchName.endswith("v7") ||
- ArchName.endswith("v8.1a") ||
- ArchName.endswith("v8") || CPUArch == "6T2" || CPUArchVer >= 7;
+
+ bool supportsThumb(StringRef CPUAttr) const {
+ return CPUAttr.count('T') || ArchVersion >= 6;
}
+
+ bool supportsThumb2(StringRef CPUAttr) const {
+ return CPUAttr.equals("6T2") || ArchVersion >= 7;
+ }
+
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
+ StringRef CPUAttr = getCPUAttr();
+ StringRef CPUProfile = getCPUProfile();
+
// Target identification.
Builder.defineMacro("__arm");
Builder.defineMacro("__arm__");
// Target properties.
Builder.defineMacro("__REGISTER_PREFIX__", "");
-
- StringRef CPUArch = getCPUDefineSuffix(CPU);
- unsigned int CPUArchVer;
- if (CPUArch.substr(0, 1).getAsInteger<unsigned int>(10, CPUArchVer))
- llvm_unreachable("Invalid char for architecture version number");
- Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
+ Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
// ACLE 6.4.1 ARM/Thumb instruction set architecture
- StringRef CPUProfile = getCPUProfile(CPU);
- StringRef ArchName = getTriple().getArchName();
-
// __ARM_ARCH is defined as an integer value indicating the current ARM ISA
- Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
- if (CPUArch[0] >= '8') {
+ Builder.defineMacro("__ARM_ARCH", std::to_string(ArchVersion));
+ if (ArchVersion >= 8) {
Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN");
Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING");
}
@@ -4535,9 +4517,9 @@
// __ARM_ARCH_ISA_THUMB is defined to 1 if the core supporst the original
// Thumb ISA (including v6-M). It is set to 2 if the core supports the
// Thumb-2 ISA as found in the v6T2 architecture and all v7 architecture.
- if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
+ if (supportsThumb2(CPUAttr))
Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
- else if (supportsThumb(ArchName, CPUArch, CPUArchVer))
+ else if (supportsThumb(CPUAttr))
Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
// __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
@@ -4562,7 +4544,7 @@
// FIXME: It's more complicated than this and we don't really support
// interworking.
// Windows on ARM does not "support" interworking
- if (5 <= CPUArchVer && CPUArchVer <= 8 && !getTriple().isOSWindows())
+ if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
Builder.defineMacro("__THUMB_INTERWORK__");
if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
@@ -4585,7 +4567,7 @@
if (IsThumb) {
Builder.defineMacro("__THUMBEL__");
Builder.defineMacro("__thumb__");
- if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
+ if (supportsThumb2(CPUAttr))
Builder.defineMacro("__thumb2__");
}
if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb))
@@ -4608,7 +4590,7 @@
// the VFP define, hence the soft float and arch check. This is subtly
// different from gcc, we follow the intent which was that it should be set
// when Neon instructions are actually available.
- if ((FPU & NeonFPU) && !SoftFloat && CPUArchVer >= 7) {
+ if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
Builder.defineMacro("__ARM_NEON");
Builder.defineMacro("__ARM_NEON__");
}
@@ -4625,20 +4607,21 @@
if (Crypto)
Builder.defineMacro("__ARM_FEATURE_CRYPTO");
- if (CPUArchVer >= 6 && CPUArch != "6M") {
+ if (ArchVersion >= 6 && CPUAttr != "6M") {
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
}
- bool is5EOrAbove = (CPUArchVer >= 6 ||
- (CPUArchVer == 5 &&
- CPUArch.find('E') != StringRef::npos));
- bool is32Bit = (!IsThumb || supportsThumb2(ArchName, CPUArch, CPUArchVer));
- if (is5EOrAbove && is32Bit && (CPUProfile != "M" || CPUArch == "7EM"))
+ bool is5EOrAbove = (ArchVersion >= 6 ||
+ (ArchVersion == 5 && CPUAttr.count('E')));
+ // FIXME: We are not getting all 32-bit ARM architectures
+ bool is32Bit = (!IsThumb || supportsThumb2(CPUAttr));
+ if (is5EOrAbove && is32Bit && (CPUProfile != "M" || CPUAttr == "7EM"))
Builder.defineMacro("__ARM_FEATURE_DSP");
}
+
void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const override {
Records = BuiltinInfo;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits