blob: cceed8880ffe4663c187ab6a2a4e50223cf208df [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";
George Burgess IV2c074bb2019-06-14 00:35:17 +0000326
327 SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000328}
329
330StringRef ARMTargetInfo::getABI() const { return ABI; }
331
332bool ARMTargetInfo::setABI(const std::string &Name) {
333 ABI = Name;
334
335 // The defaults (above) are for AAPCS, check if we need to change them.
336 //
337 // FIXME: We need support for -meabi... we could just mangle it into the
338 // name.
339 if (Name == "apcs-gnu" || Name == "aapcs16") {
340 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000341 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000342 }
343 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
344 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000345 return true;
346 }
347 return false;
348}
349
Tim Northoverad4c5db2017-07-24 17:06:23 +0000350// FIXME: This should be based on Arch attributes, not CPU names.
351bool ARMTargetInfo::initFeatureMap(
352 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
353 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000354
Eli Friedman642a5ee2018-04-16 23:52:58 +0000355 std::string ArchFeature;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000356 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000357 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000358
Eli Friedman642a5ee2018-04-16 23:52:58 +0000359 // Map the base architecture to an appropriate target feature, so we don't
360 // rely on the target triple.
361 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
362 if (CPUArch == llvm::ARM::ArchKind::INVALID)
363 CPUArch = Arch;
364 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
365 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
366 TargetFeatures.push_back(ArchFeature);
367 }
368
Tim Northoverad4c5db2017-07-24 17:06:23 +0000369 // get default FPU features
370 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
371 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000372
Tim Northoverad4c5db2017-07-24 17:06:23 +0000373 // get default Extension features
374 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
375 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000376
Tim Northoverad4c5db2017-07-24 17:06:23 +0000377 for (auto Feature : TargetFeatures)
378 if (Feature[0] == '+')
379 Features[Feature.drop_front(1)] = true;
380
381 // Enable or disable thumb-mode explicitly per function to enable mixed
382 // ARM and Thumb code generation.
383 if (isThumb())
384 Features["thumb-mode"] = true;
385 else
386 Features["thumb-mode"] = false;
387
388 // Convert user-provided arm and thumb GNU target attributes to
389 // [-|+]thumb-mode target features respectively.
George Burgess IV2c074bb2019-06-14 00:35:17 +0000390 std::vector<std::string> UpdatedFeaturesVec;
391 for (const auto &Feature : FeaturesVec) {
392 // Skip soft-float-abi; it's something we only use to initialize a bit of
393 // class state, and is otherwise unrecognized.
394 if (Feature == "+soft-float-abi")
395 continue;
396
397 StringRef FixedFeature;
398 if (Feature == "+arm")
399 FixedFeature = "-thumb-mode";
400 else if (Feature == "+thumb")
401 FixedFeature = "+thumb-mode";
402 else
403 FixedFeature = Feature;
404 UpdatedFeaturesVec.push_back(FixedFeature.str());
Tim Northoverad4c5db2017-07-24 17:06:23 +0000405 }
406
407 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000408}
409
Erich Keaneebba5922017-07-21 22:37:03 +0000410
Tim Northoverad4c5db2017-07-24 17:06:23 +0000411bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
412 DiagnosticsEngine &Diags) {
413 FPU = 0;
David Green54823152019-06-07 17:28:12 +0000414 MVE = 0;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000415 CRC = 0;
416 Crypto = 0;
417 DSP = 0;
418 Unaligned = 1;
George Burgess IV2c074bb2019-06-14 00:35:17 +0000419 SoftFloat = false;
420 // Note that SoftFloatABI is initialized in our constructor.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000421 HWDiv = 0;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000422 DotProd = 0;
Erich Keane1d1d4382019-01-25 17:27:57 +0000423 HasFloat16 = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000424
425 // This does not diagnose illegal cases like having both
Simon Tatham760df472019-05-28 16:13:20 +0000426 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
Tim Northoverad4c5db2017-07-24 17:06:23 +0000427 for (const auto &Feature : Features) {
428 if (Feature == "+soft-float") {
429 SoftFloat = true;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000430 } else if (Feature == "+vfp2sp" || Feature == "+vfp2d16sp" ||
431 Feature == "+vfp2" || Feature == "+vfp2d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000432 FPU |= VFP2FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000433 HW_FP |= HW_FP_SP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000434 if (Feature == "+vfp2" || Feature == "+vfp2d16")
435 HW_FP |= HW_FP_DP;
436 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
437 Feature == "+vfp3" || Feature == "+vfp3d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000438 FPU |= VFP3FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000439 HW_FP |= HW_FP_SP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000440 if (Feature == "+vfp3" || Feature == "+vfp3d16")
441 HW_FP |= HW_FP_DP;
442 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
443 Feature == "+vfp4" || Feature == "+vfp4d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000444 FPU |= VFP4FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000445 HW_FP |= HW_FP_SP | HW_FP_HP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000446 if (Feature == "+vfp4" || Feature == "+vfp4d16")
447 HW_FP |= HW_FP_DP;
448 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
449 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000450 FPU |= FPARMV8;
Simon Tatham760df472019-05-28 16:13:20 +0000451 HW_FP |= HW_FP_SP | HW_FP_HP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000452 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
453 HW_FP |= HW_FP_DP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000454 } else if (Feature == "+neon") {
455 FPU |= NeonFPU;
Simon Tatham760df472019-05-28 16:13:20 +0000456 HW_FP |= HW_FP_SP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000457 } else if (Feature == "+hwdiv") {
458 HWDiv |= HWDivThumb;
459 } else if (Feature == "+hwdiv-arm") {
460 HWDiv |= HWDivARM;
461 } else if (Feature == "+crc") {
462 CRC = 1;
463 } else if (Feature == "+crypto") {
464 Crypto = 1;
465 } else if (Feature == "+dsp") {
466 DSP = 1;
Simon Tatham760df472019-05-28 16:13:20 +0000467 } else if (Feature == "+fp64") {
468 HW_FP |= HW_FP_DP;
Javed Absar603a2ba2019-05-21 14:21:26 +0000469 } else if (Feature == "+8msecext") {
470 if (CPUProfile != "M" || ArchVersion != 8) {
471 Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
472 return false;
473 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000474 } else if (Feature == "+strict-align") {
475 Unaligned = 0;
476 } else if (Feature == "+fp16") {
477 HW_FP |= HW_FP_HP;
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000478 } else if (Feature == "+fullfp16") {
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000479 HasLegalHalfType = true;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000480 } else if (Feature == "+dotprod") {
481 DotProd = true;
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000482 } else if (Feature == "+mve") {
483 DSP = 1;
484 MVE |= MVE_INT;
485 } else if (Feature == "+mve.fp") {
486 DSP = 1;
487 HasLegalHalfType = true;
488 FPU |= FPARMV8;
489 MVE |= MVE_INT | MVE_FP;
490 HW_FP |= HW_FP_SP | HW_FP_HP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000491 }
492 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000493
494 switch (ArchVersion) {
495 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000496 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000497 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000498 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000499 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
500 else
501 LDREX = LDREX_W;
502 break;
503 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000504 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000505 LDREX = LDREX_W | LDREX_H | LDREX_B;
506 else
507 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
508 break;
509 case 8:
510 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
511 }
512
513 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
514 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
515 return false;
516 }
517
518 if (FPMath == FP_Neon)
519 Features.push_back("+neonfp");
520 else if (FPMath == FP_VFP)
521 Features.push_back("-neonfp");
522
Tim Northoverad4c5db2017-07-24 17:06:23 +0000523 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000524}
525
Erich Keaneebba5922017-07-21 22:37:03 +0000526bool ARMTargetInfo::hasFeature(StringRef Feature) const {
527 return llvm::StringSwitch<bool>(Feature)
528 .Case("arm", true)
529 .Case("aarch32", true)
530 .Case("softfloat", SoftFloat)
531 .Case("thumb", isThumb())
532 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
533 .Case("vfp", FPU && !SoftFloat)
534 .Case("hwdiv", HWDiv & HWDivThumb)
535 .Case("hwdiv-arm", HWDiv & HWDivARM)
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000536 .Case("mve", hasMVE())
Erich Keaneebba5922017-07-21 22:37:03 +0000537 .Default(false);
538}
539
Tim Northoverad4c5db2017-07-24 17:06:23 +0000540bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
541 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000542 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000543}
544
Erich Keane3ec17432018-02-08 23:14:15 +0000545void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
546 llvm::ARM::fillValidCPUArchList(Values);
547}
548
Tim Northoverad4c5db2017-07-24 17:06:23 +0000549bool ARMTargetInfo::setCPU(const std::string &Name) {
550 if (Name != "generic")
551 setArchInfo(llvm::ARM::parseCPUArch(Name));
552
Florian Hahnef5bbd62017-07-27 16:28:39 +0000553 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000554 return false;
555 setAtomic();
556 CPU = Name;
557 return true;
558}
559
560bool ARMTargetInfo::setFPMath(StringRef Name) {
561 if (Name == "neon") {
562 FPMath = FP_Neon;
563 return true;
564 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
565 Name == "vfp4") {
566 FPMath = FP_VFP;
567 return true;
568 }
569 return false;
570}
571
572void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
573 MacroBuilder &Builder) const {
574 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
575}
576
577void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
578 MacroBuilder &Builder) const {
579 // Also include the ARMv8.1-A defines
580 getTargetDefinesARMV81A(Opts, Builder);
581}
582
Erich Keaneebba5922017-07-21 22:37:03 +0000583void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
584 MacroBuilder &Builder) const {
585 // Target identification.
586 Builder.defineMacro("__arm");
587 Builder.defineMacro("__arm__");
588 // For bare-metal none-eabi.
589 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
590 (getTriple().getEnvironment() == llvm::Triple::EABI ||
591 getTriple().getEnvironment() == llvm::Triple::EABIHF))
592 Builder.defineMacro("__ELF__");
593
594 // Target properties.
595 Builder.defineMacro("__REGISTER_PREFIX__", "");
596
597 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
598 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
599 if (getTriple().isWatchABI())
600 Builder.defineMacro("__ARM_ARCH_7K__", "2");
601
602 if (!CPUAttr.empty())
603 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
604
605 // ACLE 6.4.1 ARM/Thumb instruction set architecture
606 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
607 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
608
609 if (ArchVersion >= 8) {
610 // ACLE 6.5.7 Crypto Extension
611 if (Crypto)
612 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
613 // ACLE 6.5.8 CRC32 Extension
614 if (CRC)
615 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
616 // ACLE 6.5.10 Numeric Maximum and Minimum
617 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
618 // ACLE 6.5.9 Directed Rounding
619 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
620 }
621
622 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
623 // is not defined for the M-profile.
624 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000625 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000626 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
627
628 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
629 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
630 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
631 // v7 and v8 architectures excluding v8-M Baseline.
632 if (supportsThumb2())
633 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
634 else if (supportsThumb())
635 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
636
637 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
638 // instruction set such as ARM or Thumb.
639 Builder.defineMacro("__ARM_32BIT_STATE", "1");
640
641 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
642
643 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
644 if (!CPUProfile.empty())
645 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
646
647 // ACLE 6.4.3 Unaligned access supported in hardware
648 if (Unaligned)
649 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
650
651 // ACLE 6.4.4 LDREX/STREX
652 if (LDREX)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000653 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
Erich Keaneebba5922017-07-21 22:37:03 +0000654
655 // ACLE 6.4.5 CLZ
656 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
657 ArchVersion > 6)
658 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
659
660 // ACLE 6.5.1 Hardware Floating Point
661 if (HW_FP)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000662 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
Erich Keaneebba5922017-07-21 22:37:03 +0000663
664 // ACLE predefines.
665 Builder.defineMacro("__ARM_ACLE", "200");
666
667 // FP16 support (we currently only support IEEE format).
668 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
669 Builder.defineMacro("__ARM_FP16_ARGS", "1");
670
671 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
672 if (ArchVersion >= 7 && (FPU & VFP4FPU))
673 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
674
675 // Subtarget options.
676
677 // FIXME: It's more complicated than this and we don't really support
678 // interworking.
679 // Windows on ARM does not "support" interworking
680 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
681 Builder.defineMacro("__THUMB_INTERWORK__");
682
683 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
684 // Embedded targets on Darwin follow AAPCS, but not EABI.
685 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
686 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
687 Builder.defineMacro("__ARM_EABI__");
688 Builder.defineMacro("__ARM_PCS", "1");
689 }
690
691 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
692 Builder.defineMacro("__ARM_PCS_VFP", "1");
693
694 if (SoftFloat)
695 Builder.defineMacro("__SOFTFP__");
696
Oliver Stannarde3c8ce82019-02-18 12:39:47 +0000697 // ACLE position independent code macros.
698 if (Opts.ROPI)
699 Builder.defineMacro("__ARM_ROPI", "1");
700 if (Opts.RWPI)
701 Builder.defineMacro("__ARM_RWPI", "1");
702
Florian Hahnef5bbd62017-07-27 16:28:39 +0000703 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000704 Builder.defineMacro("__XSCALE__");
705
706 if (isThumb()) {
707 Builder.defineMacro("__THUMBEL__");
708 Builder.defineMacro("__thumb__");
709 if (supportsThumb2())
710 Builder.defineMacro("__thumb2__");
711 }
712
713 // ACLE 6.4.9 32-bit SIMD instructions
Sam Parkerd476cd32018-09-28 10:18:02 +0000714 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
Erich Keaneebba5922017-07-21 22:37:03 +0000715 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
716
717 // ACLE 6.4.10 Hardware Integer Divide
718 if (((HWDiv & HWDivThumb) && isThumb()) ||
719 ((HWDiv & HWDivARM) && !isThumb())) {
720 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
721 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
722 }
723
724 // Note, this is always on in gcc, even though it doesn't make sense.
725 Builder.defineMacro("__APCS_32__");
726
727 if (FPUModeIsVFP((FPUMode)FPU)) {
728 Builder.defineMacro("__VFP_FP__");
729 if (FPU & VFP2FPU)
730 Builder.defineMacro("__ARM_VFPV2__");
731 if (FPU & VFP3FPU)
732 Builder.defineMacro("__ARM_VFPV3__");
733 if (FPU & VFP4FPU)
734 Builder.defineMacro("__ARM_VFPV4__");
735 if (FPU & FPARMV8)
736 Builder.defineMacro("__ARM_FPV5__");
737 }
738
739 // This only gets set when Neon instructions are actually available, unlike
740 // the VFP define, hence the soft float and arch check. This is subtly
741 // different from gcc, we follow the intent which was that it should be set
742 // when Neon instructions are actually available.
743 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
744 Builder.defineMacro("__ARM_NEON", "1");
745 Builder.defineMacro("__ARM_NEON__");
746 // current AArch32 NEON implementations do not support double-precision
747 // floating-point even when it is present in VFP.
748 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000749 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000750 }
751
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000752 if (hasMVE()) {
753 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
754 }
755
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000756 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000757 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000758
759 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
760
Javed Absar603a2ba2019-05-21 14:21:26 +0000761 // CMSE
762 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
763 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
764
Erich Keaneebba5922017-07-21 22:37:03 +0000765 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
766 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
767 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
768 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
769 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
770 }
771
772 // ACLE 6.4.7 DSP instructions
773 if (DSP) {
774 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
775 }
776
777 // ACLE 6.4.8 Saturation instructions
778 bool SAT = false;
779 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
780 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
781 SAT = true;
782 }
783
784 // ACLE 6.4.6 Q (saturation) flag
785 if (DSP || SAT)
786 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
787
788 if (Opts.UnsafeFPMath)
789 Builder.defineMacro("__ARM_FP_FAST", "1");
790
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000791 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000792 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000793 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
794
795 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000796 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000797 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
798
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000799 // Armv8.2-A dot product intrinsics
800 if (DotProd)
801 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000802
Erich Keaneebba5922017-07-21 22:37:03 +0000803 switch (ArchKind) {
804 default:
805 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000806 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000807 getTargetDefinesARMV81A(Opts, Builder);
808 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000809 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000810 getTargetDefinesARMV82A(Opts, Builder);
811 break;
812 }
813}
814
Tim Northoverad4c5db2017-07-24 17:06:23 +0000815const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
816#define BUILTIN(ID, TYPE, ATTRS) \
817 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
818#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
819 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
820#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000821
Tim Northoverad4c5db2017-07-24 17:06:23 +0000822#define BUILTIN(ID, TYPE, ATTRS) \
823 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
824#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
825 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
826#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
827 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
828#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
829 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
830#include "clang/Basic/BuiltinsARM.def"
831};
832
833ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
834 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
835 Builtin::FirstTSBuiltin);
836}
837
838bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
839TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
840 return IsAAPCS
841 ? AAPCSABIBuiltinVaList
842 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
843 : TargetInfo::VoidPtrBuiltinVaList);
844}
845
846const char *const ARMTargetInfo::GCCRegNames[] = {
847 // Integer registers
848 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
849 "r12", "sp", "lr", "pc",
850
851 // Float registers
852 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
853 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
854 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
855
856 // Double registers
857 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
858 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
859 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
860
861 // Quad registers
862 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
863 "q12", "q13", "q14", "q15"};
864
865ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
866 return llvm::makeArrayRef(GCCRegNames);
867}
868
869const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
870 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
871 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
872 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
873 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
874 // The S, D and Q registers overlap, but aren't really aliases; we
875 // don't want to substitute one of these for a different-sized one.
876};
877
878ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
879 return llvm::makeArrayRef(GCCRegAliases);
880}
881
882bool ARMTargetInfo::validateAsmConstraint(
883 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
884 switch (*Name) {
885 default:
886 break;
887 case 'l': // r0-r7
888 case 'h': // r8-r15
889 case 't': // VFP Floating point register single precision
890 case 'w': // VFP Floating point register double precision
891 Info.setAllowsRegister();
892 return true;
893 case 'I':
894 case 'J':
895 case 'K':
896 case 'L':
897 case 'M':
898 // FIXME
899 return true;
900 case 'Q': // A memory address that is a single base register.
901 Info.setAllowsMemory();
902 return true;
Simon Tathame8de8ba2019-06-25 16:49:32 +0000903 case 'T':
904 switch (Name[1]) {
905 default:
906 break;
907 case 'e': // Even general-purpose register
908 case 'o': // Odd general-purpose register
909 Info.setAllowsRegister();
910 Name++;
911 return true;
912 }
Yaxun Liud325eb32019-06-26 03:33:03 +0000913 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000914 case 'U': // a memory reference...
915 switch (Name[1]) {
916 case 'q': // ...ARMV4 ldrsb
917 case 'v': // ...VFP load/store (reg+constant offset)
918 case 'y': // ...iWMMXt load/store
919 case 't': // address valid for load/store opaque types wider
920 // than 128-bits
921 case 'n': // valid address for Neon doubleword vector load/store
922 case 'm': // valid address for Neon element and structure load/store
923 case 's': // valid address for non-offset loads/stores of quad-word
924 // values in four ARM registers
925 Info.setAllowsMemory();
926 Name++;
927 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000928 }
Yaxun Liud325eb32019-06-26 03:33:03 +0000929 break;
Erich Keaneebba5922017-07-21 22:37:03 +0000930 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000931 return false;
932}
Erich Keaneebba5922017-07-21 22:37:03 +0000933
Tim Northoverad4c5db2017-07-24 17:06:23 +0000934std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
935 std::string R;
936 switch (*Constraint) {
937 case 'U': // Two-character constraint; add "^" hint for later parsing.
Simon Tathame8de8ba2019-06-25 16:49:32 +0000938 case 'T':
Tim Northoverad4c5db2017-07-24 17:06:23 +0000939 R = std::string("^") + std::string(Constraint, 2);
940 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000941 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000942 case 'p': // 'p' should be translated to 'r' by default.
943 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000944 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000945 default:
946 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000947 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000948 return R;
949}
Erich Keaneebba5922017-07-21 22:37:03 +0000950
Tim Northoverad4c5db2017-07-24 17:06:23 +0000951bool ARMTargetInfo::validateConstraintModifier(
952 StringRef Constraint, char Modifier, unsigned Size,
953 std::string &SuggestedModifier) const {
954 bool isOutput = (Constraint[0] == '=');
955 bool isInOut = (Constraint[0] == '+');
956
957 // Strip off constraint modifiers.
958 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
959 Constraint = Constraint.substr(1);
960
961 switch (Constraint[0]) {
962 default:
963 break;
964 case 'r': {
965 switch (Modifier) {
966 default:
967 return (isInOut || isOutput || Size <= 64);
968 case 'q':
969 // A register of size 32 cannot fit a vector type.
970 return false;
971 }
Erich Keaneebba5922017-07-21 22:37:03 +0000972 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000973 }
Erich Keaneebba5922017-07-21 22:37:03 +0000974
975 return true;
976}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000977const char *ARMTargetInfo::getClobbers() const {
978 // FIXME: Is this really right?
979 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000980}
981
Tim Northoverad4c5db2017-07-24 17:06:23 +0000982TargetInfo::CallingConvCheckResult
983ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
984 switch (CC) {
985 case CC_AAPCS:
986 case CC_AAPCS_VFP:
987 case CC_Swift:
988 case CC_OpenCLKernel:
989 return CCCR_OK;
990 default:
991 return CCCR_Warning;
992 }
993}
994
995int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
996 if (RegNo == 0)
997 return 0;
998 if (RegNo == 1)
999 return 1;
1000 return -1;
1001}
1002
1003bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1004
1005ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1006 const TargetOptions &Opts)
1007 : ARMTargetInfo(Triple, Opts) {}
1008
Erich Keaneebba5922017-07-21 22:37:03 +00001009void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1010 MacroBuilder &Builder) const {
1011 Builder.defineMacro("__ARMEL__");
1012 ARMTargetInfo::getTargetDefines(Opts, Builder);
1013}
1014
Tim Northoverad4c5db2017-07-24 17:06:23 +00001015ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1016 const TargetOptions &Opts)
1017 : ARMTargetInfo(Triple, Opts) {}
1018
Erich Keaneebba5922017-07-21 22:37:03 +00001019void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1020 MacroBuilder &Builder) const {
1021 Builder.defineMacro("__ARMEB__");
1022 Builder.defineMacro("__ARM_BIG_ENDIAN");
1023 ARMTargetInfo::getTargetDefines(Opts, Builder);
1024}
1025
Tim Northoverad4c5db2017-07-24 17:06:23 +00001026WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1027 const TargetOptions &Opts)
1028 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +00001029}
1030
Erich Keaneebba5922017-07-21 22:37:03 +00001031void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1032 MacroBuilder &Builder) const {
1033 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
1034
1035 // FIXME: this is invalid for WindowsCE
1036 Builder.defineMacro("_M_ARM_NT", "1");
1037 Builder.defineMacro("_M_ARMT", "_M_ARM");
1038 Builder.defineMacro("_M_THUMB", "_M_ARM");
1039
1040 assert((Triple.getArch() == llvm::Triple::arm ||
1041 Triple.getArch() == llvm::Triple::thumb) &&
1042 "invalid architecture for Windows ARM target info");
1043 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1044 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1045
1046 // TODO map the complete set of values
1047 // 31: VFPv3 40: VFPv4
1048 Builder.defineMacro("_M_ARM_FP", "31");
1049}
1050
Tim Northoverad4c5db2017-07-24 17:06:23 +00001051TargetInfo::BuiltinVaListKind
1052WindowsARMTargetInfo::getBuiltinVaListKind() const {
1053 return TargetInfo::CharPtrBuiltinVaList;
1054}
1055
1056TargetInfo::CallingConvCheckResult
1057WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1058 switch (CC) {
1059 case CC_X86StdCall:
1060 case CC_X86ThisCall:
1061 case CC_X86FastCall:
1062 case CC_X86VectorCall:
1063 return CCCR_Ignore;
1064 case CC_C:
1065 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +00001066 case CC_PreserveMost:
1067 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +00001068 case CC_Swift:
Tim Northoverad4c5db2017-07-24 17:06:23 +00001069 return CCCR_OK;
1070 default:
1071 return CCCR_Warning;
1072 }
1073}
1074
1075// Windows ARM + Itanium C++ ABI Target
1076ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1077 const llvm::Triple &Triple, const TargetOptions &Opts)
1078 : WindowsARMTargetInfo(Triple, Opts) {
1079 TheCXXABI.set(TargetCXXABI::GenericARM);
1080}
1081
1082void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1083 const LangOptions &Opts, MacroBuilder &Builder) const {
1084 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1085
1086 if (Opts.MSVCCompat)
1087 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1088}
1089
1090// Windows ARM, MS (C++) ABI
1091MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1092 const TargetOptions &Opts)
1093 : WindowsARMTargetInfo(Triple, Opts) {
1094 TheCXXABI.set(TargetCXXABI::Microsoft);
1095}
1096
1097void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1098 MacroBuilder &Builder) const {
1099 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1100 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1101}
1102
1103MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1104 const TargetOptions &Opts)
1105 : WindowsARMTargetInfo(Triple, Opts) {
1106 TheCXXABI.set(TargetCXXABI::GenericARM);
1107}
1108
Erich Keaneebba5922017-07-21 22:37:03 +00001109void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1110 MacroBuilder &Builder) const {
1111 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001112 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001113}
1114
Tim Northoverad4c5db2017-07-24 17:06:23 +00001115CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1116 const TargetOptions &Opts)
1117 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001118 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001119 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001120 DoubleAlign = LongLongAlign = 64;
Michael Platings308e82e2019-03-08 10:44:06 +00001121 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 +00001122}
1123
Erich Keaneebba5922017-07-21 22:37:03 +00001124void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1125 MacroBuilder &Builder) const {
1126 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1127 Builder.defineMacro("_ARM_");
1128 Builder.defineMacro("__CYGWIN__");
1129 Builder.defineMacro("__CYGWIN32__");
1130 DefineStd(Builder, "unix", Opts);
1131 if (Opts.CPlusPlus)
1132 Builder.defineMacro("_GNU_SOURCE");
1133}
1134
Tim Northoverad4c5db2017-07-24 17:06:23 +00001135DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1136 const TargetOptions &Opts)
1137 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1138 HasAlignMac68kSupport = true;
1139 // iOS always has 64-bit atomic instructions.
1140 // FIXME: This should be based off of the target features in
1141 // ARMleTargetInfo.
1142 MaxAtomicInlineWidth = 64;
1143
1144 if (Triple.isWatchABI()) {
1145 // Darwin on iOS uses a variant of the ARM C++ ABI.
1146 TheCXXABI.set(TargetCXXABI::WatchOS);
1147
Tim Northoverad4c5db2017-07-24 17:06:23 +00001148 // BOOL should be a real boolean on the new ABI
1149 UseSignedCharForObjCBool = false;
1150 } else
1151 TheCXXABI.set(TargetCXXABI::iOS);
1152}
1153
1154void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1155 const llvm::Triple &Triple,
1156 MacroBuilder &Builder) const {
1157 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1158}
1159
1160RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1161 const TargetOptions &Opts)
1162 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1163 Triple.getOSName(),
1164 Triple.getEnvironmentName()),
1165 Opts) {
1166 IsRenderScriptTarget = true;
1167 LongWidth = LongAlign = 64;
1168}
1169
Erich Keaneebba5922017-07-21 22:37:03 +00001170void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1171 MacroBuilder &Builder) const {
1172 Builder.defineMacro("__RENDERSCRIPT__");
1173 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1174}