diff --git a/llvm/CODE_OWNERS.TXT b/llvm/CODE_OWNERS.TXT --- a/llvm/CODE_OWNERS.TXT +++ b/llvm/CODE_OWNERS.TXT @@ -153,6 +153,10 @@ W: http://nondot.org/~sabre/ D: Everything not covered by someone else +N: Weining Lu +E: luweining@loongson.cn +D: LoongArch backend (lib/Target/LoongArch/*) + N: David Majnemer E: david.majnemer@gmail.com D: IR Constant Folder, InstCombine diff --git a/llvm/docs/CompilerWriterInfo.rst b/llvm/docs/CompilerWriterInfo.rst --- a/llvm/docs/CompilerWriterInfo.rst +++ b/llvm/docs/CompilerWriterInfo.rst @@ -107,6 +107,11 @@ * `C-SKY Architecture User Guide `_ * `C-SKY V2 ABI `_ +LoongArch +--------- +* `LoongArch Reference Manual - Volume 1: Basic Architecture `_ +* `LoongArch ELF ABI specification `_ + SPARC ----- diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -57,6 +57,8 @@ bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian) csky, // CSKY: csky hexagon, // Hexagon: hexagon + loongarch32, // LoongArch (32-bit): loongarch32 + loongarch64, // LoongArch (64-bit): loongarch64 m68k, // M68k: Motorola 680x0 family mips, // MIPS: mips, mipsallegrex, mipsr6 mipsel, // MIPSEL: mipsel, mipsallegrexe, mipsr6el @@ -774,6 +776,11 @@ : PointerWidth == 64; } + /// Tests whether the target is LoongArch (32- and 64-bit). + bool isLoongArch() const { + return getArch() == Triple::loongarch32 || getArch() == Triple::loongarch64; + } + /// Tests whether the target is MIPS 32-bit (little and big endian). bool isMIPS32() const { return getArch() == Triple::mips || getArch() == Triple::mipsel; diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -44,6 +44,8 @@ case lanai: return "lanai"; case le32: return "le32"; case le64: return "le64"; + case loongarch32: return "loongarch32"; + case loongarch64: return "loongarch64"; case m68k: return "m68k"; case mips64: return "mips64"; case mips64el: return "mips64el"; @@ -164,6 +166,9 @@ case ve: return "ve"; case csky: return "csky"; + + case loongarch32: + case loongarch64: return "loongarch"; } } @@ -340,6 +345,8 @@ .Case("renderscript64", renderscript64) .Case("ve", ve) .Case("csky", csky) + .Case("loongarch32", loongarch32) + .Case("loongarch64", loongarch64) .Default(UnknownArch); } @@ -475,6 +482,8 @@ .Case("wasm32", Triple::wasm32) .Case("wasm64", Triple::wasm64) .Case("csky", Triple::csky) + .Case("loongarch32", Triple::loongarch32) + .Case("loongarch64", Triple::loongarch64) .Default(Triple::UnknownArch); // Some architectures require special parsing logic just to compute the @@ -731,6 +740,8 @@ case Triple::lanai: case Triple::le32: case Triple::le64: + case Triple::loongarch32: + case Triple::loongarch64: case Triple::m68k: case Triple::mips64: case Triple::mips64el: @@ -1290,6 +1301,7 @@ case llvm::Triple::kalimba: case llvm::Triple::lanai: case llvm::Triple::le32: + case llvm::Triple::loongarch32: case llvm::Triple::m68k: case llvm::Triple::mips: case llvm::Triple::mipsel: @@ -1321,6 +1333,7 @@ case llvm::Triple::bpfel: case llvm::Triple::hsail64: case llvm::Triple::le64: + case llvm::Triple::loongarch64: case llvm::Triple::mips64: case llvm::Triple::mips64el: case llvm::Triple::nvptx64: @@ -1377,6 +1390,7 @@ case Triple::kalimba: case Triple::lanai: case Triple::le32: + case Triple::loongarch32: case Triple::m68k: case Triple::mips: case Triple::mipsel: @@ -1406,6 +1420,7 @@ 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::loongarch64: T.setArch(Triple::loongarch32); break; case Triple::mips64: T.setArch(Triple::mips, getSubArch()); break; @@ -1455,6 +1470,7 @@ case Triple::bpfel: case Triple::hsail64: case Triple::le64: + case Triple::loongarch64: case Triple::mips64: case Triple::mips64el: case Triple::nvptx64: @@ -1478,6 +1494,7 @@ 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::loongarch32: T.setArch(Triple::loongarch64); break; case Triple::mips: T.setArch(Triple::mips64, getSubArch()); break; @@ -1517,6 +1534,8 @@ case Triple::kalimba: case Triple::le32: case Triple::le64: + case Triple::loongarch32: + case Triple::loongarch64: case Triple::msp430: case Triple::nvptx64: case Triple::nvptx: @@ -1617,6 +1636,8 @@ case Triple::kalimba: case Triple::le32: case Triple::le64: + case Triple::loongarch32: + case Triple::loongarch64: case Triple::mips64el: case Triple::mipsel: case Triple::msp430: diff --git a/llvm/unittests/ADT/TripleTest.cpp b/llvm/unittests/ADT/TripleTest.cpp --- a/llvm/unittests/ADT/TripleTest.cpp +++ b/llvm/unittests/ADT/TripleTest.cpp @@ -354,6 +354,18 @@ EXPECT_EQ(Triple::Linux, T.getOS()); EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); + T = Triple("loongarch32-unknown-unknown"); + EXPECT_EQ(Triple::loongarch32, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::UnknownOS, T.getOS()); + EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); + + T = Triple("loongarch64-unknown-linux"); + EXPECT_EQ(Triple::loongarch64, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); + T = Triple("riscv32-unknown-unknown"); EXPECT_EQ(Triple::riscv32, T.getArch()); EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); @@ -949,6 +961,18 @@ EXPECT_TRUE(T.isArch32Bit()); EXPECT_FALSE(T.isArch64Bit()); EXPECT_TRUE(T.isCSKY()); + + T.setArch(Triple::loongarch32); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); + EXPECT_TRUE(T.isLoongArch()); + + T.setArch(Triple::loongarch64); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_TRUE(T.isArch64Bit()); + EXPECT_TRUE(T.isLoongArch()); } TEST(TripleTest, BitWidthArchVariants) { @@ -1092,6 +1116,14 @@ EXPECT_EQ(Triple::csky, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch()); + T.setArch(Triple::loongarch32); + EXPECT_EQ(Triple::loongarch32, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::loongarch64, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::loongarch64); + EXPECT_EQ(Triple::loongarch32, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::loongarch64, T.get64BitArchVariant().getArch()); + T.setArch(Triple::thumbeb); EXPECT_EQ(Triple::thumbeb, T.get32BitArchVariant().getArch()); EXPECT_EQ(Triple::aarch64_be, T.get64BitArchVariant().getArch()); @@ -1269,6 +1301,16 @@ T.setArch(Triple::csky); EXPECT_EQ(Triple::UnknownArch, T.getBigEndianArchVariant().getArch()); EXPECT_EQ(Triple::csky, T.getLittleEndianArchVariant().getArch()); + + T.setArch(Triple::loongarch32); + EXPECT_TRUE(T.isLittleEndian()); + EXPECT_EQ(Triple::UnknownArch, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::loongarch32, T.getLittleEndianArchVariant().getArch()); + + T.setArch(Triple::loongarch64); + EXPECT_TRUE(T.isLittleEndian()); + EXPECT_EQ(Triple::UnknownArch, T.getBigEndianArchVariant().getArch()); + EXPECT_EQ(Triple::loongarch64, T.getLittleEndianArchVariant().getArch()); } TEST(TripleTest, getOSVersion) { @@ -1485,6 +1527,10 @@ EXPECT_EQ(Triple::ELF, Triple("csky-unknown-unknown").getObjectFormat()); EXPECT_EQ(Triple::ELF, Triple("csky-unknown-linux").getObjectFormat()); + EXPECT_EQ(Triple::ELF, + Triple("loongarch32-unknown-unknown").getObjectFormat()); + EXPECT_EQ(Triple::ELF, Triple("loongarch64-unknown-linux").getObjectFormat()); + Triple MSVCNormalized(Triple::normalize("i686-pc-windows-msvc-elf")); EXPECT_EQ(Triple::ELF, MSVCNormalized.getObjectFormat());