aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/TargetParser/XtensaTargetParser.cpp
blob: 25725f2688cf35ca4feff64be15cf2667584199d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//==-- XtensaTargetParser - Parser for Xtensa features ------------*- C++ -*-=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements a target parser to recognise Xtensa hardware features
//
//===----------------------------------------------------------------------===//

#include "llvm/TargetParser/XtensaTargetParser.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"

namespace llvm {

namespace Xtensa {
struct CPUInfo {
  StringLiteral Name;
  CPUKind Kind;
  uint64_t Features;
};

struct FeatureName {
  uint64_t ID;
  const char *NameCStr;
  size_t NameLength;

  StringRef getName() const { return StringRef(NameCStr, NameLength); }
};

const FeatureName XtensaFeatureNames[] = {
#define XTENSA_FEATURE(ID, NAME) {ID, "+" NAME, sizeof(NAME)},
#include "llvm/TargetParser/XtensaTargetParser.def"
};

constexpr CPUInfo XtensaCPUInfo[] = {
#define XTENSA_CPU(ENUM, NAME, FEATURES) {NAME, CK_##ENUM, FEATURES},
#include "llvm/TargetParser/XtensaTargetParser.def"
};

StringRef getBaseName(StringRef CPU) {
  return llvm::StringSwitch<StringRef>(CPU)
#define XTENSA_CPU_ALIAS(NAME, ANAME) .Case(ANAME, NAME)
#include "llvm/TargetParser/XtensaTargetParser.def"
      .Default(CPU);
}

StringRef getAliasName(StringRef CPU) {
  return llvm::StringSwitch<StringRef>(CPU)
#define XTENSA_CPU_ALIAS(NAME, ANAME) .Case(NAME, ANAME)
#include "llvm/TargetParser/XtensaTargetParser.def"
      .Default(CPU);
}

CPUKind parseCPUKind(StringRef CPU) {
  CPU = getBaseName(CPU);
  return llvm::StringSwitch<CPUKind>(CPU)
#define XTENSA_CPU(ENUM, NAME, FEATURES) .Case(NAME, CK_##ENUM)
#include "llvm/TargetParser/XtensaTargetParser.def"
      .Default(CK_INVALID);
}

// Get all features for the CPU
void getCPUFeatures(StringRef CPU, std::vector<StringRef> &Features) {
  CPU = getBaseName(CPU);
  auto I = llvm::find_if(XtensaCPUInfo,
                         [&](const CPUInfo &CI) { return CI.Name == CPU; });
  assert(I != std::end(XtensaCPUInfo) && "CPU not found!");
  uint64_t Bits = I->Features;

  for (const auto &F : XtensaFeatureNames) {
    if ((Bits & F.ID) == F.ID)
      Features.push_back(F.getName());
  }
}

// Find all valid CPUs
void fillValidCPUList(std::vector<StringRef> &Values) {
  for (const auto &C : XtensaCPUInfo) {
    if (C.Kind != CK_INVALID) {
      Values.emplace_back(C.Name);
      StringRef Name = getAliasName(C.Name);
      if (Name != C.Name)
        Values.emplace_back(Name);
    }
  }
}

} // namespace Xtensa
} // namespace llvm