aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/SubtargetFeature.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2007-05-04 20:38:40 +0000
committerBill Wendling <isanbard@gmail.com>2007-05-04 20:38:40 +0000
commit4222d806faae71ecc794cfdaa873817873c2f3d8 (patch)
tree975d4537adf36a11ff1f7dcf6b403bf5b52b0f95 /lib/Target/SubtargetFeature.cpp
parent2e7899dae991e4c3c0b0e967402d1c7ee348c1be (diff)
Add an "implies" field to features. This indicates that, if the current
feature is set, then the features in the implied list should be set also. The opposite is also enforced: if a feature in the implied list isn't set, then the feature that owns that implies list shouldn't be set either. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36756 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SubtargetFeature.cpp')
-rw-r--r--lib/Target/SubtargetFeature.cpp51
1 files changed, 49 insertions, 2 deletions
diff --git a/lib/Target/SubtargetFeature.cpp b/lib/Target/SubtargetFeature.cpp
index 4669e0fdc3..598f02982b 100644
--- a/lib/Target/SubtargetFeature.cpp
+++ b/lib/Target/SubtargetFeature.cpp
@@ -199,6 +199,43 @@ void SubtargetFeatures::setCPUIfNone(const std::string &String) {
if (Features[0].empty()) setCPU(String);
}
+/// SetImpliedBits - For each feature that is (transitively) implied by this
+/// feature, set it.
+///
+static
+void SetImpliedBits(uint32_t &Bits, const SubtargetFeatureKV *FeatureEntry,
+ const SubtargetFeatureKV *FeatureTable,
+ size_t FeatureTableSize) {
+ for (size_t i = 0; i < FeatureTableSize; ++i) {
+ const SubtargetFeatureKV &FE = FeatureTable[i];
+
+ if (FeatureEntry->Value == FE.Value) continue;
+
+ if (FeatureEntry->Implies & FE.Value) {
+ Bits |= FE.Value;
+ SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
+ }
+ }
+}
+
+/// ClearImpliedBits - For each feature that (transitively) implies this
+/// feature, clear it.
+///
+static
+void ClearImpliedBits(uint32_t &Bits, const SubtargetFeatureKV *FeatureEntry,
+ const SubtargetFeatureKV *FeatureTable,
+ size_t FeatureTableSize) {
+ for (size_t i = 0; i < FeatureTableSize; ++i) {
+ const SubtargetFeatureKV &FE = FeatureTable[i];
+
+ if (FeatureEntry->Value == FE.Value) continue;
+
+ if (FE.Implies & FeatureEntry->Value) {
+ Bits &= ~FE.Value;
+ ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
+ }
+ }
+}
/// getBits - Get feature bits.
///
@@ -251,8 +288,17 @@ uint32_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable,
// If there is a match
if (FeatureEntry) {
// Enable/disable feature in bits
- if (isEnabled(Feature)) Bits |= FeatureEntry->Value;
- else Bits &= ~FeatureEntry->Value;
+ if (isEnabled(Feature)) {
+ Bits |= FeatureEntry->Value;
+
+ // For each feature that this implies, set it.
+ SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
+ } else {
+ Bits &= ~FeatureEntry->Value;
+
+ // For each feature that implies this, clear it.
+ ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
+ }
} else {
cerr << "'" << Feature
<< "' is not a recognized feature for this target"
@@ -260,6 +306,7 @@ uint32_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable,
<< "\n";
}
}
+
return Bits;
}