Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/vixl/src/cpu-features.cc
4253 views
1
// Copyright 2018, VIXL authors
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
6
//
7
// * Redistributions of source code must retain the above copyright notice,
8
// this list of conditions and the following disclaimer.
9
// * Redistributions in binary form must reproduce the above copyright notice,
10
// this list of conditions and the following disclaimer in the documentation
11
// and/or other materials provided with the distribution.
12
// * Neither the name of ARM Limited nor the names of its contributors may be
13
// used to endorse or promote products derived from this software without
14
// specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27
#include "cpu-features.h"
28
29
#include <ostream>
30
31
#include "globals-vixl.h"
32
#include "utils-vixl.h"
33
34
#if defined(__aarch64__) && defined(VIXL_INCLUDE_TARGET_AARCH64)
35
#include "aarch64/cpu-aarch64.h"
36
#define VIXL_USE_AARCH64_CPU_HELPERS
37
#endif
38
39
namespace vixl {
40
41
CPUFeatures CPUFeatures::All() {
42
CPUFeatures all;
43
all.features_.set();
44
return all;
45
}
46
47
CPUFeatures CPUFeatures::InferFromIDRegisters() {
48
// This function assumes that kIDRegisterEmulation is available.
49
CPUFeatures features(CPUFeatures::kIDRegisterEmulation);
50
#ifdef VIXL_USE_AARCH64_CPU_HELPERS
51
// Note that the Linux kernel filters these values during emulation, so the
52
// results may not exactly match the expected hardware support.
53
features.Combine(aarch64::CPU::InferCPUFeaturesFromIDRegisters());
54
#endif
55
return features;
56
}
57
58
CPUFeatures CPUFeatures::InferFromOS(QueryIDRegistersOption option) {
59
#ifdef VIXL_USE_AARCH64_CPU_HELPERS
60
return aarch64::CPU::InferCPUFeaturesFromOS(option);
61
#else
62
USE(option);
63
return CPUFeatures();
64
#endif
65
}
66
67
void CPUFeatures::Combine(const CPUFeatures& other) {
68
features_ |= other.features_;
69
}
70
71
void CPUFeatures::Combine(Feature feature) {
72
if (feature != CPUFeatures::kNone) features_.set(feature);
73
}
74
75
void CPUFeatures::Remove(const CPUFeatures& other) {
76
features_ &= ~other.features_;
77
}
78
79
void CPUFeatures::Remove(Feature feature) {
80
if (feature != CPUFeatures::kNone) features_.reset(feature);
81
}
82
83
bool CPUFeatures::Has(const CPUFeatures& other) const {
84
return (features_ & other.features_) == other.features_;
85
}
86
87
bool CPUFeatures::Has(Feature feature) const {
88
return (feature == CPUFeatures::kNone) || features_[feature];
89
}
90
91
size_t CPUFeatures::Count() const { return features_.count(); }
92
93
std::ostream& operator<<(std::ostream& os, CPUFeatures::Feature feature) {
94
// clang-format off
95
switch (feature) {
96
#define VIXL_FORMAT_FEATURE(SYMBOL, NAME, CPUINFO) \
97
case CPUFeatures::SYMBOL: \
98
return os << NAME;
99
VIXL_CPU_FEATURE_LIST(VIXL_FORMAT_FEATURE)
100
#undef VIXL_FORMAT_FEATURE
101
case CPUFeatures::kNone:
102
return os << "none";
103
case CPUFeatures::kNumberOfFeatures:
104
VIXL_UNREACHABLE();
105
}
106
// clang-format on
107
VIXL_UNREACHABLE();
108
return os;
109
}
110
111
CPUFeatures::const_iterator CPUFeatures::begin() const {
112
// For iterators in general, it's undefined to increment `end()`, but here we
113
// control the implementation and it is safe to do this.
114
return ++end();
115
}
116
117
CPUFeatures::const_iterator CPUFeatures::end() const {
118
return const_iterator(this, kNone);
119
}
120
121
std::ostream& operator<<(std::ostream& os, const CPUFeatures& features) {
122
bool need_separator = false;
123
for (CPUFeatures::Feature feature : features) {
124
if (need_separator) os << ", ";
125
need_separator = true;
126
os << feature;
127
}
128
return os;
129
}
130
131
bool CPUFeaturesConstIterator::operator==(
132
const CPUFeaturesConstIterator& other) const {
133
VIXL_ASSERT(IsValid());
134
return (cpu_features_ == other.cpu_features_) && (feature_ == other.feature_);
135
}
136
137
CPUFeaturesConstIterator& CPUFeaturesConstIterator::operator++() { // Prefix
138
VIXL_ASSERT(IsValid());
139
do {
140
// Find the next feature. The order is unspecified.
141
feature_ = static_cast<CPUFeatures::Feature>(feature_ + 1);
142
if (feature_ == CPUFeatures::kNumberOfFeatures) {
143
feature_ = CPUFeatures::kNone;
144
VIXL_STATIC_ASSERT(CPUFeatures::kNone == -1);
145
}
146
VIXL_ASSERT(CPUFeatures::kNone <= feature_);
147
VIXL_ASSERT(feature_ < CPUFeatures::kNumberOfFeatures);
148
// cpu_features_->Has(kNone) is always true, so this will terminate even if
149
// the features list is empty.
150
} while (!cpu_features_->Has(feature_));
151
return *this;
152
}
153
154
CPUFeaturesConstIterator CPUFeaturesConstIterator::operator++(int) { // Postfix
155
CPUFeaturesConstIterator result = *this;
156
++(*this);
157
return result;
158
}
159
160
} // namespace vixl
161
162