| Index: src/arm/assembler-arm.h
 | 
| diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
 | 
| index 27befaa51aa71c4dbc36eedc97659c705dd9313b..235e56e7e357579713d7d2eb797c2f1cf081c49a 100644
 | 
| --- a/src/arm/assembler-arm.h
 | 
| +++ b/src/arm/assembler-arm.h
 | 
| @@ -47,6 +47,116 @@
 | 
|  namespace v8 {
 | 
|  namespace internal {
 | 
|  
 | 
| +// CpuFeatures keeps track of which features are supported by the target CPU.
 | 
| +// Supported features must be enabled by a Scope before use.
 | 
| +class CpuFeatures : public AllStatic {
 | 
| + public:
 | 
| +  // Detect features of the target CPU. Set safe defaults if the serializer
 | 
| +  // is enabled (snapshots must be portable).
 | 
| +  static void Probe();
 | 
| +
 | 
| +  // Check whether a feature is supported by the target CPU.
 | 
| +  static bool IsSupported(CpuFeature f) {
 | 
| +    ASSERT(initialized_);
 | 
| +    if (f == VFP3 && !FLAG_enable_vfp3) return false;
 | 
| +    if (f == VFP2 && !FLAG_enable_vfp2) return false;
 | 
| +    if (f == SUDIV && !FLAG_enable_sudiv) return false;
 | 
| +    if (f == UNALIGNED_ACCESSES && !FLAG_enable_unaligned_accesses) {
 | 
| +      return false;
 | 
| +    }
 | 
| +    if (f == VFP32DREGS && !FLAG_enable_32dregs) return false;
 | 
| +    return (supported_ & (1u << f)) != 0;
 | 
| +  }
 | 
| +
 | 
| +#ifdef DEBUG
 | 
| +  // Check whether a feature is currently enabled.
 | 
| +  static bool IsEnabled(CpuFeature f) {
 | 
| +    ASSERT(initialized_);
 | 
| +    Isolate* isolate = Isolate::UncheckedCurrent();
 | 
| +    if (isolate == NULL) {
 | 
| +      // When no isolate is available, work as if we're running in
 | 
| +      // release mode.
 | 
| +      return IsSupported(f);
 | 
| +    }
 | 
| +    unsigned enabled = static_cast<unsigned>(isolate->enabled_cpu_features());
 | 
| +    return (enabled & (1u << f)) != 0;
 | 
| +  }
 | 
| +#endif
 | 
| +
 | 
| +  // Enable a specified feature within a scope.
 | 
| +  class Scope BASE_EMBEDDED {
 | 
| +#ifdef DEBUG
 | 
| +
 | 
| +   public:
 | 
| +    explicit Scope(CpuFeature f) {
 | 
| +      unsigned mask = 1u << f;
 | 
| +      // VFP2 and ARMv7 are implied by VFP3.
 | 
| +      if (f == VFP3) mask |= 1u << VFP2 | 1u << ARMv7;
 | 
| +      ASSERT(CpuFeatures::IsSupported(f));
 | 
| +      ASSERT(!Serializer::enabled() ||
 | 
| +             (CpuFeatures::found_by_runtime_probing_ & mask) == 0);
 | 
| +      isolate_ = Isolate::UncheckedCurrent();
 | 
| +      old_enabled_ = 0;
 | 
| +      if (isolate_ != NULL) {
 | 
| +        old_enabled_ = static_cast<unsigned>(isolate_->enabled_cpu_features());
 | 
| +        isolate_->set_enabled_cpu_features(old_enabled_ | mask);
 | 
| +      }
 | 
| +    }
 | 
| +    ~Scope() {
 | 
| +      ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_);
 | 
| +      if (isolate_ != NULL) {
 | 
| +        isolate_->set_enabled_cpu_features(old_enabled_);
 | 
| +      }
 | 
| +    }
 | 
| +
 | 
| +   private:
 | 
| +    Isolate* isolate_;
 | 
| +    unsigned old_enabled_;
 | 
| +#else
 | 
| +
 | 
| +   public:
 | 
| +    explicit Scope(CpuFeature f) {}
 | 
| +#endif
 | 
| +  };
 | 
| +
 | 
| +  class TryForceFeatureScope BASE_EMBEDDED {
 | 
| +   public:
 | 
| +    explicit TryForceFeatureScope(CpuFeature f)
 | 
| +        : old_supported_(CpuFeatures::supported_) {
 | 
| +      if (CanForce()) {
 | 
| +        CpuFeatures::supported_ |= (1u << f);
 | 
| +      }
 | 
| +    }
 | 
| +
 | 
| +    ~TryForceFeatureScope() {
 | 
| +      if (CanForce()) {
 | 
| +        CpuFeatures::supported_ = old_supported_;
 | 
| +      }
 | 
| +    }
 | 
| +
 | 
| +   private:
 | 
| +    static bool CanForce() {
 | 
| +      // It's only safe to temporarily force support of CPU features
 | 
| +      // when there's only a single isolate, which is guaranteed when
 | 
| +      // the serializer is enabled.
 | 
| +      return Serializer::enabled();
 | 
| +    }
 | 
| +
 | 
| +    const unsigned old_supported_;
 | 
| +  };
 | 
| +
 | 
| + private:
 | 
| +#ifdef DEBUG
 | 
| +  static bool initialized_;
 | 
| +#endif
 | 
| +  static unsigned supported_;
 | 
| +  static unsigned found_by_runtime_probing_;
 | 
| +
 | 
| +  friend class ExternalReference;
 | 
| +  DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
 | 
| +};
 | 
| +
 | 
| +
 | 
|  // CPU Registers.
 | 
|  //
 | 
|  // 1) We would prefer to use an enum, but enum values are assignment-
 | 
| @@ -192,7 +302,7 @@ struct SwVfpRegister {
 | 
|  
 | 
|  // Double word VFP register.
 | 
|  struct DwVfpRegister {
 | 
| -  static const int kNumRegisters = 16;
 | 
| +  static const int kNumRegisters = 32;
 | 
|    // A few double registers are reserved: one as a scratch register and one to
 | 
|    // hold 0.0, that does not fit in the immediate field of vmov instructions.
 | 
|    //  d14: 0.0
 | 
| @@ -201,25 +311,27 @@ struct DwVfpRegister {
 | 
|    static const int kMaxNumAllocatableRegisters = kNumRegisters -
 | 
|        kNumReservedRegisters;
 | 
|  
 | 
| +  // Note: the number of registers can be different at snapshot and run-time.
 | 
| +  // Any code included in the snapshot must be able to run both with 16 or 32
 | 
| +  // registers.
 | 
|    inline static int NumRegisters();
 | 
|    inline static int NumAllocatableRegisters();
 | 
| +
 | 
|    inline static int ToAllocationIndex(DwVfpRegister reg);
 | 
|    static const char* AllocationIndexToString(int index);
 | 
| -
 | 
| -  static DwVfpRegister FromAllocationIndex(int index) {
 | 
| -    ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
 | 
| -    return from_code(index);
 | 
| -  }
 | 
| +  inline static DwVfpRegister FromAllocationIndex(int index);
 | 
|  
 | 
|    static DwVfpRegister from_code(int code) {
 | 
|      DwVfpRegister r = { code };
 | 
|      return r;
 | 
|    }
 | 
|  
 | 
| -  // Supporting d0 to d15, can be later extended to d31.
 | 
| -  bool is_valid() const { return 0 <= code_ && code_ < 16; }
 | 
| +  bool is_valid() const {
 | 
| +    return 0 <= code_ && code_ < kNumRegisters;
 | 
| +  }
 | 
|    bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
 | 
|    SwVfpRegister low() const {
 | 
| +    ASSERT(code_ < 16);
 | 
|      SwVfpRegister reg;
 | 
|      reg.code_ = code_ * 2;
 | 
|  
 | 
| @@ -227,6 +339,7 @@ struct DwVfpRegister {
 | 
|      return reg;
 | 
|    }
 | 
|    SwVfpRegister high() const {
 | 
| +    ASSERT(code_ < 16);
 | 
|      SwVfpRegister reg;
 | 
|      reg.code_ = (code_ * 2) + 1;
 | 
|  
 | 
| @@ -306,6 +419,22 @@ const DwVfpRegister d12 = { 12 };
 | 
|  const DwVfpRegister d13 = { 13 };
 | 
|  const DwVfpRegister d14 = { 14 };
 | 
|  const DwVfpRegister d15 = { 15 };
 | 
| +const DwVfpRegister d16 = { 16 };
 | 
| +const DwVfpRegister d17 = { 17 };
 | 
| +const DwVfpRegister d18 = { 18 };
 | 
| +const DwVfpRegister d19 = { 19 };
 | 
| +const DwVfpRegister d20 = { 20 };
 | 
| +const DwVfpRegister d21 = { 21 };
 | 
| +const DwVfpRegister d22 = { 22 };
 | 
| +const DwVfpRegister d23 = { 23 };
 | 
| +const DwVfpRegister d24 = { 24 };
 | 
| +const DwVfpRegister d25 = { 25 };
 | 
| +const DwVfpRegister d26 = { 26 };
 | 
| +const DwVfpRegister d27 = { 27 };
 | 
| +const DwVfpRegister d28 = { 28 };
 | 
| +const DwVfpRegister d29 = { 29 };
 | 
| +const DwVfpRegister d30 = { 30 };
 | 
| +const DwVfpRegister d31 = { 31 };
 | 
|  
 | 
|  const Register sfpd_lo  = { kRegister_r6_Code };
 | 
|  const Register sfpd_hi  = { kRegister_r7_Code };
 | 
| @@ -485,114 +614,6 @@ class MemOperand BASE_EMBEDDED {
 | 
|    friend class Assembler;
 | 
|  };
 | 
|  
 | 
| -// CpuFeatures keeps track of which features are supported by the target CPU.
 | 
| -// Supported features must be enabled by a Scope before use.
 | 
| -class CpuFeatures : public AllStatic {
 | 
| - public:
 | 
| -  // Detect features of the target CPU. Set safe defaults if the serializer
 | 
| -  // is enabled (snapshots must be portable).
 | 
| -  static void Probe();
 | 
| -
 | 
| -  // Check whether a feature is supported by the target CPU.
 | 
| -  static bool IsSupported(CpuFeature f) {
 | 
| -    ASSERT(initialized_);
 | 
| -    if (f == VFP3 && !FLAG_enable_vfp3) return false;
 | 
| -    if (f == VFP2 && !FLAG_enable_vfp2) return false;
 | 
| -    if (f == SUDIV && !FLAG_enable_sudiv) return false;
 | 
| -    if (f == UNALIGNED_ACCESSES && !FLAG_enable_unaligned_accesses) {
 | 
| -      return false;
 | 
| -    }
 | 
| -    return (supported_ & (1u << f)) != 0;
 | 
| -  }
 | 
| -
 | 
| -#ifdef DEBUG
 | 
| -  // Check whether a feature is currently enabled.
 | 
| -  static bool IsEnabled(CpuFeature f) {
 | 
| -    ASSERT(initialized_);
 | 
| -    Isolate* isolate = Isolate::UncheckedCurrent();
 | 
| -    if (isolate == NULL) {
 | 
| -      // When no isolate is available, work as if we're running in
 | 
| -      // release mode.
 | 
| -      return IsSupported(f);
 | 
| -    }
 | 
| -    unsigned enabled = static_cast<unsigned>(isolate->enabled_cpu_features());
 | 
| -    return (enabled & (1u << f)) != 0;
 | 
| -  }
 | 
| -#endif
 | 
| -
 | 
| -  // Enable a specified feature within a scope.
 | 
| -  class Scope BASE_EMBEDDED {
 | 
| -#ifdef DEBUG
 | 
| -
 | 
| -   public:
 | 
| -    explicit Scope(CpuFeature f) {
 | 
| -      unsigned mask = 1u << f;
 | 
| -      // VFP2 and ARMv7 are implied by VFP3.
 | 
| -      if (f == VFP3) mask |= 1u << VFP2 | 1u << ARMv7;
 | 
| -      ASSERT(CpuFeatures::IsSupported(f));
 | 
| -      ASSERT(!Serializer::enabled() ||
 | 
| -             (CpuFeatures::found_by_runtime_probing_ & mask) == 0);
 | 
| -      isolate_ = Isolate::UncheckedCurrent();
 | 
| -      old_enabled_ = 0;
 | 
| -      if (isolate_ != NULL) {
 | 
| -        old_enabled_ = static_cast<unsigned>(isolate_->enabled_cpu_features());
 | 
| -        isolate_->set_enabled_cpu_features(old_enabled_ | mask);
 | 
| -      }
 | 
| -    }
 | 
| -    ~Scope() {
 | 
| -      ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_);
 | 
| -      if (isolate_ != NULL) {
 | 
| -        isolate_->set_enabled_cpu_features(old_enabled_);
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -   private:
 | 
| -    Isolate* isolate_;
 | 
| -    unsigned old_enabled_;
 | 
| -#else
 | 
| -
 | 
| -   public:
 | 
| -    explicit Scope(CpuFeature f) {}
 | 
| -#endif
 | 
| -  };
 | 
| -
 | 
| -  class TryForceFeatureScope BASE_EMBEDDED {
 | 
| -   public:
 | 
| -    explicit TryForceFeatureScope(CpuFeature f)
 | 
| -        : old_supported_(CpuFeatures::supported_) {
 | 
| -      if (CanForce()) {
 | 
| -        CpuFeatures::supported_ |= (1u << f);
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    ~TryForceFeatureScope() {
 | 
| -      if (CanForce()) {
 | 
| -        CpuFeatures::supported_ = old_supported_;
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -   private:
 | 
| -    static bool CanForce() {
 | 
| -      // It's only safe to temporarily force support of CPU features
 | 
| -      // when there's only a single isolate, which is guaranteed when
 | 
| -      // the serializer is enabled.
 | 
| -      return Serializer::enabled();
 | 
| -    }
 | 
| -
 | 
| -    const unsigned old_supported_;
 | 
| -  };
 | 
| -
 | 
| - private:
 | 
| -#ifdef DEBUG
 | 
| -  static bool initialized_;
 | 
| -#endif
 | 
| -  static unsigned supported_;
 | 
| -  static unsigned found_by_runtime_probing_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
 | 
| -};
 | 
| -
 | 
| -
 | 
|  extern const Instr kMovLrPc;
 | 
|  extern const Instr kLdrPCMask;
 | 
|  extern const Instr kLdrPCPattern;
 | 
| @@ -981,10 +1002,7 @@ class Assembler : public AssemblerBase {
 | 
|              LFlag l = Short);  // v5 and above
 | 
|  
 | 
|    // Support for VFP.
 | 
| -  // All these APIs support S0 to S31 and D0 to D15.
 | 
| -  // Currently these APIs do not support extended D registers, i.e, D16 to D31.
 | 
| -  // However, some simple modifications can allow
 | 
| -  // these APIs to support D16 to D31.
 | 
| +  // All these APIs support S0 to S31 and D0 to D31.
 | 
|  
 | 
|    void vldr(const DwVfpRegister dst,
 | 
|              const Register base,
 | 
| @@ -1053,6 +1071,10 @@ class Assembler : public AssemblerBase {
 | 
|              const DwVfpRegister src,
 | 
|              const Condition cond = al);
 | 
|    void vmov(const DwVfpRegister dst,
 | 
| +            int index,
 | 
| +            const Register src,
 | 
| +            const Condition cond = al);
 | 
| +  void vmov(const DwVfpRegister dst,
 | 
|              const Register src1,
 | 
|              const Register src2,
 | 
|              const Condition cond = al);
 | 
| 
 |