}
// 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);
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<Address> d = deferred_float32x4s_[i];
+ float32x4_value_t x4 = d.value().f4;
+ Handle<Object> float32x4 = isolate_->factory()->NewFloat32x4(x4);
+ if (trace_scope_ != NULL) {
+ PrintF(trace_scope_->file(),
+ "Materialized a new float32x4 %p "
+ "[float32x4(%e, %e, %e, %e)] in slot %p\n",
+ reinterpret_cast<void*>(*float32x4),
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ d.destination());
+ }
+ Memory::Object_at(d.destination()) = *float32x4;
+ }
+
+ // Materialize all float64x2 before looking at arguments because when the
+ // output frames are used to materialize arguments objects later on they need
+ // to already contain valid float64x2 values.
+ for (int i = 0; i < deferred_float64x2s_.length(); i++) {
+ SIMD128MaterializationDescriptor<Address> d = deferred_float64x2s_[i];
+ float64x2_value_t x2 = d.value().d2;
+ Handle<Object> float64x2 = isolate_->factory()->NewFloat64x2(x2);
+ if (trace_scope_ != NULL) {
+ PrintF(trace_scope_->file(),
+ "Materialized a new float64x2 %p "
+ "[float64x2(%e, %e)] in slot %p\n",
+ reinterpret_cast<void*>(*float64x2),
+ x2.storage[0], x2.storage[1],
+ d.destination());
+ }
+ Memory::Object_at(d.destination()) = *float64x2;
+ }
+
+ // Materialize all int32x4 before looking at arguments because when the
+ // output frames are used to materialize arguments objects later on they need
+ // to already contain valid int32x4 values.
+ for (int i = 0; i < deferred_int32x4s_.length(); i++) {
+ SIMD128MaterializationDescriptor<Address> d = deferred_int32x4s_[i];
+ int32x4_value_t x4 = d.value().i4;
+ Handle<Object> int32x4 = isolate_->factory()->NewInt32x4(x4);
+ if (trace_scope_ != NULL) {
+ PrintF(trace_scope_->file(),
+ "Materialized a new int32x4 %p "
+ "[int32x4(%u, %u, %u, %u)] in slot %p\n",
+ reinterpret_cast<void*>(*int32x4),
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ d.destination());
+ }
+ Memory::Object_at(d.destination()) = *int32x4;
+ }
+
+
// Materialize all heap numbers required for arguments/captured objects.
for (int i = 0; i < deferred_objects_double_values_.length(); i++) {
HeapNumberMaterializationDescriptor<int> d =
// Play it safe and clear all object double values before we continue.
deferred_objects_double_values_.Clear();
+ // Materialize all float32x4 values required for arguments/captured objects.
+ for (int i = 0; i < deferred_objects_float32x4_values_.length(); i++) {
+ SIMD128MaterializationDescriptor<int> d =
+ deferred_objects_float32x4_values_[i];
+ float32x4_value_t x4 = d.value().f4;
+ Handle<Object> float32x4 = isolate_->factory()->NewFloat32x4(x4);
+ if (trace_scope_ != NULL) {
+ PrintF(trace_scope_->file(),
+ "Materialized a new float32x4 %p "
+ "[float32x4(%e, %e, %e, %e)] for object at %d\n",
+ reinterpret_cast<void*>(*float32x4),
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ d.destination());
+ }
+ DCHECK(values.at(d.destination())->IsTheHole());
+ values.Set(d.destination(), float32x4);
+ }
+
+ // Play it safe and clear all object float32x4 values before we continue.
+ deferred_objects_float32x4_values_.Clear();
+
+ // Materialize all float64x2 values required for arguments/captured objects.
+ for (int i = 0; i < deferred_objects_float64x2_values_.length(); i++) {
+ SIMD128MaterializationDescriptor<int> d =
+ deferred_objects_float64x2_values_[i];
+ float64x2_value_t x2 = d.value().d2;
+ Handle<Object> float64x2 = isolate_->factory()->NewFloat64x2(x2);
+ if (trace_scope_ != NULL) {
+ PrintF(trace_scope_->file(),
+ "Materialized a new float64x2 %p "
+ "[float64x2(%e, %e)] for object at %d\n",
+ reinterpret_cast<void*>(*float64x2),
+ x2.storage[0], x2.storage[1],
+ d.destination());
+ }
+ DCHECK(values.at(d.destination())->IsTheHole());
+ values.Set(d.destination(), float64x2);
+ }
+
+ // Play it safe and clear all object float64x2 values before we continue.
+ deferred_objects_float64x2_values_.Clear();
+
+ // Materialize all int32x4 values required for arguments/captured objects.
+ for (int i = 0; i < deferred_objects_int32x4_values_.length(); i++) {
+ SIMD128MaterializationDescriptor<int> d =
+ deferred_objects_int32x4_values_[i];
+ int32x4_value_t x4 = d.value().i4;
+ Handle<Object> int32x4 = isolate_->factory()->NewInt32x4(x4);
+ if (trace_scope_ != NULL) {
+ PrintF(trace_scope_->file(),
+ "Materialized a new int32x4 %p "
+ "[int32x4(%u, %u, %u, %u)] for object at %d\n",
+ reinterpret_cast<void*>(*int32x4),
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ d.destination());
+ }
+ DCHECK(values.at(d.destination())->IsTheHole());
+ values.Set(d.destination(), int32x4);
+ }
+
+ // Play it safe and clear all object int32x4 values before we continue.
+ deferred_objects_int32x4_values_.Clear();
+
// Materialize arguments/captured objects.
if (!deferred_objects_.is_empty()) {
List<Handle<Object> > materialized_objects(deferred_objects_.length());
case Translation::INT32_REGISTER:
case Translation::UINT32_REGISTER:
case Translation::DOUBLE_REGISTER:
+ case Translation::FLOAT32x4_REGISTER:
+ case Translation::FLOAT64x2_REGISTER:
+ case Translation::INT32x4_REGISTER:
case Translation::STACK_SLOT:
case Translation::INT32_STACK_SLOT:
case Translation::UINT32_STACK_SLOT:
case Translation::DOUBLE_STACK_SLOT:
+ case Translation::FLOAT32x4_STACK_SLOT:
+ case Translation::FLOAT64x2_STACK_SLOT:
+ case Translation::INT32x4_STACK_SLOT:
case Translation::LITERAL: {
// The value is not part of any materialized object, so we can ignore it.
iterator->Skip(Translation::NumberOfOperandsFor(opcode));
return;
}
+ case Translation::FLOAT32x4_REGISTER:
+ case Translation::FLOAT64x2_REGISTER:
+ case Translation::INT32x4_REGISTER: {
+ int input_reg = iterator->Next();
+ simd128_value_t value = input_->GetSIMD128Register(input_reg);
+ if (trace_scope_ != NULL) {
+ if (opcode == Translation::FLOAT32x4_REGISTER) {
+ float32x4_value_t x4 = value.f4;
+ PrintF(trace_scope_->file(),
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+ reinterpret_cast<intptr_t>(object_slot),
+ field_index);
+ PrintF(trace_scope_->file(),
+ "float32x4(%e, %e, %e, %e) ; %s\n",
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ SIMD128Register::AllocationIndexToString(input_reg));
+ } else if (opcode == Translation::FLOAT64x2_REGISTER) {
+ float64x2_value_t x2 = value.d2;
+ PrintF(trace_scope_->file(),
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+ reinterpret_cast<intptr_t>(object_slot),
+ field_index);
+ PrintF(trace_scope_->file(),
+ "float64x2(%e, %e) ; %s\n",
+ x2.storage[0], x2.storage[1],
+ SIMD128Register::AllocationIndexToString(input_reg));
+ } else {
+ DCHECK(opcode == Translation::INT32x4_REGISTER);
+ int32x4_value_t x4 = value.i4;
+ PrintF(trace_scope_->file(),
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+ reinterpret_cast<intptr_t>(object_slot),
+ field_index);
+ PrintF(trace_scope_->file(),
+ "int32x4(%u, %u, %u, %u) ; %s\n",
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ SIMD128Register::AllocationIndexToString(input_reg));
+ }
+ }
+ AddObjectSIMD128Value(value, opcode);
+ return;
+ }
+
case Translation::STACK_SLOT: {
int input_slot_index = iterator->Next();
unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
return;
}
+ case Translation::FLOAT32x4_STACK_SLOT:
+ case Translation::FLOAT64x2_STACK_SLOT:
+ case Translation::INT32x4_STACK_SLOT: {
+ int input_slot_index = iterator->Next();
+ unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
+ simd128_value_t value = input_->GetSIMD128FrameSlot(input_offset);
+ if (trace_scope_ != NULL) {
+ if (opcode == Translation::FLOAT32x4_STACK_SLOT) {
+ float32x4_value_t x4 = value.f4;
+ PrintF(trace_scope_->file(),
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+ reinterpret_cast<intptr_t>(object_slot),
+ field_index);
+ PrintF(trace_scope_->file(),
+ "float32x4(%e, %e, %e, %e) ; [sp + %d]\n",
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ input_offset);
+ } else if (opcode == Translation::FLOAT64x2_STACK_SLOT) {
+ float64x2_value_t x2 = value.d2;
+ PrintF(trace_scope_->file(),
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+ reinterpret_cast<intptr_t>(object_slot),
+ field_index);
+ PrintF(trace_scope_->file(),
+ "float64x2(%e, %e) ; [sp + %d]\n",
+ x2.storage[0], x2.storage[1],
+ input_offset);
+ } else {
+ DCHECK(opcode == Translation::INT32x4_STACK_SLOT);
+ int32x4_value_t x4 = value.i4;
+ PrintF(trace_scope_->file(),
+ " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
+ reinterpret_cast<intptr_t>(object_slot),
+ field_index);
+ PrintF(trace_scope_->file(),
+ "int32x4(%u, %u, %u, %u) ; [sp + %d]\n",
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ input_offset);
+ }
+ }
+ AddObjectSIMD128Value(value, opcode);
+ return;
+ }
+
case Translation::LITERAL: {
Object* literal = ComputeLiteral(iterator->Next());
if (trace_scope_ != NULL) {
return;
}
+ case Translation::FLOAT32x4_REGISTER:
+ case Translation::FLOAT64x2_REGISTER:
+ case Translation::INT32x4_REGISTER: {
+ int input_reg = iterator->Next();
+ simd128_value_t value = input_->GetSIMD128Register(input_reg);
+ if (trace_scope_ != NULL) {
+ if (opcode == Translation::FLOAT32x4_REGISTER) {
+ float32x4_value_t x4 = value.f4;
+ PrintF(trace_scope_->file(),
+ " 0x%08" V8PRIxPTR ":"
+ " [top + %d] <- float32x4(%e, %e, %e, %e) ; %s\n",
+ output_[frame_index]->GetTop() + output_offset,
+ output_offset,
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ SIMD128Register::AllocationIndexToString(input_reg));
+ } else if (opcode == Translation::FLOAT64x2_REGISTER) {
+ float64x2_value_t x2 = value.d2;
+ PrintF(trace_scope_->file(),
+ " 0x%08" V8PRIxPTR ":"
+ " [top + %d] <- float64x2(%e, %e) ; %s\n",
+ output_[frame_index]->GetTop() + output_offset,
+ output_offset,
+ x2.storage[0], x2.storage[1],
+ SIMD128Register::AllocationIndexToString(input_reg));
+ } else {
+ DCHECK(opcode == Translation::INT32x4_REGISTER);
+ int32x4_value_t x4 = value.i4;
+ PrintF(trace_scope_->file(),
+ " 0x%08" V8PRIxPTR ":"
+ " [top + %d] <- int32x4(%u, %u, %u, %u) ; %s\n",
+ output_[frame_index]->GetTop() + output_offset,
+ output_offset,
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ SIMD128Register::AllocationIndexToString(input_reg));
+ }
+ }
+ // We save the untagged value on the side and store a GC-safe
+ // temporary placeholder in the frame.
+ AddSIMD128Value(output_[frame_index]->GetTop() + output_offset, value,
+ opcode);
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
+ return;
+ }
+
case Translation::STACK_SLOT: {
int input_slot_index = iterator->Next();
unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
return;
}
+ case Translation::FLOAT32x4_STACK_SLOT:
+ case Translation::FLOAT64x2_STACK_SLOT:
+ case Translation::INT32x4_STACK_SLOT: {
+ int input_slot_index = iterator->Next();
+ unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
+ simd128_value_t value = input_->GetSIMD128FrameSlot(input_offset);
+ if (trace_scope_ != NULL) {
+ if (opcode == Translation::FLOAT32x4_STACK_SLOT) {
+ float32x4_value_t x4 = value.f4;
+ PrintF(trace_scope_->file(),
+ " 0x%08" V8PRIxPTR ": "
+ "[top + %d] <- float32x4(%e, %e, %e, %e) ; [sp + %d]\n",
+ output_[frame_index]->GetTop() + output_offset,
+ output_offset,
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ input_offset);
+ } else if (opcode == Translation::FLOAT64x2_STACK_SLOT) {
+ float64x2_value_t x2 = value.d2;
+ PrintF(trace_scope_->file(),
+ " 0x%08" V8PRIxPTR ": "
+ "[top + %d] <- float64x2(%e, %e) ; [sp + %d]\n",
+ output_[frame_index]->GetTop() + output_offset,
+ output_offset,
+ x2.storage[0], x2.storage[1],
+ input_offset);
+ } else {
+ DCHECK(opcode == Translation::INT32x4_STACK_SLOT);
+ int32x4_value_t x4 = value.i4;
+ PrintF(trace_scope_->file(),
+ " 0x%08" V8PRIxPTR ": "
+ "[top + %d] <- int32x4(%u, %u, %u, %u) ; [sp + %d]\n",
+ output_[frame_index]->GetTop() + output_offset,
+ output_offset,
+ x4.storage[0], x4.storage[1], x4.storage[2], x4.storage[3],
+ input_offset);
+ }
+ }
+ // We save the untagged value on the side and store a GC-safe
+ // temporary placeholder in the frame.
+ AddSIMD128Value(output_[frame_index]->GetTop() + output_offset, value,
+ opcode);
+ output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
+ return;
+ }
+
case Translation::LITERAL: {
Object* literal = ComputeLiteral(iterator->Next());
if (trace_scope_ != NULL) {
}
+void Deoptimizer::AddObjectSIMD128Value(simd128_value_t value,
+ int translation_opcode) {
+ deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value());
+ SIMD128MaterializationDescriptor<int> value_desc(
+ deferred_objects_tagged_values_.length() - 1, value);
+ Translation::Opcode opcode =
+ static_cast<Translation::Opcode>(translation_opcode);
+ if (opcode == Translation::FLOAT32x4_REGISTER ||
+ opcode == Translation::FLOAT32x4_STACK_SLOT) {
+ deferred_objects_float32x4_values_.Add(value_desc);
+ } else if (opcode == Translation::FLOAT64x2_REGISTER ||
+ opcode == Translation::FLOAT64x2_STACK_SLOT) {
+ deferred_objects_float64x2_values_.Add(value_desc);
+ } else {
+ DCHECK(opcode == Translation::INT32x4_REGISTER ||
+ opcode == Translation::INT32x4_STACK_SLOT);
+ deferred_objects_int32x4_values_.Add(value_desc);
+ }
+}
+
+
void Deoptimizer::AddDoubleValue(intptr_t slot_address, double value) {
HeapNumberMaterializationDescriptor<Address> value_desc(
reinterpret_cast<Address>(slot_address), value);
}
+void Deoptimizer::AddSIMD128Value(intptr_t slot_address,
+ simd128_value_t value,
+ int translation_opcode) {
+ SIMD128MaterializationDescriptor<Address> value_desc(
+ reinterpret_cast<Address>(slot_address), value);
+ Translation::Opcode opcode =
+ static_cast<Translation::Opcode>(translation_opcode);
+ if (opcode == Translation::FLOAT32x4_REGISTER ||
+ opcode == Translation::FLOAT32x4_STACK_SLOT) {
+ deferred_float32x4s_.Add(value_desc);
+ } else if (opcode == Translation::FLOAT64x2_REGISTER ||
+ opcode == Translation::FLOAT64x2_STACK_SLOT) {
+ deferred_float64x2s_.Add(value_desc);
+ } else {
+ DCHECK(opcode == Translation::INT32x4_REGISTER ||
+ opcode == Translation::INT32x4_STACK_SLOT);
+ deferred_int32x4s_.Add(value_desc);
+ }
+}
+
+
void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
BailoutType type,
int max_entry_id) {
}
+void Translation::StoreSIMD128Register(SIMD128Register reg, Opcode opcode) {
+ buffer_->Add(opcode, zone());
+ buffer_->Add(SIMD128Register::ToAllocationIndex(reg), zone());
+}
+
+
void Translation::StoreStackSlot(int index) {
buffer_->Add(STACK_SLOT, zone());
buffer_->Add(index, zone());
}
+void Translation::StoreSIMD128StackSlot(int index, Opcode opcode) {
+ buffer_->Add(opcode, zone());
+ buffer_->Add(index, zone());
+}
+
+
void Translation::StoreLiteral(int literal_id) {
buffer_->Add(LITERAL, zone());
buffer_->Add(literal_id, zone());
case INT32_REGISTER:
case UINT32_REGISTER:
case DOUBLE_REGISTER:
+ case FLOAT32x4_REGISTER:
+ case FLOAT64x2_REGISTER:
+ case INT32x4_REGISTER:
case STACK_SLOT:
case INT32_STACK_SLOT:
case UINT32_STACK_SLOT:
case DOUBLE_STACK_SLOT:
+ case FLOAT32x4_STACK_SLOT:
+ case FLOAT64x2_STACK_SLOT:
+ case INT32x4_STACK_SLOT:
case LITERAL:
case COMPILED_STUB_FRAME:
return 1;
case Translation::INT32_REGISTER:
case Translation::UINT32_REGISTER:
case Translation::DOUBLE_REGISTER:
+ case Translation::FLOAT32x4_REGISTER:
+ case Translation::FLOAT64x2_REGISTER:
+ case Translation::INT32x4_REGISTER:
// We are at safepoint which corresponds to call. All registers are
// saved by caller so there would be no live registers at this
// point. Thus these translation commands should not be used.
return SlotRef(slot_addr, SlotRef::DOUBLE);
}
+ case Translation::FLOAT32x4_STACK_SLOT: {
+ int slot_index = iterator->Next();
+ Address slot_addr = SlotAddress(frame, slot_index);
+ return SlotRef(slot_addr, SlotRef::FLOAT32x4);
+ }
+
+ case Translation::FLOAT64x2_STACK_SLOT: {
+ int slot_index = iterator->Next();
+ Address slot_addr = SlotAddress(frame, slot_index);
+ return SlotRef(slot_addr, SlotRef::FLOAT64x2);
+ }
+
+ case Translation::INT32x4_STACK_SLOT: {
+ int slot_index = iterator->Next();
+ Address slot_addr = SlotAddress(frame, slot_index);
+ return SlotRef(slot_addr, SlotRef::INT32x4);
+ }
+
case Translation::LITERAL: {
int literal_index = iterator->Next();
return SlotRef(data->GetIsolate(),
return isolate->factory()->NewNumber(value);
}
+ case FLOAT32x4:
+ return isolate->factory()->NewFloat32x4(read_simd128_value(addr_).f4);
+
+ case FLOAT64x2:
+ return isolate->factory()->NewFloat64x2(read_simd128_value(addr_).d2);
+
+ case INT32x4:
+ return isolate->factory()->NewInt32x4(read_simd128_value(addr_).i4);
+
case LITERAL:
return literal_;