Index: src/x64/ic-x64.cc |
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc |
index 20ed734b8a57ebe6139ae7331b3fbf56c4f318fe..e17ff1fa4ba50315fb2d071e732e8d6ed0f86d56 100644 |
--- a/src/x64/ic-x64.cc |
+++ b/src/x64/ic-x64.cc |
@@ -702,7 +702,7 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm, |
// -- rdx : receiver |
// -- rsp[0] : return address |
// ----------------------------------- |
- Label slow, failed_allocation; |
+ Label slow; |
// Check that the object isn't a smi. |
__ JumpIfSmi(rdx, &slow); |
@@ -761,7 +761,7 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm, |
__ movl(rcx, Operand(rbx, rcx, times_4, 0)); |
break; |
case kExternalFloatArray: |
- __ fld_s(Operand(rbx, rcx, times_4, 0)); |
+ __ cvtss2sd(xmm0, Operand(rbx, rcx, times_4, 0)); |
break; |
default: |
UNREACHABLE(); |
@@ -773,20 +773,16 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm, |
// For integer array types: |
// rcx: value |
// For floating-point array type: |
- // FP(0): value |
+ // xmm0: value as double. |
- if (array_type == kExternalIntArray || |
- array_type == kExternalUnsignedIntArray) { |
- // For the Int and UnsignedInt array types, we need to see whether |
+ ASSERT(kSmiValueSize == 32); |
+ if (array_type == kExternalUnsignedIntArray) { |
+ // For the UnsignedInt array type, we need to see whether |
// the value can be represented in a Smi. If not, we need to convert |
// it to a HeapNumber. |
Label box_int; |
- if (array_type == kExternalIntArray) { |
- __ JumpIfNotValidSmiValue(rcx, &box_int); |
- } else { |
- ASSERT_EQ(array_type, kExternalUnsignedIntArray); |
- __ JumpIfUIntNotValidSmiValue(rcx, &box_int); |
- } |
+ |
+ __ JumpIfUIntNotValidSmiValue(rcx, &box_int); |
__ Integer32ToSmi(rax, rcx); |
__ ret(0); |
@@ -795,42 +791,29 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm, |
// Allocate a HeapNumber for the int and perform int-to-double |
// conversion. |
- __ push(rcx); |
- if (array_type == kExternalIntArray) { |
- __ fild_s(Operand(rsp, 0)); |
- } else { |
- ASSERT(array_type == kExternalUnsignedIntArray); |
- // The value is zero-extended on the stack, because all pushes are |
- // 64-bit and we loaded the value from memory with movl. |
- __ fild_d(Operand(rsp, 0)); |
- } |
- __ pop(rcx); |
- // FP(0): value |
- __ AllocateHeapNumber(rcx, rbx, &failed_allocation); |
+ ASSERT(array_type == kExternalUnsignedIntArray); |
+ // The value is zero-extended since we loaded the value from memory |
+ // with movl. |
+ __ cvtqsi2sd(xmm0, rcx); |
+ |
+ __ AllocateHeapNumber(rcx, rbx, &slow); |
// Set the value. |
+ __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); |
__ movq(rax, rcx); |
- __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); |
__ ret(0); |
} else if (array_type == kExternalFloatArray) { |
// For the floating-point array type, we need to always allocate a |
// HeapNumber. |
- __ AllocateHeapNumber(rcx, rbx, &failed_allocation); |
+ __ AllocateHeapNumber(rcx, rbx, &slow); |
// Set the value. |
+ __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); |
__ movq(rax, rcx); |
- __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); |
__ ret(0); |
} else { |
__ Integer32ToSmi(rax, rcx); |
__ ret(0); |
} |
- // If we fail allocation of the HeapNumber, we still have a value on |
- // top of the FPU stack. Remove it. |
- __ bind(&failed_allocation); |
- __ ffree(); |
- __ fincstp(); |
- // Fall through to slow case. |
- |
// Slow case: Jump to runtime. |
__ bind(&slow); |
__ IncrementCounter(&Counters::keyed_load_external_array_slow, 1); |
@@ -1116,10 +1099,8 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, |
break; |
case kExternalFloatArray: |
// Need to perform int-to-float conversion. |
- __ push(rdx); |
- __ fild_s(Operand(rsp, 0)); |
- __ pop(rdx); |
- __ fstp_s(Operand(rbx, rdi, times_4, 0)); |
+ __ cvtlsi2ss(xmm0, rdx); |
+ __ movss(Operand(rbx, rdi, times_4, 0), xmm0); |
break; |
default: |
UNREACHABLE(); |
@@ -1156,6 +1137,8 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, |
__ j(parity_even, &is_nan); |
__ push(rdx); // Make room on the stack. Receiver is no longer needed. |
+ // TODO(lrn): If the rounding of this conversion is not deliberate, maybe |
+ // switch to xmm registers. |
__ fistp_d(Operand(rsp, 0)); |
__ pop(rdx); |
// rdx: value (converted to an untagged integer) |
@@ -1201,7 +1184,7 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, |
// rbx: base pointer of external storage |
__ ffree(); |
__ fincstp(); |
- __ movq(rdx, Immediate(0)); |
+ __ Set(rdx, 0); |
switch (array_type) { |
case kExternalByteArray: |
case kExternalUnsignedByteArray: |