]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Basic/Targets/Sparc.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Basic / Targets / Sparc.h
1 //===--- Sparc.h - declare sparc target feature support ---------*- C++ -*-===//
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 declares Sparc TargetInfo objects.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H
15 #define LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/Basic/TargetOptions.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/Compiler.h"
20 namespace clang {
21 namespace targets {
22 // Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).
23 class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo {
24   static const TargetInfo::GCCRegAlias GCCRegAliases[];
25   static const char *const GCCRegNames[];
26   bool SoftFloat;
27
28 public:
29   SparcTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
30       : TargetInfo(Triple), SoftFloat(false) {}
31
32   int getEHDataRegisterNumber(unsigned RegNo) const override {
33     if (RegNo == 0)
34       return 24;
35     if (RegNo == 1)
36       return 25;
37     return -1;
38   }
39
40   bool handleTargetFeatures(std::vector<std::string> &Features,
41                             DiagnosticsEngine &Diags) override {
42     // Check if software floating point is enabled
43     auto Feature = std::find(Features.begin(), Features.end(), "+soft-float");
44     if (Feature != Features.end()) {
45       SoftFloat = true;
46     }
47     return true;
48   }
49   void getTargetDefines(const LangOptions &Opts,
50                         MacroBuilder &Builder) const override;
51
52   bool hasFeature(StringRef Feature) const override;
53
54   bool hasSjLjLowering() const override { return true; }
55
56   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
57     // FIXME: Implement!
58     return None;
59   }
60   BuiltinVaListKind getBuiltinVaListKind() const override {
61     return TargetInfo::VoidPtrBuiltinVaList;
62   }
63   ArrayRef<const char *> getGCCRegNames() const override;
64   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
65   bool validateAsmConstraint(const char *&Name,
66                              TargetInfo::ConstraintInfo &info) const override {
67     // FIXME: Implement!
68     switch (*Name) {
69     case 'I': // Signed 13-bit constant
70     case 'J': // Zero
71     case 'K': // 32-bit constant with the low 12 bits clear
72     case 'L': // A constant in the range supported by movcc (11-bit signed imm)
73     case 'M': // A constant in the range supported by movrcc (19-bit signed imm)
74     case 'N': // Same as 'K' but zext (required for SIMode)
75     case 'O': // The constant 4096
76       return true;
77
78     case 'f':
79     case 'e':
80       info.setAllowsRegister();
81       return true;
82     }
83     return false;
84   }
85   const char *getClobbers() const override {
86     // FIXME: Implement!
87     return "";
88   }
89
90   // No Sparc V7 for now, the backend doesn't support it anyway.
91   enum CPUKind {
92     CK_GENERIC,
93     CK_V8,
94     CK_SUPERSPARC,
95     CK_SPARCLITE,
96     CK_F934,
97     CK_HYPERSPARC,
98     CK_SPARCLITE86X,
99     CK_SPARCLET,
100     CK_TSC701,
101     CK_V9,
102     CK_ULTRASPARC,
103     CK_ULTRASPARC3,
104     CK_NIAGARA,
105     CK_NIAGARA2,
106     CK_NIAGARA3,
107     CK_NIAGARA4,
108     CK_MYRIAD2100,
109     CK_MYRIAD2150,
110     CK_MYRIAD2155,
111     CK_MYRIAD2450,
112     CK_MYRIAD2455,
113     CK_MYRIAD2x5x,
114     CK_MYRIAD2080,
115     CK_MYRIAD2085,
116     CK_MYRIAD2480,
117     CK_MYRIAD2485,
118     CK_MYRIAD2x8x,
119     CK_LEON2,
120     CK_LEON2_AT697E,
121     CK_LEON2_AT697F,
122     CK_LEON3,
123     CK_LEON3_UT699,
124     CK_LEON3_GR712RC,
125     CK_LEON4,
126     CK_LEON4_GR740
127   } CPU = CK_GENERIC;
128
129   enum CPUGeneration {
130     CG_V8,
131     CG_V9,
132   };
133
134   CPUGeneration getCPUGeneration(CPUKind Kind) const;
135
136   CPUKind getCPUKind(StringRef Name) const;
137
138   bool isValidCPUName(StringRef Name) const override {
139     return getCPUKind(Name) != CK_GENERIC;
140   }
141
142   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
143
144   bool setCPU(const std::string &Name) override {
145     CPU = getCPUKind(Name);
146     return CPU != CK_GENERIC;
147   }
148 };
149
150 // SPARC v8 is the 32-bit mode selected by Triple::sparc.
151 class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
152 public:
153   SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
154       : SparcTargetInfo(Triple, Opts) {
155     resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64");
156     // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int.
157     switch (getTriple().getOS()) {
158     default:
159       SizeType = UnsignedInt;
160       IntPtrType = SignedInt;
161       PtrDiffType = SignedInt;
162       break;
163     case llvm::Triple::NetBSD:
164     case llvm::Triple::OpenBSD:
165       SizeType = UnsignedLong;
166       IntPtrType = SignedLong;
167       PtrDiffType = SignedLong;
168       break;
169     }
170     // Up to 32 bits are lock-free atomic, but we're willing to do atomic ops
171     // on up to 64 bits.
172     MaxAtomicPromoteWidth = 64;
173     MaxAtomicInlineWidth = 32;
174   }
175
176   void getTargetDefines(const LangOptions &Opts,
177                         MacroBuilder &Builder) const override;
178
179   bool hasSjLjLowering() const override { return true; }
180 };
181
182 // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
183 class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo {
184 public:
185   SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
186       : SparcV8TargetInfo(Triple, Opts) {
187     resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
188   }
189 };
190
191 // SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
192 class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo {
193 public:
194   SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
195       : SparcTargetInfo(Triple, Opts) {
196     // FIXME: Support Sparc quad-precision long double?
197     resetDataLayout("E-m:e-i64:64-n32:64-S128");
198     // This is an LP64 platform.
199     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
200
201     // OpenBSD uses long long for int64_t and intmax_t.
202     if (getTriple().getOS() == llvm::Triple::OpenBSD)
203       IntMaxType = SignedLongLong;
204     else
205       IntMaxType = SignedLong;
206     Int64Type = IntMaxType;
207
208     // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
209     // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
210     LongDoubleWidth = 128;
211     LongDoubleAlign = 128;
212     LongDoubleFormat = &llvm::APFloat::IEEEquad();
213     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
214   }
215
216   void getTargetDefines(const LangOptions &Opts,
217                         MacroBuilder &Builder) const override;
218
219   bool isValidCPUName(StringRef Name) const override {
220     return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9;
221   }
222
223   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
224
225   bool setCPU(const std::string &Name) override {
226     if (!SparcTargetInfo::setCPU(Name))
227       return false;
228     return getCPUGeneration(CPU) == CG_V9;
229   }
230 };
231 } // namespace targets
232 } // namespace clang
233 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H