blob: 2d23b050bbc9eced0bc83ebc1791a7515b88e6a0 [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
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000149bool ARMTargetInfo::hasMVE() const {
150 return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;
151}
152
153bool ARMTargetInfo::hasMVEFloat() const {
154 return hasMVE() && (MVE & MVE_FP);
155}
156
Florian Hahnef5bbd62017-07-27 16:28:39 +0000157bool ARMTargetInfo::isThumb() const {
158 return ArchISA == llvm::ARM::ISAKind::THUMB;
159}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000160
161bool ARMTargetInfo::supportsThumb() const {
162 return CPUAttr.count('T') || ArchVersion >= 6;
163}
164
165bool ARMTargetInfo::supportsThumb2() const {
166 return CPUAttr.equals("6T2") ||
167 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
168}
169
170StringRef ARMTargetInfo::getCPUAttr() const {
171 // For most sub-arches, the build attribute CPU name is enough.
172 // For Cortex variants, it's slightly different.
173 switch (ArchKind) {
174 default:
175 return llvm::ARM::getCPUAttr(ArchKind);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000176 case llvm::ARM::ArchKind::ARMV6M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000177 return "6M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000178 case llvm::ARM::ArchKind::ARMV7S:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000179 return "7S";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000180 case llvm::ARM::ArchKind::ARMV7A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000181 return "7A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000182 case llvm::ARM::ArchKind::ARMV7R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000183 return "7R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000184 case llvm::ARM::ArchKind::ARMV7M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000185 return "7M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000186 case llvm::ARM::ArchKind::ARMV7EM:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000187 return "7EM";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000188 case llvm::ARM::ArchKind::ARMV7VE:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000189 return "7VE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000190 case llvm::ARM::ArchKind::ARMV8A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000191 return "8A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000192 case llvm::ARM::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000193 return "8_1A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000194 case llvm::ARM::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000195 return "8_2A";
Sjoerd Meijere6e4f312018-08-01 12:41:10 +0000196 case llvm::ARM::ArchKind::ARMV8_3A:
197 return "8_3A";
198 case llvm::ARM::ArchKind::ARMV8_4A:
199 return "8_4A";
Oliver Stannarda30b48d2018-09-26 14:20:29 +0000200 case llvm::ARM::ArchKind::ARMV8_5A:
201 return "8_5A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000202 case llvm::ARM::ArchKind::ARMV8MBaseline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000203 return "8M_BASE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000204 case llvm::ARM::ArchKind::ARMV8MMainline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000205 return "8M_MAIN";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000206 case llvm::ARM::ArchKind::ARMV8R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000207 return "8R";
Sjoerd Meijer24f12712019-05-30 14:22:26 +0000208 case llvm::ARM::ArchKind::ARMV8_1MMainline:
209 return "8_1M_MAIN";
Tim Northoverad4c5db2017-07-24 17:06:23 +0000210 }
211}
212
213StringRef ARMTargetInfo::getCPUProfile() const {
214 switch (ArchProfile) {
Florian Hahnef5bbd62017-07-27 16:28:39 +0000215 case llvm::ARM::ProfileKind::A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000216 return "A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000217 case llvm::ARM::ProfileKind::R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000218 return "R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000219 case llvm::ARM::ProfileKind::M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000220 return "M";
221 default:
222 return "";
223 }
224}
225
226ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
227 const TargetOptions &Opts)
228 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
229 HW_FP(0) {
Michal Gorny5a409d02018-12-20 13:09:30 +0000230 bool IsOpenBSD = Triple.isOSOpenBSD();
231 bool IsNetBSD = Triple.isOSNetBSD();
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000232
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000233 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
234 // environment where size_t is `unsigned long` rather than `unsigned int`
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000235
236 PtrDiffType = IntPtrType =
237 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
238 IsNetBSD)
239 ? SignedLong
240 : SignedInt;
241
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000242 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
243 IsNetBSD)
244 ? UnsignedLong
245 : UnsignedInt;
246
247 // ptrdiff_t is inconsistent on Darwin
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000248 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
249 !Triple.isWatchABI())
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000250 PtrDiffType = SignedInt;
251
Tim Northoverad4c5db2017-07-24 17:06:23 +0000252 // Cache arch related info.
253 setArchInfo();
254
255 // {} in inline assembly are neon specifiers, not assembly variant
256 // specifiers.
257 NoAsmVariants = true;
258
259 // FIXME: This duplicates code from the driver that sets the -target-abi
260 // option - this code is used if -target-abi isn't passed and should
261 // be unified in some way.
262 if (Triple.isOSBinFormatMachO()) {
263 // The backend is hardwired to assume AAPCS for M-class processors, ensure
264 // the frontend matches that.
265 if (Triple.getEnvironment() == llvm::Triple::EABI ||
266 Triple.getOS() == llvm::Triple::UnknownOS ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000267 ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000268 setABI("aapcs");
269 } else if (Triple.isWatchABI()) {
270 setABI("aapcs16");
271 } else {
272 setABI("apcs-gnu");
273 }
274 } else if (Triple.isOSWindows()) {
275 // FIXME: this is invalid for WindowsCE
276 setABI("aapcs");
277 } else {
278 // Select the default based on the platform.
279 switch (Triple.getEnvironment()) {
280 case llvm::Triple::Android:
281 case llvm::Triple::GNUEABI:
282 case llvm::Triple::GNUEABIHF:
283 case llvm::Triple::MuslEABI:
284 case llvm::Triple::MuslEABIHF:
285 setABI("aapcs-linux");
286 break;
287 case llvm::Triple::EABIHF:
288 case llvm::Triple::EABI:
289 setABI("aapcs");
290 break;
291 case llvm::Triple::GNU:
292 setABI("apcs-gnu");
293 break;
294 default:
Michal Gorny5a409d02018-12-20 13:09:30 +0000295 if (IsNetBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000296 setABI("apcs-gnu");
Michal Gorny5a409d02018-12-20 13:09:30 +0000297 else if (IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000298 setABI("aapcs-linux");
299 else
300 setABI("aapcs");
301 break;
302 }
303 }
304
305 // ARM targets default to using the ARM C++ ABI.
306 TheCXXABI.set(TargetCXXABI::GenericARM);
307
308 // ARM has atomics up to 8 bytes
309 setAtomic();
310
311 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
Diogo N. Sampaio9427aa22019-08-08 12:50:36 +0000312 // as well the default alignment
Tim Northoverad4c5db2017-07-24 17:06:23 +0000313 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
Diogo N. Sampaio9427aa22019-08-08 12:50:36 +0000314 DefaultAlignForAttributeAligned = MaxVectorAlign = 64;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000315
316 // Do force alignment of members that follow zero length bitfields. If
317 // the alignment of the zero-length bitfield is greater than the member
318 // that follows it, `bar', `bar' will be aligned as the type of the
319 // zero length bitfield.
320 UseZeroLengthBitfieldAlignment = true;
321
322 if (Triple.getOS() == llvm::Triple::Linux ||
323 Triple.getOS() == llvm::Triple::UnknownOS)
324 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
Jian Cai16fa8b02019-08-16 23:30:16 +0000325 ? "llvm.arm.gnu.eabi.mcount"
Tim Northoverad4c5db2017-07-24 17:06:23 +0000326 : "\01mcount";
George Burgess IV2c074bb2019-06-14 00:35:17 +0000327
328 SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000329}
330
331StringRef ARMTargetInfo::getABI() const { return ABI; }
332
333bool ARMTargetInfo::setABI(const std::string &Name) {
334 ABI = Name;
335
336 // The defaults (above) are for AAPCS, check if we need to change them.
337 //
338 // FIXME: We need support for -meabi... we could just mangle it into the
339 // name.
340 if (Name == "apcs-gnu" || Name == "aapcs16") {
341 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000342 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000343 }
344 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
345 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000346 return true;
347 }
348 return false;
349}
350
Tim Northoverad4c5db2017-07-24 17:06:23 +0000351// FIXME: This should be based on Arch attributes, not CPU names.
352bool ARMTargetInfo::initFeatureMap(
353 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
354 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000355
Eli Friedman642a5ee2018-04-16 23:52:58 +0000356 std::string ArchFeature;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000357 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000358 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000359
Eli Friedman642a5ee2018-04-16 23:52:58 +0000360 // Map the base architecture to an appropriate target feature, so we don't
361 // rely on the target triple.
362 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
363 if (CPUArch == llvm::ARM::ArchKind::INVALID)
364 CPUArch = Arch;
365 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
366 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
367 TargetFeatures.push_back(ArchFeature);
368 }
369
Tim Northoverad4c5db2017-07-24 17:06:23 +0000370 // get default FPU features
371 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
372 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000373
Tim Northoverad4c5db2017-07-24 17:06:23 +0000374 // get default Extension features
375 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
376 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000377
Tim Northoverad4c5db2017-07-24 17:06:23 +0000378 for (auto Feature : TargetFeatures)
379 if (Feature[0] == '+')
380 Features[Feature.drop_front(1)] = true;
381
382 // Enable or disable thumb-mode explicitly per function to enable mixed
383 // ARM and Thumb code generation.
384 if (isThumb())
385 Features["thumb-mode"] = true;
386 else
387 Features["thumb-mode"] = false;
388
389 // Convert user-provided arm and thumb GNU target attributes to
390 // [-|+]thumb-mode target features respectively.
George Burgess IV2c074bb2019-06-14 00:35:17 +0000391 std::vector<std::string> UpdatedFeaturesVec;
392 for (const auto &Feature : FeaturesVec) {
393 // Skip soft-float-abi; it's something we only use to initialize a bit of
394 // class state, and is otherwise unrecognized.
395 if (Feature == "+soft-float-abi")
396 continue;
397
398 StringRef FixedFeature;
399 if (Feature == "+arm")
400 FixedFeature = "-thumb-mode";
401 else if (Feature == "+thumb")
402 FixedFeature = "+thumb-mode";
403 else
404 FixedFeature = Feature;
405 UpdatedFeaturesVec.push_back(FixedFeature.str());
Tim Northoverad4c5db2017-07-24 17:06:23 +0000406 }
407
408 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000409}
410
Erich Keaneebba5922017-07-21 22:37:03 +0000411
Tim Northoverad4c5db2017-07-24 17:06:23 +0000412bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
413 DiagnosticsEngine &Diags) {
414 FPU = 0;
David Green54823152019-06-07 17:28:12 +0000415 MVE = 0;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000416 CRC = 0;
417 Crypto = 0;
418 DSP = 0;
419 Unaligned = 1;
George Burgess IV2c074bb2019-06-14 00:35:17 +0000420 SoftFloat = false;
421 // Note that SoftFloatABI is initialized in our constructor.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000422 HWDiv = 0;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000423 DotProd = 0;
Erich Keane1d1d4382019-01-25 17:27:57 +0000424 HasFloat16 = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000425
426 // This does not diagnose illegal cases like having both
Simon Tatham760df472019-05-28 16:13:20 +0000427 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
Tim Northoverad4c5db2017-07-24 17:06:23 +0000428 for (const auto &Feature : Features) {
429 if (Feature == "+soft-float") {
430 SoftFloat = true;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000431 } else if (Feature == "+vfp2sp" || Feature == "+vfp2d16sp" ||
432 Feature == "+vfp2" || Feature == "+vfp2d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000433 FPU |= VFP2FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000434 HW_FP |= HW_FP_SP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000435 if (Feature == "+vfp2" || Feature == "+vfp2d16")
436 HW_FP |= HW_FP_DP;
437 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
438 Feature == "+vfp3" || Feature == "+vfp3d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000439 FPU |= VFP3FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000440 HW_FP |= HW_FP_SP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000441 if (Feature == "+vfp3" || Feature == "+vfp3d16")
442 HW_FP |= HW_FP_DP;
443 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
444 Feature == "+vfp4" || Feature == "+vfp4d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000445 FPU |= VFP4FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000446 HW_FP |= HW_FP_SP | HW_FP_HP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000447 if (Feature == "+vfp4" || Feature == "+vfp4d16")
448 HW_FP |= HW_FP_DP;
449 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
450 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000451 FPU |= FPARMV8;
Simon Tatham760df472019-05-28 16:13:20 +0000452 HW_FP |= HW_FP_SP | HW_FP_HP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000453 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
454 HW_FP |= HW_FP_DP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000455 } else if (Feature == "+neon") {
456 FPU |= NeonFPU;
Simon Tatham760df472019-05-28 16:13:20 +0000457 HW_FP |= HW_FP_SP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000458 } else if (Feature == "+hwdiv") {
459 HWDiv |= HWDivThumb;
460 } else if (Feature == "+hwdiv-arm") {
461 HWDiv |= HWDivARM;
462 } else if (Feature == "+crc") {
463 CRC = 1;
464 } else if (Feature == "+crypto") {
465 Crypto = 1;
466 } else if (Feature == "+dsp") {
467 DSP = 1;
Simon Tatham760df472019-05-28 16:13:20 +0000468 } else if (Feature == "+fp64") {
469 HW_FP |= HW_FP_DP;
Javed Absar603a2ba2019-05-21 14:21:26 +0000470 } else if (Feature == "+8msecext") {
471 if (CPUProfile != "M" || ArchVersion != 8) {
472 Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
473 return false;
474 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000475 } else if (Feature == "+strict-align") {
476 Unaligned = 0;
477 } else if (Feature == "+fp16") {
478 HW_FP |= HW_FP_HP;
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000479 } else if (Feature == "+fullfp16") {
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000480 HasLegalHalfType = true;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000481 } else if (Feature == "+dotprod") {
482 DotProd = true;
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000483 } else if (Feature == "+mve") {
484 DSP = 1;
485 MVE |= MVE_INT;
486 } else if (Feature == "+mve.fp") {
487 DSP = 1;
488 HasLegalHalfType = true;
489 FPU |= FPARMV8;
490 MVE |= MVE_INT | MVE_FP;
491 HW_FP |= HW_FP_SP | HW_FP_HP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000492 }
493 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000494
495 switch (ArchVersion) {
496 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000497 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000498 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000499 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000500 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
501 else
502 LDREX = LDREX_W;
503 break;
504 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000505 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000506 LDREX = LDREX_W | LDREX_H | LDREX_B;
507 else
508 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
509 break;
510 case 8:
511 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
512 }
513
514 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
515 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
516 return false;
517 }
518
519 if (FPMath == FP_Neon)
520 Features.push_back("+neonfp");
521 else if (FPMath == FP_VFP)
522 Features.push_back("-neonfp");
523
Tim Northoverad4c5db2017-07-24 17:06:23 +0000524 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000525}
526
Erich Keaneebba5922017-07-21 22:37:03 +0000527bool ARMTargetInfo::hasFeature(StringRef Feature) const {
528 return llvm::StringSwitch<bool>(Feature)
529 .Case("arm", true)
530 .Case("aarch32", true)
531 .Case("softfloat", SoftFloat)
532 .Case("thumb", isThumb())
533 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
534 .Case("vfp", FPU && !SoftFloat)
535 .Case("hwdiv", HWDiv & HWDivThumb)
536 .Case("hwdiv-arm", HWDiv & HWDivARM)
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000537 .Case("mve", hasMVE())
Erich Keaneebba5922017-07-21 22:37:03 +0000538 .Default(false);
539}
540
Tim Northoverad4c5db2017-07-24 17:06:23 +0000541bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
542 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000543 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000544}
545
Erich Keane3ec17432018-02-08 23:14:15 +0000546void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
547 llvm::ARM::fillValidCPUArchList(Values);
548}
549
Tim Northoverad4c5db2017-07-24 17:06:23 +0000550bool ARMTargetInfo::setCPU(const std::string &Name) {
551 if (Name != "generic")
552 setArchInfo(llvm::ARM::parseCPUArch(Name));
553
Florian Hahnef5bbd62017-07-27 16:28:39 +0000554 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000555 return false;
556 setAtomic();
557 CPU = Name;
558 return true;
559}
560
561bool ARMTargetInfo::setFPMath(StringRef Name) {
562 if (Name == "neon") {
563 FPMath = FP_Neon;
564 return true;
565 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
566 Name == "vfp4") {
567 FPMath = FP_VFP;
568 return true;
569 }
570 return false;
571}
572
573void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
574 MacroBuilder &Builder) const {
575 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
576}
577
578void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
579 MacroBuilder &Builder) const {
580 // Also include the ARMv8.1-A defines
581 getTargetDefinesARMV81A(Opts, Builder);
582}
583
Erich Keaneebba5922017-07-21 22:37:03 +0000584void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
585 MacroBuilder &Builder) const {
586 // Target identification.
587 Builder.defineMacro("__arm");
588 Builder.defineMacro("__arm__");
589 // For bare-metal none-eabi.
590 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
591 (getTriple().getEnvironment() == llvm::Triple::EABI ||
592 getTriple().getEnvironment() == llvm::Triple::EABIHF))
593 Builder.defineMacro("__ELF__");
594
595 // Target properties.
596 Builder.defineMacro("__REGISTER_PREFIX__", "");
597
598 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
599 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
600 if (getTriple().isWatchABI())
601 Builder.defineMacro("__ARM_ARCH_7K__", "2");
602
603 if (!CPUAttr.empty())
604 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
605
606 // ACLE 6.4.1 ARM/Thumb instruction set architecture
607 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
608 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
609
610 if (ArchVersion >= 8) {
611 // ACLE 6.5.7 Crypto Extension
612 if (Crypto)
613 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
614 // ACLE 6.5.8 CRC32 Extension
615 if (CRC)
616 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
617 // ACLE 6.5.10 Numeric Maximum and Minimum
618 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
619 // ACLE 6.5.9 Directed Rounding
620 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
621 }
622
623 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
624 // is not defined for the M-profile.
625 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000626 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000627 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
628
629 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
630 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
631 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
632 // v7 and v8 architectures excluding v8-M Baseline.
633 if (supportsThumb2())
634 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
635 else if (supportsThumb())
636 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
637
638 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
639 // instruction set such as ARM or Thumb.
640 Builder.defineMacro("__ARM_32BIT_STATE", "1");
641
642 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
643
644 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
645 if (!CPUProfile.empty())
646 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
647
648 // ACLE 6.4.3 Unaligned access supported in hardware
649 if (Unaligned)
650 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
651
652 // ACLE 6.4.4 LDREX/STREX
653 if (LDREX)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000654 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
Erich Keaneebba5922017-07-21 22:37:03 +0000655
656 // ACLE 6.4.5 CLZ
657 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
658 ArchVersion > 6)
659 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
660
661 // ACLE 6.5.1 Hardware Floating Point
662 if (HW_FP)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000663 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
Erich Keaneebba5922017-07-21 22:37:03 +0000664
665 // ACLE predefines.
666 Builder.defineMacro("__ARM_ACLE", "200");
667
668 // FP16 support (we currently only support IEEE format).
669 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
670 Builder.defineMacro("__ARM_FP16_ARGS", "1");
671
672 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
673 if (ArchVersion >= 7 && (FPU & VFP4FPU))
674 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
675
676 // Subtarget options.
677
678 // FIXME: It's more complicated than this and we don't really support
679 // interworking.
680 // Windows on ARM does not "support" interworking
681 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
682 Builder.defineMacro("__THUMB_INTERWORK__");
683
684 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
685 // Embedded targets on Darwin follow AAPCS, but not EABI.
686 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
687 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
688 Builder.defineMacro("__ARM_EABI__");
689 Builder.defineMacro("__ARM_PCS", "1");
690 }
691
692 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
693 Builder.defineMacro("__ARM_PCS_VFP", "1");
694
695 if (SoftFloat)
696 Builder.defineMacro("__SOFTFP__");
697
Oliver Stannarde3c8ce82019-02-18 12:39:47 +0000698 // ACLE position independent code macros.
699 if (Opts.ROPI)
700 Builder.defineMacro("__ARM_ROPI", "1");
701 if (Opts.RWPI)
702 Builder.defineMacro("__ARM_RWPI", "1");
703
Florian Hahnef5bbd62017-07-27 16:28:39 +0000704 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000705 Builder.defineMacro("__XSCALE__");
706
707 if (isThumb()) {
708 Builder.defineMacro("__THUMBEL__");
709 Builder.defineMacro("__thumb__");
710 if (supportsThumb2())
711 Builder.defineMacro("__thumb2__");
712 }
713
714 // ACLE 6.4.9 32-bit SIMD instructions
Sam Parkerd476cd32018-09-28 10:18:02 +0000715 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
Erich Keaneebba5922017-07-21 22:37:03 +0000716 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
717
718 // ACLE 6.4.10 Hardware Integer Divide
719 if (((HWDiv & HWDivThumb) && isThumb()) ||
720 ((HWDiv & HWDivARM) && !isThumb())) {
721 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
722 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
723 }
724
725 // Note, this is always on in gcc, even though it doesn't make sense.
726 Builder.defineMacro("__APCS_32__");
727
728 if (FPUModeIsVFP((FPUMode)FPU)) {
729 Builder.defineMacro("__VFP_FP__");
730 if (FPU & VFP2FPU)
731 Builder.defineMacro("__ARM_VFPV2__");
732 if (FPU & VFP3FPU)
733 Builder.defineMacro("__ARM_VFPV3__");
734 if (FPU & VFP4FPU)
735 Builder.defineMacro("__ARM_VFPV4__");
736 if (FPU & FPARMV8)
737 Builder.defineMacro("__ARM_FPV5__");
738 }
739
740 // This only gets set when Neon instructions are actually available, unlike
741 // the VFP define, hence the soft float and arch check. This is subtly
742 // different from gcc, we follow the intent which was that it should be set
743 // when Neon instructions are actually available.
744 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
745 Builder.defineMacro("__ARM_NEON", "1");
746 Builder.defineMacro("__ARM_NEON__");
747 // current AArch32 NEON implementations do not support double-precision
748 // floating-point even when it is present in VFP.
749 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000750 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000751 }
752
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000753 if (hasMVE()) {
754 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
755 }
756
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000757 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000758 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000759
760 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
761
Javed Absar603a2ba2019-05-21 14:21:26 +0000762 // CMSE
763 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
764 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
765
Erich Keaneebba5922017-07-21 22:37:03 +0000766 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
767 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
768 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
769 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
770 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
771 }
772
773 // ACLE 6.4.7 DSP instructions
774 if (DSP) {
775 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
776 }
777
778 // ACLE 6.4.8 Saturation instructions
779 bool SAT = false;
780 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
781 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
782 SAT = true;
783 }
784
785 // ACLE 6.4.6 Q (saturation) flag
786 if (DSP || SAT)
787 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
788
789 if (Opts.UnsafeFPMath)
790 Builder.defineMacro("__ARM_FP_FAST", "1");
791
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000792 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000793 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000794 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
795
796 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000797 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000798 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
799
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000800 // Armv8.2-A dot product intrinsics
801 if (DotProd)
802 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000803
Erich Keaneebba5922017-07-21 22:37:03 +0000804 switch (ArchKind) {
805 default:
806 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000807 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000808 getTargetDefinesARMV81A(Opts, Builder);
809 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000810 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000811 getTargetDefinesARMV82A(Opts, Builder);
812 break;
813 }
814}
815
Tim Northoverad4c5db2017-07-24 17:06:23 +0000816const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
817#define BUILTIN(ID, TYPE, ATTRS) \
818 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
819#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
820 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
821#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000822
Tim Northoverad4c5db2017-07-24 17:06:23 +0000823#define BUILTIN(ID, TYPE, ATTRS) \
824 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
825#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
826 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
827#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
828 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
829#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
830 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
831#include "clang/Basic/BuiltinsARM.def"
832};
833
834ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
835 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
836 Builtin::FirstTSBuiltin);
837}
838
839bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
840TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
841 return IsAAPCS
842 ? AAPCSABIBuiltinVaList
843 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
844 : TargetInfo::VoidPtrBuiltinVaList);
845}
846
847const char *const ARMTargetInfo::GCCRegNames[] = {
848 // Integer registers
849 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
850 "r12", "sp", "lr", "pc",
851
852 // Float registers
853 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
854 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
855 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
856
857 // Double registers
858 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
859 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
860 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
861
862 // Quad registers
863 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
864 "q12", "q13", "q14", "q15"};
865
866ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
867 return llvm::makeArrayRef(GCCRegNames);
868}
869
870const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
871 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
872 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
873 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
874 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
875 // The S, D and Q registers overlap, but aren't really aliases; we
876 // don't want to substitute one of these for a different-sized one.
877};
878
879ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
880 return llvm::makeArrayRef(GCCRegAliases);
881}
882
883bool ARMTargetInfo::validateAsmConstraint(
884 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
885 switch (*Name) {
886 default:
887 break;
David Candlera59bffb2019-09-05 15:17:25 +0000888 case 'l': // r0-r7 if thumb, r0-r15 if ARM
Tim Northoverad4c5db2017-07-24 17:06:23 +0000889 Info.setAllowsRegister();
890 return true;
David Candlera59bffb2019-09-05 15:17:25 +0000891 case 'h': // r8-r15, thumb only
892 if (isThumb()) {
893 Info.setAllowsRegister();
894 return true;
895 }
896 break;
897 case 's': // An integer constant, but allowing only relocatable values.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000898 return true;
David Candlera59bffb2019-09-05 15:17:25 +0000899 case 't': // s0-s31, d0-d31, or q0-q15
900 case 'w': // s0-s15, d0-d7, or q0-q3
901 case 'x': // s0-s31, d0-d15, or q0-q7
902 Info.setAllowsRegister();
903 return true;
904 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
905 // only available in ARMv6T2 and above
906 if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
907 Info.setRequiresImmediate(0, 65535);
908 return true;
909 }
910 break;
911 case 'I':
912 if (isThumb()) {
913 if (!supportsThumb2())
914 Info.setRequiresImmediate(0, 255);
915 else
916 // FIXME: should check if immediate value would be valid for a Thumb2
917 // data-processing instruction
918 Info.setRequiresImmediate();
919 } else
920 // FIXME: should check if immediate value would be valid for an ARM
921 // data-processing instruction
922 Info.setRequiresImmediate();
923 return true;
924 case 'J':
925 if (isThumb() && !supportsThumb2())
926 Info.setRequiresImmediate(-255, -1);
927 else
928 Info.setRequiresImmediate(-4095, 4095);
929 return true;
930 case 'K':
931 if (isThumb()) {
932 if (!supportsThumb2())
933 // FIXME: should check if immediate value can be obtained from shifting
934 // a value between 0 and 255 left by any amount
935 Info.setRequiresImmediate();
936 else
937 // FIXME: should check if immediate value would be valid for a Thumb2
938 // data-processing instruction when inverted
939 Info.setRequiresImmediate();
940 } else
941 // FIXME: should check if immediate value would be valid for an ARM
942 // data-processing instruction when inverted
943 Info.setRequiresImmediate();
944 return true;
945 case 'L':
946 if (isThumb()) {
947 if (!supportsThumb2())
948 Info.setRequiresImmediate(-7, 7);
949 else
950 // FIXME: should check if immediate value would be valid for a Thumb2
951 // data-processing instruction when negated
952 Info.setRequiresImmediate();
953 } else
954 // FIXME: should check if immediate value would be valid for an ARM
955 // data-processing instruction when negated
956 Info.setRequiresImmediate();
957 return true;
958 case 'M':
959 if (isThumb() && !supportsThumb2())
960 // FIXME: should check if immediate value is a multiple of 4 between 0 and
961 // 1020
962 Info.setRequiresImmediate();
963 else
964 // FIXME: should check if immediate value is a power of two or a integer
965 // between 0 and 32
966 Info.setRequiresImmediate();
967 return true;
968 case 'N':
969 // Thumb1 only
970 if (isThumb() && !supportsThumb2()) {
971 Info.setRequiresImmediate(0, 31);
972 return true;
973 }
974 break;
975 case 'O':
976 // Thumb1 only
977 if (isThumb() && !supportsThumb2()) {
978 // FIXME: should check if immediate value is a multiple of 4 between -508
979 // and 508
980 Info.setRequiresImmediate();
981 return true;
982 }
983 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000984 case 'Q': // A memory address that is a single base register.
985 Info.setAllowsMemory();
986 return true;
Simon Tathame8de8ba2019-06-25 16:49:32 +0000987 case 'T':
988 switch (Name[1]) {
989 default:
990 break;
991 case 'e': // Even general-purpose register
992 case 'o': // Odd general-purpose register
993 Info.setAllowsRegister();
994 Name++;
995 return true;
996 }
Yaxun Liud325eb32019-06-26 03:33:03 +0000997 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000998 case 'U': // a memory reference...
999 switch (Name[1]) {
1000 case 'q': // ...ARMV4 ldrsb
1001 case 'v': // ...VFP load/store (reg+constant offset)
1002 case 'y': // ...iWMMXt load/store
1003 case 't': // address valid for load/store opaque types wider
1004 // than 128-bits
1005 case 'n': // valid address for Neon doubleword vector load/store
1006 case 'm': // valid address for Neon element and structure load/store
1007 case 's': // valid address for non-offset loads/stores of quad-word
1008 // values in four ARM registers
1009 Info.setAllowsMemory();
1010 Name++;
1011 return true;
Erich Keaneebba5922017-07-21 22:37:03 +00001012 }
Yaxun Liud325eb32019-06-26 03:33:03 +00001013 break;
Erich Keaneebba5922017-07-21 22:37:03 +00001014 }
Tim Northoverad4c5db2017-07-24 17:06:23 +00001015 return false;
1016}
Erich Keaneebba5922017-07-21 22:37:03 +00001017
Tim Northoverad4c5db2017-07-24 17:06:23 +00001018std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
1019 std::string R;
1020 switch (*Constraint) {
1021 case 'U': // Two-character constraint; add "^" hint for later parsing.
Simon Tathame8de8ba2019-06-25 16:49:32 +00001022 case 'T':
Tim Northoverad4c5db2017-07-24 17:06:23 +00001023 R = std::string("^") + std::string(Constraint, 2);
1024 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +00001025 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001026 case 'p': // 'p' should be translated to 'r' by default.
1027 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +00001028 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001029 default:
1030 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +00001031 }
Tim Northoverad4c5db2017-07-24 17:06:23 +00001032 return R;
1033}
Erich Keaneebba5922017-07-21 22:37:03 +00001034
Tim Northoverad4c5db2017-07-24 17:06:23 +00001035bool ARMTargetInfo::validateConstraintModifier(
1036 StringRef Constraint, char Modifier, unsigned Size,
1037 std::string &SuggestedModifier) const {
1038 bool isOutput = (Constraint[0] == '=');
1039 bool isInOut = (Constraint[0] == '+');
1040
1041 // Strip off constraint modifiers.
1042 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
1043 Constraint = Constraint.substr(1);
1044
1045 switch (Constraint[0]) {
1046 default:
1047 break;
1048 case 'r': {
1049 switch (Modifier) {
1050 default:
1051 return (isInOut || isOutput || Size <= 64);
1052 case 'q':
1053 // A register of size 32 cannot fit a vector type.
1054 return false;
1055 }
Erich Keaneebba5922017-07-21 22:37:03 +00001056 }
Tim Northoverad4c5db2017-07-24 17:06:23 +00001057 }
Erich Keaneebba5922017-07-21 22:37:03 +00001058
1059 return true;
1060}
Tim Northoverad4c5db2017-07-24 17:06:23 +00001061const char *ARMTargetInfo::getClobbers() const {
1062 // FIXME: Is this really right?
1063 return "";
Erich Keaneebba5922017-07-21 22:37:03 +00001064}
1065
Tim Northoverad4c5db2017-07-24 17:06:23 +00001066TargetInfo::CallingConvCheckResult
1067ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1068 switch (CC) {
1069 case CC_AAPCS:
1070 case CC_AAPCS_VFP:
1071 case CC_Swift:
1072 case CC_OpenCLKernel:
1073 return CCCR_OK;
1074 default:
1075 return CCCR_Warning;
1076 }
1077}
1078
1079int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1080 if (RegNo == 0)
1081 return 0;
1082 if (RegNo == 1)
1083 return 1;
1084 return -1;
1085}
1086
1087bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1088
1089ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1090 const TargetOptions &Opts)
1091 : ARMTargetInfo(Triple, Opts) {}
1092
Erich Keaneebba5922017-07-21 22:37:03 +00001093void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1094 MacroBuilder &Builder) const {
1095 Builder.defineMacro("__ARMEL__");
1096 ARMTargetInfo::getTargetDefines(Opts, Builder);
1097}
1098
Tim Northoverad4c5db2017-07-24 17:06:23 +00001099ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1100 const TargetOptions &Opts)
1101 : ARMTargetInfo(Triple, Opts) {}
1102
Erich Keaneebba5922017-07-21 22:37:03 +00001103void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1104 MacroBuilder &Builder) const {
1105 Builder.defineMacro("__ARMEB__");
1106 Builder.defineMacro("__ARM_BIG_ENDIAN");
1107 ARMTargetInfo::getTargetDefines(Opts, Builder);
1108}
1109
Tim Northoverad4c5db2017-07-24 17:06:23 +00001110WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1111 const TargetOptions &Opts)
1112 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +00001113}
1114
Erich Keaneebba5922017-07-21 22:37:03 +00001115void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1116 MacroBuilder &Builder) const {
Erich Keaneebba5922017-07-21 22:37:03 +00001117 // FIXME: this is invalid for WindowsCE
1118 Builder.defineMacro("_M_ARM_NT", "1");
1119 Builder.defineMacro("_M_ARMT", "_M_ARM");
1120 Builder.defineMacro("_M_THUMB", "_M_ARM");
1121
1122 assert((Triple.getArch() == llvm::Triple::arm ||
1123 Triple.getArch() == llvm::Triple::thumb) &&
1124 "invalid architecture for Windows ARM target info");
1125 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1126 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1127
1128 // TODO map the complete set of values
1129 // 31: VFPv3 40: VFPv4
1130 Builder.defineMacro("_M_ARM_FP", "31");
1131}
1132
Tim Northoverad4c5db2017-07-24 17:06:23 +00001133TargetInfo::BuiltinVaListKind
1134WindowsARMTargetInfo::getBuiltinVaListKind() const {
1135 return TargetInfo::CharPtrBuiltinVaList;
1136}
1137
1138TargetInfo::CallingConvCheckResult
1139WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1140 switch (CC) {
1141 case CC_X86StdCall:
1142 case CC_X86ThisCall:
1143 case CC_X86FastCall:
1144 case CC_X86VectorCall:
1145 return CCCR_Ignore;
1146 case CC_C:
1147 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +00001148 case CC_PreserveMost:
1149 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +00001150 case CC_Swift:
Tim Northoverad4c5db2017-07-24 17:06:23 +00001151 return CCCR_OK;
1152 default:
1153 return CCCR_Warning;
1154 }
1155}
1156
1157// Windows ARM + Itanium C++ ABI Target
1158ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1159 const llvm::Triple &Triple, const TargetOptions &Opts)
1160 : WindowsARMTargetInfo(Triple, Opts) {
1161 TheCXXABI.set(TargetCXXABI::GenericARM);
1162}
1163
1164void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1165 const LangOptions &Opts, MacroBuilder &Builder) const {
1166 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1167
1168 if (Opts.MSVCCompat)
1169 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1170}
1171
1172// Windows ARM, MS (C++) ABI
1173MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1174 const TargetOptions &Opts)
1175 : WindowsARMTargetInfo(Triple, Opts) {
1176 TheCXXABI.set(TargetCXXABI::Microsoft);
1177}
1178
1179void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1180 MacroBuilder &Builder) const {
1181 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1182 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1183}
1184
1185MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1186 const TargetOptions &Opts)
1187 : WindowsARMTargetInfo(Triple, Opts) {
1188 TheCXXABI.set(TargetCXXABI::GenericARM);
1189}
1190
Erich Keaneebba5922017-07-21 22:37:03 +00001191void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1192 MacroBuilder &Builder) const {
1193 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001194 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001195}
1196
Tim Northoverad4c5db2017-07-24 17:06:23 +00001197CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1198 const TargetOptions &Opts)
1199 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001200 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001201 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001202 DoubleAlign = LongLongAlign = 64;
Michael Platings308e82e2019-03-08 10:44:06 +00001203 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 +00001204}
1205
Erich Keaneebba5922017-07-21 22:37:03 +00001206void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1207 MacroBuilder &Builder) const {
1208 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1209 Builder.defineMacro("_ARM_");
1210 Builder.defineMacro("__CYGWIN__");
1211 Builder.defineMacro("__CYGWIN32__");
1212 DefineStd(Builder, "unix", Opts);
1213 if (Opts.CPlusPlus)
1214 Builder.defineMacro("_GNU_SOURCE");
1215}
1216
Tim Northoverad4c5db2017-07-24 17:06:23 +00001217DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1218 const TargetOptions &Opts)
1219 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1220 HasAlignMac68kSupport = true;
1221 // iOS always has 64-bit atomic instructions.
1222 // FIXME: This should be based off of the target features in
1223 // ARMleTargetInfo.
1224 MaxAtomicInlineWidth = 64;
1225
1226 if (Triple.isWatchABI()) {
1227 // Darwin on iOS uses a variant of the ARM C++ ABI.
1228 TheCXXABI.set(TargetCXXABI::WatchOS);
1229
Tim Northoverad4c5db2017-07-24 17:06:23 +00001230 // BOOL should be a real boolean on the new ABI
1231 UseSignedCharForObjCBool = false;
1232 } else
1233 TheCXXABI.set(TargetCXXABI::iOS);
1234}
1235
1236void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1237 const llvm::Triple &Triple,
1238 MacroBuilder &Builder) const {
1239 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1240}
1241
1242RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1243 const TargetOptions &Opts)
1244 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1245 Triple.getOSName(),
1246 Triple.getEnvironmentName()),
1247 Opts) {
1248 IsRenderScriptTarget = true;
1249 LongWidth = LongAlign = 64;
1250}
1251
Erich Keaneebba5922017-07-21 22:37:03 +00001252void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1253 MacroBuilder &Builder) const {
1254 Builder.defineMacro("__RENDERSCRIPT__");
1255 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1256}