diff options
Diffstat (limited to 'runtime/instruction_set.h')
| -rw-r--r-- | runtime/instruction_set.h | 159 | 
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  |