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