diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index d998ddd9960..6299e14192e 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -241,6 +241,25 @@ public: /// @name Convenience Predicates /// @{ + /// \brief Test whether the architecture is 64-bit + /// + /// Note that this tests for 64-bit pointer width, and nothing else. Note + /// that we intentionally expose only three predicates, 64-bit, 32-bit, and + /// 16-bit. The inner details of pointer width for particular architectures + /// is not summed up in the triple, and so only a coarse grained predicate + /// system is provided. + bool isArch64Bit() const; + + /// \brief Test whether the architecture is 32-bit + /// + /// Note that this tests for 32-bit pointer width, and nothing else. + bool isArch32Bit() const; + + /// \brief Test whether the architecture is 16-bit + /// + /// Note that this tests for 16-bit pointer width, and nothing else. + bool isArch16Bit() const; + /// isOSVersionLT - Helper function for doing comparisons against version /// numbers included in the target triple. bool isOSVersionLT(unsigned Major, unsigned Minor = 0, diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index e69d4385c69..d726fa300d1 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -665,3 +665,52 @@ void Triple::setEnvironmentName(StringRef Str) { void Triple::setOSAndEnvironmentName(StringRef Str) { setTriple(getArchName() + "-" + getVendorName() + "-" + Str); } + +static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { + switch (Arch) { + case llvm::Triple::UnknownArch: + case llvm::Triple::InvalidArch: + return 0; + + case llvm::Triple::msp430: + return 16; + + case llvm::Triple::amdil: + case llvm::Triple::arm: + case llvm::Triple::cellspu: + case llvm::Triple::hexagon: + case llvm::Triple::le32: + case llvm::Triple::mblaze: + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::ppc: + case llvm::Triple::ptx32: + case llvm::Triple::sparc: + case llvm::Triple::tce: + case llvm::Triple::thumb: + case llvm::Triple::x86: + case llvm::Triple::xcore: + return 32; + + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + case llvm::Triple::ppc64: + case llvm::Triple::ptx64: + case llvm::Triple::sparcv9: + case llvm::Triple::x86_64: + return 64; + } + llvm_unreachable("Invalid architecture value"); +} + +bool Triple::isArch64Bit() const { + return getArchPointerBitWidth(getArch()) == 64; +} + +bool Triple::isArch32Bit() const { + return getArchPointerBitWidth(getArch()) == 32; +} + +bool Triple::isArch16Bit() const { + return getArchPointerBitWidth(getArch()) == 16; +} diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp index 160b69253b6..28bb928ecbc 100644 --- a/unittests/ADT/TripleTest.cpp +++ b/unittests/ADT/TripleTest.cpp @@ -267,4 +267,61 @@ TEST(TripleTest, MutateName) { } +TEST(TripleTest, BitWidthPredicates) { + Triple T; + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); + + T.setArch(Triple::InvalidArch); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); + + T.setArch(Triple::arm); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); + + T.setArch(Triple::hexagon); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); + + T.setArch(Triple::mips); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); + + T.setArch(Triple::mips64); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_TRUE(T.isArch64Bit()); + + T.setArch(Triple::msp430); + EXPECT_TRUE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); + + T.setArch(Triple::ppc); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); + + T.setArch(Triple::ppc64); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_TRUE(T.isArch64Bit()); + + T.setArch(Triple::x86); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); + + T.setArch(Triple::x86_64); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_TRUE(T.isArch64Bit()); +} + }