llvm-project

Форк
0
/
ARMTargetParser.cpp 
661 строка · 20.0 Кб
1
//===-- ARMTargetParser - Parser for ARM target features --------*- C++ -*-===//
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 a target parser to recognise ARM hardware features
10
// such as FPU/CPU/ARCH/extensions and specific support such as HWDIV.
11
//
12
//===----------------------------------------------------------------------===//
13

14
#include "llvm/TargetParser/ARMTargetParser.h"
15
#include "llvm/ADT/StringSwitch.h"
16
#include "llvm/Support/Format.h"
17
#include "llvm/Support/raw_ostream.h"
18
#include "llvm/TargetParser/ARMTargetParserCommon.h"
19
#include "llvm/TargetParser/Triple.h"
20
#include <cctype>
21

22
using namespace llvm;
23

24
static StringRef getHWDivSynonym(StringRef HWDiv) {
25
  return StringSwitch<StringRef>(HWDiv)
26
      .Case("thumb,arm", "arm,thumb")
27
      .Default(HWDiv);
28
}
29

30
// Allows partial match, ex. "v7a" matches "armv7a".
31
ARM::ArchKind ARM::parseArch(StringRef Arch) {
32
  Arch = getCanonicalArchName(Arch);
33
  StringRef Syn = getArchSynonym(Arch);
34
  for (const auto &A : ARMArchNames) {
35
    if (A.Name.ends_with(Syn))
36
      return A.ID;
37
  }
38
  return ArchKind::INVALID;
39
}
40

41
// Version number (ex. v7 = 7).
42
unsigned ARM::parseArchVersion(StringRef Arch) {
43
  Arch = getCanonicalArchName(Arch);
44
  switch (parseArch(Arch)) {
45
  case ArchKind::ARMV4:
46
  case ArchKind::ARMV4T:
47
    return 4;
48
  case ArchKind::ARMV5T:
49
  case ArchKind::ARMV5TE:
50
  case ArchKind::IWMMXT:
51
  case ArchKind::IWMMXT2:
52
  case ArchKind::XSCALE:
53
  case ArchKind::ARMV5TEJ:
54
    return 5;
55
  case ArchKind::ARMV6:
56
  case ArchKind::ARMV6K:
57
  case ArchKind::ARMV6T2:
58
  case ArchKind::ARMV6KZ:
59
  case ArchKind::ARMV6M:
60
    return 6;
61
  case ArchKind::ARMV7A:
62
  case ArchKind::ARMV7VE:
63
  case ArchKind::ARMV7R:
64
  case ArchKind::ARMV7M:
65
  case ArchKind::ARMV7S:
66
  case ArchKind::ARMV7EM:
67
  case ArchKind::ARMV7K:
68
    return 7;
69
  case ArchKind::ARMV8A:
70
  case ArchKind::ARMV8_1A:
71
  case ArchKind::ARMV8_2A:
72
  case ArchKind::ARMV8_3A:
73
  case ArchKind::ARMV8_4A:
74
  case ArchKind::ARMV8_5A:
75
  case ArchKind::ARMV8_6A:
76
  case ArchKind::ARMV8_7A:
77
  case ArchKind::ARMV8_8A:
78
  case ArchKind::ARMV8_9A:
79
  case ArchKind::ARMV8R:
80
  case ArchKind::ARMV8MBaseline:
81
  case ArchKind::ARMV8MMainline:
82
  case ArchKind::ARMV8_1MMainline:
83
    return 8;
84
  case ArchKind::ARMV9A:
85
  case ArchKind::ARMV9_1A:
86
  case ArchKind::ARMV9_2A:
87
  case ArchKind::ARMV9_3A:
88
  case ArchKind::ARMV9_4A:
89
  case ArchKind::ARMV9_5A:
90
    return 9;
91
  case ArchKind::INVALID:
92
    return 0;
93
  }
94
  llvm_unreachable("Unhandled architecture");
95
}
96

97
static ARM::ProfileKind getProfileKind(ARM::ArchKind AK) {
98
  switch (AK) {
99
  case ARM::ArchKind::ARMV6M:
100
  case ARM::ArchKind::ARMV7M:
101
  case ARM::ArchKind::ARMV7EM:
102
  case ARM::ArchKind::ARMV8MMainline:
103
  case ARM::ArchKind::ARMV8MBaseline:
104
  case ARM::ArchKind::ARMV8_1MMainline:
105
    return ARM::ProfileKind::M;
106
  case ARM::ArchKind::ARMV7R:
107
  case ARM::ArchKind::ARMV8R:
108
    return ARM::ProfileKind::R;
109
  case ARM::ArchKind::ARMV7A:
110
  case ARM::ArchKind::ARMV7VE:
111
  case ARM::ArchKind::ARMV7K:
112
  case ARM::ArchKind::ARMV8A:
113
  case ARM::ArchKind::ARMV8_1A:
114
  case ARM::ArchKind::ARMV8_2A:
115
  case ARM::ArchKind::ARMV8_3A:
116
  case ARM::ArchKind::ARMV8_4A:
117
  case ARM::ArchKind::ARMV8_5A:
118
  case ARM::ArchKind::ARMV8_6A:
119
  case ARM::ArchKind::ARMV8_7A:
120
  case ARM::ArchKind::ARMV8_8A:
121
  case ARM::ArchKind::ARMV8_9A:
122
  case ARM::ArchKind::ARMV9A:
123
  case ARM::ArchKind::ARMV9_1A:
124
  case ARM::ArchKind::ARMV9_2A:
125
  case ARM::ArchKind::ARMV9_3A:
126
  case ARM::ArchKind::ARMV9_4A:
127
  case ARM::ArchKind::ARMV9_5A:
128
    return ARM::ProfileKind::A;
129
  case ARM::ArchKind::ARMV4:
130
  case ARM::ArchKind::ARMV4T:
131
  case ARM::ArchKind::ARMV5T:
132
  case ARM::ArchKind::ARMV5TE:
133
  case ARM::ArchKind::ARMV5TEJ:
134
  case ARM::ArchKind::ARMV6:
135
  case ARM::ArchKind::ARMV6K:
136
  case ARM::ArchKind::ARMV6T2:
137
  case ARM::ArchKind::ARMV6KZ:
138
  case ARM::ArchKind::ARMV7S:
139
  case ARM::ArchKind::IWMMXT:
140
  case ARM::ArchKind::IWMMXT2:
141
  case ARM::ArchKind::XSCALE:
142
  case ARM::ArchKind::INVALID:
143
    return ARM::ProfileKind::INVALID;
144
  }
145
  llvm_unreachable("Unhandled architecture");
146
}
147

148
// Profile A/R/M
149
ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
150
  Arch = getCanonicalArchName(Arch);
151
  return getProfileKind(parseArch(Arch));
152
}
153

154
bool ARM::getFPUFeatures(ARM::FPUKind FPUKind,
155
                         std::vector<StringRef> &Features) {
156

157
  if (FPUKind >= FK_LAST || FPUKind == FK_INVALID)
158
    return false;
159

160
  static const struct FPUFeatureNameInfo {
161
    const char *PlusName, *MinusName;
162
    FPUVersion MinVersion;
163
    FPURestriction MaxRestriction;
164
  } FPUFeatureInfoList[] = {
165
    // We have to specify the + and - versions of the name in full so
166
    // that we can return them as static StringRefs.
167
    //
168
    // Also, the SubtargetFeatures ending in just "sp" are listed here
169
    // under FPURestriction::None, which is the only FPURestriction in
170
    // which they would be valid (since FPURestriction::SP doesn't
171
    // exist).
172
    {"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::D16},
173
    {"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::SP_D16},
174
    {"+vfp3", "-vfp3", FPUVersion::VFPV3, FPURestriction::None},
175
    {"+vfp3d16", "-vfp3d16", FPUVersion::VFPV3, FPURestriction::D16},
176
    {"+vfp3d16sp", "-vfp3d16sp", FPUVersion::VFPV3, FPURestriction::SP_D16},
177
    {"+vfp3sp", "-vfp3sp", FPUVersion::VFPV3, FPURestriction::None},
178
    {"+fp16", "-fp16", FPUVersion::VFPV3_FP16, FPURestriction::SP_D16},
179
    {"+vfp4", "-vfp4", FPUVersion::VFPV4, FPURestriction::None},
180
    {"+vfp4d16", "-vfp4d16", FPUVersion::VFPV4, FPURestriction::D16},
181
    {"+vfp4d16sp", "-vfp4d16sp", FPUVersion::VFPV4, FPURestriction::SP_D16},
182
    {"+vfp4sp", "-vfp4sp", FPUVersion::VFPV4, FPURestriction::None},
183
    {"+fp-armv8", "-fp-armv8", FPUVersion::VFPV5, FPURestriction::None},
184
    {"+fp-armv8d16", "-fp-armv8d16", FPUVersion::VFPV5, FPURestriction::D16},
185
    {"+fp-armv8d16sp", "-fp-armv8d16sp", FPUVersion::VFPV5, FPURestriction::SP_D16},
186
    {"+fp-armv8sp", "-fp-armv8sp", FPUVersion::VFPV5, FPURestriction::None},
187
    {"+fullfp16", "-fullfp16", FPUVersion::VFPV5_FULLFP16, FPURestriction::SP_D16},
188
    {"+fp64", "-fp64", FPUVersion::VFPV2, FPURestriction::D16},
189
    {"+d32", "-d32", FPUVersion::VFPV3, FPURestriction::None},
190
  };
191

192
  for (const auto &Info: FPUFeatureInfoList) {
193
    if (FPUNames[FPUKind].FPUVer >= Info.MinVersion &&
194
        FPUNames[FPUKind].Restriction <= Info.MaxRestriction)
195
      Features.push_back(Info.PlusName);
196
    else
197
      Features.push_back(Info.MinusName);
198
  }
199

200
  static const struct NeonFeatureNameInfo {
201
    const char *PlusName, *MinusName;
202
    NeonSupportLevel MinSupportLevel;
203
  } NeonFeatureInfoList[] = {
204
      {"+neon", "-neon", NeonSupportLevel::Neon},
205
      {"+sha2", "-sha2", NeonSupportLevel::Crypto},
206
      {"+aes", "-aes", NeonSupportLevel::Crypto},
207
  };
208

209
  for (const auto &Info: NeonFeatureInfoList) {
210
    if (FPUNames[FPUKind].NeonSupport >= Info.MinSupportLevel)
211
      Features.push_back(Info.PlusName);
212
    else
213
      Features.push_back(Info.MinusName);
214
  }
215

216
  return true;
217
}
218

219
ARM::FPUKind ARM::parseFPU(StringRef FPU) {
220
  StringRef Syn = getFPUSynonym(FPU);
221
  for (const auto &F : FPUNames) {
222
    if (Syn == F.Name)
223
      return F.ID;
224
  }
225
  return FK_INVALID;
226
}
227

228
ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(ARM::FPUKind FPUKind) {
229
  if (FPUKind >= FK_LAST)
230
    return NeonSupportLevel::None;
231
  return FPUNames[FPUKind].NeonSupport;
232
}
233

234
StringRef ARM::getFPUSynonym(StringRef FPU) {
235
  return StringSwitch<StringRef>(FPU)
236
      .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
237
      .Case("vfp2", "vfpv2")
238
      .Case("vfp3", "vfpv3")
239
      .Case("vfp4", "vfpv4")
240
      .Case("vfp3-d16", "vfpv3-d16")
241
      .Case("vfp4-d16", "vfpv4-d16")
242
      .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
243
      .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
244
      .Case("fp5-sp-d16", "fpv5-sp-d16")
245
      .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
246
      // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
247
      .Case("neon-vfpv3", "neon")
248
      .Default(FPU);
249
}
250

251
StringRef ARM::getFPUName(ARM::FPUKind FPUKind) {
252
  if (FPUKind >= FK_LAST)
253
    return StringRef();
254
  return FPUNames[FPUKind].Name;
255
}
256

257
ARM::FPUVersion ARM::getFPUVersion(ARM::FPUKind FPUKind) {
258
  if (FPUKind >= FK_LAST)
259
    return FPUVersion::NONE;
260
  return FPUNames[FPUKind].FPUVer;
261
}
262

263
ARM::FPURestriction ARM::getFPURestriction(ARM::FPUKind FPUKind) {
264
  if (FPUKind >= FK_LAST)
265
    return FPURestriction::None;
266
  return FPUNames[FPUKind].Restriction;
267
}
268

269
ARM::FPUKind ARM::getDefaultFPU(StringRef CPU, ARM::ArchKind AK) {
270
  if (CPU == "generic")
271
    return ARM::ARMArchNames[static_cast<unsigned>(AK)].DefaultFPU;
272

273
  return StringSwitch<ARM::FPUKind>(CPU)
274
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)           \
275
  .Case(NAME, DEFAULT_FPU)
276
#include "llvm/TargetParser/ARMTargetParser.def"
277
      .Default(ARM::FK_INVALID);
278
}
279

280
uint64_t ARM::getDefaultExtensions(StringRef CPU, ARM::ArchKind AK) {
281
  if (CPU == "generic")
282
    return ARM::ARMArchNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
283

284
  return StringSwitch<uint64_t>(CPU)
285
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)           \
286
  .Case(NAME,                                                                  \
287
        ARMArchNames[static_cast<unsigned>(ArchKind::ID)].ArchBaseExtensions | \
288
            DEFAULT_EXT)
289
#include "llvm/TargetParser/ARMTargetParser.def"
290
  .Default(ARM::AEK_INVALID);
291
}
292

293
bool ARM::getHWDivFeatures(uint64_t HWDivKind,
294
                           std::vector<StringRef> &Features) {
295

296
  if (HWDivKind == AEK_INVALID)
297
    return false;
298

299
  if (HWDivKind & AEK_HWDIVARM)
300
    Features.push_back("+hwdiv-arm");
301
  else
302
    Features.push_back("-hwdiv-arm");
303

304
  if (HWDivKind & AEK_HWDIVTHUMB)
305
    Features.push_back("+hwdiv");
306
  else
307
    Features.push_back("-hwdiv");
308

309
  return true;
310
}
311

312
bool ARM::getExtensionFeatures(uint64_t Extensions,
313
                               std::vector<StringRef> &Features) {
314

315
  if (Extensions == AEK_INVALID)
316
    return false;
317

318
  for (const auto &AE : ARCHExtNames) {
319
    if ((Extensions & AE.ID) == AE.ID && !AE.Feature.empty())
320
      Features.push_back(AE.Feature);
321
    else if (!AE.NegFeature.empty())
322
      Features.push_back(AE.NegFeature);
323
  }
324

325
  return getHWDivFeatures(Extensions, Features);
326
}
327

328
StringRef ARM::getArchName(ARM::ArchKind AK) {
329
  return ARMArchNames[static_cast<unsigned>(AK)].Name;
330
}
331

332
StringRef ARM::getCPUAttr(ARM::ArchKind AK) {
333
  return ARMArchNames[static_cast<unsigned>(AK)].CPUAttr;
334
}
335

336
StringRef ARM::getSubArch(ARM::ArchKind AK) {
337
  return ARMArchNames[static_cast<unsigned>(AK)].getSubArch();
338
}
339

340
unsigned ARM::getArchAttr(ARM::ArchKind AK) {
341
  return ARMArchNames[static_cast<unsigned>(AK)].ArchAttr;
342
}
343

344
StringRef ARM::getArchExtName(uint64_t ArchExtKind) {
345
  for (const auto &AE : ARCHExtNames) {
346
    if (ArchExtKind == AE.ID)
347
      return AE.Name;
348
  }
349
  return StringRef();
350
}
351

352
static bool stripNegationPrefix(StringRef &Name) {
353
  return Name.consume_front("no");
354
}
355

356
StringRef ARM::getArchExtFeature(StringRef ArchExt) {
357
  bool Negated = stripNegationPrefix(ArchExt);
358
  for (const auto &AE : ARCHExtNames) {
359
    if (!AE.Feature.empty() && ArchExt == AE.Name)
360
      return StringRef(Negated ? AE.NegFeature : AE.Feature);
361
  }
362

363
  return StringRef();
364
}
365

366
static ARM::FPUKind findDoublePrecisionFPU(ARM::FPUKind InputFPUKind) {
367
  if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
368
    return ARM::FK_INVALID;
369

370
  const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
371

372
  // If the input FPU already supports double-precision, then there
373
  // isn't any different FPU we can return here.
374
  if (ARM::isDoublePrecision(InputFPU.Restriction))
375
    return InputFPUKind;
376

377
  // Otherwise, look for an FPU entry with all the same fields, except
378
  // that it supports double precision.
379
  for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
380
    if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
381
        CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
382
        ARM::has32Regs(CandidateFPU.Restriction) ==
383
            ARM::has32Regs(InputFPU.Restriction) &&
384
        ARM::isDoublePrecision(CandidateFPU.Restriction)) {
385
      return CandidateFPU.ID;
386
    }
387
  }
388

389
  // nothing found
390
  return ARM::FK_INVALID;
391
}
392

393
static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind) {
394
  if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
395
    return ARM::FK_INVALID;
396

397
  const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
398

399
  // If the input FPU already is single-precision only, then there
400
  // isn't any different FPU we can return here.
401
  if (!ARM::isDoublePrecision(InputFPU.Restriction))
402
    return InputFPUKind;
403

404
  // Otherwise, look for an FPU entry with all the same fields, except
405
  // that it does not support double precision.
406
  for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
407
    if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
408
        CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
409
        ARM::has32Regs(CandidateFPU.Restriction) ==
410
            ARM::has32Regs(InputFPU.Restriction) &&
411
        !ARM::isDoublePrecision(CandidateFPU.Restriction)) {
412
      return CandidateFPU.ID;
413
    }
414
  }
415

416
  // nothing found
417
  return ARM::FK_INVALID;
418
}
419

420
bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
421
                                StringRef ArchExt,
422
                                std::vector<StringRef> &Features,
423
                                ARM::FPUKind &ArgFPUKind) {
424

425
  size_t StartingNumFeatures = Features.size();
426
  const bool Negated = stripNegationPrefix(ArchExt);
427
  uint64_t ID = parseArchExt(ArchExt);
428

429
  if (ID == AEK_INVALID)
430
    return false;
431

432
  for (const auto &AE : ARCHExtNames) {
433
    if (Negated) {
434
      if ((AE.ID & ID) == ID && !AE.NegFeature.empty())
435
        Features.push_back(AE.NegFeature);
436
    } else {
437
      if ((AE.ID & ID) == AE.ID && !AE.Feature.empty())
438
        Features.push_back(AE.Feature);
439
    }
440
  }
441

442
  if (CPU == "")
443
    CPU = "generic";
444

445
  if (ArchExt == "fp" || ArchExt == "fp.dp") {
446
    const ARM::FPUKind DefaultFPU = getDefaultFPU(CPU, AK);
447
    ARM::FPUKind FPUKind;
448
    if (ArchExt == "fp.dp") {
449
      const bool IsDP = ArgFPUKind != ARM::FK_INVALID &&
450
                        ArgFPUKind != ARM::FK_NONE &&
451
                        isDoublePrecision(getFPURestriction(ArgFPUKind));
452
      if (Negated) {
453
        /* If there is no FPU selected yet, we still need to set ArgFPUKind, as
454
         * leaving it as FK_INVALID, would cause default FPU to be selected
455
         * later and that could be double precision one. */
456
        if (ArgFPUKind != ARM::FK_INVALID && !IsDP)
457
          return true;
458
        FPUKind = findSinglePrecisionFPU(DefaultFPU);
459
        if (FPUKind == ARM::FK_INVALID)
460
          FPUKind = ARM::FK_NONE;
461
      } else {
462
        if (IsDP)
463
          return true;
464
        FPUKind = findDoublePrecisionFPU(DefaultFPU);
465
        if (FPUKind == ARM::FK_INVALID)
466
          return false;
467
      }
468
    } else if (Negated) {
469
      FPUKind = ARM::FK_NONE;
470
    } else {
471
      FPUKind = DefaultFPU;
472
    }
473
    ArgFPUKind = FPUKind;
474
    return true;
475
  }
476
  return StartingNumFeatures != Features.size();
477
}
478

479
ARM::ArchKind ARM::convertV9toV8(ARM::ArchKind AK) {
480
  if (getProfileKind(AK) != ProfileKind::A)
481
    return ARM::ArchKind::INVALID;
482
  if (AK < ARM::ArchKind::ARMV9A || AK > ARM::ArchKind::ARMV9_3A)
483
    return ARM::ArchKind::INVALID;
484
  unsigned AK_v8 = static_cast<unsigned>(ARM::ArchKind::ARMV8_5A);
485
  AK_v8 += static_cast<unsigned>(AK) -
486
           static_cast<unsigned>(ARM::ArchKind::ARMV9A);
487
  return static_cast<ARM::ArchKind>(AK_v8);
488
}
489

490
StringRef ARM::getDefaultCPU(StringRef Arch) {
491
  ArchKind AK = parseArch(Arch);
492
  if (AK == ArchKind::INVALID)
493
    return StringRef();
494

495
  // Look for multiple AKs to find the default for pair AK+Name.
496
  for (const auto &CPU : CPUNames) {
497
    if (CPU.ArchID == AK && CPU.Default)
498
      return CPU.Name;
499
  }
500

501
  // If we can't find a default then target the architecture instead
502
  return "generic";
503
}
504

505
uint64_t ARM::parseHWDiv(StringRef HWDiv) {
506
  StringRef Syn = getHWDivSynonym(HWDiv);
507
  for (const auto &D : HWDivNames) {
508
    if (Syn == D.Name)
509
      return D.ID;
510
  }
511
  return AEK_INVALID;
512
}
513

514
uint64_t ARM::parseArchExt(StringRef ArchExt) {
515
  for (const auto &A : ARCHExtNames) {
516
    if (ArchExt == A.Name)
517
      return A.ID;
518
  }
519
  return AEK_INVALID;
520
}
521

522
ARM::ArchKind ARM::parseCPUArch(StringRef CPU) {
523
  for (const auto &C : CPUNames) {
524
    if (CPU == C.Name)
525
      return C.ArchID;
526
  }
527
  return ArchKind::INVALID;
528
}
529

530
void ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
531
  for (const auto &Arch : CPUNames) {
532
    if (Arch.ArchID != ArchKind::INVALID)
533
      Values.push_back(Arch.Name);
534
  }
535
}
536

537
StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
538
  StringRef ArchName =
539
      CPU.empty() ? TT.getArchName() : getArchName(parseCPUArch(CPU));
540

541
  if (TT.isOSBinFormatMachO()) {
542
    if (TT.getEnvironment() == Triple::EABI ||
543
        TT.getOS() == Triple::UnknownOS ||
544
        parseArchProfile(ArchName) == ProfileKind::M)
545
      return "aapcs";
546
    if (TT.isWatchABI())
547
      return "aapcs16";
548
    return "apcs-gnu";
549
  } else if (TT.isOSWindows())
550
    // FIXME: this is invalid for WindowsCE.
551
    return "aapcs";
552

553
  // Select the default based on the platform.
554
  switch (TT.getEnvironment()) {
555
  case Triple::Android:
556
  case Triple::GNUEABI:
557
  case Triple::GNUEABIHF:
558
  case Triple::MuslEABI:
559
  case Triple::MuslEABIHF:
560
  case Triple::OpenHOS:
561
    return "aapcs-linux";
562
  case Triple::EABIHF:
563
  case Triple::EABI:
564
    return "aapcs";
565
  default:
566
    if (TT.isOSNetBSD())
567
      return "apcs-gnu";
568
    if (TT.isOSFreeBSD() || TT.isOSOpenBSD() || TT.isOSHaiku() ||
569
        TT.isOHOSFamily())
570
      return "aapcs-linux";
571
    return "aapcs";
572
  }
573
}
574

575
StringRef ARM::getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch) {
576
  if (MArch.empty())
577
    MArch = Triple.getArchName();
578
  MArch = llvm::ARM::getCanonicalArchName(MArch);
579

580
  // Some defaults are forced.
581
  switch (Triple.getOS()) {
582
  case llvm::Triple::FreeBSD:
583
  case llvm::Triple::NetBSD:
584
  case llvm::Triple::OpenBSD:
585
  case llvm::Triple::Haiku:
586
    if (!MArch.empty() && MArch == "v6")
587
      return "arm1176jzf-s";
588
    if (!MArch.empty() && MArch == "v7")
589
      return "cortex-a8";
590
    break;
591
  case llvm::Triple::Win32:
592
    // FIXME: this is invalid for WindowsCE
593
    if (llvm::ARM::parseArchVersion(MArch) <= 7)
594
      return "cortex-a9";
595
    break;
596
  case llvm::Triple::IOS:
597
  case llvm::Triple::MacOSX:
598
  case llvm::Triple::TvOS:
599
  case llvm::Triple::WatchOS:
600
  case llvm::Triple::DriverKit:
601
  case llvm::Triple::XROS:
602
    if (MArch == "v7k")
603
      return "cortex-a7";
604
    break;
605
  default:
606
    break;
607
  }
608

609
  if (MArch.empty())
610
    return StringRef();
611

612
  StringRef CPU = llvm::ARM::getDefaultCPU(MArch);
613
  if (!CPU.empty() && CPU != "invalid")
614
    return CPU;
615

616
  // If no specific architecture version is requested, return the minimum CPU
617
  // required by the OS and environment.
618
  switch (Triple.getOS()) {
619
  case llvm::Triple::Haiku:
620
    return "arm1176jzf-s";
621
  case llvm::Triple::NetBSD:
622
    switch (Triple.getEnvironment()) {
623
    case llvm::Triple::EABI:
624
    case llvm::Triple::EABIHF:
625
    case llvm::Triple::GNUEABI:
626
    case llvm::Triple::GNUEABIHF:
627
      return "arm926ej-s";
628
    default:
629
      return "strongarm";
630
    }
631
  case llvm::Triple::NaCl:
632
  case llvm::Triple::OpenBSD:
633
    return "cortex-a8";
634
  default:
635
    switch (Triple.getEnvironment()) {
636
    case llvm::Triple::EABIHF:
637
    case llvm::Triple::GNUEABIHF:
638
    case llvm::Triple::MuslEABIHF:
639
      return "arm1176jzf-s";
640
    default:
641
      return "arm7tdmi";
642
    }
643
  }
644

645
  llvm_unreachable("invalid arch name");
646
}
647

648
void ARM::PrintSupportedExtensions(StringMap<StringRef> DescMap) {
649
  outs() << "All available -march extensions for ARM\n\n"
650
         << "    " << left_justify("Name", 20)
651
         << (DescMap.empty() ? "\n" : "Description\n");
652
  for (const auto &Ext : ARCHExtNames) {
653
    // Extensions without a feature cannot be used with -march.
654
    if (!Ext.Feature.empty()) {
655
      std::string Description = DescMap[Ext.Name].str();
656
      outs() << "    "
657
             << format(Description.empty() ? "%s\n" : "%-20s%s\n",
658
                       Ext.Name.str().c_str(), Description.c_str());
659
    }
660
  }
661
}
662

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.