| 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:
|
|
|