| Index: src/ia32/stub-cache-ia32.cc
 | 
| diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
 | 
| index b7828b81ab6b2b83d107955815c1d8f4ad3f249e..c1d4f9789e387b0f4dd48219b48358d12deb5d03 100644
 | 
| --- a/src/ia32/stub-cache-ia32.cc
 | 
| +++ b/src/ia32/stub-cache-ia32.cc
 | 
| @@ -3260,30 +3260,16 @@ static void GenerateSmiKeyCheck(MacroAssembler* masm,
 | 
|                                  XMMRegister xmm_scratch0,
 | 
|                                  XMMRegister xmm_scratch1,
 | 
|                                  Label* fail) {
 | 
| -  // Check that key is a smi and if SSE2 is available a heap number
 | 
| +  // Check that key is a smi or a heap number
 | 
|    // containing a smi and branch if the check fails.
 | 
| -  if (CpuFeatures::IsSupported(SSE2)) {
 | 
| -    CpuFeatureScope use_sse2(masm, SSE2);
 | 
| -    Label key_ok;
 | 
| -    __ JumpIfSmi(key, &key_ok);
 | 
| -    __ cmp(FieldOperand(key, HeapObject::kMapOffset),
 | 
| -           Immediate(Handle<Map>(masm->isolate()->heap()->heap_number_map())));
 | 
| -    __ j(not_equal, fail);
 | 
| -    __ movdbl(xmm_scratch0, FieldOperand(key, HeapNumber::kValueOffset));
 | 
| -    __ cvttsd2si(scratch, Operand(xmm_scratch0));
 | 
| -    __ cvtsi2sd(xmm_scratch1, scratch);
 | 
| -    __ ucomisd(xmm_scratch1, xmm_scratch0);
 | 
| -    __ j(not_equal, fail);
 | 
| -    __ j(parity_even, fail);  // NaN.
 | 
| -    // Check if the key fits in the smi range.
 | 
| -    __ cmp(scratch, 0xc0000000);
 | 
| -    __ j(sign, fail);
 | 
| -    __ SmiTag(scratch);
 | 
| -    __ mov(key, scratch);
 | 
| -    __ bind(&key_ok);
 | 
| -  } else {
 | 
| -    __ JumpIfNotSmi(key, fail);
 | 
| -  }
 | 
| +  Label key_ok, key_tag;
 | 
| +  __ JumpIfSmi(key, &key_ok);
 | 
| +  __ TaggedToI(key, scratch, xmm_scratch0, false, &key_tag, fail);
 | 
| +  __ bind(&key_tag);
 | 
| +  __ SmiTag(scratch);
 | 
| +  __ j(overflow, fail);
 | 
| +  __ mov(key, scratch);
 | 
| +  __ bind(&key_ok);
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -3389,71 +3375,37 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
 | 
|        __ fstp_d(Operand(edi, ecx, times_4, 0));
 | 
|        __ ret(0);
 | 
|      } else {
 | 
| -      // Perform float-to-int conversion with truncation (round-to-zero)
 | 
| -      // behavior.
 | 
| -
 | 
| -      // For the moment we make the slow call to the runtime on
 | 
| -      // processors that don't support SSE2. The code in IntegerConvert
 | 
| -      // (code-stubs-ia32.cc) is roughly what is needed here though the
 | 
| -      // conversion failure case does not need to be handled.
 | 
| -      if (CpuFeatures::IsSupported(SSE2)) {
 | 
| -        if ((elements_kind == EXTERNAL_INT_ELEMENTS ||
 | 
| -             elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) &&
 | 
| -            CpuFeatures::IsSupported(SSE3)) {
 | 
| -          CpuFeatureScope scope(masm, SSE3);
 | 
| -          // fisttp stores values as signed integers. To represent the
 | 
| -          // entire range of int and unsigned int arrays, store as a
 | 
| -          // 64-bit int and discard the high 32 bits.
 | 
| -          __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
 | 
| -          __ sub(esp, Immediate(2 * kPointerSize));
 | 
| -          __ fisttp_d(Operand(esp, 0));
 | 
| -
 | 
| -          // If conversion failed (NaN, infinity, or a number outside
 | 
| -          // signed int64 range), the result is 0x8000000000000000, and
 | 
| -          // we must handle this case in the runtime.
 | 
| -          Label ok;
 | 
| -          __ cmp(Operand(esp, kPointerSize), Immediate(0x80000000u));
 | 
| -          __ j(not_equal, &ok);
 | 
| -          __ cmp(Operand(esp, 0), Immediate(0));
 | 
| -          __ j(not_equal, &ok);
 | 
| -          __ add(esp, Immediate(2 * kPointerSize));  // Restore the stack.
 | 
| -          __ jmp(&slow);
 | 
| -
 | 
| -          __ bind(&ok);
 | 
| -          __ pop(ebx);
 | 
| -          __ add(esp, Immediate(kPointerSize));
 | 
| +      // Truncate the HeapNumber to an int32
 | 
| +      __ TruncateHeapNumberToI(eax, ebx);
 | 
| +
 | 
| +      if ((elements_kind == EXTERNAL_INT_ELEMENTS ||
 | 
| +           elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS)) {
 | 
|            __ mov(Operand(edi, ecx, times_2, 0), ebx);
 | 
| -        } else {
 | 
| -          ASSERT(CpuFeatures::IsSupported(SSE2));
 | 
| -          CpuFeatureScope scope(masm, SSE2);
 | 
| -          __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset));
 | 
| -          __ cmp(ebx, 0x80000000u);
 | 
| -          __ j(equal, &slow);
 | 
| -          // ebx: untagged integer value
 | 
| -          switch (elements_kind) {
 | 
| -            case EXTERNAL_PIXEL_ELEMENTS:
 | 
| -              __ ClampUint8(ebx);
 | 
| -              // Fall through.
 | 
| -            case EXTERNAL_BYTE_ELEMENTS:
 | 
| -            case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
 | 
| -              __ SmiUntag(ecx);
 | 
| -              __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
 | 
| -              break;
 | 
| -            case EXTERNAL_SHORT_ELEMENTS:
 | 
| -            case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
 | 
| -              __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
 | 
| -              break;
 | 
| -            case EXTERNAL_INT_ELEMENTS:
 | 
| -            case EXTERNAL_UNSIGNED_INT_ELEMENTS:
 | 
| -              __ mov(Operand(edi, ecx, times_2, 0), ebx);
 | 
| -              break;
 | 
| -            default:
 | 
| -              UNREACHABLE();
 | 
| -              break;
 | 
| -          }
 | 
| -        }
 | 
| -        __ ret(0);  // Return original value.
 | 
| +      } else {
 | 
| +         // ebx: untagged integer value
 | 
| +         switch (elements_kind) {
 | 
| +           case EXTERNAL_PIXEL_ELEMENTS:
 | 
| +             __ ClampUint8(ebx);
 | 
| +             // Fall through.
 | 
| +           case EXTERNAL_BYTE_ELEMENTS:
 | 
| +           case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
 | 
| +             __ SmiUntag(ecx);
 | 
| +             __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
 | 
| +             break;
 | 
| +           case EXTERNAL_SHORT_ELEMENTS:
 | 
| +           case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
 | 
| +             __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
 | 
| +             break;
 | 
| +           case EXTERNAL_INT_ELEMENTS:
 | 
| +           case EXTERNAL_UNSIGNED_INT_ELEMENTS:
 | 
| +             __ mov(Operand(edi, ecx, times_2, 0), ebx);
 | 
| +             break;
 | 
| +           default:
 | 
| +             UNREACHABLE();
 | 
| +             break;
 | 
| +         }
 | 
|        }
 | 
| +      __ ret(0);  // Return original value.
 | 
|      }
 | 
|    }
 | 
|  
 | 
| 
 |