blob: b6ad82260c6278bfccad07f5d88f25e06d518bc5 [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";
Sjoerd Meijer24f12712019-05-30 14:22:26 +0000200 case llvm::ARM::ArchKind::ARMV8_1MMainline:
201 return "8_1M_MAIN";
Tim Northoverad4c5db2017-07-24 17:06:23 +0000202 }
203}
204
205StringRef ARMTargetInfo::getCPUProfile() const {
206 switch (ArchProfile) {
Florian Hahnef5bbd62017-07-27 16:28:39 +0000207 case llvm::ARM::ProfileKind::A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000208 return "A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000209 case llvm::ARM::ProfileKind::R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000210 return "R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000211 case llvm::ARM::ProfileKind::M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000212 return "M";
213 default:
214 return "";
215 }
216}
217
218ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
219 const TargetOptions &Opts)
220 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
221 HW_FP(0) {
Michal Gorny5a409d02018-12-20 13:09:30 +0000222 bool IsOpenBSD = Triple.isOSOpenBSD();
223 bool IsNetBSD = Triple.isOSNetBSD();
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000224
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000225 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
226 // environment where size_t is `unsigned long` rather than `unsigned int`
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000227
228 PtrDiffType = IntPtrType =
229 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
230 IsNetBSD)
231 ? SignedLong
232 : SignedInt;
233
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000234 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
235 IsNetBSD)
236 ? UnsignedLong
237 : UnsignedInt;
238
239 // ptrdiff_t is inconsistent on Darwin
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000240 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
241 !Triple.isWatchABI())
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000242 PtrDiffType = SignedInt;
243
Tim Northoverad4c5db2017-07-24 17:06:23 +0000244 // Cache arch related info.
245 setArchInfo();
246
247 // {} in inline assembly are neon specifiers, not assembly variant
248 // specifiers.
249 NoAsmVariants = true;
250
251 // FIXME: This duplicates code from the driver that sets the -target-abi
252 // option - this code is used if -target-abi isn't passed and should
253 // be unified in some way.
254 if (Triple.isOSBinFormatMachO()) {
255 // The backend is hardwired to assume AAPCS for M-class processors, ensure
256 // the frontend matches that.
257 if (Triple.getEnvironment() == llvm::Triple::EABI ||
258 Triple.getOS() == llvm::Triple::UnknownOS ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000259 ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000260 setABI("aapcs");
261 } else if (Triple.isWatchABI()) {
262 setABI("aapcs16");
263 } else {
264 setABI("apcs-gnu");
265 }
266 } else if (Triple.isOSWindows()) {
267 // FIXME: this is invalid for WindowsCE
268 setABI("aapcs");
269 } else {
270 // Select the default based on the platform.
271 switch (Triple.getEnvironment()) {
272 case llvm::Triple::Android:
273 case llvm::Triple::GNUEABI:
274 case llvm::Triple::GNUEABIHF:
275 case llvm::Triple::MuslEABI:
276 case llvm::Triple::MuslEABIHF:
277 setABI("aapcs-linux");
278 break;
279 case llvm::Triple::EABIHF:
280 case llvm::Triple::EABI:
281 setABI("aapcs");
282 break;
283 case llvm::Triple::GNU:
284 setABI("apcs-gnu");
285 break;
286 default:
Michal Gorny5a409d02018-12-20 13:09:30 +0000287 if (IsNetBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000288 setABI("apcs-gnu");
Michal Gorny5a409d02018-12-20 13:09:30 +0000289 else if (IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000290 setABI("aapcs-linux");
291 else
292 setABI("aapcs");
293 break;
294 }
295 }
296
297 // ARM targets default to using the ARM C++ ABI.
298 TheCXXABI.set(TargetCXXABI::GenericARM);
299
300 // ARM has atomics up to 8 bytes
301 setAtomic();
302
303 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
304 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
305 MaxVectorAlign = 64;
306
307 // Do force alignment of members that follow zero length bitfields. If
308 // the alignment of the zero-length bitfield is greater than the member
309 // that follows it, `bar', `bar' will be aligned as the type of the
310 // zero length bitfield.
311 UseZeroLengthBitfieldAlignment = true;
312
313 if (Triple.getOS() == llvm::Triple::Linux ||
314 Triple.getOS() == llvm::Triple::UnknownOS)
315 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
316 ? "\01__gnu_mcount_nc"
317 : "\01mcount";
318}
319
320StringRef ARMTargetInfo::getABI() const { return ABI; }
321
322bool ARMTargetInfo::setABI(const std::string &Name) {
323 ABI = Name;
324
325 // The defaults (above) are for AAPCS, check if we need to change them.
326 //
327 // FIXME: We need support for -meabi... we could just mangle it into the
328 // name.
329 if (Name == "apcs-gnu" || Name == "aapcs16") {
330 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000331 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000332 }
333 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
334 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000335 return true;
336 }
337 return false;
338}
339
Tim Northoverad4c5db2017-07-24 17:06:23 +0000340// FIXME: This should be based on Arch attributes, not CPU names.
341bool ARMTargetInfo::initFeatureMap(
342 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
343 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000344
Eli Friedman642a5ee2018-04-16 23:52:58 +0000345 std::string ArchFeature;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000346 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000347 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000348
Eli Friedman642a5ee2018-04-16 23:52:58 +0000349 // Map the base architecture to an appropriate target feature, so we don't
350 // rely on the target triple.
351 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
352 if (CPUArch == llvm::ARM::ArchKind::INVALID)
353 CPUArch = Arch;
354 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
355 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
356 TargetFeatures.push_back(ArchFeature);
357 }
358
Tim Northoverad4c5db2017-07-24 17:06:23 +0000359 // get default FPU features
360 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
361 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000362
Tim Northoverad4c5db2017-07-24 17:06:23 +0000363 // get default Extension features
364 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
365 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000366
Tim Northoverad4c5db2017-07-24 17:06:23 +0000367 for (auto Feature : TargetFeatures)
368 if (Feature[0] == '+')
369 Features[Feature.drop_front(1)] = true;
370
371 // Enable or disable thumb-mode explicitly per function to enable mixed
372 // ARM and Thumb code generation.
373 if (isThumb())
374 Features["thumb-mode"] = true;
375 else
376 Features["thumb-mode"] = false;
377
378 // Convert user-provided arm and thumb GNU target attributes to
379 // [-|+]thumb-mode target features respectively.
380 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
381 for (auto &Feature : UpdatedFeaturesVec) {
382 if (Feature.compare("+arm") == 0)
383 Feature = "-thumb-mode";
384 else if (Feature.compare("+thumb") == 0)
385 Feature = "+thumb-mode";
386 }
387
388 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000389}
390
Erich Keaneebba5922017-07-21 22:37:03 +0000391
Tim Northoverad4c5db2017-07-24 17:06:23 +0000392bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
393 DiagnosticsEngine &Diags) {
394 FPU = 0;
395 CRC = 0;
396 Crypto = 0;
397 DSP = 0;
398 Unaligned = 1;
399 SoftFloat = SoftFloatABI = false;
400 HWDiv = 0;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000401 DotProd = 0;
Erich Keane1d1d4382019-01-25 17:27:57 +0000402 HasFloat16 = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000403
404 // This does not diagnose illegal cases like having both
Simon Tatham760df472019-05-28 16:13:20 +0000405 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
Tim Northoverad4c5db2017-07-24 17:06:23 +0000406 for (const auto &Feature : Features) {
407 if (Feature == "+soft-float") {
408 SoftFloat = true;
409 } else if (Feature == "+soft-float-abi") {
410 SoftFloatABI = true;
411 } else if (Feature == "+vfp2") {
412 FPU |= VFP2FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000413 HW_FP |= HW_FP_SP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000414 } else if (Feature == "+vfp3") {
415 FPU |= VFP3FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000416 HW_FP |= HW_FP_SP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000417 } else if (Feature == "+vfp4") {
418 FPU |= VFP4FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000419 HW_FP |= HW_FP_SP | HW_FP_HP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000420 } else if (Feature == "+fp-armv8") {
421 FPU |= FPARMV8;
Simon Tatham760df472019-05-28 16:13:20 +0000422 HW_FP |= HW_FP_SP | HW_FP_HP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000423 } else if (Feature == "+neon") {
424 FPU |= NeonFPU;
Simon Tatham760df472019-05-28 16:13:20 +0000425 HW_FP |= HW_FP_SP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000426 } else if (Feature == "+hwdiv") {
427 HWDiv |= HWDivThumb;
428 } else if (Feature == "+hwdiv-arm") {
429 HWDiv |= HWDivARM;
430 } else if (Feature == "+crc") {
431 CRC = 1;
432 } else if (Feature == "+crypto") {
433 Crypto = 1;
434 } else if (Feature == "+dsp") {
435 DSP = 1;
Simon Tatham760df472019-05-28 16:13:20 +0000436 } else if (Feature == "+fp64") {
437 HW_FP |= HW_FP_DP;
Javed Absar603a2ba2019-05-21 14:21:26 +0000438 } else if (Feature == "+8msecext") {
439 if (CPUProfile != "M" || ArchVersion != 8) {
440 Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
441 return false;
442 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000443 } else if (Feature == "+strict-align") {
444 Unaligned = 0;
445 } else if (Feature == "+fp16") {
446 HW_FP |= HW_FP_HP;
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000447 } else if (Feature == "+fullfp16") {
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000448 HasLegalHalfType = true;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000449 } else if (Feature == "+dotprod") {
450 DotProd = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000451 }
452 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000453
454 switch (ArchVersion) {
455 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000456 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000457 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000458 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000459 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
460 else
461 LDREX = LDREX_W;
462 break;
463 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000464 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000465 LDREX = LDREX_W | LDREX_H | LDREX_B;
466 else
467 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
468 break;
469 case 8:
470 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
471 }
472
473 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
474 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
475 return false;
476 }
477
478 if (FPMath == FP_Neon)
479 Features.push_back("+neonfp");
480 else if (FPMath == FP_VFP)
481 Features.push_back("-neonfp");
482
483 // Remove front-end specific options which the backend handles differently.
Fangrui Song75e74e02019-03-31 08:48:19 +0000484 auto Feature = llvm::find(Features, "+soft-float-abi");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000485 if (Feature != Features.end())
486 Features.erase(Feature);
487
488 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000489}
490
Erich Keaneebba5922017-07-21 22:37:03 +0000491bool ARMTargetInfo::hasFeature(StringRef Feature) const {
492 return llvm::StringSwitch<bool>(Feature)
493 .Case("arm", true)
494 .Case("aarch32", true)
495 .Case("softfloat", SoftFloat)
496 .Case("thumb", isThumb())
497 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
498 .Case("vfp", FPU && !SoftFloat)
499 .Case("hwdiv", HWDiv & HWDivThumb)
500 .Case("hwdiv-arm", HWDiv & HWDivARM)
501 .Default(false);
502}
503
Tim Northoverad4c5db2017-07-24 17:06:23 +0000504bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
505 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000506 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000507}
508
Erich Keane3ec17432018-02-08 23:14:15 +0000509void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
510 llvm::ARM::fillValidCPUArchList(Values);
511}
512
Tim Northoverad4c5db2017-07-24 17:06:23 +0000513bool ARMTargetInfo::setCPU(const std::string &Name) {
514 if (Name != "generic")
515 setArchInfo(llvm::ARM::parseCPUArch(Name));
516
Florian Hahnef5bbd62017-07-27 16:28:39 +0000517 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000518 return false;
519 setAtomic();
520 CPU = Name;
521 return true;
522}
523
524bool ARMTargetInfo::setFPMath(StringRef Name) {
525 if (Name == "neon") {
526 FPMath = FP_Neon;
527 return true;
528 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
529 Name == "vfp4") {
530 FPMath = FP_VFP;
531 return true;
532 }
533 return false;
534}
535
536void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
537 MacroBuilder &Builder) const {
538 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
539}
540
541void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
542 MacroBuilder &Builder) const {
543 // Also include the ARMv8.1-A defines
544 getTargetDefinesARMV81A(Opts, Builder);
545}
546
Erich Keaneebba5922017-07-21 22:37:03 +0000547void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
548 MacroBuilder &Builder) const {
549 // Target identification.
550 Builder.defineMacro("__arm");
551 Builder.defineMacro("__arm__");
552 // For bare-metal none-eabi.
553 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
554 (getTriple().getEnvironment() == llvm::Triple::EABI ||
555 getTriple().getEnvironment() == llvm::Triple::EABIHF))
556 Builder.defineMacro("__ELF__");
557
558 // Target properties.
559 Builder.defineMacro("__REGISTER_PREFIX__", "");
560
561 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
562 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
563 if (getTriple().isWatchABI())
564 Builder.defineMacro("__ARM_ARCH_7K__", "2");
565
566 if (!CPUAttr.empty())
567 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
568
569 // ACLE 6.4.1 ARM/Thumb instruction set architecture
570 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
571 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
572
573 if (ArchVersion >= 8) {
574 // ACLE 6.5.7 Crypto Extension
575 if (Crypto)
576 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
577 // ACLE 6.5.8 CRC32 Extension
578 if (CRC)
579 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
580 // ACLE 6.5.10 Numeric Maximum and Minimum
581 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
582 // ACLE 6.5.9 Directed Rounding
583 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
584 }
585
586 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
587 // is not defined for the M-profile.
588 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000589 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000590 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
591
592 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
593 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
594 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
595 // v7 and v8 architectures excluding v8-M Baseline.
596 if (supportsThumb2())
597 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
598 else if (supportsThumb())
599 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
600
601 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
602 // instruction set such as ARM or Thumb.
603 Builder.defineMacro("__ARM_32BIT_STATE", "1");
604
605 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
606
607 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
608 if (!CPUProfile.empty())
609 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
610
611 // ACLE 6.4.3 Unaligned access supported in hardware
612 if (Unaligned)
613 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
614
615 // ACLE 6.4.4 LDREX/STREX
616 if (LDREX)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000617 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
Erich Keaneebba5922017-07-21 22:37:03 +0000618
619 // ACLE 6.4.5 CLZ
620 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
621 ArchVersion > 6)
622 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
623
624 // ACLE 6.5.1 Hardware Floating Point
625 if (HW_FP)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000626 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
Erich Keaneebba5922017-07-21 22:37:03 +0000627
628 // ACLE predefines.
629 Builder.defineMacro("__ARM_ACLE", "200");
630
631 // FP16 support (we currently only support IEEE format).
632 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
633 Builder.defineMacro("__ARM_FP16_ARGS", "1");
634
635 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
636 if (ArchVersion >= 7 && (FPU & VFP4FPU))
637 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
638
639 // Subtarget options.
640
641 // FIXME: It's more complicated than this and we don't really support
642 // interworking.
643 // Windows on ARM does not "support" interworking
644 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
645 Builder.defineMacro("__THUMB_INTERWORK__");
646
647 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
648 // Embedded targets on Darwin follow AAPCS, but not EABI.
649 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
650 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
651 Builder.defineMacro("__ARM_EABI__");
652 Builder.defineMacro("__ARM_PCS", "1");
653 }
654
655 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
656 Builder.defineMacro("__ARM_PCS_VFP", "1");
657
658 if (SoftFloat)
659 Builder.defineMacro("__SOFTFP__");
660
Oliver Stannarde3c8ce82019-02-18 12:39:47 +0000661 // ACLE position independent code macros.
662 if (Opts.ROPI)
663 Builder.defineMacro("__ARM_ROPI", "1");
664 if (Opts.RWPI)
665 Builder.defineMacro("__ARM_RWPI", "1");
666
Florian Hahnef5bbd62017-07-27 16:28:39 +0000667 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000668 Builder.defineMacro("__XSCALE__");
669
670 if (isThumb()) {
671 Builder.defineMacro("__THUMBEL__");
672 Builder.defineMacro("__thumb__");
673 if (supportsThumb2())
674 Builder.defineMacro("__thumb2__");
675 }
676
677 // ACLE 6.4.9 32-bit SIMD instructions
Sam Parkerd476cd32018-09-28 10:18:02 +0000678 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
Erich Keaneebba5922017-07-21 22:37:03 +0000679 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
680
681 // ACLE 6.4.10 Hardware Integer Divide
682 if (((HWDiv & HWDivThumb) && isThumb()) ||
683 ((HWDiv & HWDivARM) && !isThumb())) {
684 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
685 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
686 }
687
688 // Note, this is always on in gcc, even though it doesn't make sense.
689 Builder.defineMacro("__APCS_32__");
690
691 if (FPUModeIsVFP((FPUMode)FPU)) {
692 Builder.defineMacro("__VFP_FP__");
693 if (FPU & VFP2FPU)
694 Builder.defineMacro("__ARM_VFPV2__");
695 if (FPU & VFP3FPU)
696 Builder.defineMacro("__ARM_VFPV3__");
697 if (FPU & VFP4FPU)
698 Builder.defineMacro("__ARM_VFPV4__");
699 if (FPU & FPARMV8)
700 Builder.defineMacro("__ARM_FPV5__");
701 }
702
703 // This only gets set when Neon instructions are actually available, unlike
704 // the VFP define, hence the soft float and arch check. This is subtly
705 // different from gcc, we follow the intent which was that it should be set
706 // when Neon instructions are actually available.
707 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
708 Builder.defineMacro("__ARM_NEON", "1");
709 Builder.defineMacro("__ARM_NEON__");
710 // current AArch32 NEON implementations do not support double-precision
711 // floating-point even when it is present in VFP.
712 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000713 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000714 }
715
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000716 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000717 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000718
719 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
720
Javed Absar603a2ba2019-05-21 14:21:26 +0000721 // CMSE
722 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
723 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
724
Erich Keaneebba5922017-07-21 22:37:03 +0000725 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
726 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
727 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
728 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
729 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
730 }
731
732 // ACLE 6.4.7 DSP instructions
733 if (DSP) {
734 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
735 }
736
737 // ACLE 6.4.8 Saturation instructions
738 bool SAT = false;
739 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
740 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
741 SAT = true;
742 }
743
744 // ACLE 6.4.6 Q (saturation) flag
745 if (DSP || SAT)
746 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
747
748 if (Opts.UnsafeFPMath)
749 Builder.defineMacro("__ARM_FP_FAST", "1");
750
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000751 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000752 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000753 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
754
755 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000756 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000757 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
758
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000759 // Armv8.2-A dot product intrinsics
760 if (DotProd)
761 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000762
Erich Keaneebba5922017-07-21 22:37:03 +0000763 switch (ArchKind) {
764 default:
765 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000766 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000767 getTargetDefinesARMV81A(Opts, Builder);
768 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000769 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000770 getTargetDefinesARMV82A(Opts, Builder);
771 break;
772 }
773}
774
Tim Northoverad4c5db2017-07-24 17:06:23 +0000775const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
776#define BUILTIN(ID, TYPE, ATTRS) \
777 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
778#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
779 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
780#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000781
Tim Northoverad4c5db2017-07-24 17:06:23 +0000782#define BUILTIN(ID, TYPE, ATTRS) \
783 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
784#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
785 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
786#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
787 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
788#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
789 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
790#include "clang/Basic/BuiltinsARM.def"
791};
792
793ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
794 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
795 Builtin::FirstTSBuiltin);
796}
797
798bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
799TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
800 return IsAAPCS
801 ? AAPCSABIBuiltinVaList
802 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
803 : TargetInfo::VoidPtrBuiltinVaList);
804}
805
806const char *const ARMTargetInfo::GCCRegNames[] = {
807 // Integer registers
808 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
809 "r12", "sp", "lr", "pc",
810
811 // Float registers
812 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
813 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
814 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
815
816 // Double registers
817 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
818 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
819 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
820
821 // Quad registers
822 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
823 "q12", "q13", "q14", "q15"};
824
825ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
826 return llvm::makeArrayRef(GCCRegNames);
827}
828
829const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
830 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
831 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
832 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
833 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
834 // The S, D and Q registers overlap, but aren't really aliases; we
835 // don't want to substitute one of these for a different-sized one.
836};
837
838ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
839 return llvm::makeArrayRef(GCCRegAliases);
840}
841
842bool ARMTargetInfo::validateAsmConstraint(
843 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
844 switch (*Name) {
845 default:
846 break;
847 case 'l': // r0-r7
848 case 'h': // r8-r15
849 case 't': // VFP Floating point register single precision
850 case 'w': // VFP Floating point register double precision
851 Info.setAllowsRegister();
852 return true;
853 case 'I':
854 case 'J':
855 case 'K':
856 case 'L':
857 case 'M':
858 // FIXME
859 return true;
860 case 'Q': // A memory address that is a single base register.
861 Info.setAllowsMemory();
862 return true;
863 case 'U': // a memory reference...
864 switch (Name[1]) {
865 case 'q': // ...ARMV4 ldrsb
866 case 'v': // ...VFP load/store (reg+constant offset)
867 case 'y': // ...iWMMXt load/store
868 case 't': // address valid for load/store opaque types wider
869 // than 128-bits
870 case 'n': // valid address for Neon doubleword vector load/store
871 case 'm': // valid address for Neon element and structure load/store
872 case 's': // valid address for non-offset loads/stores of quad-word
873 // values in four ARM registers
874 Info.setAllowsMemory();
875 Name++;
876 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000877 }
878 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000879 return false;
880}
Erich Keaneebba5922017-07-21 22:37:03 +0000881
Tim Northoverad4c5db2017-07-24 17:06:23 +0000882std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
883 std::string R;
884 switch (*Constraint) {
885 case 'U': // Two-character constraint; add "^" hint for later parsing.
886 R = std::string("^") + std::string(Constraint, 2);
887 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000888 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000889 case 'p': // 'p' should be translated to 'r' by default.
890 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000891 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000892 default:
893 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000894 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000895 return R;
896}
Erich Keaneebba5922017-07-21 22:37:03 +0000897
Tim Northoverad4c5db2017-07-24 17:06:23 +0000898bool ARMTargetInfo::validateConstraintModifier(
899 StringRef Constraint, char Modifier, unsigned Size,
900 std::string &SuggestedModifier) const {
901 bool isOutput = (Constraint[0] == '=');
902 bool isInOut = (Constraint[0] == '+');
903
904 // Strip off constraint modifiers.
905 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
906 Constraint = Constraint.substr(1);
907
908 switch (Constraint[0]) {
909 default:
910 break;
911 case 'r': {
912 switch (Modifier) {
913 default:
914 return (isInOut || isOutput || Size <= 64);
915 case 'q':
916 // A register of size 32 cannot fit a vector type.
917 return false;
918 }
Erich Keaneebba5922017-07-21 22:37:03 +0000919 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000920 }
Erich Keaneebba5922017-07-21 22:37:03 +0000921
922 return true;
923}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000924const char *ARMTargetInfo::getClobbers() const {
925 // FIXME: Is this really right?
926 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000927}
928
Tim Northoverad4c5db2017-07-24 17:06:23 +0000929TargetInfo::CallingConvCheckResult
930ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
931 switch (CC) {
932 case CC_AAPCS:
933 case CC_AAPCS_VFP:
934 case CC_Swift:
935 case CC_OpenCLKernel:
936 return CCCR_OK;
937 default:
938 return CCCR_Warning;
939 }
940}
941
942int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
943 if (RegNo == 0)
944 return 0;
945 if (RegNo == 1)
946 return 1;
947 return -1;
948}
949
950bool ARMTargetInfo::hasSjLjLowering() const { return true; }
951
952ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
953 const TargetOptions &Opts)
954 : ARMTargetInfo(Triple, Opts) {}
955
Erich Keaneebba5922017-07-21 22:37:03 +0000956void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
957 MacroBuilder &Builder) const {
958 Builder.defineMacro("__ARMEL__");
959 ARMTargetInfo::getTargetDefines(Opts, Builder);
960}
961
Tim Northoverad4c5db2017-07-24 17:06:23 +0000962ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
963 const TargetOptions &Opts)
964 : ARMTargetInfo(Triple, Opts) {}
965
Erich Keaneebba5922017-07-21 22:37:03 +0000966void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
967 MacroBuilder &Builder) const {
968 Builder.defineMacro("__ARMEB__");
969 Builder.defineMacro("__ARM_BIG_ENDIAN");
970 ARMTargetInfo::getTargetDefines(Opts, Builder);
971}
972
Tim Northoverad4c5db2017-07-24 17:06:23 +0000973WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
974 const TargetOptions &Opts)
975 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000976}
977
Erich Keaneebba5922017-07-21 22:37:03 +0000978void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
979 MacroBuilder &Builder) const {
980 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
981
982 // FIXME: this is invalid for WindowsCE
983 Builder.defineMacro("_M_ARM_NT", "1");
984 Builder.defineMacro("_M_ARMT", "_M_ARM");
985 Builder.defineMacro("_M_THUMB", "_M_ARM");
986
987 assert((Triple.getArch() == llvm::Triple::arm ||
988 Triple.getArch() == llvm::Triple::thumb) &&
989 "invalid architecture for Windows ARM target info");
990 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
991 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
992
993 // TODO map the complete set of values
994 // 31: VFPv3 40: VFPv4
995 Builder.defineMacro("_M_ARM_FP", "31");
996}
997
Tim Northoverad4c5db2017-07-24 17:06:23 +0000998TargetInfo::BuiltinVaListKind
999WindowsARMTargetInfo::getBuiltinVaListKind() const {
1000 return TargetInfo::CharPtrBuiltinVaList;
1001}
1002
1003TargetInfo::CallingConvCheckResult
1004WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1005 switch (CC) {
1006 case CC_X86StdCall:
1007 case CC_X86ThisCall:
1008 case CC_X86FastCall:
1009 case CC_X86VectorCall:
1010 return CCCR_Ignore;
1011 case CC_C:
1012 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +00001013 case CC_PreserveMost:
1014 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +00001015 case CC_Swift:
Tim Northoverad4c5db2017-07-24 17:06:23 +00001016 return CCCR_OK;
1017 default:
1018 return CCCR_Warning;
1019 }
1020}
1021
1022// Windows ARM + Itanium C++ ABI Target
1023ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1024 const llvm::Triple &Triple, const TargetOptions &Opts)
1025 : WindowsARMTargetInfo(Triple, Opts) {
1026 TheCXXABI.set(TargetCXXABI::GenericARM);
1027}
1028
1029void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1030 const LangOptions &Opts, MacroBuilder &Builder) const {
1031 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1032
1033 if (Opts.MSVCCompat)
1034 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1035}
1036
1037// Windows ARM, MS (C++) ABI
1038MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1039 const TargetOptions &Opts)
1040 : WindowsARMTargetInfo(Triple, Opts) {
1041 TheCXXABI.set(TargetCXXABI::Microsoft);
1042}
1043
1044void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1045 MacroBuilder &Builder) const {
1046 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1047 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1048}
1049
1050MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1051 const TargetOptions &Opts)
1052 : WindowsARMTargetInfo(Triple, Opts) {
1053 TheCXXABI.set(TargetCXXABI::GenericARM);
1054}
1055
Erich Keaneebba5922017-07-21 22:37:03 +00001056void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1057 MacroBuilder &Builder) const {
1058 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001059 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001060}
1061
Tim Northoverad4c5db2017-07-24 17:06:23 +00001062CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1063 const TargetOptions &Opts)
1064 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001065 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001066 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001067 DoubleAlign = LongLongAlign = 64;
Michael Platings308e82e2019-03-08 10:44:06 +00001068 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 +00001069}
1070
Erich Keaneebba5922017-07-21 22:37:03 +00001071void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1072 MacroBuilder &Builder) const {
1073 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1074 Builder.defineMacro("_ARM_");
1075 Builder.defineMacro("__CYGWIN__");
1076 Builder.defineMacro("__CYGWIN32__");
1077 DefineStd(Builder, "unix", Opts);
1078 if (Opts.CPlusPlus)
1079 Builder.defineMacro("_GNU_SOURCE");
1080}
1081
Tim Northoverad4c5db2017-07-24 17:06:23 +00001082DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1083 const TargetOptions &Opts)
1084 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1085 HasAlignMac68kSupport = true;
1086 // iOS always has 64-bit atomic instructions.
1087 // FIXME: This should be based off of the target features in
1088 // ARMleTargetInfo.
1089 MaxAtomicInlineWidth = 64;
1090
1091 if (Triple.isWatchABI()) {
1092 // Darwin on iOS uses a variant of the ARM C++ ABI.
1093 TheCXXABI.set(TargetCXXABI::WatchOS);
1094
Tim Northoverad4c5db2017-07-24 17:06:23 +00001095 // BOOL should be a real boolean on the new ABI
1096 UseSignedCharForObjCBool = false;
1097 } else
1098 TheCXXABI.set(TargetCXXABI::iOS);
1099}
1100
1101void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1102 const llvm::Triple &Triple,
1103 MacroBuilder &Builder) const {
1104 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1105}
1106
1107RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1108 const TargetOptions &Opts)
1109 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1110 Triple.getOSName(),
1111 Triple.getEnvironmentName()),
1112 Opts) {
1113 IsRenderScriptTarget = true;
1114 LongWidth = LongAlign = 64;
1115}
1116
Erich Keaneebba5922017-07-21 22:37:03 +00001117void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1118 MacroBuilder &Builder) const {
1119 Builder.defineMacro("__RENDERSCRIPT__");
1120 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1121}