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