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); |