1 //===--- Hexagon.cpp - Implement Hexagon target feature support -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements Hexagon TargetInfo objects.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "Hexagon.h"
15 #include "Targets.h"
16 #include "clang/Basic/MacroBuilder.h"
17 #include "clang/Basic/TargetBuiltins.h"
18 #include "llvm/ADT/StringSwitch.h"
19 
20 using namespace clang;
21 using namespace clang::targets;
22 
23 void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
24                                          MacroBuilder &Builder) const {
25   Builder.defineMacro("__qdsp6__", "1");
26   Builder.defineMacro("__hexagon__", "1");
27 
28   if (CPU == "hexagonv4") {
29     Builder.defineMacro("__HEXAGON_V4__");
30     Builder.defineMacro("__HEXAGON_ARCH__", "4");
31     if (Opts.HexagonQdsp6Compat) {
32       Builder.defineMacro("__QDSP6_V4__");
33       Builder.defineMacro("__QDSP6_ARCH__", "4");
34     }
35   } else if (CPU == "hexagonv5") {
36     Builder.defineMacro("__HEXAGON_V5__");
37     Builder.defineMacro("__HEXAGON_ARCH__", "5");
38     if (Opts.HexagonQdsp6Compat) {
39       Builder.defineMacro("__QDSP6_V5__");
40       Builder.defineMacro("__QDSP6_ARCH__", "5");
41     }
42   } else if (CPU == "hexagonv55") {
43     Builder.defineMacro("__HEXAGON_V55__");
44     Builder.defineMacro("__HEXAGON_ARCH__", "55");
45     Builder.defineMacro("__QDSP6_V55__");
46     Builder.defineMacro("__QDSP6_ARCH__", "55");
47   } else if (CPU == "hexagonv60") {
48     Builder.defineMacro("__HEXAGON_V60__");
49     Builder.defineMacro("__HEXAGON_ARCH__", "60");
50     Builder.defineMacro("__QDSP6_V60__");
51     Builder.defineMacro("__QDSP6_ARCH__", "60");
52   } else if (CPU == "hexagonv62") {
53     Builder.defineMacro("__HEXAGON_V62__");
54     Builder.defineMacro("__HEXAGON_ARCH__", "62");
55   }
56 
57   if (hasFeature("hvx-length64b")) {
58     Builder.defineMacro("__HVX__");
59     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
60     Builder.defineMacro("__HVX_LENGTH__", "64");
61   }
62 
63   if (hasFeature("hvx-length128b")) {
64     Builder.defineMacro("__HVX__");
65     Builder.defineMacro("__HVX_ARCH__", HVXVersion);
66     Builder.defineMacro("__HVX_LENGTH__", "128");
67     // FIXME: This macro is deprecated.
68     Builder.defineMacro("__HVXDBL__");
69   }
70 }
71 
72 bool HexagonTargetInfo::initFeatureMap(
73     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
74     const std::vector<std::string> &FeaturesVec) const {
75   Features["hvx-double"] = false;
76   Features["long-calls"] = false;
77 
78   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
79 }
80 
81 bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
82                                              DiagnosticsEngine &Diags) {
83   for (auto &F : Features) {
84     if (F == "+hvx-length64b")
85       HasHVX = HasHVX64B = true;
86     else if (F == "+hvx-length128b")
87       HasHVX = HasHVX128B = true;
88     else if (F.find("+hvxv") != std::string::npos) {
89       HasHVX = true;
90       HVXVersion = F.substr(std::string("+hvxv").length());
91     } else if (F == "-hvx")
92       HasHVX = HasHVX64B = HasHVX128B = false;
93     else if (F == "+long-calls")
94       UseLongCalls = true;
95     else if (F == "-long-calls")
96       UseLongCalls = false;
97   }
98   return true;
99 }
100 
101 const char *const HexagonTargetInfo::GCCRegNames[] = {
102     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",
103     "r9",  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
104     "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
105     "r27", "r28", "r29", "r30", "r31", "p0",  "p1",  "p2",  "p3",
106     "sa0", "lc0", "sa1", "lc1", "m0",  "m1",  "usr", "ugp"
107 };
108 
109 ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
110   return llvm::makeArrayRef(GCCRegNames);
111 }
112 
113 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
114     {{"sp"}, "r29"},
115     {{"fp"}, "r30"},
116     {{"lr"}, "r31"},
117 };
118 
119 ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
120   return llvm::makeArrayRef(GCCRegAliases);
121 }
122 
123 const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
124 #define BUILTIN(ID, TYPE, ATTRS)                                               \
125   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
126 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
127   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
128 #include "clang/Basic/BuiltinsHexagon.def"
129 };
130 
131 bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
132   return llvm::StringSwitch<bool>(Feature)
133       .Case("hexagon", true)
134       .Case("hvx", HasHVX)
135       .Case("hvx-length64b", HasHVX64B)
136       .Case("hvx-length128b", HasHVX128B)
137       .Case("long-calls", UseLongCalls)
138       .Default(false);
139 }
140 
141 const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
142   return llvm::StringSwitch<const char *>(Name)
143       .Case("hexagonv4", "4")
144       .Case("hexagonv5", "5")
145       .Case("hexagonv55", "55")
146       .Case("hexagonv60", "60")
147       .Case("hexagonv62", "62")
148       .Default(nullptr);
149 }
150 
151 ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
152   return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
153                                              Builtin::FirstTSBuiltin);
154 }
155