blob: bb89cc7d2eb5769f159af86641950e717de84e40 [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- ARM.cpp - Implement ARM target feature support -------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Erich Keaneebba5922017-07-21 22:37:03 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements ARM TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#include "ARM.h"
14#include "clang/Basic/Builtins.h"
15#include "clang/Basic/Diagnostic.h"
16#include "clang/Basic/TargetBuiltins.h"
17#include "llvm/ADT/StringExtras.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/StringSwitch.h"
20
21using namespace clang;
22using namespace clang::targets;
23
Tim Northoverad4c5db2017-07-24 17:06:23 +000024void ARMTargetInfo::setABIAAPCS() {
25 IsAAPCS = true;
26
27 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
28 const llvm::Triple &T = getTriple();
29
Michal Gorny5a409d02018-12-20 13:09:30 +000030 bool IsNetBSD = T.isOSNetBSD();
31 bool IsOpenBSD = T.isOSOpenBSD();
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000032 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +000033 WCharType = UnsignedInt;
Tim Northoverad4c5db2017-07-24 17:06:23 +000034
35 UseBitFieldTypeAlignment = true;
36
37 ZeroLengthBitfieldBoundary = 0;
38
39 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
40 // so set preferred for small types to 32.
41 if (T.isOSBinFormatMachO()) {
42 resetDataLayout(BigEndian
43 ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
44 : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
45 } else if (T.isOSWindows()) {
46 assert(!BigEndian && "Windows on ARM does not support big endian");
47 resetDataLayout("e"
48 "-m:w"
49 "-p:32:32"
50 "-i64:64"
51 "-v128:64:128"
52 "-a:0:32"
53 "-n32"
54 "-S64");
55 } else if (T.isOSNaCl()) {
56 assert(!BigEndian && "NaCl on ARM does not support big endian");
57 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
58 } else {
59 resetDataLayout(BigEndian
60 ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
61 : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
62 }
63
64 // FIXME: Enumerated types are variable width in straight AAPCS.
65}
66
67void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
68 const llvm::Triple &T = getTriple();
69
70 IsAAPCS = false;
71
72 if (IsAAPCS16)
73 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
74 else
75 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
76
Tim Northoverad4c5db2017-07-24 17:06:23 +000077 WCharType = SignedInt;
78
79 // Do not respect the alignment of bit-field types when laying out
80 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
81 UseBitFieldTypeAlignment = false;
82
83 /// gcc forces the alignment to 4 bytes, regardless of the type of the
84 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
85 /// gcc.
86 ZeroLengthBitfieldBoundary = 32;
87
88 if (T.isOSBinFormatMachO() && IsAAPCS16) {
89 assert(!BigEndian && "AAPCS16 does not support big-endian");
90 resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
91 } else if (T.isOSBinFormatMachO())
92 resetDataLayout(
93 BigEndian
94 ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
95 : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
96 else
97 resetDataLayout(
98 BigEndian
99 ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
100 : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
101
102 // FIXME: Override "preferred align" for double and long long.
103}
104
105void ARMTargetInfo::setArchInfo() {
106 StringRef ArchName = getTriple().getArchName();
107
108 ArchISA = llvm::ARM::parseArchISA(ArchName);
109 CPU = llvm::ARM::getDefaultCPU(ArchName);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000110 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
111 if (AK != llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000112 ArchKind = AK;
113 setArchInfo(ArchKind);
114}
115
Florian Hahnef5bbd62017-07-27 16:28:39 +0000116void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000117 StringRef SubArch;
118
119 // cache TargetParser info
120 ArchKind = Kind;
121 SubArch = llvm::ARM::getSubArch(ArchKind);
122 ArchProfile = llvm::ARM::parseArchProfile(SubArch);
123 ArchVersion = llvm::ARM::parseArchVersion(SubArch);
124
125 // cache CPU related strings
126 CPUAttr = getCPUAttr();
127 CPUProfile = getCPUProfile();
128}
129
130void ARMTargetInfo::setAtomic() {
131 // when triple does not specify a sub arch,
132 // then we are not using inline atomics
133 bool ShouldUseInlineAtomic =
Florian Hahnef5bbd62017-07-27 16:28:39 +0000134 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
135 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000136 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
Florian Hahnef5bbd62017-07-27 16:28:39 +0000137 if (ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000138 MaxAtomicPromoteWidth = 32;
139 if (ShouldUseInlineAtomic)
140 MaxAtomicInlineWidth = 32;
141 } else {
142 MaxAtomicPromoteWidth = 64;
143 if (ShouldUseInlineAtomic)
144 MaxAtomicInlineWidth = 64;
145 }
146}
147
Florian Hahnef5bbd62017-07-27 16:28:39 +0000148bool ARMTargetInfo::isThumb() const {
149 return ArchISA == llvm::ARM::ISAKind::THUMB;
150}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000151
152bool ARMTargetInfo::supportsThumb() const {
153 return CPUAttr.count('T') || ArchVersion >= 6;
154}
155
156bool ARMTargetInfo::supportsThumb2() const {
157 return CPUAttr.equals("6T2") ||
158 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
159}
160
161StringRef ARMTargetInfo::getCPUAttr() const {
162 // For most sub-arches, the build attribute CPU name is enough.
163 // For Cortex variants, it's slightly different.
164 switch (ArchKind) {
165 default:
166 return llvm::ARM::getCPUAttr(ArchKind);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000167 case llvm::ARM::ArchKind::ARMV6M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000168 return "6M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000169 case llvm::ARM::ArchKind::ARMV7S:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000170 return "7S";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000171 case llvm::ARM::ArchKind::ARMV7A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000172 return "7A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000173 case llvm::ARM::ArchKind::ARMV7R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000174 return "7R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000175 case llvm::ARM::ArchKind::ARMV7M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000176 return "7M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000177 case llvm::ARM::ArchKind::ARMV7EM:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000178 return "7EM";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000179 case llvm::ARM::ArchKind::ARMV7VE:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000180 return "7VE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000181 case llvm::ARM::ArchKind::ARMV8A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000182 return "8A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000183 case llvm::ARM::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000184 return "8_1A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000185 case llvm::ARM::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000186 return "8_2A";
Sjoerd Meijere6e4f312018-08-01 12:41:10 +0000187 case llvm::ARM::ArchKind::ARMV8_3A:
188 return "8_3A";
189 case llvm::ARM::ArchKind::ARMV8_4A:
190 return "8_4A";
Oliver Stannarda30b48d2018-09-26 14:20:29 +0000191 case llvm::ARM::ArchKind::ARMV8_5A:
192 return "8_5A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000193 case llvm::ARM::ArchKind::ARMV8MBaseline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000194 return "8M_BASE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000195 case llvm::ARM::ArchKind::ARMV8MMainline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000196 return "8M_MAIN";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000197 case llvm::ARM::ArchKind::ARMV8R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000198 return "8R";
199 }
200}
201
202StringRef ARMTargetInfo::getCPUProfile() const {
203 switch (ArchProfile) {
Florian Hahnef5bbd62017-07-27 16:28:39 +0000204 case llvm::ARM::ProfileKind::A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000205 return "A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000206 case llvm::ARM::ProfileKind::R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000207 return "R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000208 case llvm::ARM::ProfileKind::M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000209 return "M";
210 default:
211 return "";
212 }
213}
214
215ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
216 const TargetOptions &Opts)
217 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
218 HW_FP(0) {
Michal Gorny5a409d02018-12-20 13:09:30 +0000219 bool IsOpenBSD = Triple.isOSOpenBSD();
220 bool IsNetBSD = Triple.isOSNetBSD();
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000221
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000222 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
223 // environment where size_t is `unsigned long` rather than `unsigned int`
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000224
225 PtrDiffType = IntPtrType =
226 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
227 IsNetBSD)
228 ? SignedLong
229 : SignedInt;
230
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000231 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
232 IsNetBSD)
233 ? UnsignedLong
234 : UnsignedInt;
235
236 // ptrdiff_t is inconsistent on Darwin
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000237 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
238 !Triple.isWatchABI())
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000239 PtrDiffType = SignedInt;
240
Tim Northoverad4c5db2017-07-24 17:06:23 +0000241 // Cache arch related info.
242 setArchInfo();
243
244 // {} in inline assembly are neon specifiers, not assembly variant
245 // specifiers.
246 NoAsmVariants = true;
247
248 // FIXME: This duplicates code from the driver that sets the -target-abi
249 // option - this code is used if -target-abi isn't passed and should
250 // be unified in some way.
251 if (Triple.isOSBinFormatMachO()) {
252 // The backend is hardwired to assume AAPCS for M-class processors, ensure
253 // the frontend matches that.
254 if (Triple.getEnvironment() == llvm::Triple::EABI ||
255 Triple.getOS() == llvm::Triple::UnknownOS ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000256 ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000257 setABI("aapcs");
258 } else if (Triple.isWatchABI()) {
259 setABI("aapcs16");
260 } else {
261 setABI("apcs-gnu");
262 }
263 } else if (Triple.isOSWindows()) {
264 // FIXME: this is invalid for WindowsCE
265 setABI("aapcs");
266 } else {
267 // Select the default based on the platform.
268 switch (Triple.getEnvironment()) {
269 case llvm::Triple::Android:
270 case llvm::Triple::GNUEABI:
271 case llvm::Triple::GNUEABIHF:
272 case llvm::Triple::MuslEABI:
273 case llvm::Triple::MuslEABIHF:
274 setABI("aapcs-linux");
275 break;
276 case llvm::Triple::EABIHF:
277 case llvm::Triple::EABI:
278 setABI("aapcs");
279 break;
280 case llvm::Triple::GNU:
281 setABI("apcs-gnu");
282 break;
283 default:
Michal Gorny5a409d02018-12-20 13:09:30 +0000284 if (IsNetBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000285 setABI("apcs-gnu");
Michal Gorny5a409d02018-12-20 13:09:30 +0000286 else if (IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000287 setABI("aapcs-linux");
288 else
289 setABI("aapcs");
290 break;
291 }
292 }
293
294 // ARM targets default to using the ARM C++ ABI.
295 TheCXXABI.set(TargetCXXABI::GenericARM);
296
297 // ARM has atomics up to 8 bytes
298 setAtomic();
299
300 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
301 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
302 MaxVectorAlign = 64;
303
304 // Do force alignment of members that follow zero length bitfields. If
305 // the alignment of the zero-length bitfield is greater than the member
306 // that follows it, `bar', `bar' will be aligned as the type of the
307 // zero length bitfield.
308 UseZeroLengthBitfieldAlignment = true;
309
310 if (Triple.getOS() == llvm::Triple::Linux ||
311 Triple.getOS() == llvm::Triple::UnknownOS)
312 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
313 ? "\01__gnu_mcount_nc"
314 : "\01mcount";
315}
316
317StringRef ARMTargetInfo::getABI() const { return ABI; }
318
319bool ARMTargetInfo::setABI(const std::string &Name) {
320 ABI = Name;
321
322 // The defaults (above) are for AAPCS, check if we need to change them.
323 //
324 // FIXME: We need support for -meabi... we could just mangle it into the
325 // name.
326 if (Name == "apcs-gnu" || Name == "aapcs16") {
327 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000328 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000329 }
330 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
331 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000332 return true;
333 }
334 return false;
335}
336
Tim Northoverad4c5db2017-07-24 17:06:23 +0000337// FIXME: This should be based on Arch attributes, not CPU names.
338bool ARMTargetInfo::initFeatureMap(
339 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
340 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000341
Eli Friedman642a5ee2018-04-16 23:52:58 +0000342 std::string ArchFeature;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000343 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000344 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000345
Eli Friedman642a5ee2018-04-16 23:52:58 +0000346 // Map the base architecture to an appropriate target feature, so we don't
347 // rely on the target triple.
348 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
349 if (CPUArch == llvm::ARM::ArchKind::INVALID)
350 CPUArch = Arch;
351 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
352 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
353 TargetFeatures.push_back(ArchFeature);
354 }
355
Tim Northoverad4c5db2017-07-24 17:06:23 +0000356 // get default FPU features
357 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
358 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000359
Tim Northoverad4c5db2017-07-24 17:06:23 +0000360 // get default Extension features
361 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
362 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000363
Tim Northoverad4c5db2017-07-24 17:06:23 +0000364 for (auto Feature : TargetFeatures)
365 if (Feature[0] == '+')
366 Features[Feature.drop_front(1)] = true;
367
368 // Enable or disable thumb-mode explicitly per function to enable mixed
369 // ARM and Thumb code generation.
370 if (isThumb())
371 Features["thumb-mode"] = true;
372 else
373 Features["thumb-mode"] = false;
374
375 // Convert user-provided arm and thumb GNU target attributes to
376 // [-|+]thumb-mode target features respectively.
377 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
378 for (auto &Feature : UpdatedFeaturesVec) {
379 if (Feature.compare("+arm") == 0)
380 Feature = "-thumb-mode";
381 else if (Feature.compare("+thumb") == 0)
382 Feature = "+thumb-mode";
383 }
384
385 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000386}
387
Erich Keaneebba5922017-07-21 22:37:03 +0000388
Tim Northoverad4c5db2017-07-24 17:06:23 +0000389bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
390 DiagnosticsEngine &Diags) {
391 FPU = 0;
392 CRC = 0;
393 Crypto = 0;
394 DSP = 0;
395 Unaligned = 1;
396 SoftFloat = SoftFloatABI = false;
397 HWDiv = 0;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000398 DotProd = 0;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000399
400 // This does not diagnose illegal cases like having both
401 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
402 uint32_t HW_FP_remove = 0;
403 for (const auto &Feature : Features) {
404 if (Feature == "+soft-float") {
405 SoftFloat = true;
406 } else if (Feature == "+soft-float-abi") {
407 SoftFloatABI = true;
408 } else if (Feature == "+vfp2") {
409 FPU |= VFP2FPU;
410 HW_FP |= HW_FP_SP | HW_FP_DP;
411 } else if (Feature == "+vfp3") {
412 FPU |= VFP3FPU;
413 HW_FP |= HW_FP_SP | HW_FP_DP;
414 } else if (Feature == "+vfp4") {
415 FPU |= VFP4FPU;
416 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
417 } else if (Feature == "+fp-armv8") {
418 FPU |= FPARMV8;
419 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
420 } else if (Feature == "+neon") {
421 FPU |= NeonFPU;
422 HW_FP |= HW_FP_SP | HW_FP_DP;
423 } else if (Feature == "+hwdiv") {
424 HWDiv |= HWDivThumb;
425 } else if (Feature == "+hwdiv-arm") {
426 HWDiv |= HWDivARM;
427 } else if (Feature == "+crc") {
428 CRC = 1;
429 } else if (Feature == "+crypto") {
430 Crypto = 1;
431 } else if (Feature == "+dsp") {
432 DSP = 1;
433 } else if (Feature == "+fp-only-sp") {
434 HW_FP_remove |= HW_FP_DP;
435 } else if (Feature == "+strict-align") {
436 Unaligned = 0;
437 } else if (Feature == "+fp16") {
438 HW_FP |= HW_FP_HP;
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000439 } else if (Feature == "+fullfp16") {
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000440 HasLegalHalfType = true;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000441 } else if (Feature == "+dotprod") {
442 DotProd = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000443 }
444 }
445 HW_FP &= ~HW_FP_remove;
446
447 switch (ArchVersion) {
448 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000449 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000450 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000451 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000452 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
453 else
454 LDREX = LDREX_W;
455 break;
456 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000457 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000458 LDREX = LDREX_W | LDREX_H | LDREX_B;
459 else
460 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
461 break;
462 case 8:
463 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
464 }
465
466 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
467 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
468 return false;
469 }
470
471 if (FPMath == FP_Neon)
472 Features.push_back("+neonfp");
473 else if (FPMath == FP_VFP)
474 Features.push_back("-neonfp");
475
476 // Remove front-end specific options which the backend handles differently.
477 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
478 if (Feature != Features.end())
479 Features.erase(Feature);
480
481 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000482}
483
Erich Keaneebba5922017-07-21 22:37:03 +0000484bool ARMTargetInfo::hasFeature(StringRef Feature) const {
485 return llvm::StringSwitch<bool>(Feature)
486 .Case("arm", true)
487 .Case("aarch32", true)
488 .Case("softfloat", SoftFloat)
489 .Case("thumb", isThumb())
490 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
491 .Case("vfp", FPU && !SoftFloat)
492 .Case("hwdiv", HWDiv & HWDivThumb)
493 .Case("hwdiv-arm", HWDiv & HWDivARM)
494 .Default(false);
495}
496
Tim Northoverad4c5db2017-07-24 17:06:23 +0000497bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
498 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000499 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000500}
501
Erich Keane3ec17432018-02-08 23:14:15 +0000502void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
503 llvm::ARM::fillValidCPUArchList(Values);
504}
505
Tim Northoverad4c5db2017-07-24 17:06:23 +0000506bool ARMTargetInfo::setCPU(const std::string &Name) {
507 if (Name != "generic")
508 setArchInfo(llvm::ARM::parseCPUArch(Name));
509
Florian Hahnef5bbd62017-07-27 16:28:39 +0000510 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000511 return false;
512 setAtomic();
513 CPU = Name;
514 return true;
515}
516
517bool ARMTargetInfo::setFPMath(StringRef Name) {
518 if (Name == "neon") {
519 FPMath = FP_Neon;
520 return true;
521 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
522 Name == "vfp4") {
523 FPMath = FP_VFP;
524 return true;
525 }
526 return false;
527}
528
529void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
530 MacroBuilder &Builder) const {
531 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
532}
533
534void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
535 MacroBuilder &Builder) const {
536 // Also include the ARMv8.1-A defines
537 getTargetDefinesARMV81A(Opts, Builder);
538}
539
Erich Keaneebba5922017-07-21 22:37:03 +0000540void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
541 MacroBuilder &Builder) const {
542 // Target identification.
543 Builder.defineMacro("__arm");
544 Builder.defineMacro("__arm__");
545 // For bare-metal none-eabi.
546 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
547 (getTriple().getEnvironment() == llvm::Triple::EABI ||
548 getTriple().getEnvironment() == llvm::Triple::EABIHF))
549 Builder.defineMacro("__ELF__");
550
551 // Target properties.
552 Builder.defineMacro("__REGISTER_PREFIX__", "");
553
554 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
555 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
556 if (getTriple().isWatchABI())
557 Builder.defineMacro("__ARM_ARCH_7K__", "2");
558
559 if (!CPUAttr.empty())
560 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
561
562 // ACLE 6.4.1 ARM/Thumb instruction set architecture
563 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
564 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
565
566 if (ArchVersion >= 8) {
567 // ACLE 6.5.7 Crypto Extension
568 if (Crypto)
569 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
570 // ACLE 6.5.8 CRC32 Extension
571 if (CRC)
572 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
573 // ACLE 6.5.10 Numeric Maximum and Minimum
574 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
575 // ACLE 6.5.9 Directed Rounding
576 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
577 }
578
579 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
580 // is not defined for the M-profile.
581 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000582 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000583 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
584
585 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
586 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
587 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
588 // v7 and v8 architectures excluding v8-M Baseline.
589 if (supportsThumb2())
590 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
591 else if (supportsThumb())
592 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
593
594 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
595 // instruction set such as ARM or Thumb.
596 Builder.defineMacro("__ARM_32BIT_STATE", "1");
597
598 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
599
600 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
601 if (!CPUProfile.empty())
602 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
603
604 // ACLE 6.4.3 Unaligned access supported in hardware
605 if (Unaligned)
606 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
607
608 // ACLE 6.4.4 LDREX/STREX
609 if (LDREX)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000610 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
Erich Keaneebba5922017-07-21 22:37:03 +0000611
612 // ACLE 6.4.5 CLZ
613 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
614 ArchVersion > 6)
615 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
616
617 // ACLE 6.5.1 Hardware Floating Point
618 if (HW_FP)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000619 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
Erich Keaneebba5922017-07-21 22:37:03 +0000620
621 // ACLE predefines.
622 Builder.defineMacro("__ARM_ACLE", "200");
623
624 // FP16 support (we currently only support IEEE format).
625 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
626 Builder.defineMacro("__ARM_FP16_ARGS", "1");
627
628 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
629 if (ArchVersion >= 7 && (FPU & VFP4FPU))
630 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
631
632 // Subtarget options.
633
634 // FIXME: It's more complicated than this and we don't really support
635 // interworking.
636 // Windows on ARM does not "support" interworking
637 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
638 Builder.defineMacro("__THUMB_INTERWORK__");
639
640 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
641 // Embedded targets on Darwin follow AAPCS, but not EABI.
642 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
643 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
644 Builder.defineMacro("__ARM_EABI__");
645 Builder.defineMacro("__ARM_PCS", "1");
646 }
647
648 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
649 Builder.defineMacro("__ARM_PCS_VFP", "1");
650
651 if (SoftFloat)
652 Builder.defineMacro("__SOFTFP__");
653
Florian Hahnef5bbd62017-07-27 16:28:39 +0000654 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000655 Builder.defineMacro("__XSCALE__");
656
657 if (isThumb()) {
658 Builder.defineMacro("__THUMBEL__");
659 Builder.defineMacro("__thumb__");
660 if (supportsThumb2())
661 Builder.defineMacro("__thumb2__");
662 }
663
664 // ACLE 6.4.9 32-bit SIMD instructions
Sam Parkerd476cd32018-09-28 10:18:02 +0000665 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
Erich Keaneebba5922017-07-21 22:37:03 +0000666 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
667
668 // ACLE 6.4.10 Hardware Integer Divide
669 if (((HWDiv & HWDivThumb) && isThumb()) ||
670 ((HWDiv & HWDivARM) && !isThumb())) {
671 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
672 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
673 }
674
675 // Note, this is always on in gcc, even though it doesn't make sense.
676 Builder.defineMacro("__APCS_32__");
677
678 if (FPUModeIsVFP((FPUMode)FPU)) {
679 Builder.defineMacro("__VFP_FP__");
680 if (FPU & VFP2FPU)
681 Builder.defineMacro("__ARM_VFPV2__");
682 if (FPU & VFP3FPU)
683 Builder.defineMacro("__ARM_VFPV3__");
684 if (FPU & VFP4FPU)
685 Builder.defineMacro("__ARM_VFPV4__");
686 if (FPU & FPARMV8)
687 Builder.defineMacro("__ARM_FPV5__");
688 }
689
690 // This only gets set when Neon instructions are actually available, unlike
691 // the VFP define, hence the soft float and arch check. This is subtly
692 // different from gcc, we follow the intent which was that it should be set
693 // when Neon instructions are actually available.
694 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
695 Builder.defineMacro("__ARM_NEON", "1");
696 Builder.defineMacro("__ARM_NEON__");
697 // current AArch32 NEON implementations do not support double-precision
698 // floating-point even when it is present in VFP.
699 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000700 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000701 }
702
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000703 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000704 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000705
706 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
707
708 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
709 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
710 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
711 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
712 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
713 }
714
715 // ACLE 6.4.7 DSP instructions
716 if (DSP) {
717 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
718 }
719
720 // ACLE 6.4.8 Saturation instructions
721 bool SAT = false;
722 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
723 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
724 SAT = true;
725 }
726
727 // ACLE 6.4.6 Q (saturation) flag
728 if (DSP || SAT)
729 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
730
731 if (Opts.UnsafeFPMath)
732 Builder.defineMacro("__ARM_FP_FAST", "1");
733
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000734 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000735 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000736 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
737
738 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000739 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000740 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
741
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000742 // Armv8.2-A dot product intrinsics
743 if (DotProd)
744 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000745
Erich Keaneebba5922017-07-21 22:37:03 +0000746 switch (ArchKind) {
747 default:
748 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000749 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000750 getTargetDefinesARMV81A(Opts, Builder);
751 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000752 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000753 getTargetDefinesARMV82A(Opts, Builder);
754 break;
755 }
756}
757
Tim Northoverad4c5db2017-07-24 17:06:23 +0000758const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
759#define BUILTIN(ID, TYPE, ATTRS) \
760 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
761#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
762 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
763#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000764
Tim Northoverad4c5db2017-07-24 17:06:23 +0000765#define BUILTIN(ID, TYPE, ATTRS) \
766 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
767#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
768 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
769#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
770 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
771#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
772 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
773#include "clang/Basic/BuiltinsARM.def"
774};
775
776ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
777 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
778 Builtin::FirstTSBuiltin);
779}
780
781bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
782TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
783 return IsAAPCS
784 ? AAPCSABIBuiltinVaList
785 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
786 : TargetInfo::VoidPtrBuiltinVaList);
787}
788
789const char *const ARMTargetInfo::GCCRegNames[] = {
790 // Integer registers
791 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
792 "r12", "sp", "lr", "pc",
793
794 // Float registers
795 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
796 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
797 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
798
799 // Double registers
800 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
801 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
802 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
803
804 // Quad registers
805 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
806 "q12", "q13", "q14", "q15"};
807
808ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
809 return llvm::makeArrayRef(GCCRegNames);
810}
811
812const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
813 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
814 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
815 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
816 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
817 // The S, D and Q registers overlap, but aren't really aliases; we
818 // don't want to substitute one of these for a different-sized one.
819};
820
821ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
822 return llvm::makeArrayRef(GCCRegAliases);
823}
824
825bool ARMTargetInfo::validateAsmConstraint(
826 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
827 switch (*Name) {
828 default:
829 break;
830 case 'l': // r0-r7
831 case 'h': // r8-r15
832 case 't': // VFP Floating point register single precision
833 case 'w': // VFP Floating point register double precision
834 Info.setAllowsRegister();
835 return true;
836 case 'I':
837 case 'J':
838 case 'K':
839 case 'L':
840 case 'M':
841 // FIXME
842 return true;
843 case 'Q': // A memory address that is a single base register.
844 Info.setAllowsMemory();
845 return true;
846 case 'U': // a memory reference...
847 switch (Name[1]) {
848 case 'q': // ...ARMV4 ldrsb
849 case 'v': // ...VFP load/store (reg+constant offset)
850 case 'y': // ...iWMMXt load/store
851 case 't': // address valid for load/store opaque types wider
852 // than 128-bits
853 case 'n': // valid address for Neon doubleword vector load/store
854 case 'm': // valid address for Neon element and structure load/store
855 case 's': // valid address for non-offset loads/stores of quad-word
856 // values in four ARM registers
857 Info.setAllowsMemory();
858 Name++;
859 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000860 }
861 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000862 return false;
863}
Erich Keaneebba5922017-07-21 22:37:03 +0000864
Tim Northoverad4c5db2017-07-24 17:06:23 +0000865std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
866 std::string R;
867 switch (*Constraint) {
868 case 'U': // Two-character constraint; add "^" hint for later parsing.
869 R = std::string("^") + std::string(Constraint, 2);
870 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000871 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000872 case 'p': // 'p' should be translated to 'r' by default.
873 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000874 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000875 default:
876 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000877 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000878 return R;
879}
Erich Keaneebba5922017-07-21 22:37:03 +0000880
Tim Northoverad4c5db2017-07-24 17:06:23 +0000881bool ARMTargetInfo::validateConstraintModifier(
882 StringRef Constraint, char Modifier, unsigned Size,
883 std::string &SuggestedModifier) const {
884 bool isOutput = (Constraint[0] == '=');
885 bool isInOut = (Constraint[0] == '+');
886
887 // Strip off constraint modifiers.
888 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
889 Constraint = Constraint.substr(1);
890
891 switch (Constraint[0]) {
892 default:
893 break;
894 case 'r': {
895 switch (Modifier) {
896 default:
897 return (isInOut || isOutput || Size <= 64);
898 case 'q':
899 // A register of size 32 cannot fit a vector type.
900 return false;
901 }
Erich Keaneebba5922017-07-21 22:37:03 +0000902 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000903 }
Erich Keaneebba5922017-07-21 22:37:03 +0000904
905 return true;
906}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000907const char *ARMTargetInfo::getClobbers() const {
908 // FIXME: Is this really right?
909 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000910}
911
Tim Northoverad4c5db2017-07-24 17:06:23 +0000912TargetInfo::CallingConvCheckResult
913ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
914 switch (CC) {
915 case CC_AAPCS:
916 case CC_AAPCS_VFP:
917 case CC_Swift:
918 case CC_OpenCLKernel:
919 return CCCR_OK;
920 default:
921 return CCCR_Warning;
922 }
923}
924
925int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
926 if (RegNo == 0)
927 return 0;
928 if (RegNo == 1)
929 return 1;
930 return -1;
931}
932
933bool ARMTargetInfo::hasSjLjLowering() const { return true; }
934
935ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
936 const TargetOptions &Opts)
937 : ARMTargetInfo(Triple, Opts) {}
938
Erich Keaneebba5922017-07-21 22:37:03 +0000939void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
940 MacroBuilder &Builder) const {
941 Builder.defineMacro("__ARMEL__");
942 ARMTargetInfo::getTargetDefines(Opts, Builder);
943}
944
Tim Northoverad4c5db2017-07-24 17:06:23 +0000945ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
946 const TargetOptions &Opts)
947 : ARMTargetInfo(Triple, Opts) {}
948
Erich Keaneebba5922017-07-21 22:37:03 +0000949void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
950 MacroBuilder &Builder) const {
951 Builder.defineMacro("__ARMEB__");
952 Builder.defineMacro("__ARM_BIG_ENDIAN");
953 ARMTargetInfo::getTargetDefines(Opts, Builder);
954}
955
Tim Northoverad4c5db2017-07-24 17:06:23 +0000956WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
957 const TargetOptions &Opts)
958 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000959}
960
Erich Keaneebba5922017-07-21 22:37:03 +0000961void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
962 MacroBuilder &Builder) const {
963 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
964
965 // FIXME: this is invalid for WindowsCE
966 Builder.defineMacro("_M_ARM_NT", "1");
967 Builder.defineMacro("_M_ARMT", "_M_ARM");
968 Builder.defineMacro("_M_THUMB", "_M_ARM");
969
970 assert((Triple.getArch() == llvm::Triple::arm ||
971 Triple.getArch() == llvm::Triple::thumb) &&
972 "invalid architecture for Windows ARM target info");
973 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
974 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
975
976 // TODO map the complete set of values
977 // 31: VFPv3 40: VFPv4
978 Builder.defineMacro("_M_ARM_FP", "31");
979}
980
Tim Northoverad4c5db2017-07-24 17:06:23 +0000981TargetInfo::BuiltinVaListKind
982WindowsARMTargetInfo::getBuiltinVaListKind() const {
983 return TargetInfo::CharPtrBuiltinVaList;
984}
985
986TargetInfo::CallingConvCheckResult
987WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
988 switch (CC) {
989 case CC_X86StdCall:
990 case CC_X86ThisCall:
991 case CC_X86FastCall:
992 case CC_X86VectorCall:
993 return CCCR_Ignore;
994 case CC_C:
995 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +0000996 case CC_PreserveMost:
997 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +0000998 case CC_Swift:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000999 return CCCR_OK;
1000 default:
1001 return CCCR_Warning;
1002 }
1003}
1004
1005// Windows ARM + Itanium C++ ABI Target
1006ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1007 const llvm::Triple &Triple, const TargetOptions &Opts)
1008 : WindowsARMTargetInfo(Triple, Opts) {
1009 TheCXXABI.set(TargetCXXABI::GenericARM);
1010}
1011
1012void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1013 const LangOptions &Opts, MacroBuilder &Builder) const {
1014 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1015
1016 if (Opts.MSVCCompat)
1017 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1018}
1019
1020// Windows ARM, MS (C++) ABI
1021MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1022 const TargetOptions &Opts)
1023 : WindowsARMTargetInfo(Triple, Opts) {
1024 TheCXXABI.set(TargetCXXABI::Microsoft);
1025}
1026
1027void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1028 MacroBuilder &Builder) const {
1029 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1030 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1031}
1032
1033MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1034 const TargetOptions &Opts)
1035 : WindowsARMTargetInfo(Triple, Opts) {
1036 TheCXXABI.set(TargetCXXABI::GenericARM);
1037}
1038
Erich Keaneebba5922017-07-21 22:37:03 +00001039void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1040 MacroBuilder &Builder) const {
1041 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001042 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001043}
1044
Tim Northoverad4c5db2017-07-24 17:06:23 +00001045CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1046 const TargetOptions &Opts)
1047 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001048 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001049 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001050 DoubleAlign = LongLongAlign = 64;
1051 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1052}
1053
Erich Keaneebba5922017-07-21 22:37:03 +00001054void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1055 MacroBuilder &Builder) const {
1056 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1057 Builder.defineMacro("_ARM_");
1058 Builder.defineMacro("__CYGWIN__");
1059 Builder.defineMacro("__CYGWIN32__");
1060 DefineStd(Builder, "unix", Opts);
1061 if (Opts.CPlusPlus)
1062 Builder.defineMacro("_GNU_SOURCE");
1063}
1064
Tim Northoverad4c5db2017-07-24 17:06:23 +00001065DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1066 const TargetOptions &Opts)
1067 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1068 HasAlignMac68kSupport = true;
1069 // iOS always has 64-bit atomic instructions.
1070 // FIXME: This should be based off of the target features in
1071 // ARMleTargetInfo.
1072 MaxAtomicInlineWidth = 64;
1073
1074 if (Triple.isWatchABI()) {
1075 // Darwin on iOS uses a variant of the ARM C++ ABI.
1076 TheCXXABI.set(TargetCXXABI::WatchOS);
1077
Tim Northoverad4c5db2017-07-24 17:06:23 +00001078 // BOOL should be a real boolean on the new ABI
1079 UseSignedCharForObjCBool = false;
1080 } else
1081 TheCXXABI.set(TargetCXXABI::iOS);
1082}
1083
1084void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1085 const llvm::Triple &Triple,
1086 MacroBuilder &Builder) const {
1087 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1088}
1089
1090RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1091 const TargetOptions &Opts)
1092 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1093 Triple.getOSName(),
1094 Triple.getEnvironmentName()),
1095 Opts) {
1096 IsRenderScriptTarget = true;
1097 LongWidth = LongAlign = 64;
1098}
1099
Erich Keaneebba5922017-07-21 22:37:03 +00001100void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1101 MacroBuilder &Builder) const {
1102 Builder.defineMacro("__RENDERSCRIPT__");
1103 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1104}