blob: 2273c1cdf4b4806c60bda5ced825946f672b8f66 [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
Michael Platings308e82e2019-03-08 10:44:06 +000043 ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
44 : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
Tim Northoverad4c5db2017-07-24 17:06:23 +000045 } 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"
Michael Platings308e82e2019-03-08 10:44:06 +000050 "-Fi8"
Tim Northoverad4c5db2017-07-24 17:06:23 +000051 "-i64:64"
52 "-v128:64:128"
53 "-a:0:32"
54 "-n32"
55 "-S64");
56 } else if (T.isOSNaCl()) {
57 assert(!BigEndian && "NaCl on ARM does not support big endian");
Michael Platings308e82e2019-03-08 10:44:06 +000058 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
Tim Northoverad4c5db2017-07-24 17:06:23 +000059 } else {
60 resetDataLayout(BigEndian
Michael Platings308e82e2019-03-08 10:44:06 +000061 ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
62 : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
Tim Northoverad4c5db2017-07-24 17:06:23 +000063 }
64
65 // FIXME: Enumerated types are variable width in straight AAPCS.
66}
67
68void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
69 const llvm::Triple &T = getTriple();
70
71 IsAAPCS = false;
72
73 if (IsAAPCS16)
74 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
75 else
76 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
77
Tim Northoverad4c5db2017-07-24 17:06:23 +000078 WCharType = SignedInt;
79
80 // Do not respect the alignment of bit-field types when laying out
81 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
82 UseBitFieldTypeAlignment = false;
83
84 /// gcc forces the alignment to 4 bytes, regardless of the type of the
85 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
86 /// gcc.
87 ZeroLengthBitfieldBoundary = 32;
88
89 if (T.isOSBinFormatMachO() && IsAAPCS16) {
90 assert(!BigEndian && "AAPCS16 does not support big-endian");
Michael Platings308e82e2019-03-08 10:44:06 +000091 resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128");
Tim Northoverad4c5db2017-07-24 17:06:23 +000092 } else if (T.isOSBinFormatMachO())
93 resetDataLayout(
94 BigEndian
Michael Platings308e82e2019-03-08 10:44:06 +000095 ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
96 : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
Tim Northoverad4c5db2017-07-24 17:06:23 +000097 else
98 resetDataLayout(
99 BigEndian
Michael Platings308e82e2019-03-08 10:44:06 +0000100 ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
101 : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000102
103 // FIXME: Override "preferred align" for double and long long.
104}
105
106void ARMTargetInfo::setArchInfo() {
107 StringRef ArchName = getTriple().getArchName();
108
109 ArchISA = llvm::ARM::parseArchISA(ArchName);
110 CPU = llvm::ARM::getDefaultCPU(ArchName);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000111 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
112 if (AK != llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000113 ArchKind = AK;
114 setArchInfo(ArchKind);
115}
116
Florian Hahnef5bbd62017-07-27 16:28:39 +0000117void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000118 StringRef SubArch;
119
120 // cache TargetParser info
121 ArchKind = Kind;
122 SubArch = llvm::ARM::getSubArch(ArchKind);
123 ArchProfile = llvm::ARM::parseArchProfile(SubArch);
124 ArchVersion = llvm::ARM::parseArchVersion(SubArch);
125
126 // cache CPU related strings
127 CPUAttr = getCPUAttr();
128 CPUProfile = getCPUProfile();
129}
130
131void ARMTargetInfo::setAtomic() {
132 // when triple does not specify a sub arch,
133 // then we are not using inline atomics
134 bool ShouldUseInlineAtomic =
Florian Hahnef5bbd62017-07-27 16:28:39 +0000135 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
136 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000137 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
Florian Hahnef5bbd62017-07-27 16:28:39 +0000138 if (ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000139 MaxAtomicPromoteWidth = 32;
140 if (ShouldUseInlineAtomic)
141 MaxAtomicInlineWidth = 32;
142 } else {
143 MaxAtomicPromoteWidth = 64;
144 if (ShouldUseInlineAtomic)
145 MaxAtomicInlineWidth = 64;
146 }
147}
148
Florian Hahnef5bbd62017-07-27 16:28:39 +0000149bool ARMTargetInfo::isThumb() const {
150 return ArchISA == llvm::ARM::ISAKind::THUMB;
151}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000152
153bool ARMTargetInfo::supportsThumb() const {
154 return CPUAttr.count('T') || ArchVersion >= 6;
155}
156
157bool ARMTargetInfo::supportsThumb2() const {
158 return CPUAttr.equals("6T2") ||
159 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
160}
161
162StringRef ARMTargetInfo::getCPUAttr() const {
163 // For most sub-arches, the build attribute CPU name is enough.
164 // For Cortex variants, it's slightly different.
165 switch (ArchKind) {
166 default:
167 return llvm::ARM::getCPUAttr(ArchKind);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000168 case llvm::ARM::ArchKind::ARMV6M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000169 return "6M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000170 case llvm::ARM::ArchKind::ARMV7S:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000171 return "7S";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000172 case llvm::ARM::ArchKind::ARMV7A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000173 return "7A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000174 case llvm::ARM::ArchKind::ARMV7R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000175 return "7R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000176 case llvm::ARM::ArchKind::ARMV7M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000177 return "7M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000178 case llvm::ARM::ArchKind::ARMV7EM:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000179 return "7EM";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000180 case llvm::ARM::ArchKind::ARMV7VE:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000181 return "7VE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000182 case llvm::ARM::ArchKind::ARMV8A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000183 return "8A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000184 case llvm::ARM::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000185 return "8_1A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000186 case llvm::ARM::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000187 return "8_2A";
Sjoerd Meijere6e4f312018-08-01 12:41:10 +0000188 case llvm::ARM::ArchKind::ARMV8_3A:
189 return "8_3A";
190 case llvm::ARM::ArchKind::ARMV8_4A:
191 return "8_4A";
Oliver Stannarda30b48d2018-09-26 14:20:29 +0000192 case llvm::ARM::ArchKind::ARMV8_5A:
193 return "8_5A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000194 case llvm::ARM::ArchKind::ARMV8MBaseline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000195 return "8M_BASE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000196 case llvm::ARM::ArchKind::ARMV8MMainline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000197 return "8M_MAIN";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000198 case llvm::ARM::ArchKind::ARMV8R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000199 return "8R";
200 }
201}
202
203StringRef ARMTargetInfo::getCPUProfile() const {
204 switch (ArchProfile) {
Florian Hahnef5bbd62017-07-27 16:28:39 +0000205 case llvm::ARM::ProfileKind::A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000206 return "A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000207 case llvm::ARM::ProfileKind::R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000208 return "R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000209 case llvm::ARM::ProfileKind::M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000210 return "M";
211 default:
212 return "";
213 }
214}
215
216ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
217 const TargetOptions &Opts)
218 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
219 HW_FP(0) {
Michal Gorny5a409d02018-12-20 13:09:30 +0000220 bool IsOpenBSD = Triple.isOSOpenBSD();
221 bool IsNetBSD = Triple.isOSNetBSD();
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000222
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000223 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
224 // environment where size_t is `unsigned long` rather than `unsigned int`
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000225
226 PtrDiffType = IntPtrType =
227 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
228 IsNetBSD)
229 ? SignedLong
230 : SignedInt;
231
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000232 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
233 IsNetBSD)
234 ? UnsignedLong
235 : UnsignedInt;
236
237 // ptrdiff_t is inconsistent on Darwin
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000238 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
239 !Triple.isWatchABI())
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000240 PtrDiffType = SignedInt;
241
Tim Northoverad4c5db2017-07-24 17:06:23 +0000242 // Cache arch related info.
243 setArchInfo();
244
245 // {} in inline assembly are neon specifiers, not assembly variant
246 // specifiers.
247 NoAsmVariants = true;
248
249 // FIXME: This duplicates code from the driver that sets the -target-abi
250 // option - this code is used if -target-abi isn't passed and should
251 // be unified in some way.
252 if (Triple.isOSBinFormatMachO()) {
253 // The backend is hardwired to assume AAPCS for M-class processors, ensure
254 // the frontend matches that.
255 if (Triple.getEnvironment() == llvm::Triple::EABI ||
256 Triple.getOS() == llvm::Triple::UnknownOS ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000257 ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000258 setABI("aapcs");
259 } else if (Triple.isWatchABI()) {
260 setABI("aapcs16");
261 } else {
262 setABI("apcs-gnu");
263 }
264 } else if (Triple.isOSWindows()) {
265 // FIXME: this is invalid for WindowsCE
266 setABI("aapcs");
267 } else {
268 // Select the default based on the platform.
269 switch (Triple.getEnvironment()) {
270 case llvm::Triple::Android:
271 case llvm::Triple::GNUEABI:
272 case llvm::Triple::GNUEABIHF:
273 case llvm::Triple::MuslEABI:
274 case llvm::Triple::MuslEABIHF:
275 setABI("aapcs-linux");
276 break;
277 case llvm::Triple::EABIHF:
278 case llvm::Triple::EABI:
279 setABI("aapcs");
280 break;
281 case llvm::Triple::GNU:
282 setABI("apcs-gnu");
283 break;
284 default:
Michal Gorny5a409d02018-12-20 13:09:30 +0000285 if (IsNetBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000286 setABI("apcs-gnu");
Michal Gorny5a409d02018-12-20 13:09:30 +0000287 else if (IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000288 setABI("aapcs-linux");
289 else
290 setABI("aapcs");
291 break;
292 }
293 }
294
295 // ARM targets default to using the ARM C++ ABI.
296 TheCXXABI.set(TargetCXXABI::GenericARM);
297
298 // ARM has atomics up to 8 bytes
299 setAtomic();
300
301 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
302 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
303 MaxVectorAlign = 64;
304
305 // Do force alignment of members that follow zero length bitfields. If
306 // the alignment of the zero-length bitfield is greater than the member
307 // that follows it, `bar', `bar' will be aligned as the type of the
308 // zero length bitfield.
309 UseZeroLengthBitfieldAlignment = true;
310
311 if (Triple.getOS() == llvm::Triple::Linux ||
312 Triple.getOS() == llvm::Triple::UnknownOS)
313 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
314 ? "\01__gnu_mcount_nc"
315 : "\01mcount";
316}
317
318StringRef ARMTargetInfo::getABI() const { return ABI; }
319
320bool ARMTargetInfo::setABI(const std::string &Name) {
321 ABI = Name;
322
323 // The defaults (above) are for AAPCS, check if we need to change them.
324 //
325 // FIXME: We need support for -meabi... we could just mangle it into the
326 // name.
327 if (Name == "apcs-gnu" || Name == "aapcs16") {
328 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000329 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000330 }
331 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
332 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000333 return true;
334 }
335 return false;
336}
337
Tim Northoverad4c5db2017-07-24 17:06:23 +0000338// FIXME: This should be based on Arch attributes, not CPU names.
339bool ARMTargetInfo::initFeatureMap(
340 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
341 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000342
Eli Friedman642a5ee2018-04-16 23:52:58 +0000343 std::string ArchFeature;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000344 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000345 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000346
Eli Friedman642a5ee2018-04-16 23:52:58 +0000347 // Map the base architecture to an appropriate target feature, so we don't
348 // rely on the target triple.
349 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
350 if (CPUArch == llvm::ARM::ArchKind::INVALID)
351 CPUArch = Arch;
352 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
353 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
354 TargetFeatures.push_back(ArchFeature);
355 }
356
Tim Northoverad4c5db2017-07-24 17:06:23 +0000357 // get default FPU features
358 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
359 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000360
Tim Northoverad4c5db2017-07-24 17:06:23 +0000361 // get default Extension features
362 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
363 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000364
Tim Northoverad4c5db2017-07-24 17:06:23 +0000365 for (auto Feature : TargetFeatures)
366 if (Feature[0] == '+')
367 Features[Feature.drop_front(1)] = true;
368
369 // Enable or disable thumb-mode explicitly per function to enable mixed
370 // ARM and Thumb code generation.
371 if (isThumb())
372 Features["thumb-mode"] = true;
373 else
374 Features["thumb-mode"] = false;
375
376 // Convert user-provided arm and thumb GNU target attributes to
377 // [-|+]thumb-mode target features respectively.
378 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
379 for (auto &Feature : UpdatedFeaturesVec) {
380 if (Feature.compare("+arm") == 0)
381 Feature = "-thumb-mode";
382 else if (Feature.compare("+thumb") == 0)
383 Feature = "+thumb-mode";
384 }
385
386 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000387}
388
Erich Keaneebba5922017-07-21 22:37:03 +0000389
Tim Northoverad4c5db2017-07-24 17:06:23 +0000390bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
391 DiagnosticsEngine &Diags) {
392 FPU = 0;
393 CRC = 0;
394 Crypto = 0;
395 DSP = 0;
396 Unaligned = 1;
397 SoftFloat = SoftFloatABI = false;
398 HWDiv = 0;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000399 DotProd = 0;
Erich Keane1d1d4382019-01-25 17:27:57 +0000400 HasFloat16 = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000401
402 // This does not diagnose illegal cases like having both
403 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
404 uint32_t HW_FP_remove = 0;
405 for (const auto &Feature : Features) {
406 if (Feature == "+soft-float") {
407 SoftFloat = true;
408 } else if (Feature == "+soft-float-abi") {
409 SoftFloatABI = true;
410 } else if (Feature == "+vfp2") {
411 FPU |= VFP2FPU;
412 HW_FP |= HW_FP_SP | HW_FP_DP;
413 } else if (Feature == "+vfp3") {
414 FPU |= VFP3FPU;
415 HW_FP |= HW_FP_SP | HW_FP_DP;
416 } else if (Feature == "+vfp4") {
417 FPU |= VFP4FPU;
418 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
419 } else if (Feature == "+fp-armv8") {
420 FPU |= FPARMV8;
421 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
422 } else if (Feature == "+neon") {
423 FPU |= NeonFPU;
424 HW_FP |= HW_FP_SP | HW_FP_DP;
425 } else if (Feature == "+hwdiv") {
426 HWDiv |= HWDivThumb;
427 } else if (Feature == "+hwdiv-arm") {
428 HWDiv |= HWDivARM;
429 } else if (Feature == "+crc") {
430 CRC = 1;
431 } else if (Feature == "+crypto") {
432 Crypto = 1;
433 } else if (Feature == "+dsp") {
434 DSP = 1;
435 } else if (Feature == "+fp-only-sp") {
436 HW_FP_remove |= HW_FP_DP;
437 } else if (Feature == "+strict-align") {
438 Unaligned = 0;
439 } else if (Feature == "+fp16") {
440 HW_FP |= HW_FP_HP;
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000441 } else if (Feature == "+fullfp16") {
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000442 HasLegalHalfType = true;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000443 } else if (Feature == "+dotprod") {
444 DotProd = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000445 }
446 }
447 HW_FP &= ~HW_FP_remove;
448
449 switch (ArchVersion) {
450 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000451 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000452 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000453 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000454 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
455 else
456 LDREX = LDREX_W;
457 break;
458 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000459 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000460 LDREX = LDREX_W | LDREX_H | LDREX_B;
461 else
462 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
463 break;
464 case 8:
465 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
466 }
467
468 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
469 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
470 return false;
471 }
472
473 if (FPMath == FP_Neon)
474 Features.push_back("+neonfp");
475 else if (FPMath == FP_VFP)
476 Features.push_back("-neonfp");
477
478 // Remove front-end specific options which the backend handles differently.
479 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
480 if (Feature != Features.end())
481 Features.erase(Feature);
482
483 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000484}
485
Erich Keaneebba5922017-07-21 22:37:03 +0000486bool ARMTargetInfo::hasFeature(StringRef Feature) const {
487 return llvm::StringSwitch<bool>(Feature)
488 .Case("arm", true)
489 .Case("aarch32", true)
490 .Case("softfloat", SoftFloat)
491 .Case("thumb", isThumb())
492 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
493 .Case("vfp", FPU && !SoftFloat)
494 .Case("hwdiv", HWDiv & HWDivThumb)
495 .Case("hwdiv-arm", HWDiv & HWDivARM)
496 .Default(false);
497}
498
Tim Northoverad4c5db2017-07-24 17:06:23 +0000499bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
500 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000501 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000502}
503
Erich Keane3ec17432018-02-08 23:14:15 +0000504void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
505 llvm::ARM::fillValidCPUArchList(Values);
506}
507
Tim Northoverad4c5db2017-07-24 17:06:23 +0000508bool ARMTargetInfo::setCPU(const std::string &Name) {
509 if (Name != "generic")
510 setArchInfo(llvm::ARM::parseCPUArch(Name));
511
Florian Hahnef5bbd62017-07-27 16:28:39 +0000512 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000513 return false;
514 setAtomic();
515 CPU = Name;
516 return true;
517}
518
519bool ARMTargetInfo::setFPMath(StringRef Name) {
520 if (Name == "neon") {
521 FPMath = FP_Neon;
522 return true;
523 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
524 Name == "vfp4") {
525 FPMath = FP_VFP;
526 return true;
527 }
528 return false;
529}
530
531void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
532 MacroBuilder &Builder) const {
533 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
534}
535
536void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
537 MacroBuilder &Builder) const {
538 // Also include the ARMv8.1-A defines
539 getTargetDefinesARMV81A(Opts, Builder);
540}
541
Erich Keaneebba5922017-07-21 22:37:03 +0000542void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
543 MacroBuilder &Builder) const {
544 // Target identification.
545 Builder.defineMacro("__arm");
546 Builder.defineMacro("__arm__");
547 // For bare-metal none-eabi.
548 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
549 (getTriple().getEnvironment() == llvm::Triple::EABI ||
550 getTriple().getEnvironment() == llvm::Triple::EABIHF))
551 Builder.defineMacro("__ELF__");
552
553 // Target properties.
554 Builder.defineMacro("__REGISTER_PREFIX__", "");
555
556 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
557 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
558 if (getTriple().isWatchABI())
559 Builder.defineMacro("__ARM_ARCH_7K__", "2");
560
561 if (!CPUAttr.empty())
562 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
563
564 // ACLE 6.4.1 ARM/Thumb instruction set architecture
565 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
566 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
567
568 if (ArchVersion >= 8) {
569 // ACLE 6.5.7 Crypto Extension
570 if (Crypto)
571 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
572 // ACLE 6.5.8 CRC32 Extension
573 if (CRC)
574 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
575 // ACLE 6.5.10 Numeric Maximum and Minimum
576 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
577 // ACLE 6.5.9 Directed Rounding
578 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
579 }
580
581 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
582 // is not defined for the M-profile.
583 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000584 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000585 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
586
587 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
588 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
589 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
590 // v7 and v8 architectures excluding v8-M Baseline.
591 if (supportsThumb2())
592 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
593 else if (supportsThumb())
594 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
595
596 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
597 // instruction set such as ARM or Thumb.
598 Builder.defineMacro("__ARM_32BIT_STATE", "1");
599
600 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
601
602 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
603 if (!CPUProfile.empty())
604 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
605
606 // ACLE 6.4.3 Unaligned access supported in hardware
607 if (Unaligned)
608 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
609
610 // ACLE 6.4.4 LDREX/STREX
611 if (LDREX)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000612 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
Erich Keaneebba5922017-07-21 22:37:03 +0000613
614 // ACLE 6.4.5 CLZ
615 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
616 ArchVersion > 6)
617 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
618
619 // ACLE 6.5.1 Hardware Floating Point
620 if (HW_FP)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000621 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
Erich Keaneebba5922017-07-21 22:37:03 +0000622
623 // ACLE predefines.
624 Builder.defineMacro("__ARM_ACLE", "200");
625
626 // FP16 support (we currently only support IEEE format).
627 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
628 Builder.defineMacro("__ARM_FP16_ARGS", "1");
629
630 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
631 if (ArchVersion >= 7 && (FPU & VFP4FPU))
632 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
633
634 // Subtarget options.
635
636 // FIXME: It's more complicated than this and we don't really support
637 // interworking.
638 // Windows on ARM does not "support" interworking
639 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
640 Builder.defineMacro("__THUMB_INTERWORK__");
641
642 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
643 // Embedded targets on Darwin follow AAPCS, but not EABI.
644 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
645 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
646 Builder.defineMacro("__ARM_EABI__");
647 Builder.defineMacro("__ARM_PCS", "1");
648 }
649
650 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
651 Builder.defineMacro("__ARM_PCS_VFP", "1");
652
653 if (SoftFloat)
654 Builder.defineMacro("__SOFTFP__");
655
Oliver Stannarde3c8ce82019-02-18 12:39:47 +0000656 // ACLE position independent code macros.
657 if (Opts.ROPI)
658 Builder.defineMacro("__ARM_ROPI", "1");
659 if (Opts.RWPI)
660 Builder.defineMacro("__ARM_RWPI", "1");
661
Florian Hahnef5bbd62017-07-27 16:28:39 +0000662 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000663 Builder.defineMacro("__XSCALE__");
664
665 if (isThumb()) {
666 Builder.defineMacro("__THUMBEL__");
667 Builder.defineMacro("__thumb__");
668 if (supportsThumb2())
669 Builder.defineMacro("__thumb2__");
670 }
671
672 // ACLE 6.4.9 32-bit SIMD instructions
Sam Parkerd476cd32018-09-28 10:18:02 +0000673 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
Erich Keaneebba5922017-07-21 22:37:03 +0000674 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
675
676 // ACLE 6.4.10 Hardware Integer Divide
677 if (((HWDiv & HWDivThumb) && isThumb()) ||
678 ((HWDiv & HWDivARM) && !isThumb())) {
679 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
680 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
681 }
682
683 // Note, this is always on in gcc, even though it doesn't make sense.
684 Builder.defineMacro("__APCS_32__");
685
686 if (FPUModeIsVFP((FPUMode)FPU)) {
687 Builder.defineMacro("__VFP_FP__");
688 if (FPU & VFP2FPU)
689 Builder.defineMacro("__ARM_VFPV2__");
690 if (FPU & VFP3FPU)
691 Builder.defineMacro("__ARM_VFPV3__");
692 if (FPU & VFP4FPU)
693 Builder.defineMacro("__ARM_VFPV4__");
694 if (FPU & FPARMV8)
695 Builder.defineMacro("__ARM_FPV5__");
696 }
697
698 // This only gets set when Neon instructions are actually available, unlike
699 // the VFP define, hence the soft float and arch check. This is subtly
700 // different from gcc, we follow the intent which was that it should be set
701 // when Neon instructions are actually available.
702 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
703 Builder.defineMacro("__ARM_NEON", "1");
704 Builder.defineMacro("__ARM_NEON__");
705 // current AArch32 NEON implementations do not support double-precision
706 // floating-point even when it is present in VFP.
707 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000708 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000709 }
710
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000711 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000712 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000713
714 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
715
716 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
717 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
718 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
719 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
720 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
721 }
722
723 // ACLE 6.4.7 DSP instructions
724 if (DSP) {
725 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
726 }
727
728 // ACLE 6.4.8 Saturation instructions
729 bool SAT = false;
730 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
731 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
732 SAT = true;
733 }
734
735 // ACLE 6.4.6 Q (saturation) flag
736 if (DSP || SAT)
737 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
738
739 if (Opts.UnsafeFPMath)
740 Builder.defineMacro("__ARM_FP_FAST", "1");
741
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000742 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000743 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000744 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
745
746 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000747 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000748 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
749
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000750 // Armv8.2-A dot product intrinsics
751 if (DotProd)
752 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000753
Erich Keaneebba5922017-07-21 22:37:03 +0000754 switch (ArchKind) {
755 default:
756 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000757 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000758 getTargetDefinesARMV81A(Opts, Builder);
759 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000760 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000761 getTargetDefinesARMV82A(Opts, Builder);
762 break;
763 }
764}
765
Tim Northoverad4c5db2017-07-24 17:06:23 +0000766const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
767#define BUILTIN(ID, TYPE, ATTRS) \
768 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
769#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
770 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
771#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000772
Tim Northoverad4c5db2017-07-24 17:06:23 +0000773#define BUILTIN(ID, TYPE, ATTRS) \
774 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
775#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
776 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
777#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
778 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
779#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
780 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
781#include "clang/Basic/BuiltinsARM.def"
782};
783
784ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
785 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
786 Builtin::FirstTSBuiltin);
787}
788
789bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
790TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
791 return IsAAPCS
792 ? AAPCSABIBuiltinVaList
793 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
794 : TargetInfo::VoidPtrBuiltinVaList);
795}
796
797const char *const ARMTargetInfo::GCCRegNames[] = {
798 // Integer registers
799 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
800 "r12", "sp", "lr", "pc",
801
802 // Float registers
803 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
804 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
805 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
806
807 // Double registers
808 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
809 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
810 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
811
812 // Quad registers
813 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
814 "q12", "q13", "q14", "q15"};
815
816ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
817 return llvm::makeArrayRef(GCCRegNames);
818}
819
820const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
821 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
822 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
823 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
824 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
825 // The S, D and Q registers overlap, but aren't really aliases; we
826 // don't want to substitute one of these for a different-sized one.
827};
828
829ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
830 return llvm::makeArrayRef(GCCRegAliases);
831}
832
833bool ARMTargetInfo::validateAsmConstraint(
834 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
835 switch (*Name) {
836 default:
837 break;
838 case 'l': // r0-r7
839 case 'h': // r8-r15
840 case 't': // VFP Floating point register single precision
841 case 'w': // VFP Floating point register double precision
842 Info.setAllowsRegister();
843 return true;
844 case 'I':
845 case 'J':
846 case 'K':
847 case 'L':
848 case 'M':
849 // FIXME
850 return true;
851 case 'Q': // A memory address that is a single base register.
852 Info.setAllowsMemory();
853 return true;
854 case 'U': // a memory reference...
855 switch (Name[1]) {
856 case 'q': // ...ARMV4 ldrsb
857 case 'v': // ...VFP load/store (reg+constant offset)
858 case 'y': // ...iWMMXt load/store
859 case 't': // address valid for load/store opaque types wider
860 // than 128-bits
861 case 'n': // valid address for Neon doubleword vector load/store
862 case 'm': // valid address for Neon element and structure load/store
863 case 's': // valid address for non-offset loads/stores of quad-word
864 // values in four ARM registers
865 Info.setAllowsMemory();
866 Name++;
867 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000868 }
869 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000870 return false;
871}
Erich Keaneebba5922017-07-21 22:37:03 +0000872
Tim Northoverad4c5db2017-07-24 17:06:23 +0000873std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
874 std::string R;
875 switch (*Constraint) {
876 case 'U': // Two-character constraint; add "^" hint for later parsing.
877 R = std::string("^") + std::string(Constraint, 2);
878 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000879 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000880 case 'p': // 'p' should be translated to 'r' by default.
881 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000882 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000883 default:
884 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000885 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000886 return R;
887}
Erich Keaneebba5922017-07-21 22:37:03 +0000888
Tim Northoverad4c5db2017-07-24 17:06:23 +0000889bool ARMTargetInfo::validateConstraintModifier(
890 StringRef Constraint, char Modifier, unsigned Size,
891 std::string &SuggestedModifier) const {
892 bool isOutput = (Constraint[0] == '=');
893 bool isInOut = (Constraint[0] == '+');
894
895 // Strip off constraint modifiers.
896 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
897 Constraint = Constraint.substr(1);
898
899 switch (Constraint[0]) {
900 default:
901 break;
902 case 'r': {
903 switch (Modifier) {
904 default:
905 return (isInOut || isOutput || Size <= 64);
906 case 'q':
907 // A register of size 32 cannot fit a vector type.
908 return false;
909 }
Erich Keaneebba5922017-07-21 22:37:03 +0000910 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000911 }
Erich Keaneebba5922017-07-21 22:37:03 +0000912
913 return true;
914}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000915const char *ARMTargetInfo::getClobbers() const {
916 // FIXME: Is this really right?
917 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000918}
919
Tim Northoverad4c5db2017-07-24 17:06:23 +0000920TargetInfo::CallingConvCheckResult
921ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
922 switch (CC) {
923 case CC_AAPCS:
924 case CC_AAPCS_VFP:
925 case CC_Swift:
926 case CC_OpenCLKernel:
927 return CCCR_OK;
928 default:
929 return CCCR_Warning;
930 }
931}
932
933int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
934 if (RegNo == 0)
935 return 0;
936 if (RegNo == 1)
937 return 1;
938 return -1;
939}
940
941bool ARMTargetInfo::hasSjLjLowering() const { return true; }
942
943ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
944 const TargetOptions &Opts)
945 : ARMTargetInfo(Triple, Opts) {}
946
Erich Keaneebba5922017-07-21 22:37:03 +0000947void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
948 MacroBuilder &Builder) const {
949 Builder.defineMacro("__ARMEL__");
950 ARMTargetInfo::getTargetDefines(Opts, Builder);
951}
952
Tim Northoverad4c5db2017-07-24 17:06:23 +0000953ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
954 const TargetOptions &Opts)
955 : ARMTargetInfo(Triple, Opts) {}
956
Erich Keaneebba5922017-07-21 22:37:03 +0000957void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
958 MacroBuilder &Builder) const {
959 Builder.defineMacro("__ARMEB__");
960 Builder.defineMacro("__ARM_BIG_ENDIAN");
961 ARMTargetInfo::getTargetDefines(Opts, Builder);
962}
963
Tim Northoverad4c5db2017-07-24 17:06:23 +0000964WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
965 const TargetOptions &Opts)
966 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000967}
968
Erich Keaneebba5922017-07-21 22:37:03 +0000969void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
970 MacroBuilder &Builder) const {
971 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
972
973 // FIXME: this is invalid for WindowsCE
974 Builder.defineMacro("_M_ARM_NT", "1");
975 Builder.defineMacro("_M_ARMT", "_M_ARM");
976 Builder.defineMacro("_M_THUMB", "_M_ARM");
977
978 assert((Triple.getArch() == llvm::Triple::arm ||
979 Triple.getArch() == llvm::Triple::thumb) &&
980 "invalid architecture for Windows ARM target info");
981 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
982 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
983
984 // TODO map the complete set of values
985 // 31: VFPv3 40: VFPv4
986 Builder.defineMacro("_M_ARM_FP", "31");
987}
988
Tim Northoverad4c5db2017-07-24 17:06:23 +0000989TargetInfo::BuiltinVaListKind
990WindowsARMTargetInfo::getBuiltinVaListKind() const {
991 return TargetInfo::CharPtrBuiltinVaList;
992}
993
994TargetInfo::CallingConvCheckResult
995WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
996 switch (CC) {
997 case CC_X86StdCall:
998 case CC_X86ThisCall:
999 case CC_X86FastCall:
1000 case CC_X86VectorCall:
1001 return CCCR_Ignore;
1002 case CC_C:
1003 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +00001004 case CC_PreserveMost:
1005 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +00001006 case CC_Swift:
Tim Northoverad4c5db2017-07-24 17:06:23 +00001007 return CCCR_OK;
1008 default:
1009 return CCCR_Warning;
1010 }
1011}
1012
1013// Windows ARM + Itanium C++ ABI Target
1014ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1015 const llvm::Triple &Triple, const TargetOptions &Opts)
1016 : WindowsARMTargetInfo(Triple, Opts) {
1017 TheCXXABI.set(TargetCXXABI::GenericARM);
1018}
1019
1020void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1021 const LangOptions &Opts, MacroBuilder &Builder) const {
1022 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1023
1024 if (Opts.MSVCCompat)
1025 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1026}
1027
1028// Windows ARM, MS (C++) ABI
1029MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1030 const TargetOptions &Opts)
1031 : WindowsARMTargetInfo(Triple, Opts) {
1032 TheCXXABI.set(TargetCXXABI::Microsoft);
1033}
1034
1035void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1036 MacroBuilder &Builder) const {
1037 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1038 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1039}
1040
1041MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1042 const TargetOptions &Opts)
1043 : WindowsARMTargetInfo(Triple, Opts) {
1044 TheCXXABI.set(TargetCXXABI::GenericARM);
1045}
1046
Erich Keaneebba5922017-07-21 22:37:03 +00001047void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1048 MacroBuilder &Builder) const {
1049 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001050 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001051}
1052
Tim Northoverad4c5db2017-07-24 17:06:23 +00001053CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1054 const TargetOptions &Opts)
1055 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001056 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001057 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001058 DoubleAlign = LongLongAlign = 64;
Michael Platings308e82e2019-03-08 10:44:06 +00001059 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
Tim Northoverad4c5db2017-07-24 17:06:23 +00001060}
1061
Erich Keaneebba5922017-07-21 22:37:03 +00001062void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1063 MacroBuilder &Builder) const {
1064 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1065 Builder.defineMacro("_ARM_");
1066 Builder.defineMacro("__CYGWIN__");
1067 Builder.defineMacro("__CYGWIN32__");
1068 DefineStd(Builder, "unix", Opts);
1069 if (Opts.CPlusPlus)
1070 Builder.defineMacro("_GNU_SOURCE");
1071}
1072
Tim Northoverad4c5db2017-07-24 17:06:23 +00001073DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1074 const TargetOptions &Opts)
1075 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1076 HasAlignMac68kSupport = true;
1077 // iOS always has 64-bit atomic instructions.
1078 // FIXME: This should be based off of the target features in
1079 // ARMleTargetInfo.
1080 MaxAtomicInlineWidth = 64;
1081
1082 if (Triple.isWatchABI()) {
1083 // Darwin on iOS uses a variant of the ARM C++ ABI.
1084 TheCXXABI.set(TargetCXXABI::WatchOS);
1085
Tim Northoverad4c5db2017-07-24 17:06:23 +00001086 // BOOL should be a real boolean on the new ABI
1087 UseSignedCharForObjCBool = false;
1088 } else
1089 TheCXXABI.set(TargetCXXABI::iOS);
1090}
1091
1092void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1093 const llvm::Triple &Triple,
1094 MacroBuilder &Builder) const {
1095 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1096}
1097
1098RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1099 const TargetOptions &Opts)
1100 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1101 Triple.getOSName(),
1102 Triple.getEnvironmentName()),
1103 Opts) {
1104 IsRenderScriptTarget = true;
1105 LongWidth = LongAlign = 64;
1106}
1107
Erich Keaneebba5922017-07-21 22:37:03 +00001108void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1109 MacroBuilder &Builder) const {
1110 Builder.defineMacro("__RENDERSCRIPT__");
1111 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1112}