1//==-- XtensaTargetParser - Parser for Xtensa 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 Xtensa hardware features
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/TargetParser/XtensaTargetParser.h"
14#include "llvm/ADT/Enum.h"
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/StringSwitch.h"
17#include <vector>
18
19namespace llvm {
20
21namespace Xtensa {
22struct CPUInfo {
23 CPUKind Kind;
24 uint64_t Features;
25};
26
27constexpr EnumStringDef<uint64_t> FeatureNameDefs[] = {
28#define XTENSA_FEATURE(ID, NAME) {{NAME}, ID},
29#include "llvm/TargetParser/XtensaTargetParser.def"
30};
31constexpr auto FeatureNames = BUILD_ENUM_STRINGS(FeatureNameDefs);
32
33constexpr EnumStringDef<CPUInfo> CPUInfoDefs[] = {
34#define XTENSA_CPU(ENUM, NAME, FEATURES) {{NAME}, {CK_##ENUM, FEATURES}},
35#include "llvm/TargetParser/XtensaTargetParser.def"
36};
37constexpr auto CPUInfos = BUILD_ENUM_STRINGS(CPUInfoDefs);
38
39StringRef getBaseName(StringRef CPU) {
40 return llvm::StringSwitch<StringRef>(CPU)
41#define XTENSA_CPU_ALIAS(NAME, ANAME) .Case(ANAME, NAME)
42#include "llvm/TargetParser/XtensaTargetParser.def"
43 .Default(Value: CPU);
44}
45
46StringRef getAliasName(StringRef CPU) {
47 return llvm::StringSwitch<StringRef>(CPU)
48#define XTENSA_CPU_ALIAS(NAME, ANAME) .Case(NAME, ANAME)
49#include "llvm/TargetParser/XtensaTargetParser.def"
50 .Default(Value: CPU);
51}
52
53CPUKind parseCPUKind(StringRef CPU) {
54 CPU = getBaseName(CPU);
55 for (const auto &C : CPUInfos)
56 if (C.name() == CPU)
57 return C.value().Kind;
58 return CK_INVALID;
59}
60
61// Get all features for the CPU
62void getCPUFeatures(StringRef CPU, std::vector<StringRef> &Features) {
63 CPU = getBaseName(CPU);
64 auto I =
65 llvm::find_if(Range: CPUInfos, P: [&](const auto &CI) { return CI.name() == CPU; });
66 assert(I != std::end(CPUInfos) && "CPU not found!");
67 uint64_t Bits = I->value().Features;
68
69 for (const auto &F : FeatureNames) {
70 if ((Bits & F.value()) == F.value())
71 Features.push_back(x: F.name());
72 }
73}
74
75// Find all valid CPUs
76void fillValidCPUList(std::vector<StringRef> &Values) {
77 for (const auto &C : CPUInfos) {
78 if (C.value().Kind != CK_INVALID) {
79 Values.emplace_back(args: C.name());
80 StringRef Name = getAliasName(CPU: C.name());
81 if (Name != C.name())
82 Values.emplace_back(args&: Name);
83 }
84 }
85}
86
87} // namespace Xtensa
88} // namespace llvm
89