blob: 549cb1f611db43de980717e81e6a1230afd947a9 [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)
312 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
313 MaxVectorAlign = 64;
314
315 // Do force alignment of members that follow zero length bitfields. If
316 // the alignment of the zero-length bitfield is greater than the member
317 // that follows it, `bar', `bar' will be aligned as the type of the
318 // zero length bitfield.
319 UseZeroLengthBitfieldAlignment = true;
320
321 if (Triple.getOS() == llvm::Triple::Linux ||
322 Triple.getOS() == llvm::Triple::UnknownOS)
323 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
324 ? "\01__gnu_mcount_nc"
325 : "\01mcount";
326}
327
328StringRef ARMTargetInfo::getABI() const { return ABI; }
329
330bool ARMTargetInfo::setABI(const std::string &Name) {
331 ABI = Name;
332
333 // The defaults (above) are for AAPCS, check if we need to change them.
334 //
335 // FIXME: We need support for -meabi... we could just mangle it into the
336 // name.
337 if (Name == "apcs-gnu" || Name == "aapcs16") {
338 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000339 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000340 }
341 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
342 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000343 return true;
344 }
345 return false;
346}
347
Tim Northoverad4c5db2017-07-24 17:06:23 +0000348// FIXME: This should be based on Arch attributes, not CPU names.
349bool ARMTargetInfo::initFeatureMap(
350 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
351 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000352
Eli Friedman642a5ee2018-04-16 23:52:58 +0000353 std::string ArchFeature;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000354 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000355 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000356
Eli Friedman642a5ee2018-04-16 23:52:58 +0000357 // Map the base architecture to an appropriate target feature, so we don't
358 // rely on the target triple.
359 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
360 if (CPUArch == llvm::ARM::ArchKind::INVALID)
361 CPUArch = Arch;
362 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
363 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
364 TargetFeatures.push_back(ArchFeature);
365 }
366
Tim Northoverad4c5db2017-07-24 17:06:23 +0000367 // get default FPU features
368 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
369 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000370
Tim Northoverad4c5db2017-07-24 17:06:23 +0000371 // get default Extension features
372 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
373 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000374
Tim Northoverad4c5db2017-07-24 17:06:23 +0000375 for (auto Feature : TargetFeatures)
376 if (Feature[0] == '+')
377 Features[Feature.drop_front(1)] = true;
378
379 // Enable or disable thumb-mode explicitly per function to enable mixed
380 // ARM and Thumb code generation.
381 if (isThumb())
382 Features["thumb-mode"] = true;
383 else
384 Features["thumb-mode"] = false;
385
386 // Convert user-provided arm and thumb GNU target attributes to
387 // [-|+]thumb-mode target features respectively.
388 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
389 for (auto &Feature : UpdatedFeaturesVec) {
390 if (Feature.compare("+arm") == 0)
391 Feature = "-thumb-mode";
392 else if (Feature.compare("+thumb") == 0)
393 Feature = "+thumb-mode";
394 }
395
396 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000397}
398
Erich Keaneebba5922017-07-21 22:37:03 +0000399
Tim Northoverad4c5db2017-07-24 17:06:23 +0000400bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
401 DiagnosticsEngine &Diags) {
402 FPU = 0;
David Green54823152019-06-07 17:28:12 +0000403 MVE = 0;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000404 CRC = 0;
405 Crypto = 0;
406 DSP = 0;
407 Unaligned = 1;
408 SoftFloat = SoftFloatABI = false;
409 HWDiv = 0;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000410 DotProd = 0;
Erich Keane1d1d4382019-01-25 17:27:57 +0000411 HasFloat16 = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000412
413 // This does not diagnose illegal cases like having both
Simon Tatham760df472019-05-28 16:13:20 +0000414 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
Tim Northoverad4c5db2017-07-24 17:06:23 +0000415 for (const auto &Feature : Features) {
416 if (Feature == "+soft-float") {
417 SoftFloat = true;
418 } else if (Feature == "+soft-float-abi") {
419 SoftFloatABI = true;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000420 } else if (Feature == "+vfp2sp" || Feature == "+vfp2d16sp" ||
421 Feature == "+vfp2" || Feature == "+vfp2d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000422 FPU |= VFP2FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000423 HW_FP |= HW_FP_SP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000424 if (Feature == "+vfp2" || Feature == "+vfp2d16")
425 HW_FP |= HW_FP_DP;
426 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
427 Feature == "+vfp3" || Feature == "+vfp3d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000428 FPU |= VFP3FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000429 HW_FP |= HW_FP_SP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000430 if (Feature == "+vfp3" || Feature == "+vfp3d16")
431 HW_FP |= HW_FP_DP;
432 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
433 Feature == "+vfp4" || Feature == "+vfp4d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000434 FPU |= VFP4FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000435 HW_FP |= HW_FP_SP | HW_FP_HP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000436 if (Feature == "+vfp4" || Feature == "+vfp4d16")
437 HW_FP |= HW_FP_DP;
438 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
439 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000440 FPU |= FPARMV8;
Simon Tatham760df472019-05-28 16:13:20 +0000441 HW_FP |= HW_FP_SP | HW_FP_HP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000442 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
443 HW_FP |= HW_FP_DP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000444 } else if (Feature == "+neon") {
445 FPU |= NeonFPU;
Simon Tatham760df472019-05-28 16:13:20 +0000446 HW_FP |= HW_FP_SP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000447 } else if (Feature == "+hwdiv") {
448 HWDiv |= HWDivThumb;
449 } else if (Feature == "+hwdiv-arm") {
450 HWDiv |= HWDivARM;
451 } else if (Feature == "+crc") {
452 CRC = 1;
453 } else if (Feature == "+crypto") {
454 Crypto = 1;
455 } else if (Feature == "+dsp") {
456 DSP = 1;
Simon Tatham760df472019-05-28 16:13:20 +0000457 } else if (Feature == "+fp64") {
458 HW_FP |= HW_FP_DP;
Javed Absar603a2ba2019-05-21 14:21:26 +0000459 } else if (Feature == "+8msecext") {
460 if (CPUProfile != "M" || ArchVersion != 8) {
461 Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
462 return false;
463 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000464 } else if (Feature == "+strict-align") {
465 Unaligned = 0;
466 } else if (Feature == "+fp16") {
467 HW_FP |= HW_FP_HP;
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000468 } else if (Feature == "+fullfp16") {
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000469 HasLegalHalfType = true;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000470 } else if (Feature == "+dotprod") {
471 DotProd = true;
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000472 } else if (Feature == "+mve") {
473 DSP = 1;
474 MVE |= MVE_INT;
475 } else if (Feature == "+mve.fp") {
476 DSP = 1;
477 HasLegalHalfType = true;
478 FPU |= FPARMV8;
479 MVE |= MVE_INT | MVE_FP;
480 HW_FP |= HW_FP_SP | HW_FP_HP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000481 }
482 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000483
484 switch (ArchVersion) {
485 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000486 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000487 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000488 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000489 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
490 else
491 LDREX = LDREX_W;
492 break;
493 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000494 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000495 LDREX = LDREX_W | LDREX_H | LDREX_B;
496 else
497 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
498 break;
499 case 8:
500 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
501 }
502
503 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
504 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
505 return false;
506 }
507
508 if (FPMath == FP_Neon)
509 Features.push_back("+neonfp");
510 else if (FPMath == FP_VFP)
511 Features.push_back("-neonfp");
512
513 // Remove front-end specific options which the backend handles differently.
Fangrui Song75e74e02019-03-31 08:48:19 +0000514 auto Feature = llvm::find(Features, "+soft-float-abi");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000515 if (Feature != Features.end())
516 Features.erase(Feature);
517
518 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000519}
520
Erich Keaneebba5922017-07-21 22:37:03 +0000521bool ARMTargetInfo::hasFeature(StringRef Feature) const {
522 return llvm::StringSwitch<bool>(Feature)
523 .Case("arm", true)
524 .Case("aarch32", true)
525 .Case("softfloat", SoftFloat)
526 .Case("thumb", isThumb())
527 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
528 .Case("vfp", FPU && !SoftFloat)
529 .Case("hwdiv", HWDiv & HWDivThumb)
530 .Case("hwdiv-arm", HWDiv & HWDivARM)
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000531 .Case("mve", hasMVE())
Erich Keaneebba5922017-07-21 22:37:03 +0000532 .Default(false);
533}
534
Tim Northoverad4c5db2017-07-24 17:06:23 +0000535bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
536 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000537 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000538}
539
Erich Keane3ec17432018-02-08 23:14:15 +0000540void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
541 llvm::ARM::fillValidCPUArchList(Values);
542}
543
Tim Northoverad4c5db2017-07-24 17:06:23 +0000544bool ARMTargetInfo::setCPU(const std::string &Name) {
545 if (Name != "generic")
546 setArchInfo(llvm::ARM::parseCPUArch(Name));
547
Florian Hahnef5bbd62017-07-27 16:28:39 +0000548 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000549 return false;
550 setAtomic();
551 CPU = Name;
552 return true;
553}
554
555bool ARMTargetInfo::setFPMath(StringRef Name) {
556 if (Name == "neon") {
557 FPMath = FP_Neon;
558 return true;
559 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
560 Name == "vfp4") {
561 FPMath = FP_VFP;
562 return true;
563 }
564 return false;
565}
566
567void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
568 MacroBuilder &Builder) const {
569 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
570}
571
572void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
573 MacroBuilder &Builder) const {
574 // Also include the ARMv8.1-A defines
575 getTargetDefinesARMV81A(Opts, Builder);
576}
577
Erich Keaneebba5922017-07-21 22:37:03 +0000578void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
579 MacroBuilder &Builder) const {
580 // Target identification.
581 Builder.defineMacro("__arm");
582 Builder.defineMacro("__arm__");
583 // For bare-metal none-eabi.
584 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
585 (getTriple().getEnvironment() == llvm::Triple::EABI ||
586 getTriple().getEnvironment() == llvm::Triple::EABIHF))
587 Builder.defineMacro("__ELF__");
588
589 // Target properties.
590 Builder.defineMacro("__REGISTER_PREFIX__", "");
591
592 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
593 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
594 if (getTriple().isWatchABI())
595 Builder.defineMacro("__ARM_ARCH_7K__", "2");
596
597 if (!CPUAttr.empty())
598 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
599
600 // ACLE 6.4.1 ARM/Thumb instruction set architecture
601 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
602 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
603
604 if (ArchVersion >= 8) {
605 // ACLE 6.5.7 Crypto Extension
606 if (Crypto)
607 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
608 // ACLE 6.5.8 CRC32 Extension
609 if (CRC)
610 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
611 // ACLE 6.5.10 Numeric Maximum and Minimum
612 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
613 // ACLE 6.5.9 Directed Rounding
614 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
615 }
616
617 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
618 // is not defined for the M-profile.
619 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000620 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000621 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
622
623 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
624 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
625 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
626 // v7 and v8 architectures excluding v8-M Baseline.
627 if (supportsThumb2())
628 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
629 else if (supportsThumb())
630 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
631
632 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
633 // instruction set such as ARM or Thumb.
634 Builder.defineMacro("__ARM_32BIT_STATE", "1");
635
636 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
637
638 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
639 if (!CPUProfile.empty())
640 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
641
642 // ACLE 6.4.3 Unaligned access supported in hardware
643 if (Unaligned)
644 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
645
646 // ACLE 6.4.4 LDREX/STREX
647 if (LDREX)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000648 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
Erich Keaneebba5922017-07-21 22:37:03 +0000649
650 // ACLE 6.4.5 CLZ
651 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
652 ArchVersion > 6)
653 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
654
655 // ACLE 6.5.1 Hardware Floating Point
656 if (HW_FP)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000657 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
Erich Keaneebba5922017-07-21 22:37:03 +0000658
659 // ACLE predefines.
660 Builder.defineMacro("__ARM_ACLE", "200");
661
662 // FP16 support (we currently only support IEEE format).
663 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
664 Builder.defineMacro("__ARM_FP16_ARGS", "1");
665
666 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
667 if (ArchVersion >= 7 && (FPU & VFP4FPU))
668 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
669
670 // Subtarget options.
671
672 // FIXME: It's more complicated than this and we don't really support
673 // interworking.
674 // Windows on ARM does not "support" interworking
675 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
676 Builder.defineMacro("__THUMB_INTERWORK__");
677
678 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
679 // Embedded targets on Darwin follow AAPCS, but not EABI.
680 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
681 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
682 Builder.defineMacro("__ARM_EABI__");
683 Builder.defineMacro("__ARM_PCS", "1");
684 }
685
686 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
687 Builder.defineMacro("__ARM_PCS_VFP", "1");
688
689 if (SoftFloat)
690 Builder.defineMacro("__SOFTFP__");
691
Oliver Stannarde3c8ce82019-02-18 12:39:47 +0000692 // ACLE position independent code macros.
693 if (Opts.ROPI)
694 Builder.defineMacro("__ARM_ROPI", "1");
695 if (Opts.RWPI)
696 Builder.defineMacro("__ARM_RWPI", "1");
697
Florian Hahnef5bbd62017-07-27 16:28:39 +0000698 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000699 Builder.defineMacro("__XSCALE__");
700
701 if (isThumb()) {
702 Builder.defineMacro("__THUMBEL__");
703 Builder.defineMacro("__thumb__");
704 if (supportsThumb2())
705 Builder.defineMacro("__thumb2__");
706 }
707
708 // ACLE 6.4.9 32-bit SIMD instructions
Sam Parkerd476cd32018-09-28 10:18:02 +0000709 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
Erich Keaneebba5922017-07-21 22:37:03 +0000710 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
711
712 // ACLE 6.4.10 Hardware Integer Divide
713 if (((HWDiv & HWDivThumb) && isThumb()) ||
714 ((HWDiv & HWDivARM) && !isThumb())) {
715 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
716 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
717 }
718
719 // Note, this is always on in gcc, even though it doesn't make sense.
720 Builder.defineMacro("__APCS_32__");
721
722 if (FPUModeIsVFP((FPUMode)FPU)) {
723 Builder.defineMacro("__VFP_FP__");
724 if (FPU & VFP2FPU)
725 Builder.defineMacro("__ARM_VFPV2__");
726 if (FPU & VFP3FPU)
727 Builder.defineMacro("__ARM_VFPV3__");
728 if (FPU & VFP4FPU)
729 Builder.defineMacro("__ARM_VFPV4__");
730 if (FPU & FPARMV8)
731 Builder.defineMacro("__ARM_FPV5__");
732 }
733
734 // This only gets set when Neon instructions are actually available, unlike
735 // the VFP define, hence the soft float and arch check. This is subtly
736 // different from gcc, we follow the intent which was that it should be set
737 // when Neon instructions are actually available.
738 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
739 Builder.defineMacro("__ARM_NEON", "1");
740 Builder.defineMacro("__ARM_NEON__");
741 // current AArch32 NEON implementations do not support double-precision
742 // floating-point even when it is present in VFP.
743 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000744 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000745 }
746
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000747 if (hasMVE()) {
748 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
749 }
750
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000751 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000752 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000753
754 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
755
Javed Absar603a2ba2019-05-21 14:21:26 +0000756 // CMSE
757 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
758 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
759
Erich Keaneebba5922017-07-21 22:37:03 +0000760 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
761 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
762 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
763 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
764 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
765 }
766
767 // ACLE 6.4.7 DSP instructions
768 if (DSP) {
769 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
770 }
771
772 // ACLE 6.4.8 Saturation instructions
773 bool SAT = false;
774 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
775 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
776 SAT = true;
777 }
778
779 // ACLE 6.4.6 Q (saturation) flag
780 if (DSP || SAT)
781 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
782
783 if (Opts.UnsafeFPMath)
784 Builder.defineMacro("__ARM_FP_FAST", "1");
785
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000786 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000787 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000788 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
789
790 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000791 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000792 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
793
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000794 // Armv8.2-A dot product intrinsics
795 if (DotProd)
796 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000797
Erich Keaneebba5922017-07-21 22:37:03 +0000798 switch (ArchKind) {
799 default:
800 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000801 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000802 getTargetDefinesARMV81A(Opts, Builder);
803 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000804 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000805 getTargetDefinesARMV82A(Opts, Builder);
806 break;
807 }
808}
809
Tim Northoverad4c5db2017-07-24 17:06:23 +0000810const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
811#define BUILTIN(ID, TYPE, ATTRS) \
812 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
813#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
814 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
815#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000816
Tim Northoverad4c5db2017-07-24 17:06:23 +0000817#define BUILTIN(ID, TYPE, ATTRS) \
818 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
819#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
820 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
821#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
822 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
823#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
824 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
825#include "clang/Basic/BuiltinsARM.def"
826};
827
828ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
829 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
830 Builtin::FirstTSBuiltin);
831}
832
833bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
834TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
835 return IsAAPCS
836 ? AAPCSABIBuiltinVaList
837 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
838 : TargetInfo::VoidPtrBuiltinVaList);
839}
840
841const char *const ARMTargetInfo::GCCRegNames[] = {
842 // Integer registers
843 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
844 "r12", "sp", "lr", "pc",
845
846 // Float registers
847 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
848 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
849 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
850
851 // Double registers
852 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
853 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
854 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
855
856 // Quad registers
857 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
858 "q12", "q13", "q14", "q15"};
859
860ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
861 return llvm::makeArrayRef(GCCRegNames);
862}
863
864const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
865 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
866 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
867 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
868 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
869 // The S, D and Q registers overlap, but aren't really aliases; we
870 // don't want to substitute one of these for a different-sized one.
871};
872
873ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
874 return llvm::makeArrayRef(GCCRegAliases);
875}
876
877bool ARMTargetInfo::validateAsmConstraint(
878 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
879 switch (*Name) {
880 default:
881 break;
882 case 'l': // r0-r7
883 case 'h': // r8-r15
884 case 't': // VFP Floating point register single precision
885 case 'w': // VFP Floating point register double precision
886 Info.setAllowsRegister();
887 return true;
888 case 'I':
889 case 'J':
890 case 'K':
891 case 'L':
892 case 'M':
893 // FIXME
894 return true;
895 case 'Q': // A memory address that is a single base register.
896 Info.setAllowsMemory();
897 return true;
898 case 'U': // a memory reference...
899 switch (Name[1]) {
900 case 'q': // ...ARMV4 ldrsb
901 case 'v': // ...VFP load/store (reg+constant offset)
902 case 'y': // ...iWMMXt load/store
903 case 't': // address valid for load/store opaque types wider
904 // than 128-bits
905 case 'n': // valid address for Neon doubleword vector load/store
906 case 'm': // valid address for Neon element and structure load/store
907 case 's': // valid address for non-offset loads/stores of quad-word
908 // values in four ARM registers
909 Info.setAllowsMemory();
910 Name++;
911 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000912 }
913 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000914 return false;
915}
Erich Keaneebba5922017-07-21 22:37:03 +0000916
Tim Northoverad4c5db2017-07-24 17:06:23 +0000917std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
918 std::string R;
919 switch (*Constraint) {
920 case 'U': // Two-character constraint; add "^" hint for later parsing.
921 R = std::string("^") + std::string(Constraint, 2);
922 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000923 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000924 case 'p': // 'p' should be translated to 'r' by default.
925 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000926 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000927 default:
928 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000929 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000930 return R;
931}
Erich Keaneebba5922017-07-21 22:37:03 +0000932
Tim Northoverad4c5db2017-07-24 17:06:23 +0000933bool ARMTargetInfo::validateConstraintModifier(
934 StringRef Constraint, char Modifier, unsigned Size,
935 std::string &SuggestedModifier) const {
936 bool isOutput = (Constraint[0] == '=');
937 bool isInOut = (Constraint[0] == '+');
938
939 // Strip off constraint modifiers.
940 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
941 Constraint = Constraint.substr(1);
942
943 switch (Constraint[0]) {
944 default:
945 break;
946 case 'r': {
947 switch (Modifier) {
948 default:
949 return (isInOut || isOutput || Size <= 64);
950 case 'q':
951 // A register of size 32 cannot fit a vector type.
952 return false;
953 }
Erich Keaneebba5922017-07-21 22:37:03 +0000954 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000955 }
Erich Keaneebba5922017-07-21 22:37:03 +0000956
957 return true;
958}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000959const char *ARMTargetInfo::getClobbers() const {
960 // FIXME: Is this really right?
961 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000962}
963
Tim Northoverad4c5db2017-07-24 17:06:23 +0000964TargetInfo::CallingConvCheckResult
965ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
966 switch (CC) {
967 case CC_AAPCS:
968 case CC_AAPCS_VFP:
969 case CC_Swift:
970 case CC_OpenCLKernel:
971 return CCCR_OK;
972 default:
973 return CCCR_Warning;
974 }
975}
976
977int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
978 if (RegNo == 0)
979 return 0;
980 if (RegNo == 1)
981 return 1;
982 return -1;
983}
984
985bool ARMTargetInfo::hasSjLjLowering() const { return true; }
986
987ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
988 const TargetOptions &Opts)
989 : ARMTargetInfo(Triple, Opts) {}
990
Erich Keaneebba5922017-07-21 22:37:03 +0000991void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
992 MacroBuilder &Builder) const {
993 Builder.defineMacro("__ARMEL__");
994 ARMTargetInfo::getTargetDefines(Opts, Builder);
995}
996
Tim Northoverad4c5db2017-07-24 17:06:23 +0000997ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
998 const TargetOptions &Opts)
999 : ARMTargetInfo(Triple, Opts) {}
1000
Erich Keaneebba5922017-07-21 22:37:03 +00001001void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1002 MacroBuilder &Builder) const {
1003 Builder.defineMacro("__ARMEB__");
1004 Builder.defineMacro("__ARM_BIG_ENDIAN");
1005 ARMTargetInfo::getTargetDefines(Opts, Builder);
1006}
1007
Tim Northoverad4c5db2017-07-24 17:06:23 +00001008WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1009 const TargetOptions &Opts)
1010 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +00001011}
1012
Erich Keaneebba5922017-07-21 22:37:03 +00001013void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1014 MacroBuilder &Builder) const {
1015 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
1016
1017 // FIXME: this is invalid for WindowsCE
1018 Builder.defineMacro("_M_ARM_NT", "1");
1019 Builder.defineMacro("_M_ARMT", "_M_ARM");
1020 Builder.defineMacro("_M_THUMB", "_M_ARM");
1021
1022 assert((Triple.getArch() == llvm::Triple::arm ||
1023 Triple.getArch() == llvm::Triple::thumb) &&
1024 "invalid architecture for Windows ARM target info");
1025 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1026 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1027
1028 // TODO map the complete set of values
1029 // 31: VFPv3 40: VFPv4
1030 Builder.defineMacro("_M_ARM_FP", "31");
1031}
1032
Tim Northoverad4c5db2017-07-24 17:06:23 +00001033TargetInfo::BuiltinVaListKind
1034WindowsARMTargetInfo::getBuiltinVaListKind() const {
1035 return TargetInfo::CharPtrBuiltinVaList;
1036}
1037
1038TargetInfo::CallingConvCheckResult
1039WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1040 switch (CC) {
1041 case CC_X86StdCall:
1042 case CC_X86ThisCall:
1043 case CC_X86FastCall:
1044 case CC_X86VectorCall:
1045 return CCCR_Ignore;
1046 case CC_C:
1047 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +00001048 case CC_PreserveMost:
1049 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +00001050 case CC_Swift:
Tim Northoverad4c5db2017-07-24 17:06:23 +00001051 return CCCR_OK;
1052 default:
1053 return CCCR_Warning;
1054 }
1055}
1056
1057// Windows ARM + Itanium C++ ABI Target
1058ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1059 const llvm::Triple &Triple, const TargetOptions &Opts)
1060 : WindowsARMTargetInfo(Triple, Opts) {
1061 TheCXXABI.set(TargetCXXABI::GenericARM);
1062}
1063
1064void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1065 const LangOptions &Opts, MacroBuilder &Builder) const {
1066 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1067
1068 if (Opts.MSVCCompat)
1069 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1070}
1071
1072// Windows ARM, MS (C++) ABI
1073MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1074 const TargetOptions &Opts)
1075 : WindowsARMTargetInfo(Triple, Opts) {
1076 TheCXXABI.set(TargetCXXABI::Microsoft);
1077}
1078
1079void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1080 MacroBuilder &Builder) const {
1081 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1082 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1083}
1084
1085MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1086 const TargetOptions &Opts)
1087 : WindowsARMTargetInfo(Triple, Opts) {
1088 TheCXXABI.set(TargetCXXABI::GenericARM);
1089}
1090
Erich Keaneebba5922017-07-21 22:37:03 +00001091void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1092 MacroBuilder &Builder) const {
1093 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001094 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001095}
1096
Tim Northoverad4c5db2017-07-24 17:06:23 +00001097CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1098 const TargetOptions &Opts)
1099 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001100 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001101 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001102 DoubleAlign = LongLongAlign = 64;
Michael Platings308e82e2019-03-08 10:44:06 +00001103 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 +00001104}
1105
Erich Keaneebba5922017-07-21 22:37:03 +00001106void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1107 MacroBuilder &Builder) const {
1108 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1109 Builder.defineMacro("_ARM_");
1110 Builder.defineMacro("__CYGWIN__");
1111 Builder.defineMacro("__CYGWIN32__");
1112 DefineStd(Builder, "unix", Opts);
1113 if (Opts.CPlusPlus)
1114 Builder.defineMacro("_GNU_SOURCE");
1115}
1116
Tim Northoverad4c5db2017-07-24 17:06:23 +00001117DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1118 const TargetOptions &Opts)
1119 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1120 HasAlignMac68kSupport = true;
1121 // iOS always has 64-bit atomic instructions.
1122 // FIXME: This should be based off of the target features in
1123 // ARMleTargetInfo.
1124 MaxAtomicInlineWidth = 64;
1125
1126 if (Triple.isWatchABI()) {
1127 // Darwin on iOS uses a variant of the ARM C++ ABI.
1128 TheCXXABI.set(TargetCXXABI::WatchOS);
1129
Tim Northoverad4c5db2017-07-24 17:06:23 +00001130 // BOOL should be a real boolean on the new ABI
1131 UseSignedCharForObjCBool = false;
1132 } else
1133 TheCXXABI.set(TargetCXXABI::iOS);
1134}
1135
1136void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1137 const llvm::Triple &Triple,
1138 MacroBuilder &Builder) const {
1139 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1140}
1141
1142RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1143 const TargetOptions &Opts)
1144 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1145 Triple.getOSName(),
1146 Triple.getEnvironmentName()),
1147 Opts) {
1148 IsRenderScriptTarget = true;
1149 LongWidth = LongAlign = 64;
1150}
1151
Erich Keaneebba5922017-07-21 22:37:03 +00001152void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1153 MacroBuilder &Builder) const {
1154 Builder.defineMacro("__RENDERSCRIPT__");
1155 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1156}