[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
This commit is contained in:
YunQiang Su 2021-10-21 10:46:22 +03:00 committed by Simon Atanasyan
parent 9bfe7af159
commit 302a165e18
3 changed files with 122 additions and 11 deletions

View File

@ -384,6 +384,9 @@ public:
/// triple. /// triple.
StringRef getArchName() const; 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. /// getVendorName - Get the vendor (second) component of the triple.
StringRef getVendorName() const; StringRef getVendorName() const;
@ -838,7 +841,7 @@ public:
/// setArch - Set the architecture (first) component of the triple /// setArch - Set the architecture (first) component of the triple
/// to a known type. /// 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 /// setVendor - Set the vendor (second) component of the triple to a
/// known type. /// known type.

View File

@ -1030,6 +1030,30 @@ StringRef Triple::getArchName() const {
return StringRef(Data).split('-').first; // Isolate first component 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 Triple::getVendorName() const {
StringRef Tmp = StringRef(Data).split('-').second; // Strip first component StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
return Tmp.split('-').first; // Isolate second component return Tmp.split('-').first; // Isolate second component
@ -1211,8 +1235,8 @@ void Triple::setTriple(const Twine &Str) {
*this = Triple(Str); *this = Triple(Str);
} }
void Triple::setArch(ArchType Kind) { void Triple::setArch(ArchType Kind, SubArchType SubArch) {
setArchName(getArchTypeName(Kind)); setArchName(getArchName(Kind, SubArch));
} }
void Triple::setVendor(VendorType Kind) { void Triple::setVendor(VendorType Kind) {
@ -1404,8 +1428,12 @@ Triple Triple::get32BitArchVariant() const {
case Triple::amdil64: T.setArch(Triple::amdil); break; case Triple::amdil64: T.setArch(Triple::amdil); break;
case Triple::hsail64: T.setArch(Triple::hsail); break; case Triple::hsail64: T.setArch(Triple::hsail); break;
case Triple::le64: T.setArch(Triple::le32); break; case Triple::le64: T.setArch(Triple::le32); break;
case Triple::mips64: T.setArch(Triple::mips); break; case Triple::mips64:
case Triple::mips64el: T.setArch(Triple::mipsel); break; 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::nvptx64: T.setArch(Triple::nvptx); break;
case Triple::ppc64: T.setArch(Triple::ppc); break; case Triple::ppc64: T.setArch(Triple::ppc); break;
case Triple::ppc64le: T.setArch(Triple::ppcle); 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::armeb: T.setArch(Triple::aarch64_be); break;
case Triple::hsail: T.setArch(Triple::hsail64); break; case Triple::hsail: T.setArch(Triple::hsail64); break;
case Triple::le32: T.setArch(Triple::le64); break; case Triple::le32: T.setArch(Triple::le64); break;
case Triple::mips: T.setArch(Triple::mips64); break; case Triple::mips:
case Triple::mipsel: T.setArch(Triple::mips64el); break; 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::nvptx: T.setArch(Triple::nvptx64); break;
case Triple::ppc: T.setArch(Triple::ppc64); break; case Triple::ppc: T.setArch(Triple::ppc64); break;
case Triple::ppcle: T.setArch(Triple::ppc64le); 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::aarch64: T.setArch(Triple::aarch64_be); break;
case Triple::bpfel: T.setArch(Triple::bpfeb); break; case Triple::bpfel: T.setArch(Triple::bpfeb); break;
case Triple::mips64el:T.setArch(Triple::mips64); break; case Triple::mips64el:
case Triple::mipsel: T.setArch(Triple::mips); break; 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::ppcle: T.setArch(Triple::ppc); break;
case Triple::ppc64le: T.setArch(Triple::ppc64); break; case Triple::ppc64le: T.setArch(Triple::ppc64); break;
case Triple::sparcel: T.setArch(Triple::sparc); 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::aarch64_be: T.setArch(Triple::aarch64); break;
case Triple::bpfeb: T.setArch(Triple::bpfel); break; case Triple::bpfeb: T.setArch(Triple::bpfel); break;
case Triple::mips64: T.setArch(Triple::mips64el); break; case Triple::mips64:
case Triple::mips: T.setArch(Triple::mipsel); break; 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::ppc: T.setArch(Triple::ppcle); break;
case Triple::ppc64: T.setArch(Triple::ppc64le); break; case Triple::ppc64: T.setArch(Triple::ppc64le); break;
case Triple::sparc: T.setArch(Triple::sparcel); break; case Triple::sparc: T.setArch(Triple::sparcel); break;

View File

@ -930,11 +930,27 @@ TEST(TripleTest, BitWidthArchVariants) {
T.setArch(Triple::mips); T.setArch(Triple::mips);
EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::NoSubArch, T.get32BitArchVariant().getSubArch());
EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch()); 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); T.setArch(Triple::mipsel);
EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::NoSubArch, T.get32BitArchVariant().getSubArch());
EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch()); 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); T.setArch(Triple::ppc);
EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch());
@ -954,11 +970,27 @@ TEST(TripleTest, BitWidthArchVariants) {
T.setArch(Triple::mips64); T.setArch(Triple::mips64);
EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::NoSubArch, T.get32BitArchVariant().getSubArch());
EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch()); 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); T.setArch(Triple::mips64el);
EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::NoSubArch, T.get32BitArchVariant().getSubArch());
EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch()); 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); T.setArch(Triple::ppc64);
EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch());
@ -1104,19 +1136,55 @@ TEST(TripleTest, EndianArchVariants) {
T.setArch(Triple::mips64); T.setArch(Triple::mips64);
EXPECT_EQ(Triple::mips64, T.getBigEndianArchVariant().getArch()); EXPECT_EQ(Triple::mips64, T.getBigEndianArchVariant().getArch());
EXPECT_EQ(Triple::NoSubArch, T.getBigEndianArchVariant().getSubArch());
EXPECT_EQ(Triple::mips64el, T.getLittleEndianArchVariant().getArch()); 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); T.setArch(Triple::mips64el);
EXPECT_EQ(Triple::mips64, T.getBigEndianArchVariant().getArch()); EXPECT_EQ(Triple::mips64, T.getBigEndianArchVariant().getArch());
EXPECT_EQ(Triple::NoSubArch, T.getBigEndianArchVariant().getSubArch());
EXPECT_EQ(Triple::mips64el, T.getLittleEndianArchVariant().getArch()); 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); T.setArch(Triple::mips);
EXPECT_EQ(Triple::mips, T.getBigEndianArchVariant().getArch()); EXPECT_EQ(Triple::mips, T.getBigEndianArchVariant().getArch());
EXPECT_EQ(Triple::NoSubArch, T.getBigEndianArchVariant().getSubArch());
EXPECT_EQ(Triple::mipsel, T.getLittleEndianArchVariant().getArch()); 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); T.setArch(Triple::mipsel);
EXPECT_EQ(Triple::mips, T.getBigEndianArchVariant().getArch()); EXPECT_EQ(Triple::mips, T.getBigEndianArchVariant().getArch());
EXPECT_EQ(Triple::NoSubArch, T.getBigEndianArchVariant().getSubArch());
EXPECT_EQ(Triple::mipsel, T.getLittleEndianArchVariant().getArch()); 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); T.setArch(Triple::ppc);
EXPECT_EQ(Triple::ppc, T.getBigEndianArchVariant().getArch()); EXPECT_EQ(Triple::ppc, T.getBigEndianArchVariant().getArch());