[clang][LoongArch] Add support for LoongArch32 (#172619)
This patch adds support for LoongArch32, as introduced in la-toolchain-conventions v1.2. Co-authored-by: Sun Haiyong <sunhaiyong@zdbr.net> Link: https://github.com/loongson/la-toolchain-conventions/releases/tag/releases%2Fv1.2 Link: https://gcc.gnu.org/pipermail/gcc-patches/2025-December/703312.html
This commit is contained in:
parent
7cbd8d509c
commit
0a9d480fad
@ -228,6 +228,13 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
Builder.defineMacro("__loongarch_arch",
|
||||
Twine('"') + ArchName + Twine('"'));
|
||||
}
|
||||
} else if (ArchName == "loongarch32") {
|
||||
if (HasFeature32S)
|
||||
Builder.defineMacro("__loongarch_arch",
|
||||
Twine('"') + "la32v1.0" + Twine('"'));
|
||||
else
|
||||
Builder.defineMacro("__loongarch_arch",
|
||||
Twine('"') + "la32rv1.0" + Twine('"'));
|
||||
} else {
|
||||
Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"'));
|
||||
}
|
||||
@ -268,6 +275,8 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
|
||||
StringRef ABI = getABI();
|
||||
if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s")
|
||||
Builder.defineMacro("__loongarch_lp64");
|
||||
else if (ABI == "ilp32d" || ABI == "ilp32f" || ABI == "ilp32s")
|
||||
Builder.defineMacro("__loongarch_ilp32");
|
||||
|
||||
if (ABI == "lp64d" || ABI == "ilp32d") {
|
||||
Builder.defineMacro("__loongarch_hard_float");
|
||||
@ -356,6 +365,7 @@ bool LoongArchTargetInfo::hasFeature(StringRef Feature) const {
|
||||
.Case("loongarch64", Is64Bit)
|
||||
.Case("32bit", !Is64Bit)
|
||||
.Case("64bit", Is64Bit)
|
||||
.Case("32s", HasFeature32S)
|
||||
.Case("lsx", HasFeatureLSX)
|
||||
.Case("lasx", HasFeatureLASX)
|
||||
.Default(false);
|
||||
@ -373,7 +383,9 @@ LoongArchTargetInfo::getTargetBuiltins() const {
|
||||
bool LoongArchTargetInfo::handleTargetFeatures(
|
||||
std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
|
||||
for (const auto &Feature : Features) {
|
||||
if (Feature == "+d" || Feature == "+f") {
|
||||
if (Feature == "+32s") {
|
||||
HasFeature32S = true;
|
||||
} else if (Feature == "+d" || Feature == "+f") {
|
||||
// "d" implies "f".
|
||||
HasFeatureF = true;
|
||||
if (Feature == "+d") {
|
||||
@ -430,7 +442,7 @@ LoongArchTargetInfo::parseTargetAttr(StringRef Features) const {
|
||||
switch (Kind) {
|
||||
case AttrFeatureKind::Arch: {
|
||||
if (llvm::LoongArch::isValidArchName(Value) || Value == "la64v1.0" ||
|
||||
Value == "la64v1.1") {
|
||||
Value == "la64v1.1" || Value == "la32v1.0" || Value == "la32rv1.0") {
|
||||
std::vector<llvm::StringRef> ArchFeatures;
|
||||
if (llvm::LoongArch::getArchFeatures(Value, ArchFeatures)) {
|
||||
Ret.Features.insert(Ret.Features.end(), ArchFeatures.begin(),
|
||||
@ -441,6 +453,8 @@ LoongArchTargetInfo::parseTargetAttr(StringRef Features) const {
|
||||
Ret.Duplicate = "arch=";
|
||||
else if (Value == "la64v1.0" || Value == "la64v1.1")
|
||||
Ret.CPU = "loongarch64";
|
||||
else if (Value == "la32v1.0" || Value == "la32rv1.0")
|
||||
Ret.CPU = "loongarch32";
|
||||
else
|
||||
Ret.CPU = Value;
|
||||
} else {
|
||||
|
||||
@ -25,6 +25,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
|
||||
protected:
|
||||
std::string ABI;
|
||||
std::string CPU;
|
||||
bool HasFeature32S;
|
||||
bool HasFeatureD;
|
||||
bool HasFeatureF;
|
||||
bool HasFeatureLSX;
|
||||
@ -39,6 +40,7 @@ protected:
|
||||
public:
|
||||
LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
|
||||
: TargetInfo(Triple) {
|
||||
HasFeature32S = false;
|
||||
HasFeatureD = false;
|
||||
HasFeatureF = false;
|
||||
HasFeatureLSX = false;
|
||||
|
||||
@ -299,7 +299,8 @@ std::string loongarch::getLoongArchTargetCPU(const llvm::opt::ArgList &Args,
|
||||
// If we have -march, use that.
|
||||
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
|
||||
Arch = A->getValue();
|
||||
if (Arch == "la64v1.0" || Arch == "la64v1.1")
|
||||
if (Arch == "la64v1.0" || Arch == "la64v1.1" || Arch == "la32v1.0" ||
|
||||
Arch == "la32rv1.0")
|
||||
CPU = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
|
||||
else
|
||||
CPU = Arch;
|
||||
|
||||
@ -751,7 +751,12 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
|
||||
|
||||
break;
|
||||
}
|
||||
// TODO: handle loongarch32.
|
||||
case llvm::Triple::loongarch32: {
|
||||
StringRef ABIName =
|
||||
loongarch::getLoongArchABI(D, Args, getToolChain().getTriple());
|
||||
CmdArgs.push_back(Args.MakeArgString("-mabi=" + ABIName));
|
||||
break;
|
||||
}
|
||||
case llvm::Triple::loongarch64: {
|
||||
StringRef ABIName =
|
||||
loongarch::getLoongArchABI(D, Args, getToolChain().getTriple());
|
||||
@ -2369,6 +2374,12 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
|
||||
"i586-suse-linux", "i686-montavista-linux",
|
||||
};
|
||||
|
||||
static const char *const LoongArch32LibDirs[] = {"/lib32", "/lib"};
|
||||
static const char *const LoongArch32Triples[] = {
|
||||
"loongarch32-linux-gnu", "loongarch32-unknown-linux-gnu",
|
||||
"loongarch32-linux-gnuf32", "loongarch32-unknown-linux-gnuf32",
|
||||
"loongarch32-linux-gnusf", "loongarch32-unknown-linux-gnusf"};
|
||||
|
||||
static const char *const LoongArch64LibDirs[] = {"/lib64", "/lib"};
|
||||
static const char *const LoongArch64Triples[] = {
|
||||
"loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu"};
|
||||
@ -2639,7 +2650,10 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
|
||||
BiarchTripleAliases.append(begin(X32Triples), end(X32Triples));
|
||||
}
|
||||
break;
|
||||
// TODO: Handle loongarch32.
|
||||
case llvm::Triple::loongarch32:
|
||||
LibDirs.append(begin(LoongArch32LibDirs), end(LoongArch32LibDirs));
|
||||
TripleAliases.append(begin(LoongArch32Triples), end(LoongArch32Triples));
|
||||
break;
|
||||
case llvm::Triple::loongarch64:
|
||||
LibDirs.append(begin(LoongArch64LibDirs), end(LoongArch64LibDirs));
|
||||
TripleAliases.append(begin(LoongArch64Triples), end(LoongArch64Triples));
|
||||
|
||||
@ -206,6 +206,19 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
|
||||
if (Triple.getArch() == llvm::Triple::riscv32)
|
||||
return "lib32";
|
||||
|
||||
if (Triple.getArch() == llvm::Triple::loongarch32) {
|
||||
switch (Triple.getEnvironment()) {
|
||||
default:
|
||||
return "lib32";
|
||||
case llvm::Triple::GNUSF:
|
||||
case llvm::Triple::MuslSF:
|
||||
return "lib32/sf";
|
||||
case llvm::Triple::GNUF32:
|
||||
case llvm::Triple::MuslF32:
|
||||
return "lib32/f32";
|
||||
}
|
||||
}
|
||||
|
||||
return Triple.isArch32Bit() ? "lib" : "lib64";
|
||||
}
|
||||
|
||||
|
||||
26
clang/test/CodeGen/LoongArch/targetattr-la32.c
Normal file
26
clang/test/CodeGen/LoongArch/targetattr-la32.c
Normal file
@ -0,0 +1,26 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5
|
||||
// RUN: %clang_cc1 -triple loongarch32 -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
__attribute__((target("arch=la32v1.0")))
|
||||
// CHECK-LABEL: define dso_local void @testLa32v10(
|
||||
// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void testLa32v10() {}
|
||||
|
||||
__attribute__((target("arch=la32rv1.0")))
|
||||
// CHECK-LABEL: define dso_local void @testLa32rv10(
|
||||
// CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
|
||||
// CHECK-NEXT: [[ENTRY:.*:]]
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void testLa32rv10() {}
|
||||
|
||||
//.
|
||||
// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="loongarch32" "target-features"="+32bit,+32s" }
|
||||
// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="loongarch32" "target-features"="+32bit" }
|
||||
//.
|
||||
// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
|
||||
// CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
|
||||
//.
|
||||
@ -1,3 +1,11 @@
|
||||
// RUN: %clang --target=loongarch32 -march=la32v1.0 -fsyntax-only %s -### 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CC1-LA32V1P0
|
||||
// RUN: %clang --target=loongarch32 -march=la32v1.0 -S -emit-llvm %s -o - | \
|
||||
// RUN: FileCheck %s --check-prefix=IR-LA32V1P0
|
||||
// RUN: %clang --target=loongarch32 -march=la32rv1.0 -fsyntax-only %s -### 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CC1-LA32RV1P0
|
||||
// RUN: %clang --target=loongarch32 -march=la32rv1.0 -S -emit-llvm %s -o - | \
|
||||
// RUN: FileCheck %s --check-prefix=IR-LA32RV1P0
|
||||
// RUN: %clang --target=loongarch64 -march=loongarch64 -fsyntax-only %s -### 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CC1-LOONGARCH64
|
||||
// RUN: %clang --target=loongarch64 -march=la464 -fsyntax-only %s -### 2>&1 | \
|
||||
@ -19,6 +27,18 @@
|
||||
// RUN: %clang --target=loongarch64 -march=la664 -S -emit-llvm %s -o - | \
|
||||
// RUN: FileCheck %s --check-prefix=IR-LA664
|
||||
|
||||
// CC1-LA32V1P0: "-target-cpu" "loongarch32"
|
||||
// CC1-LA32V1P0-NOT: "-target-feature"
|
||||
// CC1-LA32V1P0: "-target-feature" "+32bit" "-target-feature" "+32s"
|
||||
// CC1-LA32V1P0-NOT: "-target-feature"
|
||||
// CC1-LA32V1P0: "-target-abi" "ilp32d"
|
||||
|
||||
// CC1-LA32RV1P0: "-target-cpu" "loongarch32"
|
||||
// CC1-LA32RV1P0-NOT: "-target-feature"
|
||||
// CC1-LA32RV1P0: "-target-feature" "+32bit"
|
||||
// CC1-LA32RV1P0-NOT: "-target-feature"
|
||||
// CC1-LA32RV1P0: "-target-abi" "ilp32d"
|
||||
|
||||
// CC1-LOONGARCH64: "-target-cpu" "loongarch64"
|
||||
// CC1-LOONGARCH64-NOT: "-target-feature"
|
||||
// CC1-LOONGARCH64: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+ual"
|
||||
@ -49,6 +69,9 @@
|
||||
// CC1-LA664-NOT: "-target-feature"
|
||||
// CC1-LA664: "-target-abi" "lp64d"
|
||||
|
||||
// IR-LA32V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch32" {{.*}}"target-features"="+32bit,+32s"
|
||||
// IR-LA32RV1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch32" {{.*}}"target-features"="+32bit"
|
||||
|
||||
// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+relax,+ual"
|
||||
// IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+relax,+ual"
|
||||
// IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+lsx,+relax,+ual"
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
// RUN: %clang --target=loongarch32 -mtune=loongarch32 -fsyntax-only %s -### 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=loongarch32
|
||||
// RUN: %clang --target=loongarch32 -mtune=loongarch32 -S -emit-llvm %s -o - | \
|
||||
// RUN: FileCheck %s --check-prefix=IRATTR -DCPU=loongarch32
|
||||
|
||||
// RUN: %clang --target=loongarch64 -mtune=loongarch64 -fsyntax-only %s -### 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=loongarch64
|
||||
// RUN: %clang --target=loongarch64 -mtune=loongarch64 -S -emit-llvm %s -o - | \
|
||||
|
||||
@ -822,6 +822,12 @@
|
||||
|
||||
/// Check __loongarch_arch{_tune/_frecipe/_lam_bh/_lamcas/_ld_seq_sa/_div32/_scq}.
|
||||
|
||||
// RUN: %clang --target=loongarch32 -x c -E -dM %s -o - | \
|
||||
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la32rv1.0 -DTUNE=loongarch32 %s
|
||||
// RUN: %clang --target=loongarch32 -x c -E -dM %s -o - -march=la32v1.0 | \
|
||||
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la32v1.0 -DTUNE=loongarch32 %s
|
||||
// RUN: %clang --target=loongarch32 -x c -E -dM %s -o - -march=la32rv1.0 | \
|
||||
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la32rv1.0 -DTUNE=loongarch32 %s
|
||||
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - | \
|
||||
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s
|
||||
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 | \
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define LOONGARCH_FEATURE(NAME, KIND)
|
||||
#endif
|
||||
|
||||
LOONGARCH_FEATURE("+32bit", FK_32BIT)
|
||||
LOONGARCH_FEATURE("+64bit", FK_64BIT)
|
||||
LOONGARCH_FEATURE("+f", FK_FP32)
|
||||
LOONGARCH_FEATURE("+d", FK_FP64)
|
||||
@ -16,6 +17,7 @@ LOONGARCH_FEATURE("+lamcas", FK_LAMCAS)
|
||||
LOONGARCH_FEATURE("+ld-seq-sa", FK_LD_SEQ_SA)
|
||||
LOONGARCH_FEATURE("+div32", FK_DIV32)
|
||||
LOONGARCH_FEATURE("+scq", FK_SCQ)
|
||||
LOONGARCH_FEATURE("+32s", FK_32S)
|
||||
|
||||
#undef LOONGARCH_FEATURE
|
||||
|
||||
@ -23,6 +25,7 @@ LOONGARCH_FEATURE("+scq", FK_SCQ)
|
||||
#define LOONGARCH_ARCH(NAME, KIND, FEATURES)
|
||||
#endif
|
||||
|
||||
LOONGARCH_ARCH("loongarch32", AK_LOONGARCH32, FK_32BIT)
|
||||
LOONGARCH_ARCH("loongarch64", AK_LOONGARCH64, FK_64BIT | FK_FP32 | FK_FP64 | FK_UAL)
|
||||
LOONGARCH_ARCH("la464", AK_LA464, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL)
|
||||
LOONGARCH_ARCH("la664", AK_LA664, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL | FK_FRECIPE | FK_LAM_BH | FK_LAMCAS | FK_LD_SEQ_SA | FK_DIV32 | FK_SCQ)
|
||||
|
||||
@ -24,6 +24,9 @@ class StringRef;
|
||||
namespace LoongArch {
|
||||
|
||||
enum FeatureKind : uint32_t {
|
||||
// 32-bit ISA is available.
|
||||
FK_32BIT = 1 << 0,
|
||||
|
||||
// 64-bit ISA is available.
|
||||
FK_64BIT = 1 << 1,
|
||||
|
||||
@ -67,6 +70,9 @@ enum FeatureKind : uint32_t {
|
||||
|
||||
// sc.q is available.
|
||||
FK_SCQ = 1 << 14,
|
||||
|
||||
// 32-bit standard variant is available.
|
||||
FK_32S = 1 << 15,
|
||||
};
|
||||
|
||||
struct FeatureInfo {
|
||||
|
||||
@ -171,6 +171,9 @@ def : ProcessorModel<"generic-la64", NoSchedModel, [Feature64Bit,
|
||||
FeatureUAL,
|
||||
FeatureExtLSX]>;
|
||||
|
||||
// Generic 32-bit processor.
|
||||
def : ProcessorModel<"loongarch32", NoSchedModel, [Feature32Bit]>;
|
||||
|
||||
// Generic 64-bit processor with double-precision floating-point support.
|
||||
def : ProcessorModel<"loongarch64", NoSchedModel, [Feature64Bit,
|
||||
FeatureUAL,
|
||||
|
||||
@ -26,18 +26,14 @@ namespace LoongArchABI {
|
||||
static ABI checkABIStandardized(ABI Abi) {
|
||||
StringRef ABIName;
|
||||
switch (Abi) {
|
||||
case ABI_ILP32S:
|
||||
ABIName = "ilp32s";
|
||||
break;
|
||||
case ABI_ILP32F:
|
||||
ABIName = "ilp32f";
|
||||
break;
|
||||
case ABI_ILP32D:
|
||||
ABIName = "ilp32d";
|
||||
break;
|
||||
case ABI_LP64F:
|
||||
ABIName = "lp64f";
|
||||
break;
|
||||
case ABI_ILP32S:
|
||||
case ABI_ILP32D:
|
||||
case ABI_LP64S:
|
||||
case ABI_LP64D:
|
||||
return Abi;
|
||||
|
||||
@ -74,6 +74,13 @@ bool LoongArch::getArchFeatures(StringRef Arch,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Arch == "la32v1.0" || Arch == "la32rv1.0") {
|
||||
Features.push_back("+32bit");
|
||||
if (Arch == "la32v1.0")
|
||||
Features.push_back("+32s");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -85,6 +92,5 @@ void LoongArch::fillValidCPUList(SmallVectorImpl<StringRef> &Values) {
|
||||
}
|
||||
|
||||
StringRef LoongArch::getDefaultArch(bool Is64Bit) {
|
||||
// TODO: use a real 32-bit arch name.
|
||||
return Is64Bit ? "loongarch64" : "";
|
||||
return Is64Bit ? "loongarch64" : "loongarch32";
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
; RUN: llc --mtriple=loongarch32 --mattr=+d --target-abi=ilp32s < %s 2>&1 \
|
||||
; RUN: | FileCheck %s -DABI=ilp32s --check-prefixes=CHECK,WARNING
|
||||
; RUN: llc --mtriple=loongarch32 --mattr=+d --target-abi=ilp32f < %s 2>&1 \
|
||||
; RUN: | FileCheck %s -DABI=ilp32f --check-prefixes=CHECK,WARNING
|
||||
; RUN: llc --mtriple=loongarch32 --mattr=+d --target-abi=ilp32d < %s 2>&1 \
|
||||
; RUN: | FileCheck %s -DABI=ilp32d --check-prefixes=CHECK,WARNING
|
||||
; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64f < %s 2>&1 \
|
||||
; RUN: | FileCheck %s -DABI=lp64f --check-prefixes=CHECK,WARNING
|
||||
|
||||
; RUN: llc --mtriple=loongarch32 --mattr=+d --target-abi=ilp32s < %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefixes=CHECK,NO-WARNING
|
||||
; RUN: llc --mtriple=loongarch32 --mattr=+d --target-abi=ilp32d < %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefixes=CHECK,NO-WARNING
|
||||
; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64s < %s 2>&1 \
|
||||
; RUN: | FileCheck %s --check-prefixes=CHECK,NO-WARNING
|
||||
; RUN: llc --mtriple=loongarch64 --mattr=+d --target-abi=lp64d < %s 2>&1 \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user