Index: src/ia32/lithium-codegen-ia32.cc |
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc |
index 32c66a05f509df7df7d7314401f628dfbdcf4e87..7468d310a3d7721b01495aa16294a3aa79ff7ee3 100644 |
--- a/src/ia32/lithium-codegen-ia32.cc |
+++ b/src/ia32/lithium-codegen-ia32.cc |
@@ -2749,33 +2749,71 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
} |
-void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
- Register result = ToRegister(instr->result()); |
- |
- // Load the result. |
- __ mov(result, |
- BuildFastArrayOperand(instr->elements(), |
- instr->key(), |
- instr->hydrogen()->key()->representation(), |
- FAST_ELEMENTS, |
- FixedArray::kHeaderSize - kHeapObjectTag, |
- instr->additional_index())); |
- |
- // Check for the hole value. |
- if (instr->hydrogen()->RequiresHoleCheck()) { |
- if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
- __ test(result, Immediate(kSmiTagMask)); |
- DeoptimizeIf(not_equal, instr->environment()); |
- } else { |
- __ cmp(result, factory()->the_hole_value()); |
- DeoptimizeIf(equal, instr->environment()); |
+void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
+ ElementsKind elements_kind = instr->elements_kind(); |
+ LOperand* key = instr->key(); |
+ if (!key->IsConstantOperand() && |
+ ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), |
+ elements_kind)) { |
+ __ SmiUntag(ToRegister(key)); |
+ } |
+ Operand operand(BuildFastArrayOperand( |
+ instr->elements(), |
+ key, |
+ instr->hydrogen()->key()->representation(), |
+ elements_kind, |
+ 0, |
+ instr->additional_index())); |
+ if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
+ XMMRegister result(ToDoubleRegister(instr->result())); |
+ __ movss(result, operand); |
+ __ cvtss2sd(result, result); |
+ } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
+ __ movdbl(ToDoubleRegister(instr->result()), operand); |
+ } else { |
+ Register result(ToRegister(instr->result())); |
+ switch (elements_kind) { |
+ case EXTERNAL_BYTE_ELEMENTS: |
+ __ movsx_b(result, operand); |
+ break; |
+ case EXTERNAL_PIXEL_ELEMENTS: |
+ case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
+ __ movzx_b(result, operand); |
+ break; |
+ case EXTERNAL_SHORT_ELEMENTS: |
+ __ movsx_w(result, operand); |
+ break; |
+ case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
+ __ movzx_w(result, operand); |
+ break; |
+ case EXTERNAL_INT_ELEMENTS: |
+ __ mov(result, operand); |
+ break; |
+ case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
+ __ mov(result, operand); |
+ if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
+ __ test(result, Operand(result)); |
+ DeoptimizeIf(negative, instr->environment()); |
+ } |
+ break; |
+ case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_DOUBLE_ELEMENTS: |
+ case FAST_SMI_ELEMENTS: |
+ case FAST_ELEMENTS: |
+ case FAST_DOUBLE_ELEMENTS: |
+ case FAST_HOLEY_SMI_ELEMENTS: |
+ case FAST_HOLEY_ELEMENTS: |
+ case FAST_HOLEY_DOUBLE_ELEMENTS: |
+ case DICTIONARY_ELEMENTS: |
+ case NON_STRICT_ARGUMENTS_ELEMENTS: |
+ UNREACHABLE(); |
+ break; |
} |
} |
} |
-void LCodeGen::DoLoadKeyedFastDoubleElement( |
- LLoadKeyedFastDoubleElement* instr) { |
+void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
XMMRegister result = ToDoubleRegister(instr->result()); |
if (instr->hydrogen()->RequiresHoleCheck()) { |
@@ -2802,6 +2840,42 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( |
} |
+void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
+ Register result = ToRegister(instr->result()); |
+ |
+ // Load the result. |
+ __ mov(result, |
+ BuildFastArrayOperand(instr->elements(), |
+ instr->key(), |
+ instr->hydrogen()->key()->representation(), |
+ FAST_ELEMENTS, |
+ FixedArray::kHeaderSize - kHeapObjectTag, |
+ instr->additional_index())); |
+ |
+ // Check for the hole value. |
+ if (instr->hydrogen()->RequiresHoleCheck()) { |
+ if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
+ __ test(result, Immediate(kSmiTagMask)); |
+ DeoptimizeIf(not_equal, instr->environment()); |
+ } else { |
+ __ cmp(result, factory()->the_hole_value()); |
+ DeoptimizeIf(equal, instr->environment()); |
+ } |
+ } |
+} |
+ |
+ |
+void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
+ if (instr->is_external()) { |
+ DoLoadKeyedExternalArray(instr); |
+ } else if (instr->hydrogen()->representation().IsDouble()) { |
+ DoLoadKeyedFixedDoubleArray(instr); |
+ } else { |
+ DoLoadKeyedFixedArray(instr); |
+ } |
+} |
+ |
+ |
Operand LCodeGen::BuildFastArrayOperand( |
LOperand* elements_pointer, |
LOperand* key, |
@@ -2811,7 +2885,7 @@ Operand LCodeGen::BuildFastArrayOperand( |
uint32_t additional_index) { |
Register elements_pointer_reg = ToRegister(elements_pointer); |
int shift_size = ElementsKindToShiftSize(elements_kind); |
- // Even though the HLoad/StoreKeyedFastElement instructions force the input |
+ // Even though the HLoad/StoreKeyed instructions force the input |
// representation for the key to be an integer, the input gets replaced during |
// bound check elimination with the index argument to the bounds check, which |
// can be tagged, so that case must be handled here, too. |
@@ -2836,71 +2910,6 @@ Operand LCodeGen::BuildFastArrayOperand( |
} |
-void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
- LLoadKeyedSpecializedArrayElement* instr) { |
- ElementsKind elements_kind = instr->elements_kind(); |
- LOperand* key = instr->key(); |
- if (!key->IsConstantOperand() && |
- ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), |
- elements_kind)) { |
- __ SmiUntag(ToRegister(key)); |
- } |
- Operand operand(BuildFastArrayOperand( |
- instr->external_pointer(), |
- key, |
- instr->hydrogen()->key()->representation(), |
- elements_kind, |
- 0, |
- instr->additional_index())); |
- if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
- XMMRegister result(ToDoubleRegister(instr->result())); |
- __ movss(result, operand); |
- __ cvtss2sd(result, result); |
- } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
- __ movdbl(ToDoubleRegister(instr->result()), operand); |
- } else { |
- Register result(ToRegister(instr->result())); |
- switch (elements_kind) { |
- case EXTERNAL_BYTE_ELEMENTS: |
- __ movsx_b(result, operand); |
- break; |
- case EXTERNAL_PIXEL_ELEMENTS: |
- case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
- __ movzx_b(result, operand); |
- break; |
- case EXTERNAL_SHORT_ELEMENTS: |
- __ movsx_w(result, operand); |
- break; |
- case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
- __ movzx_w(result, operand); |
- break; |
- case EXTERNAL_INT_ELEMENTS: |
- __ mov(result, operand); |
- break; |
- case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
- __ mov(result, operand); |
- if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
- __ test(result, Operand(result)); |
- DeoptimizeIf(negative, instr->environment()); |
- } |
- break; |
- case EXTERNAL_FLOAT_ELEMENTS: |
- case EXTERNAL_DOUBLE_ELEMENTS: |
- case FAST_SMI_ELEMENTS: |
- case FAST_ELEMENTS: |
- case FAST_DOUBLE_ELEMENTS: |
- case FAST_HOLEY_SMI_ELEMENTS: |
- case FAST_HOLEY_ELEMENTS: |
- case FAST_HOLEY_DOUBLE_ELEMENTS: |
- case DICTIONARY_ELEMENTS: |
- case NON_STRICT_ARGUMENTS_ELEMENTS: |
- UNREACHABLE(); |
- break; |
- } |
- } |
-} |
- |
- |
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
ASSERT(ToRegister(instr->context()).is(esi)); |
ASSERT(ToRegister(instr->object()).is(edx)); |
@@ -3818,8 +3827,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
} |
-void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
- LStoreKeyedSpecializedArrayElement* instr) { |
+void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
ElementsKind elements_kind = instr->elements_kind(); |
LOperand* key = instr->key(); |
if (!key->IsConstantOperand() && |
@@ -3828,7 +3836,7 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
__ SmiUntag(ToRegister(key)); |
} |
Operand operand(BuildFastArrayOperand( |
- instr->external_pointer(), |
+ instr->elements(), |
key, |
instr->hydrogen()->key()->representation(), |
elements_kind, |
@@ -3872,13 +3880,39 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
} |
-void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { |
+void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
+ XMMRegister value = ToDoubleRegister(instr->value()); |
+ |
+ if (instr->NeedsCanonicalization()) { |
+ Label have_value; |
+ |
+ __ ucomisd(value, value); |
+ __ j(parity_odd, &have_value); // NaN. |
+ |
+ ExternalReference canonical_nan_reference = |
+ ExternalReference::address_of_canonical_non_hole_nan(); |
+ __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); |
+ __ bind(&have_value); |
+ } |
+ |
+ Operand double_store_operand = BuildFastArrayOperand( |
+ instr->elements(), |
+ instr->key(), |
+ instr->hydrogen()->key()->representation(), |
+ FAST_DOUBLE_ELEMENTS, |
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
+ instr->additional_index()); |
+ __ movdbl(double_store_operand, value); |
+} |
+ |
+ |
+void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
Register value = ToRegister(instr->value()); |
- Register elements = ToRegister(instr->object()); |
+ Register elements = ToRegister(instr->elements()); |
Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
Operand operand = BuildFastArrayOperand( |
- instr->object(), |
+ instr->elements(), |
instr->key(), |
instr->hydrogen()->key()->representation(), |
FAST_ELEMENTS, |
@@ -3903,30 +3937,15 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { |
} |
-void LCodeGen::DoStoreKeyedFastDoubleElement( |
- LStoreKeyedFastDoubleElement* instr) { |
- XMMRegister value = ToDoubleRegister(instr->value()); |
- |
- if (instr->NeedsCanonicalization()) { |
- Label have_value; |
- |
- __ ucomisd(value, value); |
- __ j(parity_odd, &have_value); // NaN. |
- |
- ExternalReference canonical_nan_reference = |
- ExternalReference::address_of_canonical_non_hole_nan(); |
- __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); |
- __ bind(&have_value); |
+void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
+ // By cases...external, fast-double, fast |
+ if (instr->is_external()) { |
+ DoStoreKeyedExternalArray(instr); |
+ } else if (instr->hydrogen()->value()->representation().IsDouble()) { |
+ DoStoreKeyedFixedDoubleArray(instr); |
+ } else { |
+ DoStoreKeyedFixedArray(instr); |
} |
- |
- Operand double_store_operand = BuildFastArrayOperand( |
- instr->elements(), |
- instr->key(), |
- instr->hydrogen()->key()->representation(), |
- FAST_DOUBLE_ELEMENTS, |
- FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
- instr->additional_index()); |
- __ movdbl(double_store_operand, value); |
} |