Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Basic/Targets/ARM.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- ARM.cpp - Implement ARM target feature support -------------------===//
2
//
3
// 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
6
//
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
#include "llvm/TargetParser/ARMTargetParser.h"
21
22
using namespace clang;
23
using namespace clang::targets;
24
25
0
void ARMTargetInfo::setABIAAPCS() {
26
0
  IsAAPCS = true;
27
28
0
  DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
29
0
  BFloat16Width = BFloat16Align = 16;
30
0
  BFloat16Format = &llvm::APFloat::BFloat();
31
32
0
  const llvm::Triple &T = getTriple();
33
34
0
  bool IsNetBSD = T.isOSNetBSD();
35
0
  bool IsOpenBSD = T.isOSOpenBSD();
36
0
  if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
37
0
    WCharType = UnsignedInt;
38
39
0
  UseBitFieldTypeAlignment = true;
40
41
0
  ZeroLengthBitfieldBoundary = 0;
42
43
  // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
44
  // so set preferred for small types to 32.
45
0
  if (T.isOSBinFormatMachO()) {
46
0
    resetDataLayout(BigEndian
47
0
                        ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
48
0
                        : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
49
0
                    "_");
50
0
  } else if (T.isOSWindows()) {
51
0
    assert(!BigEndian && "Windows on ARM does not support big endian");
52
0
    resetDataLayout("e"
53
0
                    "-m:w"
54
0
                    "-p:32:32"
55
0
                    "-Fi8"
56
0
                    "-i64:64"
57
0
                    "-v128:64:128"
58
0
                    "-a:0:32"
59
0
                    "-n32"
60
0
                    "-S64");
61
0
  } else if (T.isOSNaCl()) {
62
0
    assert(!BigEndian && "NaCl on ARM does not support big endian");
63
0
    resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
64
0
  } else {
65
0
    resetDataLayout(BigEndian
66
0
                        ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
67
0
                        : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
68
0
  }
69
70
  // FIXME: Enumerated types are variable width in straight AAPCS.
71
0
}
72
73
0
void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
74
0
  const llvm::Triple &T = getTriple();
75
76
0
  IsAAPCS = false;
77
78
0
  if (IsAAPCS16)
79
0
    DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
80
0
  else
81
0
    DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
82
0
  BFloat16Width = BFloat16Align = 16;
83
0
  BFloat16Format = &llvm::APFloat::BFloat();
84
85
0
  WCharType = SignedInt;
86
87
  // Do not respect the alignment of bit-field types when laying out
88
  // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
89
0
  UseBitFieldTypeAlignment = false;
90
91
  /// gcc forces the alignment to 4 bytes, regardless of the type of the
92
  /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
93
  /// gcc.
94
0
  ZeroLengthBitfieldBoundary = 32;
95
96
0
  if (T.isOSBinFormatMachO() && IsAAPCS16) {
97
0
    assert(!BigEndian && "AAPCS16 does not support big-endian");
98
0
    resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_");
99
0
  } else if (T.isOSBinFormatMachO())
100
0
    resetDataLayout(
101
0
        BigEndian
102
0
            ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
103
0
            : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32",
104
0
        "_");
105
0
  else
106
0
    resetDataLayout(
107
0
        BigEndian
108
0
            ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
109
0
            : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
110
111
  // FIXME: Override "preferred align" for double and long long.
112
0
}
113
114
0
void ARMTargetInfo::setArchInfo() {
115
0
  StringRef ArchName = getTriple().getArchName();
116
117
0
  ArchISA = llvm::ARM::parseArchISA(ArchName);
118
0
  CPU = std::string(llvm::ARM::getDefaultCPU(ArchName));
119
0
  llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
120
0
  if (AK != llvm::ARM::ArchKind::INVALID)
121
0
    ArchKind = AK;
122
0
  setArchInfo(ArchKind);
123
0
}
124
125
0
void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
126
0
  StringRef SubArch;
127
128
  // cache TargetParser info
129
0
  ArchKind = Kind;
130
0
  SubArch = llvm::ARM::getSubArch(ArchKind);
131
0
  ArchProfile = llvm::ARM::parseArchProfile(SubArch);
132
0
  ArchVersion = llvm::ARM::parseArchVersion(SubArch);
133
134
  // cache CPU related strings
135
0
  CPUAttr = getCPUAttr();
136
0
  CPUProfile = getCPUProfile();
137
0
}
138
139
0
void ARMTargetInfo::setAtomic() {
140
  // when triple does not specify a sub arch,
141
  // then we are not using inline atomics
142
0
  bool ShouldUseInlineAtomic =
143
0
      (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
144
0
      (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
145
  // Cortex M does not support 8 byte atomics, while general Thumb2 does.
146
0
  if (ArchProfile == llvm::ARM::ProfileKind::M) {
147
0
    MaxAtomicPromoteWidth = 32;
148
0
    if (ShouldUseInlineAtomic)
149
0
      MaxAtomicInlineWidth = 32;
150
0
  } else {
151
0
    MaxAtomicPromoteWidth = 64;
152
0
    if (ShouldUseInlineAtomic)
153
0
      MaxAtomicInlineWidth = 64;
154
0
  }
155
0
}
156
157
0
bool ARMTargetInfo::hasMVE() const {
158
0
  return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;
159
0
}
160
161
0
bool ARMTargetInfo::hasMVEFloat() const {
162
0
  return hasMVE() && (MVE & MVE_FP);
163
0
}
164
165
0
bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; }
166
167
0
bool ARMTargetInfo::isThumb() const {
168
0
  return ArchISA == llvm::ARM::ISAKind::THUMB;
169
0
}
170
171
0
bool ARMTargetInfo::supportsThumb() const {
172
0
  return CPUAttr.count('T') || ArchVersion >= 6;
173
0
}
174
175
0
bool ARMTargetInfo::supportsThumb2() const {
176
0
  return CPUAttr.equals("6T2") ||
177
0
         (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
178
0
}
179
180
0
StringRef ARMTargetInfo::getCPUAttr() const {
181
  // For most sub-arches, the build attribute CPU name is enough.
182
  // For Cortex variants, it's slightly different.
183
0
  switch (ArchKind) {
184
0
  default:
185
0
    return llvm::ARM::getCPUAttr(ArchKind);
186
0
  case llvm::ARM::ArchKind::ARMV6M:
187
0
    return "6M";
188
0
  case llvm::ARM::ArchKind::ARMV7S:
189
0
    return "7S";
190
0
  case llvm::ARM::ArchKind::ARMV7A:
191
0
    return "7A";
192
0
  case llvm::ARM::ArchKind::ARMV7R:
193
0
    return "7R";
194
0
  case llvm::ARM::ArchKind::ARMV7M:
195
0
    return "7M";
196
0
  case llvm::ARM::ArchKind::ARMV7EM:
197
0
    return "7EM";
198
0
  case llvm::ARM::ArchKind::ARMV7VE:
199
0
    return "7VE";
200
0
  case llvm::ARM::ArchKind::ARMV8A:
201
0
    return "8A";
202
0
  case llvm::ARM::ArchKind::ARMV8_1A:
203
0
    return "8_1A";
204
0
  case llvm::ARM::ArchKind::ARMV8_2A:
205
0
    return "8_2A";
206
0
  case llvm::ARM::ArchKind::ARMV8_3A:
207
0
    return "8_3A";
208
0
  case llvm::ARM::ArchKind::ARMV8_4A:
209
0
    return "8_4A";
210
0
  case llvm::ARM::ArchKind::ARMV8_5A:
211
0
    return "8_5A";
212
0
  case llvm::ARM::ArchKind::ARMV8_6A:
213
0
    return "8_6A";
214
0
  case llvm::ARM::ArchKind::ARMV8_7A:
215
0
    return "8_7A";
216
0
  case llvm::ARM::ArchKind::ARMV8_8A:
217
0
    return "8_8A";
218
0
  case llvm::ARM::ArchKind::ARMV8_9A:
219
0
    return "8_9A";
220
0
  case llvm::ARM::ArchKind::ARMV9A:
221
0
    return "9A";
222
0
  case llvm::ARM::ArchKind::ARMV9_1A:
223
0
    return "9_1A";
224
0
  case llvm::ARM::ArchKind::ARMV9_2A:
225
0
    return "9_2A";
226
0
  case llvm::ARM::ArchKind::ARMV9_3A:
227
0
    return "9_3A";
228
0
  case llvm::ARM::ArchKind::ARMV9_4A:
229
0
    return "9_4A";
230
0
  case llvm::ARM::ArchKind::ARMV8MBaseline:
231
0
    return "8M_BASE";
232
0
  case llvm::ARM::ArchKind::ARMV8MMainline:
233
0
    return "8M_MAIN";
234
0
  case llvm::ARM::ArchKind::ARMV8R:
235
0
    return "8R";
236
0
  case llvm::ARM::ArchKind::ARMV8_1MMainline:
237
0
    return "8_1M_MAIN";
238
0
  }
239
0
}
240
241
0
StringRef ARMTargetInfo::getCPUProfile() const {
242
0
  switch (ArchProfile) {
243
0
  case llvm::ARM::ProfileKind::A:
244
0
    return "A";
245
0
  case llvm::ARM::ProfileKind::R:
246
0
    return "R";
247
0
  case llvm::ARM::ProfileKind::M:
248
0
    return "M";
249
0
  default:
250
0
    return "";
251
0
  }
252
0
}
253
254
ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
255
                             const TargetOptions &Opts)
256
    : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
257
0
      HW_FP(0) {
258
0
  bool IsFreeBSD = Triple.isOSFreeBSD();
259
0
  bool IsOpenBSD = Triple.isOSOpenBSD();
260
0
  bool IsNetBSD = Triple.isOSNetBSD();
261
0
  bool IsHaiku = Triple.isOSHaiku();
262
0
  bool IsOHOS = Triple.isOHOSFamily();
263
264
  // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
265
  // environment where size_t is `unsigned long` rather than `unsigned int`
266
267
0
  PtrDiffType = IntPtrType =
268
0
      (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
269
0
       IsNetBSD)
270
0
          ? SignedLong
271
0
          : SignedInt;
272
273
0
  SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
274
0
              IsNetBSD)
275
0
                 ? UnsignedLong
276
0
                 : UnsignedInt;
277
278
  // ptrdiff_t is inconsistent on Darwin
279
0
  if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
280
0
      !Triple.isWatchABI())
281
0
    PtrDiffType = SignedInt;
282
283
  // Cache arch related info.
284
0
  setArchInfo();
285
286
  // {} in inline assembly are neon specifiers, not assembly variant
287
  // specifiers.
288
0
  NoAsmVariants = true;
289
290
  // FIXME: This duplicates code from the driver that sets the -target-abi
291
  // option - this code is used if -target-abi isn't passed and should
292
  // be unified in some way.
293
0
  if (Triple.isOSBinFormatMachO()) {
294
    // The backend is hardwired to assume AAPCS for M-class processors, ensure
295
    // the frontend matches that.
296
0
    if (Triple.getEnvironment() == llvm::Triple::EABI ||
297
0
        Triple.getOS() == llvm::Triple::UnknownOS ||
298
0
        ArchProfile == llvm::ARM::ProfileKind::M) {
299
0
      setABI("aapcs");
300
0
    } else if (Triple.isWatchABI()) {
301
0
      setABI("aapcs16");
302
0
    } else {
303
0
      setABI("apcs-gnu");
304
0
    }
305
0
  } else if (Triple.isOSWindows()) {
306
    // FIXME: this is invalid for WindowsCE
307
0
    setABI("aapcs");
308
0
  } else {
309
    // Select the default based on the platform.
310
0
    switch (Triple.getEnvironment()) {
311
0
    case llvm::Triple::Android:
312
0
    case llvm::Triple::GNUEABI:
313
0
    case llvm::Triple::GNUEABIHF:
314
0
    case llvm::Triple::MuslEABI:
315
0
    case llvm::Triple::MuslEABIHF:
316
0
    case llvm::Triple::OpenHOS:
317
0
      setABI("aapcs-linux");
318
0
      break;
319
0
    case llvm::Triple::EABIHF:
320
0
    case llvm::Triple::EABI:
321
0
      setABI("aapcs");
322
0
      break;
323
0
    case llvm::Triple::GNU:
324
0
      setABI("apcs-gnu");
325
0
      break;
326
0
    default:
327
0
      if (IsNetBSD)
328
0
        setABI("apcs-gnu");
329
0
      else if (IsFreeBSD || IsOpenBSD || IsHaiku || IsOHOS)
330
0
        setABI("aapcs-linux");
331
0
      else
332
0
        setABI("aapcs");
333
0
      break;
334
0
    }
335
0
  }
336
337
  // ARM targets default to using the ARM C++ ABI.
338
0
  TheCXXABI.set(TargetCXXABI::GenericARM);
339
340
  // ARM has atomics up to 8 bytes
341
0
  setAtomic();
342
343
  // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
344
  // as well the default alignment
345
0
  if (IsAAPCS && !Triple.isAndroid())
346
0
    DefaultAlignForAttributeAligned = MaxVectorAlign = 64;
347
348
  // Do force alignment of members that follow zero length bitfields.  If
349
  // the alignment of the zero-length bitfield is greater than the member
350
  // that follows it, `bar', `bar' will be aligned as the  type of the
351
  // zero length bitfield.
352
0
  UseZeroLengthBitfieldAlignment = true;
353
354
0
  if (Triple.getOS() == llvm::Triple::Linux ||
355
0
      Triple.getOS() == llvm::Triple::UnknownOS)
356
0
    this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
357
0
                           ? "llvm.arm.gnu.eabi.mcount"
358
0
                           : "\01mcount";
359
360
0
  SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
361
0
}
362
363
0
StringRef ARMTargetInfo::getABI() const { return ABI; }
364
365
0
bool ARMTargetInfo::setABI(const std::string &Name) {
366
0
  ABI = Name;
367
368
  // The defaults (above) are for AAPCS, check if we need to change them.
369
  //
370
  // FIXME: We need support for -meabi... we could just mangle it into the
371
  // name.
372
0
  if (Name == "apcs-gnu" || Name == "aapcs16") {
373
0
    setABIAPCS(Name == "aapcs16");
374
0
    return true;
375
0
  }
376
0
  if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
377
0
    setABIAAPCS();
378
0
    return true;
379
0
  }
380
0
  return false;
381
0
}
382
383
0
bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {
384
0
  llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);
385
0
  if (CPUArch == llvm::ARM::ArchKind::INVALID)
386
0
    CPUArch = llvm::ARM::parseArch(getTriple().getArchName());
387
388
0
  if (CPUArch == llvm::ARM::ArchKind::INVALID)
389
0
    return false;
390
391
0
  StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
392
0
  auto a =
393
0
      llvm::Triple(ArchFeature, getTriple().getVendorName(),
394
0
                   getTriple().getOSName(), getTriple().getEnvironmentName());
395
396
0
  StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
397
0
  llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
398
0
  return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
399
0
}
400
401
bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
402
                                             BranchProtectionInfo &BPI,
403
0
                                             StringRef &Err) const {
404
0
  llvm::ARM::ParsedBranchProtection PBP;
405
0
  if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
406
0
    return false;
407
408
0
  if (!isBranchProtectionSupportedArch(Arch))
409
0
    return false;
410
411
0
  BPI.SignReturnAddr =
412
0
      llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
413
0
          .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
414
0
          .Case("all", LangOptions::SignReturnAddressScopeKind::All)
415
0
          .Default(LangOptions::SignReturnAddressScopeKind::None);
416
417
  // Don't care for the sign key, beyond issuing a warning.
418
0
  if (PBP.Key == "b_key")
419
0
    Err = "b-key";
420
0
  BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
421
422
0
  BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
423
0
  BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
424
0
  return true;
425
0
}
426
427
// FIXME: This should be based on Arch attributes, not CPU names.
428
bool ARMTargetInfo::initFeatureMap(
429
    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
430
0
    const std::vector<std::string> &FeaturesVec) const {
431
432
0
  std::string ArchFeature;
433
0
  std::vector<StringRef> TargetFeatures;
434
0
  llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
435
436
  // Map the base architecture to an appropriate target feature, so we don't
437
  // rely on the target triple.
438
0
  llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
439
0
  if (CPUArch == llvm::ARM::ArchKind::INVALID)
440
0
    CPUArch = Arch;
441
0
  if (CPUArch != llvm::ARM::ArchKind::INVALID) {
442
0
    ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
443
0
    TargetFeatures.push_back(ArchFeature);
444
445
    // These features are added to allow arm_neon.h target(..) attributes to
446
    // match with both arm and aarch64. We need to add all previous architecture
447
    // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
448
    // v8.x counterparts are added too. We only need these for anything > 8.0-A.
449
0
    for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch);
450
0
         I != llvm::ARM::ArchKind::INVALID; --I)
451
0
      Features[llvm::ARM::getSubArch(I)] = true;
452
0
    if (CPUArch > llvm::ARM::ArchKind::ARMV8A &&
453
0
        CPUArch <= llvm::ARM::ArchKind::ARMV9_3A)
454
0
      for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID;
455
0
           --I)
456
0
        Features[llvm::ARM::getSubArch(I)] = true;
457
0
  }
458
459
  // get default FPU features
460
0
  llvm::ARM::FPUKind FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
461
0
  llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
462
463
  // get default Extension features
464
0
  uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
465
0
  llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
466
467
0
  for (auto Feature : TargetFeatures)
468
0
    if (Feature[0] == '+')
469
0
      Features[Feature.drop_front(1)] = true;
470
471
  // Enable or disable thumb-mode explicitly per function to enable mixed
472
  // ARM and Thumb code generation.
473
0
  if (isThumb())
474
0
    Features["thumb-mode"] = true;
475
0
  else
476
0
    Features["thumb-mode"] = false;
477
478
  // Convert user-provided arm and thumb GNU target attributes to
479
  // [-|+]thumb-mode target features respectively.
480
0
  std::vector<std::string> UpdatedFeaturesVec;
481
0
  for (const auto &Feature : FeaturesVec) {
482
    // Skip soft-float-abi; it's something we only use to initialize a bit of
483
    // class state, and is otherwise unrecognized.
484
0
    if (Feature == "+soft-float-abi")
485
0
      continue;
486
487
0
    StringRef FixedFeature;
488
0
    if (Feature == "+arm")
489
0
      FixedFeature = "-thumb-mode";
490
0
    else if (Feature == "+thumb")
491
0
      FixedFeature = "+thumb-mode";
492
0
    else
493
0
      FixedFeature = Feature;
494
0
    UpdatedFeaturesVec.push_back(FixedFeature.str());
495
0
  }
496
497
0
  return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
498
0
}
499
500
501
bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
502
0
                                         DiagnosticsEngine &Diags) {
503
0
  FPU = 0;
504
0
  MVE = 0;
505
0
  CRC = 0;
506
0
  Crypto = 0;
507
0
  SHA2 = 0;
508
0
  AES = 0;
509
0
  DSP = 0;
510
0
  Unaligned = 1;
511
0
  SoftFloat = false;
512
  // Note that SoftFloatABI is initialized in our constructor.
513
0
  HWDiv = 0;
514
0
  DotProd = 0;
515
0
  HasMatMul = 0;
516
0
  HasPAC = 0;
517
0
  HasBTI = 0;
518
0
  HasFloat16 = true;
519
0
  ARMCDECoprocMask = 0;
520
0
  HasBFloat16 = false;
521
0
  HasFullBFloat16 = false;
522
0
  FPRegsDisabled = false;
523
524
  // This does not diagnose illegal cases like having both
525
  // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
526
0
  for (const auto &Feature : Features) {
527
0
    if (Feature == "+soft-float") {
528
0
      SoftFloat = true;
529
0
    } else if (Feature == "+vfp2sp" || Feature == "+vfp2") {
530
0
      FPU |= VFP2FPU;
531
0
      HW_FP |= HW_FP_SP;
532
0
      if (Feature == "+vfp2")
533
0
          HW_FP |= HW_FP_DP;
534
0
    } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
535
0
               Feature == "+vfp3" || Feature == "+vfp3d16") {
536
0
      FPU |= VFP3FPU;
537
0
      HW_FP |= HW_FP_SP;
538
0
      if (Feature == "+vfp3" || Feature == "+vfp3d16")
539
0
          HW_FP |= HW_FP_DP;
540
0
    } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
541
0
               Feature == "+vfp4" || Feature == "+vfp4d16") {
542
0
      FPU |= VFP4FPU;
543
0
      HW_FP |= HW_FP_SP | HW_FP_HP;
544
0
      if (Feature == "+vfp4" || Feature == "+vfp4d16")
545
0
          HW_FP |= HW_FP_DP;
546
0
    } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
547
0
               Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
548
0
      FPU |= FPARMV8;
549
0
      HW_FP |= HW_FP_SP | HW_FP_HP;
550
0
      if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
551
0
          HW_FP |= HW_FP_DP;
552
0
    } else if (Feature == "+neon") {
553
0
      FPU |= NeonFPU;
554
0
      HW_FP |= HW_FP_SP;
555
0
    } else if (Feature == "+hwdiv") {
556
0
      HWDiv |= HWDivThumb;
557
0
    } else if (Feature == "+hwdiv-arm") {
558
0
      HWDiv |= HWDivARM;
559
0
    } else if (Feature == "+crc") {
560
0
      CRC = 1;
561
0
    } else if (Feature == "+crypto") {
562
0
      Crypto = 1;
563
0
    } else if (Feature == "+sha2") {
564
0
      SHA2 = 1;
565
0
    } else if (Feature == "+aes") {
566
0
      AES = 1;
567
0
    } else if (Feature == "+dsp") {
568
0
      DSP = 1;
569
0
    } else if (Feature == "+fp64") {
570
0
      HW_FP |= HW_FP_DP;
571
0
    } else if (Feature == "+8msecext") {
572
0
      if (CPUProfile != "M" || ArchVersion != 8) {
573
0
        Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
574
0
        return false;
575
0
      }
576
0
    } else if (Feature == "+strict-align") {
577
0
      Unaligned = 0;
578
0
    } else if (Feature == "+fp16") {
579
0
      HW_FP |= HW_FP_HP;
580
0
    } else if (Feature == "+fullfp16") {
581
0
      HasLegalHalfType = true;
582
0
    } else if (Feature == "+dotprod") {
583
0
      DotProd = true;
584
0
    } else if (Feature == "+mve") {
585
0
      MVE |= MVE_INT;
586
0
    } else if (Feature == "+mve.fp") {
587
0
      HasLegalHalfType = true;
588
0
      FPU |= FPARMV8;
589
0
      MVE |= MVE_INT | MVE_FP;
590
0
      HW_FP |= HW_FP_SP | HW_FP_HP;
591
0
    } else if (Feature == "+i8mm") {
592
0
      HasMatMul = 1;
593
0
    } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" &&
594
0
               Feature <= "+cdecp7") {
595
0
      unsigned Coproc = Feature.back() - '0';
596
0
      ARMCDECoprocMask |= (1U << Coproc);
597
0
    } else if (Feature == "+bf16") {
598
0
      HasBFloat16 = true;
599
0
    } else if (Feature == "-fpregs") {
600
0
      FPRegsDisabled = true;
601
0
    } else if (Feature == "+pacbti") {
602
0
      HasPAC = 1;
603
0
      HasBTI = 1;
604
0
    } else if (Feature == "+fullbf16") {
605
0
      HasFullBFloat16 = true;
606
0
    }
607
0
  }
608
609
0
  HalfArgsAndReturns = true;
610
611
0
  switch (ArchVersion) {
612
0
  case 6:
613
0
    if (ArchProfile == llvm::ARM::ProfileKind::M)
614
0
      LDREX = 0;
615
0
    else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
616
0
      LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
617
0
    else
618
0
      LDREX = LDREX_W;
619
0
    break;
620
0
  case 7:
621
0
    if (ArchProfile == llvm::ARM::ProfileKind::M)
622
0
      LDREX = LDREX_W | LDREX_H | LDREX_B;
623
0
    else
624
0
      LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
625
0
    break;
626
0
  case 8:
627
0
  case 9:
628
0
    LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
629
0
  }
630
631
0
  if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
632
0
    Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
633
0
    return false;
634
0
  }
635
636
0
  if (FPMath == FP_Neon)
637
0
    Features.push_back("+neonfp");
638
0
  else if (FPMath == FP_VFP)
639
0
    Features.push_back("-neonfp");
640
641
0
  return true;
642
0
}
643
644
0
bool ARMTargetInfo::hasFeature(StringRef Feature) const {
645
0
  return llvm::StringSwitch<bool>(Feature)
646
0
      .Case("arm", true)
647
0
      .Case("aarch32", true)
648
0
      .Case("softfloat", SoftFloat)
649
0
      .Case("thumb", isThumb())
650
0
      .Case("neon", (FPU & NeonFPU) && !SoftFloat)
651
0
      .Case("vfp", FPU && !SoftFloat)
652
0
      .Case("hwdiv", HWDiv & HWDivThumb)
653
0
      .Case("hwdiv-arm", HWDiv & HWDivARM)
654
0
      .Case("mve", hasMVE())
655
0
      .Default(false);
656
0
}
657
658
0
bool ARMTargetInfo::hasBFloat16Type() const {
659
  // The __bf16 type is generally available so long as we have any fp registers.
660
0
  return HasBFloat16 || (FPU && !SoftFloat);
661
0
}
662
663
0
bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
664
0
  return Name == "generic" ||
665
0
         llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
666
0
}
667
668
0
void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
669
0
  llvm::ARM::fillValidCPUArchList(Values);
670
0
}
671
672
0
bool ARMTargetInfo::setCPU(const std::string &Name) {
673
0
  if (Name != "generic")
674
0
    setArchInfo(llvm::ARM::parseCPUArch(Name));
675
676
0
  if (ArchKind == llvm::ARM::ArchKind::INVALID)
677
0
    return false;
678
0
  setAtomic();
679
0
  CPU = Name;
680
0
  return true;
681
0
}
682
683
0
bool ARMTargetInfo::setFPMath(StringRef Name) {
684
0
  if (Name == "neon") {
685
0
    FPMath = FP_Neon;
686
0
    return true;
687
0
  } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
688
0
             Name == "vfp4") {
689
0
    FPMath = FP_VFP;
690
0
    return true;
691
0
  }
692
0
  return false;
693
0
}
694
695
void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
696
0
                                            MacroBuilder &Builder) const {
697
0
  Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
698
0
}
699
700
void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
701
0
                                            MacroBuilder &Builder) const {
702
  // Also include the ARMv8.1-A defines
703
0
  getTargetDefinesARMV81A(Opts, Builder);
704
0
}
705
706
void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
707
0
                                            MacroBuilder &Builder) const {
708
  // Also include the ARMv8.2-A defines
709
0
  Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
710
0
  getTargetDefinesARMV82A(Opts, Builder);
711
0
}
712
713
void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
714
0
                                     MacroBuilder &Builder) const {
715
  // Target identification.
716
0
  Builder.defineMacro("__arm");
717
0
  Builder.defineMacro("__arm__");
718
  // For bare-metal none-eabi.
719
0
  if (getTriple().getOS() == llvm::Triple::UnknownOS &&
720
0
      (getTriple().getEnvironment() == llvm::Triple::EABI ||
721
0
       getTriple().getEnvironment() == llvm::Triple::EABIHF) &&
722
0
      Opts.CPlusPlus) {
723
0
    Builder.defineMacro("_GNU_SOURCE");
724
0
  }
725
726
  // Target properties.
727
0
  Builder.defineMacro("__REGISTER_PREFIX__", "");
728
729
  // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
730
  // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
731
0
  if (getTriple().isWatchABI())
732
0
    Builder.defineMacro("__ARM_ARCH_7K__", "2");
733
734
0
  if (!CPUAttr.empty())
735
0
    Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
736
737
  // ACLE 6.4.1 ARM/Thumb instruction set architecture
738
  // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
739
0
  Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
740
741
0
  if (ArchVersion >= 8) {
742
    // ACLE 6.5.7 Crypto Extension
743
    // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
744
    // feature macros for AES and SHA2
745
0
    if (SHA2 && AES)
746
0
      Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
747
0
    if (SHA2)
748
0
      Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
749
0
    if (AES)
750
0
      Builder.defineMacro("__ARM_FEATURE_AES", "1");
751
    // ACLE 6.5.8 CRC32 Extension
752
0
    if (CRC)
753
0
      Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
754
    // ACLE 6.5.10 Numeric Maximum and Minimum
755
0
    Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
756
    // ACLE 6.5.9 Directed Rounding
757
0
    Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
758
0
  }
759
760
  // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
761
  // is not defined for the M-profile.
762
  // NOTE that the default profile is assumed to be 'A'
763
0
  if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
764
0
    Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
765
766
  // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
767
  // Thumb ISA (including v6-M and v8-M Baseline).  It is set to 2 if the
768
  // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
769
  // v7 and v8 architectures excluding v8-M Baseline.
770
0
  if (supportsThumb2())
771
0
    Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
772
0
  else if (supportsThumb())
773
0
    Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
774
775
  // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
776
  // instruction set such as ARM or Thumb.
777
0
  Builder.defineMacro("__ARM_32BIT_STATE", "1");
778
779
  // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
780
781
  // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
782
0
  if (!CPUProfile.empty())
783
0
    Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
784
785
  // ACLE 6.4.3 Unaligned access supported in hardware
786
0
  if (Unaligned)
787
0
    Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
788
789
  // ACLE 6.4.4 LDREX/STREX
790
0
  if (LDREX)
791
0
    Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
792
793
  // ACLE 6.4.5 CLZ
794
0
  if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
795
0
      ArchVersion > 6)
796
0
    Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
797
798
  // ACLE 6.5.1 Hardware Floating Point
799
0
  if (HW_FP)
800
0
    Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
801
802
  // ACLE predefines.
803
0
  Builder.defineMacro("__ARM_ACLE", "200");
804
805
  // FP16 support (we currently only support IEEE format).
806
0
  Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
807
0
  Builder.defineMacro("__ARM_FP16_ARGS", "1");
808
809
  // ACLE 6.5.3 Fused multiply-accumulate (FMA)
810
0
  if (ArchVersion >= 7 && (FPU & VFP4FPU))
811
0
    Builder.defineMacro("__ARM_FEATURE_FMA", "1");
812
813
  // Subtarget options.
814
815
  // FIXME: It's more complicated than this and we don't really support
816
  // interworking.
817
  // Windows on ARM does not "support" interworking
818
0
  if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
819
0
    Builder.defineMacro("__THUMB_INTERWORK__");
820
821
0
  if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
822
    // Embedded targets on Darwin follow AAPCS, but not EABI.
823
    // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
824
0
    if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
825
0
      Builder.defineMacro("__ARM_EABI__");
826
0
    Builder.defineMacro("__ARM_PCS", "1");
827
0
  }
828
829
0
  if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
830
0
    Builder.defineMacro("__ARM_PCS_VFP", "1");
831
832
0
  if (SoftFloat || (SoftFloatABI && !FPU))
833
0
    Builder.defineMacro("__SOFTFP__");
834
835
  // ACLE position independent code macros.
836
0
  if (Opts.ROPI)
837
0
    Builder.defineMacro("__ARM_ROPI", "1");
838
0
  if (Opts.RWPI)
839
0
    Builder.defineMacro("__ARM_RWPI", "1");
840
841
  // Macros for enabling co-proc intrinsics
842
0
  uint64_t FeatureCoprocBF = 0;
843
0
  switch (ArchKind) {
844
0
  default:
845
0
    break;
846
0
  case llvm::ARM::ArchKind::ARMV4:
847
0
  case llvm::ARM::ArchKind::ARMV4T:
848
    // Filter __arm_ldcl and __arm_stcl in acle.h
849
0
    FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1;
850
0
    break;
851
0
  case llvm::ARM::ArchKind::ARMV5T:
852
0
    FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1 | FEATURE_COPROC_B2;
853
0
    break;
854
0
  case llvm::ARM::ArchKind::ARMV5TE:
855
0
  case llvm::ARM::ArchKind::ARMV5TEJ:
856
0
    if (!isThumb())
857
0
      FeatureCoprocBF =
858
0
          FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | FEATURE_COPROC_B3;
859
0
    break;
860
0
  case llvm::ARM::ArchKind::ARMV6:
861
0
  case llvm::ARM::ArchKind::ARMV6K:
862
0
  case llvm::ARM::ArchKind::ARMV6KZ:
863
0
  case llvm::ARM::ArchKind::ARMV6T2:
864
0
    if (!isThumb() || ArchKind == llvm::ARM::ArchKind::ARMV6T2)
865
0
      FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
866
0
                        FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
867
0
    break;
868
0
  case llvm::ARM::ArchKind::ARMV7A:
869
0
  case llvm::ARM::ArchKind::ARMV7R:
870
0
  case llvm::ARM::ArchKind::ARMV7M:
871
0
  case llvm::ARM::ArchKind::ARMV7S:
872
0
  case llvm::ARM::ArchKind::ARMV7EM:
873
0
    FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
874
0
                      FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
875
0
    break;
876
0
  case llvm::ARM::ArchKind::ARMV8A:
877
0
  case llvm::ARM::ArchKind::ARMV8R:
878
0
  case llvm::ARM::ArchKind::ARMV8_1A:
879
0
  case llvm::ARM::ArchKind::ARMV8_2A:
880
0
  case llvm::ARM::ArchKind::ARMV8_3A:
881
0
  case llvm::ARM::ArchKind::ARMV8_4A:
882
0
  case llvm::ARM::ArchKind::ARMV8_5A:
883
0
  case llvm::ARM::ArchKind::ARMV8_6A:
884
0
  case llvm::ARM::ArchKind::ARMV8_7A:
885
0
  case llvm::ARM::ArchKind::ARMV8_8A:
886
0
  case llvm::ARM::ArchKind::ARMV8_9A:
887
0
  case llvm::ARM::ArchKind::ARMV9A:
888
0
  case llvm::ARM::ArchKind::ARMV9_1A:
889
0
  case llvm::ARM::ArchKind::ARMV9_2A:
890
0
  case llvm::ARM::ArchKind::ARMV9_3A:
891
0
  case llvm::ARM::ArchKind::ARMV9_4A:
892
    // Filter __arm_cdp, __arm_ldcl, __arm_stcl in arm_acle.h
893
0
    FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B3;
894
0
    break;
895
0
  case llvm::ARM::ArchKind::ARMV8MMainline:
896
0
  case llvm::ARM::ArchKind::ARMV8_1MMainline:
897
0
    FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
898
0
                      FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
899
0
    break;
900
0
  }
901
0
  Builder.defineMacro("__ARM_FEATURE_COPROC",
902
0
                      "0x" + Twine::utohexstr(FeatureCoprocBF));
903
904
0
  if (ArchKind == llvm::ARM::ArchKind::XSCALE)
905
0
    Builder.defineMacro("__XSCALE__");
906
907
0
  if (isThumb()) {
908
0
    Builder.defineMacro("__THUMBEL__");
909
0
    Builder.defineMacro("__thumb__");
910
0
    if (supportsThumb2())
911
0
      Builder.defineMacro("__thumb2__");
912
0
  }
913
914
  // ACLE 6.4.9 32-bit SIMD instructions
915
0
  if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
916
0
    Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
917
918
  // ACLE 6.4.10 Hardware Integer Divide
919
0
  if (((HWDiv & HWDivThumb) && isThumb()) ||
920
0
      ((HWDiv & HWDivARM) && !isThumb())) {
921
0
    Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
922
0
    Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
923
0
  }
924
925
  // Note, this is always on in gcc, even though it doesn't make sense.
926
0
  Builder.defineMacro("__APCS_32__");
927
928
  // __VFP_FP__ means that the floating-point format is VFP, not that a hardware
929
  // FPU is present. Moreover, the VFP format is the only one supported by
930
  // clang. For these reasons, this macro is always defined.
931
0
  Builder.defineMacro("__VFP_FP__");
932
933
0
  if (FPUModeIsVFP((FPUMode)FPU)) {
934
0
    if (FPU & VFP2FPU)
935
0
      Builder.defineMacro("__ARM_VFPV2__");
936
0
    if (FPU & VFP3FPU)
937
0
      Builder.defineMacro("__ARM_VFPV3__");
938
0
    if (FPU & VFP4FPU)
939
0
      Builder.defineMacro("__ARM_VFPV4__");
940
0
    if (FPU & FPARMV8)
941
0
      Builder.defineMacro("__ARM_FPV5__");
942
0
  }
943
944
  // This only gets set when Neon instructions are actually available, unlike
945
  // the VFP define, hence the soft float and arch check. This is subtly
946
  // different from gcc, we follow the intent which was that it should be set
947
  // when Neon instructions are actually available.
948
0
  if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
949
0
    Builder.defineMacro("__ARM_NEON", "1");
950
0
    Builder.defineMacro("__ARM_NEON__");
951
    // current AArch32 NEON implementations do not support double-precision
952
    // floating-point even when it is present in VFP.
953
0
    Builder.defineMacro("__ARM_NEON_FP",
954
0
                        "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
955
0
  }
956
957
0
  if (hasMVE()) {
958
0
    Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
959
0
  }
960
961
0
  if (hasCDE()) {
962
0
    Builder.defineMacro("__ARM_FEATURE_CDE", "1");
963
0
    Builder.defineMacro("__ARM_FEATURE_CDE_COPROC",
964
0
                        "0x" + Twine::utohexstr(getARMCDECoprocMask()));
965
0
  }
966
967
0
  Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
968
0
                      Twine(Opts.WCharSize ? Opts.WCharSize : 4));
969
970
0
  Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
971
972
  // CMSE
973
0
  if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
974
0
    Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
975
976
0
  if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
977
0
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
978
0
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
979
0
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
980
0
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
981
0
  }
982
983
  // ACLE 6.4.7 DSP instructions
984
0
  if (DSP) {
985
0
    Builder.defineMacro("__ARM_FEATURE_DSP", "1");
986
0
  }
987
988
  // ACLE 6.4.8 Saturation instructions
989
0
  bool SAT = false;
990
0
  if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
991
0
    Builder.defineMacro("__ARM_FEATURE_SAT", "1");
992
0
    SAT = true;
993
0
  }
994
995
  // ACLE 6.4.6 Q (saturation) flag
996
0
  if (DSP || SAT)
997
0
    Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
998
999
0
  if (Opts.UnsafeFPMath)
1000
0
    Builder.defineMacro("__ARM_FP_FAST", "1");
1001
1002
  // Armv8.2-A FP16 vector intrinsic
1003
0
  if ((FPU & NeonFPU) && HasLegalHalfType)
1004
0
    Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
1005
1006
  // Armv8.2-A FP16 scalar intrinsics
1007
0
  if (HasLegalHalfType)
1008
0
    Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
1009
1010
  // Armv8.2-A dot product intrinsics
1011
0
  if (DotProd)
1012
0
    Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
1013
1014
0
  if (HasMatMul)
1015
0
    Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
1016
1017
0
  if (HasPAC)
1018
0
    Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
1019
1020
0
  if (HasBTI)
1021
0
    Builder.defineMacro("__ARM_FEATURE_BTI", "1");
1022
1023
0
  if (HasBFloat16) {
1024
0
    Builder.defineMacro("__ARM_FEATURE_BF16", "1");
1025
0
    Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
1026
0
    Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
1027
0
  }
1028
1029
0
  if (Opts.BranchTargetEnforcement)
1030
0
    Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
1031
1032
0
  if (Opts.hasSignReturnAddress()) {
1033
0
    unsigned Value = 1;
1034
0
    if (Opts.isSignReturnAddressScopeAll())
1035
0
      Value |= 1 << 2;
1036
0
    Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value));
1037
0
  }
1038
1039
0
  switch (ArchKind) {
1040
0
  default:
1041
0
    break;
1042
0
  case llvm::ARM::ArchKind::ARMV8_1A:
1043
0
    getTargetDefinesARMV81A(Opts, Builder);
1044
0
    break;
1045
0
  case llvm::ARM::ArchKind::ARMV8_2A:
1046
0
    getTargetDefinesARMV82A(Opts, Builder);
1047
0
    break;
1048
0
  case llvm::ARM::ArchKind::ARMV8_3A:
1049
0
  case llvm::ARM::ArchKind::ARMV8_4A:
1050
0
  case llvm::ARM::ArchKind::ARMV8_5A:
1051
0
  case llvm::ARM::ArchKind::ARMV8_6A:
1052
0
  case llvm::ARM::ArchKind::ARMV8_7A:
1053
0
  case llvm::ARM::ArchKind::ARMV8_8A:
1054
0
  case llvm::ARM::ArchKind::ARMV8_9A:
1055
0
  case llvm::ARM::ArchKind::ARMV9A:
1056
0
  case llvm::ARM::ArchKind::ARMV9_1A:
1057
0
  case llvm::ARM::ArchKind::ARMV9_2A:
1058
0
  case llvm::ARM::ArchKind::ARMV9_3A:
1059
0
  case llvm::ARM::ArchKind::ARMV9_4A:
1060
0
    getTargetDefinesARMV83A(Opts, Builder);
1061
0
    break;
1062
0
  }
1063
0
}
1064
1065
static constexpr Builtin::Info BuiltinInfo[] = {
1066
#define BUILTIN(ID, TYPE, ATTRS)                                               \
1067
  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1068
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
1069
  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1070
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
1071
  {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1072
#include "clang/Basic/BuiltinsNEON.def"
1073
1074
#define BUILTIN(ID, TYPE, ATTRS)                                               \
1075
  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1076
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
1077
  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
1078
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
1079
  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1080
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
1081
  {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1082
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
1083
  {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
1084
#include "clang/Basic/BuiltinsARM.def"
1085
};
1086
1087
0
ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
1088
0
  return llvm::ArrayRef(BuiltinInfo,
1089
0
                        clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
1090
0
}
1091
1092
0
bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
1093
0
TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
1094
0
  return IsAAPCS
1095
0
             ? AAPCSABIBuiltinVaList
1096
0
             : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
1097
0
                                         : TargetInfo::VoidPtrBuiltinVaList);
1098
0
}
1099
1100
const char *const ARMTargetInfo::GCCRegNames[] = {
1101
    // Integer registers
1102
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1103
    "r12", "sp", "lr", "pc",
1104
1105
    // Float registers
1106
    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1107
    "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1108
    "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1109
1110
    // Double registers
1111
    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1112
    "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1113
    "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1114
1115
    // Quad registers
1116
    "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1117
    "q12", "q13", "q14", "q15"};
1118
1119
0
ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
1120
0
  return llvm::ArrayRef(GCCRegNames);
1121
0
}
1122
1123
const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1124
    {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},
1125
    {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},
1126
    {{"v5"}, "r8"},  {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1127
    {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},
1128
    // The S, D and Q registers overlap, but aren't really aliases; we
1129
    // don't want to substitute one of these for a different-sized one.
1130
};
1131
1132
0
ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
1133
0
  return llvm::ArrayRef(GCCRegAliases);
1134
0
}
1135
1136
bool ARMTargetInfo::validateAsmConstraint(
1137
0
    const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1138
0
  switch (*Name) {
1139
0
  default:
1140
0
    break;
1141
0
  case 'l': // r0-r7 if thumb, r0-r15 if ARM
1142
0
    Info.setAllowsRegister();
1143
0
    return true;
1144
0
  case 'h': // r8-r15, thumb only
1145
0
    if (isThumb()) {
1146
0
      Info.setAllowsRegister();
1147
0
      return true;
1148
0
    }
1149
0
    break;
1150
0
  case 's': // An integer constant, but allowing only relocatable values.
1151
0
    return true;
1152
0
  case 't': // s0-s31, d0-d31, or q0-q15
1153
0
  case 'w': // s0-s15, d0-d7, or q0-q3
1154
0
  case 'x': // s0-s31, d0-d15, or q0-q7
1155
0
    if (FPRegsDisabled)
1156
0
      return false;
1157
0
    Info.setAllowsRegister();
1158
0
    return true;
1159
0
  case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1160
    // only available in ARMv6T2 and above
1161
0
    if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
1162
0
      Info.setRequiresImmediate(0, 65535);
1163
0
      return true;
1164
0
    }
1165
0
    break;
1166
0
  case 'I':
1167
0
    if (isThumb()) {
1168
0
      if (!supportsThumb2())
1169
0
        Info.setRequiresImmediate(0, 255);
1170
0
      else
1171
        // FIXME: should check if immediate value would be valid for a Thumb2
1172
        // data-processing instruction
1173
0
        Info.setRequiresImmediate();
1174
0
    } else
1175
      // FIXME: should check if immediate value would be valid for an ARM
1176
      // data-processing instruction
1177
0
      Info.setRequiresImmediate();
1178
0
    return true;
1179
0
  case 'J':
1180
0
    if (isThumb() && !supportsThumb2())
1181
0
      Info.setRequiresImmediate(-255, -1);
1182
0
    else
1183
0
      Info.setRequiresImmediate(-4095, 4095);
1184
0
    return true;
1185
0
  case 'K':
1186
0
    if (isThumb()) {
1187
0
      if (!supportsThumb2())
1188
        // FIXME: should check if immediate value can be obtained from shifting
1189
        // a value between 0 and 255 left by any amount
1190
0
        Info.setRequiresImmediate();
1191
0
      else
1192
        // FIXME: should check if immediate value would be valid for a Thumb2
1193
        // data-processing instruction when inverted
1194
0
        Info.setRequiresImmediate();
1195
0
    } else
1196
      // FIXME: should check if immediate value would be valid for an ARM
1197
      // data-processing instruction when inverted
1198
0
      Info.setRequiresImmediate();
1199
0
    return true;
1200
0
  case 'L':
1201
0
    if (isThumb()) {
1202
0
      if (!supportsThumb2())
1203
0
        Info.setRequiresImmediate(-7, 7);
1204
0
      else
1205
        // FIXME: should check if immediate value would be valid for a Thumb2
1206
        // data-processing instruction when negated
1207
0
        Info.setRequiresImmediate();
1208
0
    } else
1209
      // FIXME: should check if immediate value  would be valid for an ARM
1210
      // data-processing instruction when negated
1211
0
      Info.setRequiresImmediate();
1212
0
    return true;
1213
0
  case 'M':
1214
0
    if (isThumb() && !supportsThumb2())
1215
      // FIXME: should check if immediate value is a multiple of 4 between 0 and
1216
      // 1020
1217
0
      Info.setRequiresImmediate();
1218
0
    else
1219
      // FIXME: should check if immediate value is a power of two or a integer
1220
      // between 0 and 32
1221
0
      Info.setRequiresImmediate();
1222
0
    return true;
1223
0
  case 'N':
1224
    // Thumb1 only
1225
0
    if (isThumb() && !supportsThumb2()) {
1226
0
      Info.setRequiresImmediate(0, 31);
1227
0
      return true;
1228
0
    }
1229
0
    break;
1230
0
  case 'O':
1231
    // Thumb1 only
1232
0
    if (isThumb() && !supportsThumb2()) {
1233
      // FIXME: should check if immediate value is a multiple of 4 between -508
1234
      // and 508
1235
0
      Info.setRequiresImmediate();
1236
0
      return true;
1237
0
    }
1238
0
    break;
1239
0
  case 'Q': // A memory address that is a single base register.
1240
0
    Info.setAllowsMemory();
1241
0
    return true;
1242
0
  case 'T':
1243
0
    switch (Name[1]) {
1244
0
    default:
1245
0
      break;
1246
0
    case 'e': // Even general-purpose register
1247
0
    case 'o': // Odd general-purpose register
1248
0
      Info.setAllowsRegister();
1249
0
      Name++;
1250
0
      return true;
1251
0
    }
1252
0
    break;
1253
0
  case 'U': // a memory reference...
1254
0
    switch (Name[1]) {
1255
0
    case 'q': // ...ARMV4 ldrsb
1256
0
    case 'v': // ...VFP load/store (reg+constant offset)
1257
0
    case 'y': // ...iWMMXt load/store
1258
0
    case 't': // address valid for load/store opaque types wider
1259
              // than 128-bits
1260
0
    case 'n': // valid address for Neon doubleword vector load/store
1261
0
    case 'm': // valid address for Neon element and structure load/store
1262
0
    case 's': // valid address for non-offset loads/stores of quad-word
1263
              // values in four ARM registers
1264
0
      Info.setAllowsMemory();
1265
0
      Name++;
1266
0
      return true;
1267
0
    }
1268
0
    break;
1269
0
  }
1270
0
  return false;
1271
0
}
1272
1273
0
std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
1274
0
  std::string R;
1275
0
  switch (*Constraint) {
1276
0
  case 'U': // Two-character constraint; add "^" hint for later parsing.
1277
0
  case 'T':
1278
0
    R = std::string("^") + std::string(Constraint, 2);
1279
0
    Constraint++;
1280
0
    break;
1281
0
  case 'p': // 'p' should be translated to 'r' by default.
1282
0
    R = std::string("r");
1283
0
    break;
1284
0
  default:
1285
0
    return std::string(1, *Constraint);
1286
0
  }
1287
0
  return R;
1288
0
}
1289
1290
bool ARMTargetInfo::validateConstraintModifier(
1291
    StringRef Constraint, char Modifier, unsigned Size,
1292
0
    std::string &SuggestedModifier) const {
1293
0
  bool isOutput = (Constraint[0] == '=');
1294
0
  bool isInOut = (Constraint[0] == '+');
1295
1296
  // Strip off constraint modifiers.
1297
0
  Constraint = Constraint.ltrim("=+&");
1298
1299
0
  switch (Constraint[0]) {
1300
0
  default:
1301
0
    break;
1302
0
  case 'r': {
1303
0
    switch (Modifier) {
1304
0
    default:
1305
0
      return (isInOut || isOutput || Size <= 64);
1306
0
    case 'q':
1307
      // A register of size 32 cannot fit a vector type.
1308
0
      return false;
1309
0
    }
1310
0
  }
1311
0
  }
1312
1313
0
  return true;
1314
0
}
1315
0
std::string_view ARMTargetInfo::getClobbers() const {
1316
  // FIXME: Is this really right?
1317
0
  return "";
1318
0
}
1319
1320
TargetInfo::CallingConvCheckResult
1321
0
ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1322
0
  switch (CC) {
1323
0
  case CC_AAPCS:
1324
0
  case CC_AAPCS_VFP:
1325
0
  case CC_Swift:
1326
0
  case CC_SwiftAsync:
1327
0
  case CC_OpenCLKernel:
1328
0
    return CCCR_OK;
1329
0
  default:
1330
0
    return CCCR_Warning;
1331
0
  }
1332
0
}
1333
1334
0
int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1335
0
  if (RegNo == 0)
1336
0
    return 0;
1337
0
  if (RegNo == 1)
1338
0
    return 1;
1339
0
  return -1;
1340
0
}
1341
1342
0
bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1343
1344
ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1345
                                 const TargetOptions &Opts)
1346
0
    : ARMTargetInfo(Triple, Opts) {}
1347
1348
void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1349
0
                                       MacroBuilder &Builder) const {
1350
0
  Builder.defineMacro("__ARMEL__");
1351
0
  ARMTargetInfo::getTargetDefines(Opts, Builder);
1352
0
}
1353
1354
ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1355
                                 const TargetOptions &Opts)
1356
0
    : ARMTargetInfo(Triple, Opts) {}
1357
1358
void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1359
0
                                       MacroBuilder &Builder) const {
1360
0
  Builder.defineMacro("__ARMEB__");
1361
0
  Builder.defineMacro("__ARM_BIG_ENDIAN");
1362
0
  ARMTargetInfo::getTargetDefines(Opts, Builder);
1363
0
}
1364
1365
WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1366
                                           const TargetOptions &Opts)
1367
0
    : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1368
0
}
1369
1370
void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1371
0
                                                  MacroBuilder &Builder) const {
1372
  // FIXME: this is invalid for WindowsCE
1373
0
  Builder.defineMacro("_M_ARM_NT", "1");
1374
0
  Builder.defineMacro("_M_ARMT", "_M_ARM");
1375
0
  Builder.defineMacro("_M_THUMB", "_M_ARM");
1376
1377
0
  assert((Triple.getArch() == llvm::Triple::arm ||
1378
0
          Triple.getArch() == llvm::Triple::thumb) &&
1379
0
         "invalid architecture for Windows ARM target info");
1380
0
  unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1381
0
  Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1382
1383
  // TODO map the complete set of values
1384
  // 31: VFPv3 40: VFPv4
1385
0
  Builder.defineMacro("_M_ARM_FP", "31");
1386
0
}
1387
1388
TargetInfo::BuiltinVaListKind
1389
0
WindowsARMTargetInfo::getBuiltinVaListKind() const {
1390
0
  return TargetInfo::CharPtrBuiltinVaList;
1391
0
}
1392
1393
TargetInfo::CallingConvCheckResult
1394
0
WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1395
0
  switch (CC) {
1396
0
  case CC_X86StdCall:
1397
0
  case CC_X86ThisCall:
1398
0
  case CC_X86FastCall:
1399
0
  case CC_X86VectorCall:
1400
0
    return CCCR_Ignore;
1401
0
  case CC_C:
1402
0
  case CC_OpenCLKernel:
1403
0
  case CC_PreserveMost:
1404
0
  case CC_PreserveAll:
1405
0
  case CC_Swift:
1406
0
  case CC_SwiftAsync:
1407
0
    return CCCR_OK;
1408
0
  default:
1409
0
    return CCCR_Warning;
1410
0
  }
1411
0
}
1412
1413
// Windows ARM + Itanium C++ ABI Target
1414
ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1415
    const llvm::Triple &Triple, const TargetOptions &Opts)
1416
0
    : WindowsARMTargetInfo(Triple, Opts) {
1417
0
  TheCXXABI.set(TargetCXXABI::GenericARM);
1418
0
}
1419
1420
void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1421
0
    const LangOptions &Opts, MacroBuilder &Builder) const {
1422
0
  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1423
1424
0
  if (Opts.MSVCCompat)
1425
0
    WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1426
0
}
1427
1428
// Windows ARM, MS (C++) ABI
1429
MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1430
                                                   const TargetOptions &Opts)
1431
0
    : WindowsARMTargetInfo(Triple, Opts) {
1432
0
  TheCXXABI.set(TargetCXXABI::Microsoft);
1433
0
}
1434
1435
void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1436
0
                                                MacroBuilder &Builder) const {
1437
0
  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1438
0
  WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1439
0
}
1440
1441
MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1442
                                       const TargetOptions &Opts)
1443
0
    : WindowsARMTargetInfo(Triple, Opts) {
1444
0
  TheCXXABI.set(TargetCXXABI::GenericARM);
1445
0
}
1446
1447
void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1448
0
                                          MacroBuilder &Builder) const {
1449
0
  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1450
0
  Builder.defineMacro("_ARM_");
1451
0
}
1452
1453
CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1454
                                         const TargetOptions &Opts)
1455
0
    : ARMleTargetInfo(Triple, Opts) {
1456
0
  this->WCharType = TargetInfo::UnsignedShort;
1457
0
  TLSSupported = false;
1458
0
  DoubleAlign = LongLongAlign = 64;
1459
0
  resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1460
0
}
1461
1462
void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1463
0
                                           MacroBuilder &Builder) const {
1464
0
  ARMleTargetInfo::getTargetDefines(Opts, Builder);
1465
0
  Builder.defineMacro("_ARM_");
1466
0
  Builder.defineMacro("__CYGWIN__");
1467
0
  Builder.defineMacro("__CYGWIN32__");
1468
0
  DefineStd(Builder, "unix", Opts);
1469
0
  if (Opts.CPlusPlus)
1470
0
    Builder.defineMacro("_GNU_SOURCE");
1471
0
}
1472
1473
DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1474
                                         const TargetOptions &Opts)
1475
0
    : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1476
0
  HasAlignMac68kSupport = true;
1477
0
  if (Triple.isWatchABI()) {
1478
    // Darwin on iOS uses a variant of the ARM C++ ABI.
1479
0
    TheCXXABI.set(TargetCXXABI::WatchOS);
1480
1481
    // BOOL should be a real boolean on the new ABI
1482
0
    UseSignedCharForObjCBool = false;
1483
0
  } else
1484
0
    TheCXXABI.set(TargetCXXABI::iOS);
1485
0
}
1486
1487
void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1488
                                       const llvm::Triple &Triple,
1489
0
                                       MacroBuilder &Builder) const {
1490
0
  getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1491
0
}
1492
1493
RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1494
                                                   const TargetOptions &Opts)
1495
    : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1496
                                   Triple.getOSName(),
1497
                                   Triple.getEnvironmentName()),
1498
0
                      Opts) {
1499
0
  IsRenderScriptTarget = true;
1500
0
  LongWidth = LongAlign = 64;
1501
0
}
1502
1503
void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1504
0
                                                MacroBuilder &Builder) const {
1505
0
  Builder.defineMacro("__RENDERSCRIPT__");
1506
0
  ARMleTargetInfo::getTargetDefines(Opts, Builder);
1507
0
}