diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index ccb51042068..cbceca70686 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -366,6 +366,34 @@ struct QwNeonRegister {
return r;
}
+ static int ToAllocationIndex(QwNeonRegister reg) {
+ ASSERT(reg.code() < kMaxNumRegisters);
+ return reg.code();
+ }
+
+ static const char* AllocationIndexToString(int index) {
+ ASSERT(index >= 0 && index < kMaxNumRegisters);
+ const char* const names[] = {
+ "q0",
+ "q1",
+ "q2",
+ "q3",
+ "q4",
+ "q5",
+ "q6",
+ "q7",
+ "q8",
+ "q9",
+ "q10",
+ "q11",
+ "q12",
+ "q13",
+ "q14",
+ "q15",
+ };
+ return names[index];
+ }
+
bool is_valid() const {
return (0 <= code_) && (code_ < kMaxNumRegisters);
}
@@ -385,6 +413,7 @@ struct QwNeonRegister {
typedef QwNeonRegister QuadRegister;
+typedef QwNeonRegister SIMD128Register;
// Support for the VFP registers s0 to s31 (d0 to d15).
diff --git a/src/arm/cpu-arm.cc b/src/arm/cpu-arm.cc
index 20c6a5dcce3..a04f1413b88 100644
--- a/src/arm/cpu-arm.cc
+++ b/src/arm/cpu-arm.cc
@@ -56,6 +56,12 @@ bool CPU::SupportsCrankshaft() {
}
+bool CPU::SupportsSIMD128InCrankshaft() {
+ // Not Implemented.
+ return false;
+}
+
+
void CPU::FlushICache(void* start, size_t size) {
// Nothing to do flushing no instructions.
if (size == 0) {
diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
index 6031499dbd1..f3f9fd1ee68 100644
--- a/src/arm/deoptimizer-arm.cc
+++ b/src/arm/deoptimizer-arm.cc
@@ -113,7 +113,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters(
}
-void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
+void Deoptimizer::CopySIMD128Registers(FrameDescription* output_frame) {
for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) {
double double_value = input_->GetDoubleRegister(i);
output_frame->SetDoubleRegister(i, double_value);
@@ -210,7 +210,7 @@ void Deoptimizer::EntryGenerator::Generate() {
// Copy VFP registers to
// double_registers_[DoubleRegister::kMaxNumAllocatableRegisters]
- int double_regs_offset = FrameDescription::double_registers_offset();
+ int double_regs_offset = FrameDescription::simd128_registers_offset();
for (int i = 0; i < DwVfpRegister::kMaxNumAllocatableRegisters; ++i) {
int dst_offset = i * kDoubleSize + double_regs_offset;
int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
@@ -284,7 +284,7 @@ void Deoptimizer::EntryGenerator::Generate() {
__ CheckFor32DRegs(ip);
__ ldr(r1, MemOperand(r0, Deoptimizer::input_offset()));
- int src_offset = FrameDescription::double_registers_offset();
+ int src_offset = FrameDescription::simd128_registers_offset();
for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) {
if (i == kDoubleRegZero.code()) continue;
if (i == kScratchDoubleReg.code()) continue;
@@ -350,6 +350,18 @@ void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
}
+double FrameDescription::GetDoubleRegister(unsigned n) const {
+ ASSERT(n < 2 * ARRAY_SIZE(simd128_registers_));
+ return simd128_registers_[n / 2].d[n % 2];
+}
+
+
+void FrameDescription::SetDoubleRegister(unsigned n, double value) {
+ ASSERT(n < 2 * ARRAY_SIZE(simd128_registers_));
+ simd128_registers_[n / 2].d[n % 2] = value;
+}
+
+
#undef __
} } // namespace v8::internal
diff --git a/src/cpu.h b/src/cpu.h
index b2e9f7da7ee..b43e618a0d9 100644
--- a/src/cpu.h
+++ b/src/cpu.h
@@ -107,6 +107,8 @@ class CPU V8_FINAL BASE_EMBEDDED {
static bool SupportsCrankshaft();
+ static bool SupportsSIMD128InCrankshaft();
+
// Flush instruction cache.
static void FlushICache(void* start, size_t size);
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 9e7e113ed9a..4584990ed53 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -1711,7 +1711,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
}
// Copy the double registers from the input into the output frame.
- CopyDoubleRegisters(output_frame);
+ CopySIMD128Registers(output_frame);
// Fill registers containing handler and number of parameters.
SetPlatformCompiledStubRegisters(output_frame, descriptor);
@@ -1864,6 +1864,43 @@ void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
Memory::Object_at(d.destination()) = *num;
}
+ // Materialize all float32x4 before looking at arguments because when the
+ // output frames are used to materialize arguments objects later on they need
+ // to already contain valid float32x4 values.
+ for (int i = 0; i < deferred_float32x4s_.length(); i++) {
+ SIMD128MaterializationDescriptor
d = deferred_float32x4s_[i];
+ float32x4_value_t x4 = d.value().f4;
+ Handle