//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Jim Laskey and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Streams.h"
#include <algorithm>
+#include <ostream>
#include <cassert>
#include <cctype>
-#include <iostream>
using namespace llvm;
//===----------------------------------------------------------------------===//
/// Find KV in array using binary search.
template<typename T> const T *Find(const std::string &S, const T *A, size_t L) {
+ // Make the lower bound element we're looking for
+ T KV;
+ KV.Key = S.c_str();
// Determine the end of the array
const T *Hi = A + L;
// Binary search the array
- const T *F = std::lower_bound(A, Hi, S);
+ const T *F = std::lower_bound(A, Hi, KV);
// If not found then return NULL
if (F == Hi || std::string(F->Key) != S) return NULL;
// Return the found array item
unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize);
// Print the CPU table.
- std::cerr << "Available CPUs for this target:\n\n";
+ cerr << "Available CPUs for this target:\n\n";
for (size_t i = 0; i != CPUTableSize; i++)
- std::cerr << " " << CPUTable[i].Key
- << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ')
- << " - " << CPUTable[i].Desc << ".\n";
- std::cerr << "\n";
+ cerr << " " << CPUTable[i].Key
+ << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ')
+ << " - " << CPUTable[i].Desc << ".\n";
+ cerr << "\n";
// Print the Feature table.
- std::cerr << "Available features for this target:\n\n";
+ cerr << "Available features for this target:\n\n";
for (size_t i = 0; i != FeatTableSize; i++)
- std::cerr << " " << FeatTable[i].Key
- << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ')
- << " - " << FeatTable[i].Desc << ".\n";
- std::cerr << "\n";
+ cerr << " " << FeatTable[i].Key
+ << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ')
+ << " - " << FeatTable[i].Desc << ".\n";
+ cerr << "\n";
- std::cerr << "Use +feature to enable a feature, or -feature to disable it.\n"
- << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
+ cerr << "Use +feature to enable a feature, or -feature to disable it.\n"
+ << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
exit(1);
}
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.
///
if (CPUEntry) {
// Set base feature bits
Bits = CPUEntry->Value;
+
+ // Set the feature implied by this CPU feature, if any.
+ for (size_t i = 0; i < FeatureTableSize; ++i) {
+ const SubtargetFeatureKV &FE = FeatureTable[i];
+ if (CPUEntry->Value & FE.Value)
+ SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
+ }
} else {
- std::cerr << "'" << Features[0]
- << "' is not a recognized processor for this target"
- << " (ignoring processor)"
- << "\n";
+ cerr << "'" << Features[0]
+ << "' is not a recognized processor for this target"
+ << " (ignoring processor)"
+ << "\n";
}
// Iterate through each feature
for (size_t i = 1; i < Features.size(); i++) {
// 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 {
- std::cerr << "'" << Feature
- << "' is not a recognized feature for this target"
- << " (ignoring feature)"
- << "\n";
+ cerr << "'" << Feature
+ << "' is not a recognized feature for this target"
+ << " (ignoring feature)"
+ << "\n";
}
}
+
return Bits;
}
if (Entry) {
return Entry->Value;
} else {
- std::cerr << "'" << Features[0]
- << "' is not a recognized processor for this target"
- << " (ignoring processor)"
- << "\n";
+ cerr << "'" << Features[0]
+ << "' is not a recognized processor for this target"
+ << " (ignoring processor)"
+ << "\n";
return NULL;
}
}
/// dump - Dump feature info.
///
void SubtargetFeatures::dump() const {
- print(std::cerr);
+ print(*cerr.stream());
}