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")) {
58     Builder.defineMacro("__HVX__");
59     if (hasFeature("hvx-double"))
60       Builder.defineMacro("__HVXDBL__");
61   }
62 }
63 
64 bool HexagonTargetInfo::initFeatureMap(
65     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
66     const std::vector<std::string> &FeaturesVec) const {
67   // Default for v60: -hvx, -hvx-double.
68   Features["hvx"] = false;
69   Features["hvx-double"] = false;
70   Features["long-calls"] = false;
71 
72   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
73 }
74 
75 bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
76                                              DiagnosticsEngine &Diags) {
77   for (auto &F : Features) {
78     if (F == "+hvx")
79       HasHVX = true;
80     else if (F == "-hvx")
81       HasHVX = HasHVXDouble = false;
82     else if (F == "+hvx-double")
83       HasHVX = HasHVXDouble = true;
84     else if (F == "-hvx-double")
85       HasHVXDouble = false;
86 
87     if (F == "+long-calls")
88       UseLongCalls = true;
89     else if (F == "-long-calls")
90       UseLongCalls = false;
91   }
92   return true;
93 }
94 
95 void HexagonTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
96                                           StringRef Name, bool Enabled) const {
97   if (Enabled) {
98     if (Name == "hvx-double")
99       Features["hvx"] = true;
100   } else {
101     if (Name == "hvx")
102       Features["hvx-double"] = false;
103   }
104   Features[Name] = Enabled;
105 }
106 
107 const char *const HexagonTargetInfo::GCCRegNames[] = {
108     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",
109     "r9",  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
110     "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
111     "r27", "r28", "r29", "r30", "r31", "p0",  "p1",  "p2",  "p3",
112     "sa0", "lc0", "sa1", "lc1", "m0",  "m1",  "usr", "ugp"
113 };
114 
115 ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
116   return llvm::makeArrayRef(GCCRegNames);
117 }
118 
119 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
120     {{"sp"}, "r29"},
121     {{"fp"}, "r30"},
122     {{"lr"}, "r31"},
123 };
124 
125 ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
126   return llvm::makeArrayRef(GCCRegAliases);
127 }
128 
129 const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
130 #define BUILTIN(ID, TYPE, ATTRS)                                               \
131   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
132 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
133   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
134 #include "clang/Basic/BuiltinsHexagon.def"
135 };
136 
137 bool HexagonTargetInfo::hasFeature(StringRef Feature) const {
138   return llvm::StringSwitch<bool>(Feature)
139       .Case("hexagon", true)
140       .Case("hvx", HasHVX)
141       .Case("hvx-double", HasHVXDouble)
142       .Case("long-calls", UseLongCalls)
143       .Default(false);
144 }
145 
146 const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
147   return llvm::StringSwitch<const char *>(Name)
148       .Case("hexagonv4", "4")
149       .Case("hexagonv5", "5")
150       .Case("hexagonv55", "55")
151       .Case("hexagonv60", "60")
152       .Case("hexagonv62", "62")
153       .Default(nullptr);
154 }
155 
156 ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
157   return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
158                                              Builtin::FirstTSBuiltin);
159 }
160