Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index 98667ce87e35070f7410da03248b62363a847a02..c62d7d470830c5908b563610b626d8da6a9856df 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -2245,10 +2245,35 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
} |
-Operand LCodeGen::BuildExternalArrayOperand( |
+void LCodeGen::DoLoadKeyedFastDoubleElement( |
+ LLoadKeyedFastDoubleElement* instr) { |
+ Register elements = ToRegister(instr->elements()); |
+ XMMRegister result(ToDoubleRegister(instr->result())); |
+ |
+ if (instr->hydrogen()->RequiresHoleCheck()) { |
+ int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
+ sizeof(kHoleNanLower32); |
+ Operand hole_check_operand = BuildFastArrayOperand( |
+ instr->elements(), |
+ instr->key(), |
+ JSObject::FAST_DOUBLE_ELEMENTS, |
+ offset); |
+ __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
+ DeoptimizeIf(equal, instr->environment()); |
+ } |
+ |
+ Operand double_load_operand = BuildFastArrayOperand( |
+ instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, |
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag); |
+ __ movsd(result, double_load_operand); |
+} |
+ |
+ |
+Operand LCodeGen::BuildFastArrayOperand( |
LOperand* external_pointer, |
LOperand* key, |
- JSObject::ElementsKind elements_kind) { |
+ JSObject::ElementsKind elements_kind, |
+ uint32_t offset) { |
Register external_pointer_reg = ToRegister(external_pointer); |
int shift_size = ElementsKindToShiftSize(elements_kind); |
if (key->IsConstantOperand()) { |
@@ -2256,10 +2281,12 @@ Operand LCodeGen::BuildExternalArrayOperand( |
if (constant_value & 0xF0000000) { |
Abort("array index constant value too big"); |
} |
- return Operand(external_pointer_reg, constant_value * (1 << shift_size)); |
+ return Operand(external_pointer_reg, |
+ constant_value * (1 << shift_size) + offset); |
} else { |
ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
- return Operand(external_pointer_reg, ToRegister(key), scale_factor, 0); |
+ return Operand(external_pointer_reg, ToRegister(key), |
+ scale_factor, offset); |
} |
} |
@@ -2267,8 +2294,8 @@ Operand LCodeGen::BuildExternalArrayOperand( |
void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
LLoadKeyedSpecializedArrayElement* instr) { |
JSObject::ElementsKind elements_kind = instr->elements_kind(); |
- Operand operand(BuildExternalArrayOperand(instr->external_pointer(), |
- instr->key(), elements_kind)); |
+ Operand operand(BuildFastArrayOperand(instr->external_pointer(), |
+ instr->key(), elements_kind, 0)); |
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { |
XMMRegister result(ToDoubleRegister(instr->result())); |
__ movss(result, operand); |
@@ -2994,8 +3021,8 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
LStoreKeyedSpecializedArrayElement* instr) { |
JSObject::ElementsKind elements_kind = instr->elements_kind(); |
- Operand operand(BuildExternalArrayOperand(instr->external_pointer(), |
- instr->key(), elements_kind)); |
+ Operand operand(BuildFastArrayOperand(instr->external_pointer(), |
+ instr->key(), elements_kind, 0)); |
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { |
XMMRegister value(ToDoubleRegister(instr->value())); |
__ cvtsd2ss(value, value); |
@@ -3072,6 +3099,28 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { |
} |
+void LCodeGen::DoStoreKeyedFastDoubleElement( |
+ LStoreKeyedFastDoubleElement* instr) { |
+ XMMRegister value = ToDoubleRegister(instr->value()); |
+ Register elements = ToRegister(instr->elements()); |
+ Label have_value; |
+ |
+ __ ucomisd(value, value); |
+ __ j(parity_odd, &have_value); // NaN. |
+ |
+ ExternalReference canonical_nan_reference = |
+ ExternalReference::address_of_canonical_non_hole_nan(); |
+ __ Set(kScratchRegister, BitCast<uint64_t>( |
+ FixedDoubleArray::canonical_not_the_hole_nan_as_double())); |
+ __ movq(value, kScratchRegister); |
+ |
+ __ bind(&have_value); |
+ Operand double_store_operand = BuildFastArrayOperand( |
+ instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, |
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag); |
+ __ movsd(double_store_operand, value); |
+} |
+ |
void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
ASSERT(ToRegister(instr->object()).is(rdx)); |
ASSERT(ToRegister(instr->key()).is(rcx)); |