aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Basic/Targets/CSKY.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Basic/Targets/CSKY.cpp')
-rw-r--r--clang/lib/Basic/Targets/CSKY.cpp314
1 files changed, 314 insertions, 0 deletions
diff --git a/clang/lib/Basic/Targets/CSKY.cpp b/clang/lib/Basic/Targets/CSKY.cpp
new file mode 100644
index 000000000000..adcffd90ae78
--- /dev/null
+++ b/clang/lib/Basic/Targets/CSKY.cpp
@@ -0,0 +1,314 @@
+//===--- CSKY.cpp - Implement CSKY target feature support -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements CSKY TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CSKY.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+bool CSKYTargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::CSKY::parseCPUArch(Name) != llvm::CSKY::ArchKind::INVALID;
+}
+
+bool CSKYTargetInfo::setCPU(const std::string &Name) {
+ llvm::CSKY::ArchKind archKind = llvm::CSKY::parseCPUArch(Name);
+ bool isValid = (archKind != llvm::CSKY::ArchKind::INVALID);
+
+ if (isValid) {
+ CPU = Name;
+ Arch = archKind;
+ }
+
+ return isValid;
+}
+
+void CSKYTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("__ELF__");
+ Builder.defineMacro("__csky__", "2");
+ Builder.defineMacro("__CSKY__", "2");
+ Builder.defineMacro("__ckcore__", "2");
+ Builder.defineMacro("__CKCORE__", "2");
+
+ Builder.defineMacro("__CSKYABI__", ABI == "abiv2" ? "2" : "1");
+ Builder.defineMacro("__cskyabi__", ABI == "abiv2" ? "2" : "1");
+
+ StringRef ArchName = "ck810";
+ StringRef CPUName = "ck810";
+
+ if (Arch != llvm::CSKY::ArchKind::INVALID) {
+ ArchName = llvm::CSKY::getArchName(Arch);
+ CPUName = CPU;
+ }
+
+ Builder.defineMacro("__" + ArchName.upper() + "__");
+ Builder.defineMacro("__" + ArchName.lower() + "__");
+ Builder.defineMacro("__" + CPUName.upper() + "__");
+ Builder.defineMacro("__" + CPUName.lower() + "__");
+
+ // TODO: Add support for BE if BE was supported later
+ StringRef endian = "__cskyLE__";
+
+ Builder.defineMacro(endian);
+ Builder.defineMacro(endian.upper());
+ Builder.defineMacro(endian.lower());
+
+ if (DSPV2) {
+ StringRef dspv2 = "__CSKY_DSPV2__";
+ Builder.defineMacro(dspv2);
+ Builder.defineMacro(dspv2.lower());
+ }
+
+ if (VDSPV2) {
+ StringRef vdspv2 = "__CSKY_VDSPV2__";
+ Builder.defineMacro(vdspv2);
+ Builder.defineMacro(vdspv2.lower());
+
+ if (HardFloat) {
+ StringRef vdspv2_f = "__CSKY_VDSPV2_F__";
+ Builder.defineMacro(vdspv2_f);
+ Builder.defineMacro(vdspv2_f.lower());
+ }
+ }
+ if (VDSPV1) {
+ StringRef vdspv1_64 = "__CSKY_VDSP64__";
+ StringRef vdspv1_128 = "__CSKY_VDSP128__";
+
+ Builder.defineMacro(vdspv1_64);
+ Builder.defineMacro(vdspv1_64.lower());
+ Builder.defineMacro(vdspv1_128);
+ Builder.defineMacro(vdspv1_128.lower());
+ }
+ if (is3E3R1) {
+ StringRef is3e3r1 = "__CSKY_3E3R1__";
+ Builder.defineMacro(is3e3r1);
+ Builder.defineMacro(is3e3r1.lower());
+ }
+}
+
+bool CSKYTargetInfo::hasFeature(StringRef Feature) const {
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("hard-float", HardFloat)
+ .Case("hard-float-abi", HardFloatABI)
+ .Case("fpuv2_sf", FPUV2_SF)
+ .Case("fpuv2_df", FPUV2_DF)
+ .Case("fpuv3_sf", FPUV3_SF)
+ .Case("fpuv3_df", FPUV3_DF)
+ .Case("vdspv2", VDSPV2)
+ .Case("dspv2", DSPV2)
+ .Case("vdspv1", VDSPV1)
+ .Case("3e3r1", is3E3R1)
+ .Default(false);
+}
+
+bool CSKYTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
+ for (const auto &Feature : Features) {
+ if (Feature == "+hard-float")
+ HardFloat = true;
+ if (Feature == "+hard-float-abi")
+ HardFloatABI = true;
+ if (Feature == "+fpuv2_sf")
+ FPUV2_SF = true;
+ if (Feature == "+fpuv2_df")
+ FPUV2_DF = true;
+ if (Feature == "+fpuv3_sf")
+ FPUV3_SF = true;
+ if (Feature == "+fpuv3_df")
+ FPUV3_DF = true;
+ if (Feature == "+vdspv2")
+ VDSPV2 = true;
+ if (Feature == "+dspv2")
+ DSPV2 = true;
+ if (Feature == "+vdspv1")
+ VDSPV1 = true;
+ if (Feature == "+3e3r1")
+ is3E3R1 = true;
+ }
+
+ return true;
+}
+
+ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const {
+ return ArrayRef<Builtin::Info>();
+}
+
+ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const {
+ static const char *const GCCRegNames[] = {
+ // Integer registers
+ "r0",
+ "r1",
+ "r2",
+ "r3",
+ "r4",
+ "r5",
+ "r6",
+ "r7",
+ "r8",
+ "r9",
+ "r10",
+ "r11",
+ "r12",
+ "r13",
+ "r14",
+ "r15",
+ "r16",
+ "r17",
+ "r18",
+ "r19",
+ "r20",
+ "r21",
+ "r22",
+ "r23",
+ "r24",
+ "r25",
+ "r26",
+ "r27",
+ "r28",
+ "r29",
+ "r30",
+ "r31",
+
+ // Floating point registers
+ "fr0",
+ "fr1",
+ "fr2",
+ "fr3",
+ "fr4",
+ "fr5",
+ "fr6",
+ "fr7",
+ "fr8",
+ "fr9",
+ "fr10",
+ "fr11",
+ "fr12",
+ "fr13",
+ "fr14",
+ "fr15",
+ "fr16",
+ "fr17",
+ "fr18",
+ "fr19",
+ "fr20",
+ "fr21",
+ "fr22",
+ "fr23",
+ "fr24",
+ "fr25",
+ "fr26",
+ "fr27",
+ "fr28",
+ "fr29",
+ "fr30",
+ "fr31",
+
+ };
+ return llvm::makeArrayRef(GCCRegNames);
+}
+
+ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const {
+ static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+ {{"a0"}, "r0"},
+ {{"a1"}, "r1"},
+ {{"a2"}, "r2"},
+ {{"a3"}, "r3"},
+ {{"l0"}, "r4"},
+ {{"l1"}, "r5"},
+ {{"l2"}, "r6"},
+ {{"l3"}, "r7"},
+ {{"l4"}, "r8"},
+ {{"l5"}, "r9"},
+ {{"l6"}, "r10"},
+ {{"l7"}, "r11"},
+ {{"t0"}, "r12"},
+ {{"t1"}, "r13"},
+ {{"sp"}, "r14"},
+ {{"lr"}, "r15"},
+ {{"l8"}, "r16"},
+ {{"l9"}, "r17"},
+ {{"t2"}, "r18"},
+ {{"t3"}, "r19"},
+ {{"t4"}, "r20"},
+ {{"t5"}, "r21"},
+ {{"t6"}, "r22"},
+ {{"t7", "fp"}, "r23"},
+ {{"t8", "top"}, "r24"},
+ {{"t9", "bsp"}, "r25"},
+ {{"r26"}, "r26"},
+ {{"r27"}, "r27"},
+ {{"gb", "rgb", "rdb"}, "r28"},
+ {{"tb", "rtb"}, "r29"},
+ {{"svbr"}, "r30"},
+ {{"tls"}, "r31"},
+
+ {{"vr0"}, "fr0"},
+ {{"vr1"}, "fr1"},
+ {{"vr2"}, "fr2"},
+ {{"vr3"}, "fr3"},
+ {{"vr4"}, "fr4"},
+ {{"vr5"}, "fr5"},
+ {{"vr6"}, "fr6"},
+ {{"vr7"}, "fr7"},
+ {{"vr8"}, "fr8"},
+ {{"vr9"}, "fr9"},
+ {{"vr10"}, "fr10"},
+ {{"vr11"}, "fr11"},
+ {{"vr12"}, "fr12"},
+ {{"vr13"}, "fr13"},
+ {{"vr14"}, "fr14"},
+ {{"vr15"}, "fr15"},
+ {{"vr16"}, "fr16"},
+ {{"vr17"}, "fr17"},
+ {{"vr18"}, "fr18"},
+ {{"vr19"}, "fr19"},
+ {{"vr20"}, "fr20"},
+ {{"vr21"}, "fr21"},
+ {{"vr22"}, "fr22"},
+ {{"vr23"}, "fr23"},
+ {{"vr24"}, "fr24"},
+ {{"vr25"}, "fr25"},
+ {{"vr26"}, "fr26"},
+ {{"vr27"}, "fr27"},
+ {{"vr28"}, "fr28"},
+ {{"vr29"}, "fr29"},
+ {{"vr30"}, "fr30"},
+ {{"vr31"}, "fr31"},
+
+ };
+ return llvm::makeArrayRef(GCCRegAliases);
+}
+
+bool CSKYTargetInfo::validateAsmConstraint(
+ const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+ switch (*Name) {
+ default:
+ return false;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'y':
+ case 'l':
+ case 'h':
+ case 'w':
+ case 'v': // A floating-point and vector register.
+ case 'z':
+ Info.setAllowsRegister();
+ return true;
+ }
+}
+
+unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const {
+ if (Size >= 32)
+ return 32;
+ return 0;
+}