blob: d9028f8e4fa3baade46d5e0f73fe435413bff4c8 [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- ARM.cpp - Implement ARM target feature support -------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Erich Keaneebba5922017-07-21 22:37:03 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements ARM TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#include "ARM.h"
14#include "clang/Basic/Builtins.h"
15#include "clang/Basic/Diagnostic.h"
16#include "clang/Basic/TargetBuiltins.h"
17#include "llvm/ADT/StringExtras.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/StringSwitch.h"
20
21using namespace clang;
22using namespace clang::targets;
23
Tim Northoverad4c5db2017-07-24 17:06:23 +000024void ARMTargetInfo::setABIAAPCS() {
25 IsAAPCS = true;
26
27 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
28 const llvm::Triple &T = getTriple();
29
Michal Gorny5a409d02018-12-20 13:09:30 +000030 bool IsNetBSD = T.isOSNetBSD();
31 bool IsOpenBSD = T.isOSOpenBSD();
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000032 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +000033 WCharType = UnsignedInt;
Tim Northoverad4c5db2017-07-24 17:06:23 +000034
35 UseBitFieldTypeAlignment = true;
36
37 ZeroLengthBitfieldBoundary = 0;
38
39 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
40 // so set preferred for small types to 32.
41 if (T.isOSBinFormatMachO()) {
42 resetDataLayout(BigEndian
Michael Platings308e82e2019-03-08 10:44:06 +000043 ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
44 : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
Tim Northoverad4c5db2017-07-24 17:06:23 +000045 } else if (T.isOSWindows()) {
46 assert(!BigEndian && "Windows on ARM does not support big endian");
47 resetDataLayout("e"
48 "-m:w"
49 "-p:32:32"
Michael Platings308e82e2019-03-08 10:44:06 +000050 "-Fi8"
Tim Northoverad4c5db2017-07-24 17:06:23 +000051 "-i64:64"
52 "-v128:64:128"
53 "-a:0:32"
54 "-n32"
55 "-S64");
56 } else if (T.isOSNaCl()) {
57 assert(!BigEndian && "NaCl on ARM does not support big endian");
Michael Platings308e82e2019-03-08 10:44:06 +000058 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
Tim Northoverad4c5db2017-07-24 17:06:23 +000059 } else {
60 resetDataLayout(BigEndian
Michael Platings308e82e2019-03-08 10:44:06 +000061 ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
62 : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
Tim Northoverad4c5db2017-07-24 17:06:23 +000063 }
64
65 // FIXME: Enumerated types are variable width in straight AAPCS.
66}
67
68void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
69 const llvm::Triple &T = getTriple();
70
71 IsAAPCS = false;
72
73 if (IsAAPCS16)
74 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
75 else
76 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
77
Tim Northoverad4c5db2017-07-24 17:06:23 +000078 WCharType = SignedInt;
79
80 // Do not respect the alignment of bit-field types when laying out
81 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
82 UseBitFieldTypeAlignment = false;
83
84 /// gcc forces the alignment to 4 bytes, regardless of the type of the
85 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
86 /// gcc.
87 ZeroLengthBitfieldBoundary = 32;
88
89 if (T.isOSBinFormatMachO() && IsAAPCS16) {
90 assert(!BigEndian && "AAPCS16 does not support big-endian");
Michael Platings308e82e2019-03-08 10:44:06 +000091 resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128");
Tim Northoverad4c5db2017-07-24 17:06:23 +000092 } else if (T.isOSBinFormatMachO())
93 resetDataLayout(
94 BigEndian
Michael Platings308e82e2019-03-08 10:44:06 +000095 ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
96 : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
Tim Northoverad4c5db2017-07-24 17:06:23 +000097 else
98 resetDataLayout(
99 BigEndian
Michael Platings308e82e2019-03-08 10:44:06 +0000100 ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
101 : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000102
103 // FIXME: Override "preferred align" for double and long long.
104}
105
106void ARMTargetInfo::setArchInfo() {
107 StringRef ArchName = getTriple().getArchName();
108
109 ArchISA = llvm::ARM::parseArchISA(ArchName);
110 CPU = llvm::ARM::getDefaultCPU(ArchName);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000111 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
112 if (AK != llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000113 ArchKind = AK;
114 setArchInfo(ArchKind);
115}
116
Florian Hahnef5bbd62017-07-27 16:28:39 +0000117void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000118 StringRef SubArch;
119
120 // cache TargetParser info
121 ArchKind = Kind;
122 SubArch = llvm::ARM::getSubArch(ArchKind);
123 ArchProfile = llvm::ARM::parseArchProfile(SubArch);
124 ArchVersion = llvm::ARM::parseArchVersion(SubArch);
125
126 // cache CPU related strings
127 CPUAttr = getCPUAttr();
128 CPUProfile = getCPUProfile();
129}
130
131void ARMTargetInfo::setAtomic() {
132 // when triple does not specify a sub arch,
133 // then we are not using inline atomics
134 bool ShouldUseInlineAtomic =
Florian Hahnef5bbd62017-07-27 16:28:39 +0000135 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
136 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000137 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
Florian Hahnef5bbd62017-07-27 16:28:39 +0000138 if (ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000139 MaxAtomicPromoteWidth = 32;
140 if (ShouldUseInlineAtomic)
141 MaxAtomicInlineWidth = 32;
142 } else {
143 MaxAtomicPromoteWidth = 64;
144 if (ShouldUseInlineAtomic)
145 MaxAtomicInlineWidth = 64;
146 }
147}
148
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000149bool ARMTargetInfo::hasMVE() const {
150 return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;
151}
152
153bool ARMTargetInfo::hasMVEFloat() const {
154 return hasMVE() && (MVE & MVE_FP);
155}
156
Florian Hahnef5bbd62017-07-27 16:28:39 +0000157bool ARMTargetInfo::isThumb() const {
158 return ArchISA == llvm::ARM::ISAKind::THUMB;
159}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000160
161bool ARMTargetInfo::supportsThumb() const {
162 return CPUAttr.count('T') || ArchVersion >= 6;
163}
164
165bool ARMTargetInfo::supportsThumb2() const {
166 return CPUAttr.equals("6T2") ||
167 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
168}
169
170StringRef ARMTargetInfo::getCPUAttr() const {
171 // For most sub-arches, the build attribute CPU name is enough.
172 // For Cortex variants, it's slightly different.
173 switch (ArchKind) {
174 default:
175 return llvm::ARM::getCPUAttr(ArchKind);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000176 case llvm::ARM::ArchKind::ARMV6M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000177 return "6M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000178 case llvm::ARM::ArchKind::ARMV7S:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000179 return "7S";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000180 case llvm::ARM::ArchKind::ARMV7A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000181 return "7A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000182 case llvm::ARM::ArchKind::ARMV7R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000183 return "7R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000184 case llvm::ARM::ArchKind::ARMV7M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000185 return "7M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000186 case llvm::ARM::ArchKind::ARMV7EM:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000187 return "7EM";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000188 case llvm::ARM::ArchKind::ARMV7VE:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000189 return "7VE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000190 case llvm::ARM::ArchKind::ARMV8A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000191 return "8A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000192 case llvm::ARM::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000193 return "8_1A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000194 case llvm::ARM::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000195 return "8_2A";
Sjoerd Meijere6e4f312018-08-01 12:41:10 +0000196 case llvm::ARM::ArchKind::ARMV8_3A:
197 return "8_3A";
198 case llvm::ARM::ArchKind::ARMV8_4A:
199 return "8_4A";
Oliver Stannarda30b48d2018-09-26 14:20:29 +0000200 case llvm::ARM::ArchKind::ARMV8_5A:
201 return "8_5A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000202 case llvm::ARM::ArchKind::ARMV8MBaseline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000203 return "8M_BASE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000204 case llvm::ARM::ArchKind::ARMV8MMainline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000205 return "8M_MAIN";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000206 case llvm::ARM::ArchKind::ARMV8R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000207 return "8R";
Sjoerd Meijer24f12712019-05-30 14:22:26 +0000208 case llvm::ARM::ArchKind::ARMV8_1MMainline:
209 return "8_1M_MAIN";
Tim Northoverad4c5db2017-07-24 17:06:23 +0000210 }
211}
212
213StringRef ARMTargetInfo::getCPUProfile() const {
214 switch (ArchProfile) {
Florian Hahnef5bbd62017-07-27 16:28:39 +0000215 case llvm::ARM::ProfileKind::A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000216 return "A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000217 case llvm::ARM::ProfileKind::R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000218 return "R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000219 case llvm::ARM::ProfileKind::M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000220 return "M";
221 default:
222 return "";
223 }
224}
225
226ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
227 const TargetOptions &Opts)
228 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
229 HW_FP(0) {
Michal Gorny5a409d02018-12-20 13:09:30 +0000230 bool IsOpenBSD = Triple.isOSOpenBSD();
231 bool IsNetBSD = Triple.isOSNetBSD();
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000232
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000233 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
234 // environment where size_t is `unsigned long` rather than `unsigned int`
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000235
236 PtrDiffType = IntPtrType =
237 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
238 IsNetBSD)
239 ? SignedLong
240 : SignedInt;
241
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000242 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
243 IsNetBSD)
244 ? UnsignedLong
245 : UnsignedInt;
246
247 // ptrdiff_t is inconsistent on Darwin
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000248 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
249 !Triple.isWatchABI())
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000250 PtrDiffType = SignedInt;
251
Tim Northoverad4c5db2017-07-24 17:06:23 +0000252 // Cache arch related info.
253 setArchInfo();
254
255 // {} in inline assembly are neon specifiers, not assembly variant
256 // specifiers.
257 NoAsmVariants = true;
258
259 // FIXME: This duplicates code from the driver that sets the -target-abi
260 // option - this code is used if -target-abi isn't passed and should
261 // be unified in some way.
262 if (Triple.isOSBinFormatMachO()) {
263 // The backend is hardwired to assume AAPCS for M-class processors, ensure
264 // the frontend matches that.
265 if (Triple.getEnvironment() == llvm::Triple::EABI ||
266 Triple.getOS() == llvm::Triple::UnknownOS ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000267 ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000268 setABI("aapcs");
269 } else if (Triple.isWatchABI()) {
270 setABI("aapcs16");
271 } else {
272 setABI("apcs-gnu");
273 }
274 } else if (Triple.isOSWindows()) {
275 // FIXME: this is invalid for WindowsCE
276 setABI("aapcs");
277 } else {
278 // Select the default based on the platform.
279 switch (Triple.getEnvironment()) {
280 case llvm::Triple::Android:
281 case llvm::Triple::GNUEABI:
282 case llvm::Triple::GNUEABIHF:
283 case llvm::Triple::MuslEABI:
284 case llvm::Triple::MuslEABIHF:
285 setABI("aapcs-linux");
286 break;
287 case llvm::Triple::EABIHF:
288 case llvm::Triple::EABI:
289 setABI("aapcs");
290 break;
291 case llvm::Triple::GNU:
292 setABI("apcs-gnu");
293 break;
294 default:
Michal Gorny5a409d02018-12-20 13:09:30 +0000295 if (IsNetBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000296 setABI("apcs-gnu");
Michal Gorny5a409d02018-12-20 13:09:30 +0000297 else if (IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000298 setABI("aapcs-linux");
299 else
300 setABI("aapcs");
301 break;
302 }
303 }
304
305 // ARM targets default to using the ARM C++ ABI.
306 TheCXXABI.set(TargetCXXABI::GenericARM);
307
308 // ARM has atomics up to 8 bytes
309 setAtomic();
310
311 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
312 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
313 MaxVectorAlign = 64;
314
315 // Do force alignment of members that follow zero length bitfields. If
316 // the alignment of the zero-length bitfield is greater than the member
317 // that follows it, `bar', `bar' will be aligned as the type of the
318 // zero length bitfield.
319 UseZeroLengthBitfieldAlignment = true;
320
321 if (Triple.getOS() == llvm::Triple::Linux ||
322 Triple.getOS() == llvm::Triple::UnknownOS)
323 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
324 ? "\01__gnu_mcount_nc"
325 : "\01mcount";
326}
327
328StringRef ARMTargetInfo::getABI() const { return ABI; }
329
330bool ARMTargetInfo::setABI(const std::string &Name) {
331 ABI = Name;
332
333 // The defaults (above) are for AAPCS, check if we need to change them.
334 //
335 // FIXME: We need support for -meabi... we could just mangle it into the
336 // name.
337 if (Name == "apcs-gnu" || Name == "aapcs16") {
338 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000339 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000340 }
341 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
342 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000343 return true;
344 }
345 return false;
346}
347
Tim Northoverad4c5db2017-07-24 17:06:23 +0000348// FIXME: This should be based on Arch attributes, not CPU names.
349bool ARMTargetInfo::initFeatureMap(
350 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
351 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000352
Eli Friedman642a5ee2018-04-16 23:52:58 +0000353 std::string ArchFeature;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000354 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000355 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000356
Eli Friedman642a5ee2018-04-16 23:52:58 +0000357 // Map the base architecture to an appropriate target feature, so we don't
358 // rely on the target triple.
359 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
360 if (CPUArch == llvm::ARM::ArchKind::INVALID)
361 CPUArch = Arch;
362 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
363 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
364 TargetFeatures.push_back(ArchFeature);
365 }
366
Tim Northoverad4c5db2017-07-24 17:06:23 +0000367 // get default FPU features
368 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
369 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000370
Tim Northoverad4c5db2017-07-24 17:06:23 +0000371 // get default Extension features
372 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
373 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000374
Tim Northoverad4c5db2017-07-24 17:06:23 +0000375 for (auto Feature : TargetFeatures)
376 if (Feature[0] == '+')
377 Features[Feature.drop_front(1)] = true;
378
379 // Enable or disable thumb-mode explicitly per function to enable mixed
380 // ARM and Thumb code generation.
381 if (isThumb())
382 Features["thumb-mode"] = true;
383 else
384 Features["thumb-mode"] = false;
385
386 // Convert user-provided arm and thumb GNU target attributes to
387 // [-|+]thumb-mode target features respectively.
388 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
389 for (auto &Feature : UpdatedFeaturesVec) {
390 if (Feature.compare("+arm") == 0)
391 Feature = "-thumb-mode";
392 else if (Feature.compare("+thumb") == 0)
393 Feature = "+thumb-mode";
394 }
395
396 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000397}
398
Erich Keaneebba5922017-07-21 22:37:03 +0000399
Tim Northoverad4c5db2017-07-24 17:06:23 +0000400bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
401 DiagnosticsEngine &Diags) {
402 FPU = 0;
403 CRC = 0;
404 Crypto = 0;
405 DSP = 0;
406 Unaligned = 1;
407 SoftFloat = SoftFloatABI = false;
408 HWDiv = 0;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000409 DotProd = 0;
Erich Keane1d1d4382019-01-25 17:27:57 +0000410 HasFloat16 = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000411
412 // This does not diagnose illegal cases like having both
Simon Tatham760df472019-05-28 16:13:20 +0000413 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
Tim Northoverad4c5db2017-07-24 17:06:23 +0000414 for (const auto &Feature : Features) {
415 if (Feature == "+soft-float") {
416 SoftFloat = true;
417 } else if (Feature == "+soft-float-abi") {
418 SoftFloatABI = true;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000419 } else if (Feature == "+vfp2sp" || Feature == "+vfp2d16sp" ||
420 Feature == "+vfp2" || Feature == "+vfp2d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000421 FPU |= VFP2FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000422 HW_FP |= HW_FP_SP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000423 if (Feature == "+vfp2" || Feature == "+vfp2d16")
424 HW_FP |= HW_FP_DP;
425 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
426 Feature == "+vfp3" || Feature == "+vfp3d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000427 FPU |= VFP3FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000428 HW_FP |= HW_FP_SP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000429 if (Feature == "+vfp3" || Feature == "+vfp3d16")
430 HW_FP |= HW_FP_DP;
431 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
432 Feature == "+vfp4" || Feature == "+vfp4d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000433 FPU |= VFP4FPU;
Simon Tatham760df472019-05-28 16:13:20 +0000434 HW_FP |= HW_FP_SP | HW_FP_HP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000435 if (Feature == "+vfp4" || Feature == "+vfp4d16")
436 HW_FP |= HW_FP_DP;
437 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
438 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000439 FPU |= FPARMV8;
Simon Tatham760df472019-05-28 16:13:20 +0000440 HW_FP |= HW_FP_SP | HW_FP_HP;
Simon Tatham5d66f2b2019-06-07 12:42:54 +0000441 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
442 HW_FP |= HW_FP_DP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000443 } else if (Feature == "+neon") {
444 FPU |= NeonFPU;
Simon Tatham760df472019-05-28 16:13:20 +0000445 HW_FP |= HW_FP_SP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000446 } else if (Feature == "+hwdiv") {
447 HWDiv |= HWDivThumb;
448 } else if (Feature == "+hwdiv-arm") {
449 HWDiv |= HWDivARM;
450 } else if (Feature == "+crc") {
451 CRC = 1;
452 } else if (Feature == "+crypto") {
453 Crypto = 1;
454 } else if (Feature == "+dsp") {
455 DSP = 1;
Simon Tatham760df472019-05-28 16:13:20 +0000456 } else if (Feature == "+fp64") {
457 HW_FP |= HW_FP_DP;
Javed Absar603a2ba2019-05-21 14:21:26 +0000458 } else if (Feature == "+8msecext") {
459 if (CPUProfile != "M" || ArchVersion != 8) {
460 Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
461 return false;
462 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000463 } else if (Feature == "+strict-align") {
464 Unaligned = 0;
465 } else if (Feature == "+fp16") {
466 HW_FP |= HW_FP_HP;
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000467 } else if (Feature == "+fullfp16") {
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000468 HasLegalHalfType = true;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000469 } else if (Feature == "+dotprod") {
470 DotProd = true;
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000471 } else if (Feature == "+mve") {
472 DSP = 1;
473 MVE |= MVE_INT;
474 } else if (Feature == "+mve.fp") {
475 DSP = 1;
476 HasLegalHalfType = true;
477 FPU |= FPARMV8;
478 MVE |= MVE_INT | MVE_FP;
479 HW_FP |= HW_FP_SP | HW_FP_HP;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000480 }
481 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000482
483 switch (ArchVersion) {
484 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000485 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000486 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000487 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000488 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
489 else
490 LDREX = LDREX_W;
491 break;
492 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000493 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000494 LDREX = LDREX_W | LDREX_H | LDREX_B;
495 else
496 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
497 break;
498 case 8:
499 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
500 }
501
502 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
503 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
504 return false;
505 }
506
507 if (FPMath == FP_Neon)
508 Features.push_back("+neonfp");
509 else if (FPMath == FP_VFP)
510 Features.push_back("-neonfp");
511
512 // Remove front-end specific options which the backend handles differently.
Fangrui Song75e74e02019-03-31 08:48:19 +0000513 auto Feature = llvm::find(Features, "+soft-float-abi");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000514 if (Feature != Features.end())
515 Features.erase(Feature);
516
517 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000518}
519
Erich Keaneebba5922017-07-21 22:37:03 +0000520bool ARMTargetInfo::hasFeature(StringRef Feature) const {
521 return llvm::StringSwitch<bool>(Feature)
522 .Case("arm", true)
523 .Case("aarch32", true)
524 .Case("softfloat", SoftFloat)
525 .Case("thumb", isThumb())
526 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
527 .Case("vfp", FPU && !SoftFloat)
528 .Case("hwdiv", HWDiv & HWDivThumb)
529 .Case("hwdiv-arm", HWDiv & HWDivARM)
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000530 .Case("mve", hasMVE())
Erich Keaneebba5922017-07-21 22:37:03 +0000531 .Default(false);
532}
533
Tim Northoverad4c5db2017-07-24 17:06:23 +0000534bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
535 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000536 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000537}
538
Erich Keane3ec17432018-02-08 23:14:15 +0000539void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
540 llvm::ARM::fillValidCPUArchList(Values);
541}
542
Tim Northoverad4c5db2017-07-24 17:06:23 +0000543bool ARMTargetInfo::setCPU(const std::string &Name) {
544 if (Name != "generic")
545 setArchInfo(llvm::ARM::parseCPUArch(Name));
546
Florian Hahnef5bbd62017-07-27 16:28:39 +0000547 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000548 return false;
549 setAtomic();
550 CPU = Name;
551 return true;
552}
553
554bool ARMTargetInfo::setFPMath(StringRef Name) {
555 if (Name == "neon") {
556 FPMath = FP_Neon;
557 return true;
558 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
559 Name == "vfp4") {
560 FPMath = FP_VFP;
561 return true;
562 }
563 return false;
564}
565
566void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
567 MacroBuilder &Builder) const {
568 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
569}
570
571void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
572 MacroBuilder &Builder) const {
573 // Also include the ARMv8.1-A defines
574 getTargetDefinesARMV81A(Opts, Builder);
575}
576
Erich Keaneebba5922017-07-21 22:37:03 +0000577void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
578 MacroBuilder &Builder) const {
579 // Target identification.
580 Builder.defineMacro("__arm");
581 Builder.defineMacro("__arm__");
582 // For bare-metal none-eabi.
583 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
584 (getTriple().getEnvironment() == llvm::Triple::EABI ||
585 getTriple().getEnvironment() == llvm::Triple::EABIHF))
586 Builder.defineMacro("__ELF__");
587
588 // Target properties.
589 Builder.defineMacro("__REGISTER_PREFIX__", "");
590
591 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
592 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
593 if (getTriple().isWatchABI())
594 Builder.defineMacro("__ARM_ARCH_7K__", "2");
595
596 if (!CPUAttr.empty())
597 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
598
599 // ACLE 6.4.1 ARM/Thumb instruction set architecture
600 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
601 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
602
603 if (ArchVersion >= 8) {
604 // ACLE 6.5.7 Crypto Extension
605 if (Crypto)
606 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
607 // ACLE 6.5.8 CRC32 Extension
608 if (CRC)
609 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
610 // ACLE 6.5.10 Numeric Maximum and Minimum
611 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
612 // ACLE 6.5.9 Directed Rounding
613 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
614 }
615
616 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
617 // is not defined for the M-profile.
618 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000619 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000620 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
621
622 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
623 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
624 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
625 // v7 and v8 architectures excluding v8-M Baseline.
626 if (supportsThumb2())
627 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
628 else if (supportsThumb())
629 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
630
631 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
632 // instruction set such as ARM or Thumb.
633 Builder.defineMacro("__ARM_32BIT_STATE", "1");
634
635 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
636
637 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
638 if (!CPUProfile.empty())
639 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
640
641 // ACLE 6.4.3 Unaligned access supported in hardware
642 if (Unaligned)
643 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
644
645 // ACLE 6.4.4 LDREX/STREX
646 if (LDREX)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000647 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
Erich Keaneebba5922017-07-21 22:37:03 +0000648
649 // ACLE 6.4.5 CLZ
650 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
651 ArchVersion > 6)
652 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
653
654 // ACLE 6.5.1 Hardware Floating Point
655 if (HW_FP)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000656 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
Erich Keaneebba5922017-07-21 22:37:03 +0000657
658 // ACLE predefines.
659 Builder.defineMacro("__ARM_ACLE", "200");
660
661 // FP16 support (we currently only support IEEE format).
662 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
663 Builder.defineMacro("__ARM_FP16_ARGS", "1");
664
665 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
666 if (ArchVersion >= 7 && (FPU & VFP4FPU))
667 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
668
669 // Subtarget options.
670
671 // FIXME: It's more complicated than this and we don't really support
672 // interworking.
673 // Windows on ARM does not "support" interworking
674 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
675 Builder.defineMacro("__THUMB_INTERWORK__");
676
677 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
678 // Embedded targets on Darwin follow AAPCS, but not EABI.
679 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
680 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
681 Builder.defineMacro("__ARM_EABI__");
682 Builder.defineMacro("__ARM_PCS", "1");
683 }
684
685 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
686 Builder.defineMacro("__ARM_PCS_VFP", "1");
687
688 if (SoftFloat)
689 Builder.defineMacro("__SOFTFP__");
690
Oliver Stannarde3c8ce82019-02-18 12:39:47 +0000691 // ACLE position independent code macros.
692 if (Opts.ROPI)
693 Builder.defineMacro("__ARM_ROPI", "1");
694 if (Opts.RWPI)
695 Builder.defineMacro("__ARM_RWPI", "1");
696
Florian Hahnef5bbd62017-07-27 16:28:39 +0000697 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000698 Builder.defineMacro("__XSCALE__");
699
700 if (isThumb()) {
701 Builder.defineMacro("__THUMBEL__");
702 Builder.defineMacro("__thumb__");
703 if (supportsThumb2())
704 Builder.defineMacro("__thumb2__");
705 }
706
707 // ACLE 6.4.9 32-bit SIMD instructions
Sam Parkerd476cd32018-09-28 10:18:02 +0000708 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
Erich Keaneebba5922017-07-21 22:37:03 +0000709 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
710
711 // ACLE 6.4.10 Hardware Integer Divide
712 if (((HWDiv & HWDivThumb) && isThumb()) ||
713 ((HWDiv & HWDivARM) && !isThumb())) {
714 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
715 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
716 }
717
718 // Note, this is always on in gcc, even though it doesn't make sense.
719 Builder.defineMacro("__APCS_32__");
720
721 if (FPUModeIsVFP((FPUMode)FPU)) {
722 Builder.defineMacro("__VFP_FP__");
723 if (FPU & VFP2FPU)
724 Builder.defineMacro("__ARM_VFPV2__");
725 if (FPU & VFP3FPU)
726 Builder.defineMacro("__ARM_VFPV3__");
727 if (FPU & VFP4FPU)
728 Builder.defineMacro("__ARM_VFPV4__");
729 if (FPU & FPARMV8)
730 Builder.defineMacro("__ARM_FPV5__");
731 }
732
733 // This only gets set when Neon instructions are actually available, unlike
734 // the VFP define, hence the soft float and arch check. This is subtly
735 // different from gcc, we follow the intent which was that it should be set
736 // when Neon instructions are actually available.
737 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
738 Builder.defineMacro("__ARM_NEON", "1");
739 Builder.defineMacro("__ARM_NEON__");
740 // current AArch32 NEON implementations do not support double-precision
741 // floating-point even when it is present in VFP.
742 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000743 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000744 }
745
Sjoerd Meijer4ea248e2019-06-07 15:20:56 +0000746 if (hasMVE()) {
747 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
748 }
749
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000750 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000751 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000752
753 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
754
Javed Absar603a2ba2019-05-21 14:21:26 +0000755 // CMSE
756 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
757 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
758
Erich Keaneebba5922017-07-21 22:37:03 +0000759 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
760 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
761 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
762 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
763 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
764 }
765
766 // ACLE 6.4.7 DSP instructions
767 if (DSP) {
768 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
769 }
770
771 // ACLE 6.4.8 Saturation instructions
772 bool SAT = false;
773 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
774 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
775 SAT = true;
776 }
777
778 // ACLE 6.4.6 Q (saturation) flag
779 if (DSP || SAT)
780 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
781
782 if (Opts.UnsafeFPMath)
783 Builder.defineMacro("__ARM_FP_FAST", "1");
784
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000785 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000786 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000787 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
788
789 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000790 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000791 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
792
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000793 // Armv8.2-A dot product intrinsics
794 if (DotProd)
795 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000796
Erich Keaneebba5922017-07-21 22:37:03 +0000797 switch (ArchKind) {
798 default:
799 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000800 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000801 getTargetDefinesARMV81A(Opts, Builder);
802 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000803 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000804 getTargetDefinesARMV82A(Opts, Builder);
805 break;
806 }
807}
808
Tim Northoverad4c5db2017-07-24 17:06:23 +0000809const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
810#define BUILTIN(ID, TYPE, ATTRS) \
811 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
812#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
813 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
814#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000815
Tim Northoverad4c5db2017-07-24 17:06:23 +0000816#define BUILTIN(ID, TYPE, ATTRS) \
817 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
818#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
819 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
820#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
821 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
822#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
823 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
824#include "clang/Basic/BuiltinsARM.def"
825};
826
827ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
828 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
829 Builtin::FirstTSBuiltin);
830}
831
832bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
833TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
834 return IsAAPCS
835 ? AAPCSABIBuiltinVaList
836 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
837 : TargetInfo::VoidPtrBuiltinVaList);
838}
839
840const char *const ARMTargetInfo::GCCRegNames[] = {
841 // Integer registers
842 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
843 "r12", "sp", "lr", "pc",
844
845 // Float registers
846 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
847 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
848 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
849
850 // Double registers
851 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
852 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
853 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
854
855 // Quad registers
856 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
857 "q12", "q13", "q14", "q15"};
858
859ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
860 return llvm::makeArrayRef(GCCRegNames);
861}
862
863const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
864 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
865 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
866 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
867 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
868 // The S, D and Q registers overlap, but aren't really aliases; we
869 // don't want to substitute one of these for a different-sized one.
870};
871
872ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
873 return llvm::makeArrayRef(GCCRegAliases);
874}
875
876bool ARMTargetInfo::validateAsmConstraint(
877 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
878 switch (*Name) {
879 default:
880 break;
881 case 'l': // r0-r7
882 case 'h': // r8-r15
883 case 't': // VFP Floating point register single precision
884 case 'w': // VFP Floating point register double precision
885 Info.setAllowsRegister();
886 return true;
887 case 'I':
888 case 'J':
889 case 'K':
890 case 'L':
891 case 'M':
892 // FIXME
893 return true;
894 case 'Q': // A memory address that is a single base register.
895 Info.setAllowsMemory();
896 return true;
897 case 'U': // a memory reference...
898 switch (Name[1]) {
899 case 'q': // ...ARMV4 ldrsb
900 case 'v': // ...VFP load/store (reg+constant offset)
901 case 'y': // ...iWMMXt load/store
902 case 't': // address valid for load/store opaque types wider
903 // than 128-bits
904 case 'n': // valid address for Neon doubleword vector load/store
905 case 'm': // valid address for Neon element and structure load/store
906 case 's': // valid address for non-offset loads/stores of quad-word
907 // values in four ARM registers
908 Info.setAllowsMemory();
909 Name++;
910 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000911 }
912 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000913 return false;
914}
Erich Keaneebba5922017-07-21 22:37:03 +0000915
Tim Northoverad4c5db2017-07-24 17:06:23 +0000916std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
917 std::string R;
918 switch (*Constraint) {
919 case 'U': // Two-character constraint; add "^" hint for later parsing.
920 R = std::string("^") + std::string(Constraint, 2);
921 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000922 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000923 case 'p': // 'p' should be translated to 'r' by default.
924 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000925 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000926 default:
927 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000928 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000929 return R;
930}
Erich Keaneebba5922017-07-21 22:37:03 +0000931
Tim Northoverad4c5db2017-07-24 17:06:23 +0000932bool ARMTargetInfo::validateConstraintModifier(
933 StringRef Constraint, char Modifier, unsigned Size,
934 std::string &SuggestedModifier) const {
935 bool isOutput = (Constraint[0] == '=');
936 bool isInOut = (Constraint[0] == '+');
937
938 // Strip off constraint modifiers.
939 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
940 Constraint = Constraint.substr(1);
941
942 switch (Constraint[0]) {
943 default:
944 break;
945 case 'r': {
946 switch (Modifier) {
947 default:
948 return (isInOut || isOutput || Size <= 64);
949 case 'q':
950 // A register of size 32 cannot fit a vector type.
951 return false;
952 }
Erich Keaneebba5922017-07-21 22:37:03 +0000953 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000954 }
Erich Keaneebba5922017-07-21 22:37:03 +0000955
956 return true;
957}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000958const char *ARMTargetInfo::getClobbers() const {
959 // FIXME: Is this really right?
960 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000961}
962
Tim Northoverad4c5db2017-07-24 17:06:23 +0000963TargetInfo::CallingConvCheckResult
964ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
965 switch (CC) {
966 case CC_AAPCS:
967 case CC_AAPCS_VFP:
968 case CC_Swift:
969 case CC_OpenCLKernel:
970 return CCCR_OK;
971 default:
972 return CCCR_Warning;
973 }
974}
975
976int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
977 if (RegNo == 0)
978 return 0;
979 if (RegNo == 1)
980 return 1;
981 return -1;
982}
983
984bool ARMTargetInfo::hasSjLjLowering() const { return true; }
985
986ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
987 const TargetOptions &Opts)
988 : ARMTargetInfo(Triple, Opts) {}
989
Erich Keaneebba5922017-07-21 22:37:03 +0000990void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
991 MacroBuilder &Builder) const {
992 Builder.defineMacro("__ARMEL__");
993 ARMTargetInfo::getTargetDefines(Opts, Builder);
994}
995
Tim Northoverad4c5db2017-07-24 17:06:23 +0000996ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
997 const TargetOptions &Opts)
998 : ARMTargetInfo(Triple, Opts) {}
999
Erich Keaneebba5922017-07-21 22:37:03 +00001000void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1001 MacroBuilder &Builder) const {
1002 Builder.defineMacro("__ARMEB__");
1003 Builder.defineMacro("__ARM_BIG_ENDIAN");
1004 ARMTargetInfo::getTargetDefines(Opts, Builder);
1005}
1006
Tim Northoverad4c5db2017-07-24 17:06:23 +00001007WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1008 const TargetOptions &Opts)
1009 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +00001010}
1011
Erich Keaneebba5922017-07-21 22:37:03 +00001012void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1013 MacroBuilder &Builder) const {
1014 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
1015
1016 // FIXME: this is invalid for WindowsCE
1017 Builder.defineMacro("_M_ARM_NT", "1");
1018 Builder.defineMacro("_M_ARMT", "_M_ARM");
1019 Builder.defineMacro("_M_THUMB", "_M_ARM");
1020
1021 assert((Triple.getArch() == llvm::Triple::arm ||
1022 Triple.getArch() == llvm::Triple::thumb) &&
1023 "invalid architecture for Windows ARM target info");
1024 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1025 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1026
1027 // TODO map the complete set of values
1028 // 31: VFPv3 40: VFPv4
1029 Builder.defineMacro("_M_ARM_FP", "31");
1030}
1031
Tim Northoverad4c5db2017-07-24 17:06:23 +00001032TargetInfo::BuiltinVaListKind
1033WindowsARMTargetInfo::getBuiltinVaListKind() const {
1034 return TargetInfo::CharPtrBuiltinVaList;
1035}
1036
1037TargetInfo::CallingConvCheckResult
1038WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1039 switch (CC) {
1040 case CC_X86StdCall:
1041 case CC_X86ThisCall:
1042 case CC_X86FastCall:
1043 case CC_X86VectorCall:
1044 return CCCR_Ignore;
1045 case CC_C:
1046 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +00001047 case CC_PreserveMost:
1048 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +00001049 case CC_Swift:
Tim Northoverad4c5db2017-07-24 17:06:23 +00001050 return CCCR_OK;
1051 default:
1052 return CCCR_Warning;
1053 }
1054}
1055
1056// Windows ARM + Itanium C++ ABI Target
1057ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1058 const llvm::Triple &Triple, const TargetOptions &Opts)
1059 : WindowsARMTargetInfo(Triple, Opts) {
1060 TheCXXABI.set(TargetCXXABI::GenericARM);
1061}
1062
1063void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1064 const LangOptions &Opts, MacroBuilder &Builder) const {
1065 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1066
1067 if (Opts.MSVCCompat)
1068 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1069}
1070
1071// Windows ARM, MS (C++) ABI
1072MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1073 const TargetOptions &Opts)
1074 : WindowsARMTargetInfo(Triple, Opts) {
1075 TheCXXABI.set(TargetCXXABI::Microsoft);
1076}
1077
1078void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1079 MacroBuilder &Builder) const {
1080 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1081 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1082}
1083
1084MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1085 const TargetOptions &Opts)
1086 : WindowsARMTargetInfo(Triple, Opts) {
1087 TheCXXABI.set(TargetCXXABI::GenericARM);
1088}
1089
Erich Keaneebba5922017-07-21 22:37:03 +00001090void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1091 MacroBuilder &Builder) const {
1092 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001093 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001094}
1095
Tim Northoverad4c5db2017-07-24 17:06:23 +00001096CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1097 const TargetOptions &Opts)
1098 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001099 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001100 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001101 DoubleAlign = LongLongAlign = 64;
Michael Platings308e82e2019-03-08 10:44:06 +00001102 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 +00001103}
1104
Erich Keaneebba5922017-07-21 22:37:03 +00001105void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1106 MacroBuilder &Builder) const {
1107 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1108 Builder.defineMacro("_ARM_");
1109 Builder.defineMacro("__CYGWIN__");
1110 Builder.defineMacro("__CYGWIN32__");
1111 DefineStd(Builder, "unix", Opts);
1112 if (Opts.CPlusPlus)
1113 Builder.defineMacro("_GNU_SOURCE");
1114}
1115
Tim Northoverad4c5db2017-07-24 17:06:23 +00001116DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1117 const TargetOptions &Opts)
1118 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1119 HasAlignMac68kSupport = true;
1120 // iOS always has 64-bit atomic instructions.
1121 // FIXME: This should be based off of the target features in
1122 // ARMleTargetInfo.
1123 MaxAtomicInlineWidth = 64;
1124
1125 if (Triple.isWatchABI()) {
1126 // Darwin on iOS uses a variant of the ARM C++ ABI.
1127 TheCXXABI.set(TargetCXXABI::WatchOS);
1128
Tim Northoverad4c5db2017-07-24 17:06:23 +00001129 // BOOL should be a real boolean on the new ABI
1130 UseSignedCharForObjCBool = false;
1131 } else
1132 TheCXXABI.set(TargetCXXABI::iOS);
1133}
1134
1135void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1136 const llvm::Triple &Triple,
1137 MacroBuilder &Builder) const {
1138 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1139}
1140
1141RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1142 const TargetOptions &Opts)
1143 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1144 Triple.getOSName(),
1145 Triple.getEnvironmentName()),
1146 Opts) {
1147 IsRenderScriptTarget = true;
1148 LongWidth = LongAlign = 64;
1149}
1150
Erich Keaneebba5922017-07-21 22:37:03 +00001151void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1152 MacroBuilder &Builder) const {
1153 Builder.defineMacro("__RENDERSCRIPT__");
1154 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1155}