summaryrefslogtreecommitdiff
path: root/runtime/instruction_set.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/instruction_set.h')
-rw-r--r--runtime/instruction_set.h159
1 files changed, 135 insertions, 24 deletions
diff --git a/runtime/instruction_set.h b/runtime/instruction_set.h
index de6d0f47d9..529fa0c05f 100644
--- a/runtime/instruction_set.h
+++ b/runtime/instruction_set.h
@@ -22,6 +22,7 @@
#include "base/logging.h" // Logging is required for FATAL in the helper functions.
#include "base/macros.h"
+#include "base/value_object.h"
#include "globals.h" // For KB.
namespace art {
@@ -177,53 +178,163 @@ static inline size_t GetBytesPerFprSpillLocation(InstructionSet isa) {
size_t GetStackOverflowReservedBytes(InstructionSet isa);
-enum InstructionFeatures {
- kHwDiv = 0x1, // Supports hardware divide.
- kHwLpae = 0x2, // Supports Large Physical Address Extension.
+class ArmInstructionSetFeatures;
+
+// Abstraction used to describe features of a different instruction sets.
+class InstructionSetFeatures {
+ public:
+ // Process a CPU variant string for the given ISA and create an InstructionSetFeatures.
+ static const InstructionSetFeatures* FromVariant(InstructionSet isa,
+ const std::string& variant,
+ std::string* error_msg);
+
+ // Parse a string of the form "div,lpae" and create an InstructionSetFeatures.
+ static const InstructionSetFeatures* FromFeatureString(InstructionSet isa,
+ const std::string& feature_list,
+ std::string* error_msg);
+
+ // Parse a bitmap for the given isa and create an InstructionSetFeatures.
+ static const InstructionSetFeatures* FromBitmap(InstructionSet isa, uint32_t bitmap);
+
+ // Turn C pre-processor #defines into the equivalent instruction set features for kRuntimeISA.
+ static const InstructionSetFeatures* FromCppDefines();
+
+ // Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
+ static const InstructionSetFeatures* FromCpuInfo();
+
+ // Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
+ // InstructionSetFeatures.
+ static const InstructionSetFeatures* FromHwcap();
+
+ // Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
+ // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
+ static const InstructionSetFeatures* FromAssembly();
+
+ // Are these features the same as the other given features?
+ virtual bool Equals(const InstructionSetFeatures* other) const = 0;
+
+ // Return the ISA these features relate to.
+ virtual InstructionSet GetInstructionSet() const = 0;
+
+ // Return a bitmap that represents the features. ISA specific.
+ virtual uint32_t AsBitmap() const = 0;
+
+ // Return a string of the form "div,lpae" or "none".
+ virtual std::string GetFeatureString() const = 0;
+
+ // Down cast this ArmInstructionFeatures.
+ const ArmInstructionSetFeatures* AsArmInstructionSetFeatures() const;
+
+ virtual ~InstructionSetFeatures() {}
+
+ protected:
+ InstructionSetFeatures() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InstructionSetFeatures);
};
+std::ostream& operator<<(std::ostream& os, const InstructionSetFeatures& rhs);
-// This is a bitmask of supported features per architecture.
-class PACKED(4) InstructionSetFeatures {
+// Instruction set features relevant to the ARM architecture.
+class ArmInstructionSetFeatures FINAL : public InstructionSetFeatures {
public:
- InstructionSetFeatures() : mask_(0) {}
- explicit InstructionSetFeatures(uint32_t mask) : mask_(mask) {}
+ // Process a CPU variant string like "krait" or "cortex-a15" and create InstructionSetFeatures.
+ static const ArmInstructionSetFeatures* FromVariant(const std::string& variant,
+ std::string* error_msg);
- static InstructionSetFeatures GuessInstructionSetFeatures();
+ // Parse a string of the form "div,lpae" and create an InstructionSetFeatures.
+ static const ArmInstructionSetFeatures* FromFeatureString(const std::string& feature_list,
+ std::string* error_msg);
- bool HasDivideInstruction() const {
- return (mask_ & kHwDiv) != 0;
+ // Parse a bitmap and create an InstructionSetFeatures.
+ static const ArmInstructionSetFeatures* FromBitmap(uint32_t bitmap);
+
+ // Turn C pre-processor #defines into the equivalent instruction set features.
+ static const ArmInstructionSetFeatures* FromCppDefines();
+
+ // Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
+ static const ArmInstructionSetFeatures* FromCpuInfo();
+
+ // Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
+ // InstructionSetFeatures.
+ static const ArmInstructionSetFeatures* FromHwcap();
+
+ // Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
+ // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
+ static const ArmInstructionSetFeatures* FromAssembly();
+
+ bool Equals(const InstructionSetFeatures* other) const OVERRIDE;
+
+ InstructionSet GetInstructionSet() const OVERRIDE {
+ return kArm;
}
- void SetHasDivideInstruction(bool v) {
- mask_ = (mask_ & ~kHwDiv) | (v ? kHwDiv : 0);
+ uint32_t AsBitmap() const OVERRIDE;
+
+ // Return a string of the form "div,lpae" or "none".
+ std::string GetFeatureString() const OVERRIDE;
+
+ // Is the divide instruction feature enabled?
+ bool HasDivideInstruction() const {
+ return has_div_;
}
+ // Is the Large Physical Address Extension (LPAE) instruction feature enabled? When true code can
+ // be used that assumes double register loads and stores (ldrd, strd) don't tear.
bool HasLpae() const {
- return (mask_ & kHwLpae) != 0;
+ return has_lpae_;
}
- void SetHasLpae(bool v) {
- mask_ = (mask_ & ~kHwLpae) | (v ? kHwLpae : 0);
+ virtual ~ArmInstructionSetFeatures() {}
+
+ private:
+ ArmInstructionSetFeatures(bool has_lpae, bool has_div)
+ : has_lpae_(has_lpae), has_div_(has_div) {
}
- std::string GetFeatureString() const;
+ // Bitmap positions for encoding features as a bitmap.
+ enum {
+ kDivBitfield = 1,
+ kLpaeBitfield = 2,
+ };
- // Other features in here.
+ const bool has_lpae_;
+ const bool has_div_;
- bool operator==(const InstructionSetFeatures &peer) const {
- return mask_ == peer.mask_;
+ DISALLOW_COPY_AND_ASSIGN(ArmInstructionSetFeatures);
+};
+
+// A class used for instruction set features on ISAs that don't yet have any features defined.
+class UnknownInstructionSetFeatures FINAL : public InstructionSetFeatures {
+ public:
+ static const UnknownInstructionSetFeatures* Unknown(InstructionSet isa) {
+ return new UnknownInstructionSetFeatures(isa);
}
- bool operator!=(const InstructionSetFeatures &peer) const {
- return mask_ != peer.mask_;
+ bool Equals(const InstructionSetFeatures* other) const OVERRIDE {
+ return isa_ == other->GetInstructionSet();
}
- bool operator<=(const InstructionSetFeatures &peer) const {
- return (mask_ & peer.mask_) == mask_;
+ InstructionSet GetInstructionSet() const OVERRIDE {
+ return isa_;
}
+ uint32_t AsBitmap() const OVERRIDE {
+ return 0;
+ }
+
+ std::string GetFeatureString() const OVERRIDE {
+ return "none";
+ }
+
+ virtual ~UnknownInstructionSetFeatures() {}
+
private:
- uint32_t mask_;
+ explicit UnknownInstructionSetFeatures(InstructionSet isa) : isa_(isa) {}
+
+ const InstructionSet isa_;
+
+ DISALLOW_COPY_AND_ASSIGN(UnknownInstructionSetFeatures);
};
// The following definitions create return types for two word-sized entities that will be passed