From 302a165e18fda8318e9e1ce6f452a48925cb3857 Mon Sep 17 00:00:00 2001 From: YunQiang Su Date: Thu, 21 Oct 2021 10:46:22 +0300 Subject: [PATCH] [MIPS] Fix switching between 32/64-bit variants of r6 target triples If clang driver gets 64-bit r6 target triple like `mipsisa64r6` and additional option forces switching to generation of 32-bit code, it loses r6 abi and generates 32-bit r2-r5 abi code. ``` $ clang -target mipsisa64r6-linux-gnu -mabi=32 ``` This patch fixes the problem. - Add optional `SubArchType` argument to the `Triple::setArch()` method. - Implement generation of mips r6 target triples in the `Triple::getArchName()` method. Differential Revision: https://reviews.llvm.org/D110514.diff --- llvm/include/llvm/ADT/Triple.h | 5 ++- llvm/lib/Support/Triple.cpp | 60 ++++++++++++++++++++++++++++------ llvm/unittests/ADT/TripleTest.cpp | 68 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 11 deletions(-) diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index 0de884e..e0b582a 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -384,6 +384,9 @@ public: /// triple. StringRef getArchName() const; + /// getArchName - Get the architecture name based on Kind and SubArch. + StringRef getArchName(ArchType Kind, SubArchType SubArch = NoSubArch) const; + /// getVendorName - Get the vendor (second) component of the triple. StringRef getVendorName() const; @@ -838,7 +841,7 @@ public: /// setArch - Set the architecture (first) component of the triple /// to a known type. - void setArch(ArchType Kind); + void setArch(ArchType Kind, SubArchType SubArch = NoSubArch); /// setVendor - Set the vendor (second) component of the triple to a /// known type. diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp index ec05586..df43ec1 100644 --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -1030,6 +1030,30 @@ StringRef Triple::getArchName() const { return StringRef(Data).split('-').first; // Isolate first component } +StringRef Triple::getArchName(ArchType Kind, SubArchType SubArch) const { + switch (Kind) { + case Triple::mips: + if (SubArch == MipsSubArch_r6) + return "mipsisa32r6"; + break; + case Triple::mipsel: + if (SubArch == MipsSubArch_r6) + return "mipsisa32r6el"; + break; + case Triple::mips64: + if (SubArch == MipsSubArch_r6) + return "mipsisa64r6"; + break; + case Triple::mips64el: + if (SubArch == MipsSubArch_r6) + return "mipsisa64r6el"; + break; + default: + break; + } + return getArchTypeName(Kind); +} + StringRef Triple::getVendorName() const { StringRef Tmp = StringRef(Data).split('-').second; // Strip first component return Tmp.split('-').first; // Isolate second component @@ -1211,8 +1235,8 @@ void Triple::setTriple(const Twine &Str) { *this = Triple(Str); } -void Triple::setArch(ArchType Kind) { - setArchName(getArchTypeName(Kind)); +void Triple::setArch(ArchType Kind, SubArchType SubArch) { + setArchName(getArchName(Kind, SubArch)); } void Triple::setVendor(VendorType Kind) { @@ -1404,8 +1428,12 @@ Triple Triple::get32BitArchVariant() const { case Triple::amdil64: T.setArch(Triple::amdil); break; case Triple::hsail64: T.setArch(Triple::hsail); break; case Triple::le64: T.setArch(Triple::le32); break; - case Triple::mips64: T.setArch(Triple::mips); break; - case Triple::mips64el: T.setArch(Triple::mipsel); break; + case Triple::mips64: + T.setArch(Triple::mips, getSubArch()); + break; + case Triple::mips64el: + T.setArch(Triple::mipsel, getSubArch()); + break; case Triple::nvptx64: T.setArch(Triple::nvptx); break; case Triple::ppc64: T.setArch(Triple::ppc); break; case Triple::ppc64le: T.setArch(Triple::ppcle); break; @@ -1470,8 +1498,12 @@ Triple Triple::get64BitArchVariant() const { case Triple::armeb: T.setArch(Triple::aarch64_be); break; case Triple::hsail: T.setArch(Triple::hsail64); break; case Triple::le32: T.setArch(Triple::le64); break; - case Triple::mips: T.setArch(Triple::mips64); break; - case Triple::mipsel: T.setArch(Triple::mips64el); break; + case Triple::mips: + T.setArch(Triple::mips64, getSubArch()); + break; + case Triple::mipsel: + T.setArch(Triple::mips64el, getSubArch()); + break; case Triple::nvptx: T.setArch(Triple::nvptx64); break; case Triple::ppc: T.setArch(Triple::ppc64); break; case Triple::ppcle: T.setArch(Triple::ppc64le); break; @@ -1532,8 +1564,12 @@ Triple Triple::getBigEndianArchVariant() const { case Triple::aarch64: T.setArch(Triple::aarch64_be); break; case Triple::bpfel: T.setArch(Triple::bpfeb); break; - case Triple::mips64el:T.setArch(Triple::mips64); break; - case Triple::mipsel: T.setArch(Triple::mips); break; + case Triple::mips64el: + T.setArch(Triple::mips64, getSubArch()); + break; + case Triple::mipsel: + T.setArch(Triple::mips, getSubArch()); + break; case Triple::ppcle: T.setArch(Triple::ppc); break; case Triple::ppc64le: T.setArch(Triple::ppc64); break; case Triple::sparcel: T.setArch(Triple::sparc); break; @@ -1565,8 +1601,12 @@ Triple Triple::getLittleEndianArchVariant() const { case Triple::aarch64_be: T.setArch(Triple::aarch64); break; case Triple::bpfeb: T.setArch(Triple::bpfel); break; - case Triple::mips64: T.setArch(Triple::mips64el); break; - case Triple::mips: T.setArch(Triple::mipsel); break; + case Triple::mips64: + T.setArch(Triple::mips64el, getSubArch()); + break; + case Triple::mips: + T.setArch(Triple::mipsel, getSubArch()); + break; case Triple::ppc: T.setArch(Triple::ppcle); break; case Triple::ppc64: T.setArch(Triple::ppc64le); break; case Triple::sparc: T.setArch(Triple::sparcel); break; diff --git a/llvm/unittests/ADT/TripleTest.cpp b/llvm/unittests/ADT/TripleTest.cpp index f9ff7dd..a275732e 100644 --- a/llvm/unittests/ADT/TripleTest.cpp +++ b/llvm/unittests/ADT/TripleTest.cpp @@ -930,11 +930,27 @@ TEST(TripleTest, BitWidthArchVariants) { T.setArch(Triple::mips); EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.get32BitArchVariant().getSubArch()); EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.get64BitArchVariant().getSubArch()); + + T.setArch(Triple::mips, Triple::MipsSubArch_r6); + EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.get32BitArchVariant().getSubArch()); + EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.get64BitArchVariant().getSubArch()); T.setArch(Triple::mipsel); EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.get32BitArchVariant().getSubArch()); + EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.get64BitArchVariant().getSubArch()); + + T.setArch(Triple::mipsel, Triple::MipsSubArch_r6); + EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.get32BitArchVariant().getSubArch()); EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.get64BitArchVariant().getSubArch()); T.setArch(Triple::ppc); EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch()); @@ -954,11 +970,27 @@ TEST(TripleTest, BitWidthArchVariants) { T.setArch(Triple::mips64); EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.get32BitArchVariant().getSubArch()); EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.get64BitArchVariant().getSubArch()); + + T.setArch(Triple::mips64, Triple::MipsSubArch_r6); + EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.get32BitArchVariant().getSubArch()); + EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.get64BitArchVariant().getSubArch()); T.setArch(Triple::mips64el); EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.get32BitArchVariant().getSubArch()); + EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.get64BitArchVariant().getSubArch()); + + T.setArch(Triple::mips64el, Triple::MipsSubArch_r6); + EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.get32BitArchVariant().getSubArch()); EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.get64BitArchVariant().getSubArch()); T.setArch(Triple::ppc64); EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch()); @@ -1104,19 +1136,55 @@ TEST(TripleTest, EndianArchVariants) { T.setArch(Triple::mips64); EXPECT_EQ(Triple::mips64, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.getBigEndianArchVariant().getSubArch()); EXPECT_EQ(Triple::mips64el, T.getLittleEndianArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.getLittleEndianArchVariant().getSubArch()); + + T.setArch(Triple::mips64, Triple::MipsSubArch_r6); + EXPECT_EQ(Triple::mips64, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getBigEndianArchVariant().getSubArch()); + EXPECT_EQ(Triple::mips64el, T.getLittleEndianArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, + T.getLittleEndianArchVariant().getSubArch()); T.setArch(Triple::mips64el); EXPECT_EQ(Triple::mips64, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.getBigEndianArchVariant().getSubArch()); + EXPECT_EQ(Triple::mips64el, T.getLittleEndianArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.getLittleEndianArchVariant().getSubArch()); + + T.setArch(Triple::mips64el, Triple::MipsSubArch_r6); + EXPECT_EQ(Triple::mips64, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getBigEndianArchVariant().getSubArch()); EXPECT_EQ(Triple::mips64el, T.getLittleEndianArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, + T.getLittleEndianArchVariant().getSubArch()); T.setArch(Triple::mips); EXPECT_EQ(Triple::mips, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.getBigEndianArchVariant().getSubArch()); EXPECT_EQ(Triple::mipsel, T.getLittleEndianArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.getLittleEndianArchVariant().getSubArch()); + + T.setArch(Triple::mips, Triple::MipsSubArch_r6); + EXPECT_EQ(Triple::mips, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getBigEndianArchVariant().getSubArch()); + EXPECT_EQ(Triple::mipsel, T.getLittleEndianArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, + T.getLittleEndianArchVariant().getSubArch()); T.setArch(Triple::mipsel); EXPECT_EQ(Triple::mips, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.getBigEndianArchVariant().getSubArch()); + EXPECT_EQ(Triple::mipsel, T.getLittleEndianArchVariant().getArch()); + EXPECT_EQ(Triple::NoSubArch, T.getLittleEndianArchVariant().getSubArch()); + + T.setArch(Triple::mipsel, Triple::MipsSubArch_r6); + EXPECT_EQ(Triple::mips, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getBigEndianArchVariant().getSubArch()); EXPECT_EQ(Triple::mipsel, T.getLittleEndianArchVariant().getArch()); + EXPECT_EQ(Triple::MipsSubArch_r6, + T.getLittleEndianArchVariant().getSubArch()); T.setArch(Triple::ppc); EXPECT_EQ(Triple::ppc, T.getBigEndianArchVariant().getArch()); -- 2.7.4