181ad6265SDimitry Andric //===--- CSKY.cpp - Implement CSKY target feature support -----------------===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric //
981ad6265SDimitry Andric // This file implements CSKY TargetInfo objects.
1081ad6265SDimitry Andric //
1181ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1281ad6265SDimitry Andric 
1381ad6265SDimitry Andric #include "CSKY.h"
1481ad6265SDimitry Andric 
1581ad6265SDimitry Andric using namespace clang;
1681ad6265SDimitry Andric using namespace clang::targets;
1781ad6265SDimitry Andric 
isValidCPUName(StringRef Name) const1881ad6265SDimitry Andric bool CSKYTargetInfo::isValidCPUName(StringRef Name) const {
1981ad6265SDimitry Andric   return llvm::CSKY::parseCPUArch(Name) != llvm::CSKY::ArchKind::INVALID;
2081ad6265SDimitry Andric }
2181ad6265SDimitry Andric 
setCPU(const std::string & Name)2281ad6265SDimitry Andric bool CSKYTargetInfo::setCPU(const std::string &Name) {
2381ad6265SDimitry Andric   llvm::CSKY::ArchKind archKind = llvm::CSKY::parseCPUArch(Name);
2481ad6265SDimitry Andric   bool isValid = (archKind != llvm::CSKY::ArchKind::INVALID);
2581ad6265SDimitry Andric 
2681ad6265SDimitry Andric   if (isValid) {
2781ad6265SDimitry Andric     CPU = Name;
2881ad6265SDimitry Andric     Arch = archKind;
2981ad6265SDimitry Andric   }
3081ad6265SDimitry Andric 
3181ad6265SDimitry Andric   return isValid;
3281ad6265SDimitry Andric }
3381ad6265SDimitry Andric 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3481ad6265SDimitry Andric void CSKYTargetInfo::getTargetDefines(const LangOptions &Opts,
3581ad6265SDimitry Andric                                       MacroBuilder &Builder) const {
3681ad6265SDimitry Andric   Builder.defineMacro("__csky__", "2");
3781ad6265SDimitry Andric   Builder.defineMacro("__CSKY__", "2");
3881ad6265SDimitry Andric   Builder.defineMacro("__ckcore__", "2");
3981ad6265SDimitry Andric   Builder.defineMacro("__CKCORE__", "2");
4081ad6265SDimitry Andric 
4181ad6265SDimitry Andric   Builder.defineMacro("__CSKYABI__", ABI == "abiv2" ? "2" : "1");
4281ad6265SDimitry Andric   Builder.defineMacro("__cskyabi__", ABI == "abiv2" ? "2" : "1");
4381ad6265SDimitry Andric 
4481ad6265SDimitry Andric   StringRef ArchName = "ck810";
4581ad6265SDimitry Andric   StringRef CPUName = "ck810";
4681ad6265SDimitry Andric 
4781ad6265SDimitry Andric   if (Arch != llvm::CSKY::ArchKind::INVALID) {
4881ad6265SDimitry Andric     ArchName = llvm::CSKY::getArchName(Arch);
4981ad6265SDimitry Andric     CPUName = CPU;
5081ad6265SDimitry Andric   }
5181ad6265SDimitry Andric 
5281ad6265SDimitry Andric   Builder.defineMacro("__" + ArchName.upper() + "__");
5381ad6265SDimitry Andric   Builder.defineMacro("__" + ArchName.lower() + "__");
54*06c3fb27SDimitry Andric   if (ArchName != CPUName) {
5581ad6265SDimitry Andric     Builder.defineMacro("__" + CPUName.upper() + "__");
5681ad6265SDimitry Andric     Builder.defineMacro("__" + CPUName.lower() + "__");
57*06c3fb27SDimitry Andric   }
5881ad6265SDimitry Andric 
5981ad6265SDimitry Andric   // TODO: Add support for BE if BE was supported later
6081ad6265SDimitry Andric   StringRef endian = "__cskyLE__";
6181ad6265SDimitry Andric 
6281ad6265SDimitry Andric   Builder.defineMacro(endian);
6381ad6265SDimitry Andric   Builder.defineMacro(endian.upper());
6481ad6265SDimitry Andric   Builder.defineMacro(endian.lower());
6581ad6265SDimitry Andric 
6681ad6265SDimitry Andric   if (DSPV2) {
6781ad6265SDimitry Andric     StringRef dspv2 = "__CSKY_DSPV2__";
6881ad6265SDimitry Andric     Builder.defineMacro(dspv2);
6981ad6265SDimitry Andric     Builder.defineMacro(dspv2.lower());
7081ad6265SDimitry Andric   }
7181ad6265SDimitry Andric 
7281ad6265SDimitry Andric   if (VDSPV2) {
7381ad6265SDimitry Andric     StringRef vdspv2 = "__CSKY_VDSPV2__";
7481ad6265SDimitry Andric     Builder.defineMacro(vdspv2);
7581ad6265SDimitry Andric     Builder.defineMacro(vdspv2.lower());
7681ad6265SDimitry Andric 
7781ad6265SDimitry Andric     if (HardFloat) {
7881ad6265SDimitry Andric       StringRef vdspv2_f = "__CSKY_VDSPV2_F__";
7981ad6265SDimitry Andric       Builder.defineMacro(vdspv2_f);
8081ad6265SDimitry Andric       Builder.defineMacro(vdspv2_f.lower());
8181ad6265SDimitry Andric     }
8281ad6265SDimitry Andric   }
8381ad6265SDimitry Andric   if (VDSPV1) {
8481ad6265SDimitry Andric     StringRef vdspv1_64 = "__CSKY_VDSP64__";
8581ad6265SDimitry Andric     StringRef vdspv1_128 = "__CSKY_VDSP128__";
8681ad6265SDimitry Andric 
8781ad6265SDimitry Andric     Builder.defineMacro(vdspv1_64);
8881ad6265SDimitry Andric     Builder.defineMacro(vdspv1_64.lower());
8981ad6265SDimitry Andric     Builder.defineMacro(vdspv1_128);
9081ad6265SDimitry Andric     Builder.defineMacro(vdspv1_128.lower());
9181ad6265SDimitry Andric   }
9281ad6265SDimitry Andric   if (is3E3R1) {
9381ad6265SDimitry Andric     StringRef is3e3r1 = "__CSKY_3E3R1__";
9481ad6265SDimitry Andric     Builder.defineMacro(is3e3r1);
9581ad6265SDimitry Andric     Builder.defineMacro(is3e3r1.lower());
9681ad6265SDimitry Andric   }
9781ad6265SDimitry Andric }
9881ad6265SDimitry Andric 
hasFeature(StringRef Feature) const9981ad6265SDimitry Andric bool CSKYTargetInfo::hasFeature(StringRef Feature) const {
10081ad6265SDimitry Andric   return llvm::StringSwitch<bool>(Feature)
10181ad6265SDimitry Andric       .Case("hard-float", HardFloat)
10281ad6265SDimitry Andric       .Case("hard-float-abi", HardFloatABI)
10381ad6265SDimitry Andric       .Case("fpuv2_sf", FPUV2_SF)
10481ad6265SDimitry Andric       .Case("fpuv2_df", FPUV2_DF)
10581ad6265SDimitry Andric       .Case("fpuv3_sf", FPUV3_SF)
10681ad6265SDimitry Andric       .Case("fpuv3_df", FPUV3_DF)
10781ad6265SDimitry Andric       .Case("vdspv2", VDSPV2)
10881ad6265SDimitry Andric       .Case("dspv2", DSPV2)
10981ad6265SDimitry Andric       .Case("vdspv1", VDSPV1)
11081ad6265SDimitry Andric       .Case("3e3r1", is3E3R1)
11181ad6265SDimitry Andric       .Default(false);
11281ad6265SDimitry Andric }
11381ad6265SDimitry Andric 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)11481ad6265SDimitry Andric bool CSKYTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
11581ad6265SDimitry Andric                                           DiagnosticsEngine &Diags) {
11681ad6265SDimitry Andric   for (const auto &Feature : Features) {
11781ad6265SDimitry Andric     if (Feature == "+hard-float")
11881ad6265SDimitry Andric       HardFloat = true;
11981ad6265SDimitry Andric     if (Feature == "+hard-float-abi")
12081ad6265SDimitry Andric       HardFloatABI = true;
12181ad6265SDimitry Andric     if (Feature == "+fpuv2_sf")
12281ad6265SDimitry Andric       FPUV2_SF = true;
12381ad6265SDimitry Andric     if (Feature == "+fpuv2_df")
12481ad6265SDimitry Andric       FPUV2_DF = true;
12581ad6265SDimitry Andric     if (Feature == "+fpuv3_sf")
12681ad6265SDimitry Andric       FPUV3_SF = true;
12781ad6265SDimitry Andric     if (Feature == "+fpuv3_df")
12881ad6265SDimitry Andric       FPUV3_DF = true;
12981ad6265SDimitry Andric     if (Feature == "+vdspv2")
13081ad6265SDimitry Andric       VDSPV2 = true;
13181ad6265SDimitry Andric     if (Feature == "+dspv2")
13281ad6265SDimitry Andric       DSPV2 = true;
13381ad6265SDimitry Andric     if (Feature == "+vdspv1")
13481ad6265SDimitry Andric       VDSPV1 = true;
13581ad6265SDimitry Andric     if (Feature == "+3e3r1")
13681ad6265SDimitry Andric       is3E3R1 = true;
13781ad6265SDimitry Andric   }
13881ad6265SDimitry Andric 
13981ad6265SDimitry Andric   return true;
14081ad6265SDimitry Andric }
14181ad6265SDimitry Andric 
getTargetBuiltins() const14281ad6265SDimitry Andric ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const {
14381ad6265SDimitry Andric   return ArrayRef<Builtin::Info>();
14481ad6265SDimitry Andric }
14581ad6265SDimitry Andric 
getGCCRegNames() const14681ad6265SDimitry Andric ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const {
14781ad6265SDimitry Andric   static const char *const GCCRegNames[] = {
14881ad6265SDimitry Andric       // Integer registers
14981ad6265SDimitry Andric       "r0",
15081ad6265SDimitry Andric       "r1",
15181ad6265SDimitry Andric       "r2",
15281ad6265SDimitry Andric       "r3",
15381ad6265SDimitry Andric       "r4",
15481ad6265SDimitry Andric       "r5",
15581ad6265SDimitry Andric       "r6",
15681ad6265SDimitry Andric       "r7",
15781ad6265SDimitry Andric       "r8",
15881ad6265SDimitry Andric       "r9",
15981ad6265SDimitry Andric       "r10",
16081ad6265SDimitry Andric       "r11",
16181ad6265SDimitry Andric       "r12",
16281ad6265SDimitry Andric       "r13",
16381ad6265SDimitry Andric       "r14",
16481ad6265SDimitry Andric       "r15",
16581ad6265SDimitry Andric       "r16",
16681ad6265SDimitry Andric       "r17",
16781ad6265SDimitry Andric       "r18",
16881ad6265SDimitry Andric       "r19",
16981ad6265SDimitry Andric       "r20",
17081ad6265SDimitry Andric       "r21",
17181ad6265SDimitry Andric       "r22",
17281ad6265SDimitry Andric       "r23",
17381ad6265SDimitry Andric       "r24",
17481ad6265SDimitry Andric       "r25",
17581ad6265SDimitry Andric       "r26",
17681ad6265SDimitry Andric       "r27",
17781ad6265SDimitry Andric       "r28",
17881ad6265SDimitry Andric       "r29",
17981ad6265SDimitry Andric       "r30",
18081ad6265SDimitry Andric       "r31",
18181ad6265SDimitry Andric 
18281ad6265SDimitry Andric       // Floating point registers
18381ad6265SDimitry Andric       "fr0",
18481ad6265SDimitry Andric       "fr1",
18581ad6265SDimitry Andric       "fr2",
18681ad6265SDimitry Andric       "fr3",
18781ad6265SDimitry Andric       "fr4",
18881ad6265SDimitry Andric       "fr5",
18981ad6265SDimitry Andric       "fr6",
19081ad6265SDimitry Andric       "fr7",
19181ad6265SDimitry Andric       "fr8",
19281ad6265SDimitry Andric       "fr9",
19381ad6265SDimitry Andric       "fr10",
19481ad6265SDimitry Andric       "fr11",
19581ad6265SDimitry Andric       "fr12",
19681ad6265SDimitry Andric       "fr13",
19781ad6265SDimitry Andric       "fr14",
19881ad6265SDimitry Andric       "fr15",
19981ad6265SDimitry Andric       "fr16",
20081ad6265SDimitry Andric       "fr17",
20181ad6265SDimitry Andric       "fr18",
20281ad6265SDimitry Andric       "fr19",
20381ad6265SDimitry Andric       "fr20",
20481ad6265SDimitry Andric       "fr21",
20581ad6265SDimitry Andric       "fr22",
20681ad6265SDimitry Andric       "fr23",
20781ad6265SDimitry Andric       "fr24",
20881ad6265SDimitry Andric       "fr25",
20981ad6265SDimitry Andric       "fr26",
21081ad6265SDimitry Andric       "fr27",
21181ad6265SDimitry Andric       "fr28",
21281ad6265SDimitry Andric       "fr29",
21381ad6265SDimitry Andric       "fr30",
21481ad6265SDimitry Andric       "fr31",
21581ad6265SDimitry Andric 
21681ad6265SDimitry Andric   };
217bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegNames);
21881ad6265SDimitry Andric }
21981ad6265SDimitry Andric 
getGCCRegAliases() const22081ad6265SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const {
22181ad6265SDimitry Andric   static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
22281ad6265SDimitry Andric       {{"a0"}, "r0"},
22381ad6265SDimitry Andric       {{"a1"}, "r1"},
22481ad6265SDimitry Andric       {{"a2"}, "r2"},
22581ad6265SDimitry Andric       {{"a3"}, "r3"},
22681ad6265SDimitry Andric       {{"l0"}, "r4"},
22781ad6265SDimitry Andric       {{"l1"}, "r5"},
22881ad6265SDimitry Andric       {{"l2"}, "r6"},
22981ad6265SDimitry Andric       {{"l3"}, "r7"},
23081ad6265SDimitry Andric       {{"l4"}, "r8"},
23181ad6265SDimitry Andric       {{"l5"}, "r9"},
23281ad6265SDimitry Andric       {{"l6"}, "r10"},
23381ad6265SDimitry Andric       {{"l7"}, "r11"},
23481ad6265SDimitry Andric       {{"t0"}, "r12"},
23581ad6265SDimitry Andric       {{"t1"}, "r13"},
23681ad6265SDimitry Andric       {{"sp"}, "r14"},
23781ad6265SDimitry Andric       {{"lr"}, "r15"},
23881ad6265SDimitry Andric       {{"l8"}, "r16"},
23981ad6265SDimitry Andric       {{"l9"}, "r17"},
24081ad6265SDimitry Andric       {{"t2"}, "r18"},
24181ad6265SDimitry Andric       {{"t3"}, "r19"},
24281ad6265SDimitry Andric       {{"t4"}, "r20"},
24381ad6265SDimitry Andric       {{"t5"}, "r21"},
24481ad6265SDimitry Andric       {{"t6"}, "r22"},
24581ad6265SDimitry Andric       {{"t7", "fp"}, "r23"},
24681ad6265SDimitry Andric       {{"t8", "top"}, "r24"},
24781ad6265SDimitry Andric       {{"t9", "bsp"}, "r25"},
24881ad6265SDimitry Andric       {{"r26"}, "r26"},
24981ad6265SDimitry Andric       {{"r27"}, "r27"},
25081ad6265SDimitry Andric       {{"gb", "rgb", "rdb"}, "r28"},
25181ad6265SDimitry Andric       {{"tb", "rtb"}, "r29"},
25281ad6265SDimitry Andric       {{"svbr"}, "r30"},
25381ad6265SDimitry Andric       {{"tls"}, "r31"},
25481ad6265SDimitry Andric 
25581ad6265SDimitry Andric       {{"vr0"}, "fr0"},
25681ad6265SDimitry Andric       {{"vr1"}, "fr1"},
25781ad6265SDimitry Andric       {{"vr2"}, "fr2"},
25881ad6265SDimitry Andric       {{"vr3"}, "fr3"},
25981ad6265SDimitry Andric       {{"vr4"}, "fr4"},
26081ad6265SDimitry Andric       {{"vr5"}, "fr5"},
26181ad6265SDimitry Andric       {{"vr6"}, "fr6"},
26281ad6265SDimitry Andric       {{"vr7"}, "fr7"},
26381ad6265SDimitry Andric       {{"vr8"}, "fr8"},
26481ad6265SDimitry Andric       {{"vr9"}, "fr9"},
26581ad6265SDimitry Andric       {{"vr10"}, "fr10"},
26681ad6265SDimitry Andric       {{"vr11"}, "fr11"},
26781ad6265SDimitry Andric       {{"vr12"}, "fr12"},
26881ad6265SDimitry Andric       {{"vr13"}, "fr13"},
26981ad6265SDimitry Andric       {{"vr14"}, "fr14"},
27081ad6265SDimitry Andric       {{"vr15"}, "fr15"},
27181ad6265SDimitry Andric       {{"vr16"}, "fr16"},
27281ad6265SDimitry Andric       {{"vr17"}, "fr17"},
27381ad6265SDimitry Andric       {{"vr18"}, "fr18"},
27481ad6265SDimitry Andric       {{"vr19"}, "fr19"},
27581ad6265SDimitry Andric       {{"vr20"}, "fr20"},
27681ad6265SDimitry Andric       {{"vr21"}, "fr21"},
27781ad6265SDimitry Andric       {{"vr22"}, "fr22"},
27881ad6265SDimitry Andric       {{"vr23"}, "fr23"},
27981ad6265SDimitry Andric       {{"vr24"}, "fr24"},
28081ad6265SDimitry Andric       {{"vr25"}, "fr25"},
28181ad6265SDimitry Andric       {{"vr26"}, "fr26"},
28281ad6265SDimitry Andric       {{"vr27"}, "fr27"},
28381ad6265SDimitry Andric       {{"vr28"}, "fr28"},
28481ad6265SDimitry Andric       {{"vr29"}, "fr29"},
28581ad6265SDimitry Andric       {{"vr30"}, "fr30"},
28681ad6265SDimitry Andric       {{"vr31"}, "fr31"},
28781ad6265SDimitry Andric 
28881ad6265SDimitry Andric   };
289bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegAliases);
29081ad6265SDimitry Andric }
29181ad6265SDimitry Andric 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const29281ad6265SDimitry Andric bool CSKYTargetInfo::validateAsmConstraint(
29381ad6265SDimitry Andric     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
29481ad6265SDimitry Andric   switch (*Name) {
29581ad6265SDimitry Andric   default:
29681ad6265SDimitry Andric     return false;
29781ad6265SDimitry Andric   case 'a':
29881ad6265SDimitry Andric   case 'b':
29981ad6265SDimitry Andric   case 'c':
30081ad6265SDimitry Andric   case 'y':
30181ad6265SDimitry Andric   case 'l':
30281ad6265SDimitry Andric   case 'h':
30381ad6265SDimitry Andric   case 'w':
30481ad6265SDimitry Andric   case 'v': // A floating-point and vector register.
30581ad6265SDimitry Andric   case 'z':
30681ad6265SDimitry Andric     Info.setAllowsRegister();
30781ad6265SDimitry Andric     return true;
30881ad6265SDimitry Andric   }
30981ad6265SDimitry Andric }
31081ad6265SDimitry Andric 
getMinGlobalAlign(uint64_t Size) const31181ad6265SDimitry Andric unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const {
31281ad6265SDimitry Andric   if (Size >= 32)
31381ad6265SDimitry Andric     return 32;
31481ad6265SDimitry Andric   return 0;
31581ad6265SDimitry Andric }
316