Coverage Report

Created: 2021-01-19 06:58

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