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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
//===---- PPCTargetParser.cpp - Parser for target 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 hardware features
// for PPC CPUs.
//
//===----------------------------------------------------------------------===//
#include "llvm/TargetParser/PPCTargetParser.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/TargetParser/Host.h"
namespace llvm {
namespace PPC {
struct CPUInfo {
StringLiteral Name;
// FIXME: add the features field for this CPU.
};
constexpr CPUInfo PPCCPUInfo[] = {
#define PPC_CPU(Name, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD, \
AIXID) \
{Name},
#include "llvm/TargetParser/PPCTargetParser.def"
};
static const CPUInfo *getCPUInfoByName(StringRef CPU) {
for (auto &C : PPCCPUInfo)
if (C.Name == CPU)
return &C;
return nullptr;
}
StringRef normalizeCPUName(StringRef CPUName) {
// Clang/LLVM does not actually support code generation
// for the 405 CPU. However, there are uses of this CPU ID
// in projects that previously used GCC and rely on Clang
// accepting it. Clang has always ignored it and passed the
// generic CPU ID to the back end.
return StringSwitch<StringRef>(CPUName)
.Cases("common", "405", "generic")
.Cases("ppc440", "440fp", "440")
.Cases("630", "power3", "pwr3")
.Case("G3", "g3")
.Case("G4", "g4")
.Case("G4+", "g4+")
.Case("8548", "e500")
.Case("ppc970", "970")
.Case("G5", "g5")
.Case("ppca2", "a2")
.Case("power4", "pwr4")
.Case("power5", "pwr5")
.Case("power5x", "pwr5x")
.Case("power5+", "pwr5+")
.Case("power6", "pwr6")
.Case("power6x", "pwr6x")
.Case("power7", "pwr7")
.Case("power8", "pwr8")
.Case("power9", "pwr9")
.Case("power10", "pwr10")
.Case("power11", "pwr11")
.Cases("powerpc", "powerpc32", "ppc")
.Case("powerpc64", "ppc64")
.Case("powerpc64le", "ppc64le")
.Default(CPUName);
}
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) {
for (const auto &C : PPCCPUInfo)
Values.emplace_back(C.Name);
}
void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) {
for (const auto &C : PPCCPUInfo)
Values.emplace_back(C.Name);
}
bool isValidCPU(StringRef CPU) {
const CPUInfo *Info = getCPUInfoByName(CPU);
if (!Info)
return false;
return true;
}
StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName) {
if (!CPUName.empty()) {
if (CPUName == "native") {
StringRef CPU = sys::getHostCPUName();
if (!CPU.empty() && CPU != "generic")
return CPU;
}
StringRef CPU = normalizeCPUName(CPUName);
if (CPU != "generic" && CPU != "native")
return CPU;
}
// LLVM may default to generating code for the native CPU, but, like gcc, we
// default to a more generic option for each architecture. (except on AIX)
if (T.isOSAIX())
return "pwr7";
else if (T.getArch() == Triple::ppc64le)
return "ppc64le";
else if (T.getArch() == Triple::ppc64)
return "ppc64";
return "ppc";
}
StringRef getNormalizedPPCTuneCPU(const Triple &T, StringRef CPUName) {
return getNormalizedPPCTargetCPU(T, CPUName);
}
} // namespace PPC
} // namespace llvm
|