Chromium Code Reviews| Index: src/ia32/code-stubs-ia32.cc |
| =================================================================== |
| --- src/ia32/code-stubs-ia32.cc (revision 5989) |
| +++ src/ia32/code-stubs-ia32.cc (working copy) |
| @@ -2542,17 +2542,19 @@ |
| char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); |
| char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); |
| char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); |
| - CHECK_EQ(12, elem2_start - elem_start); // Two uint_32's and a pointer. |
| + char* elem_uout = reinterpret_cast<char*>(&(test_elem[0].untagged_output)); |
| + CHECK_EQ(20, elem2_start - elem_start); // Two uint_32's and a pointer. |
| CHECK_EQ(0, elem_in0 - elem_start); |
| CHECK_EQ(kIntSize, elem_in1 - elem_start); |
| CHECK_EQ(2 * kIntSize, elem_out - elem_start); |
| + CHECK_EQ(3 * kIntSize, elem_uout - elem_start); |
| } |
| #endif |
| - // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12]. |
| - __ lea(ecx, Operand(ecx, ecx, times_2, 0)); |
| + // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*20]. |
| + __ lea(ecx, Operand(ecx, ecx, times_4, 0)); |
| __ lea(ecx, Operand(eax, ecx, times_4, 0)); |
| // Check if cache matches: Double value is stored in uint32_t[2] array. |
| - NearLabel cache_miss; |
| + NearLabel cache_miss, allocate_cached_answer; |
| __ cmp(ebx, Operand(ecx, 0)); |
| __ j(not_equal, &cache_miss); |
| __ cmp(edx, Operand(ecx, kIntSize)); |
| @@ -2560,8 +2562,19 @@ |
| // Cache hit! |
| __ mov(eax, Operand(ecx, 2 * kIntSize)); |
| __ fstp(0); |
| + __ test(eax, Operand(eax)); |
| + __ j(zero, &allocate_cached_answer); // The answer is cached as untagged. |
|
Erik Corry
2010/12/13 20:26:13
"is cached, but only as untagged".
|
| __ ret(kPointerSize); |
| + __ bind(&allocate_cached_answer); |
| + __ AllocateHeapNumber(eax, edi, edx, &runtime_call); |
| + __ mov(ebx, Operand(ecx, 3 * kIntSize)); |
| + __ mov(FieldOperand(eax, HeapNumber::kValueOffset), ebx); |
| + __ mov(ebx, Operand(ecx, 4 * kIntSize)); |
| + __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx); |
| + __ mov(Operand(ecx, 2 * kIntSize), eax); |
| + __ ret(kPointerSize); |
| + |
| __ bind(&cache_miss); |
| // Update cache with new value. |
| // We are short on registers, so use no_reg as scratch. |
| @@ -2571,6 +2584,7 @@ |
| __ mov(Operand(ecx, 0), ebx); |
| __ mov(Operand(ecx, kIntSize), edx); |
| __ mov(Operand(ecx, 2 * kIntSize), eax); |
| + __ fst_d(Operand(ecx, 3 * kIntSize)); |
| __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| __ ret(kPointerSize); |
| @@ -2735,14 +2749,16 @@ |
| char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); |
| char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); |
| char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); |
| - CHECK_EQ(12, elem2_start - elem_start); // Two uint_32's and a pointer. |
| + char* elem_uout = reinterpret_cast<char*>(&(test_elem[0].untagged_output)); |
| + CHECK_EQ(20, elem2_start - elem_start); // Two uint_32's and a pointer. |
|
Erik Corry
2010/12/13 20:26:13
Comment is now wrong and type has wrong name.
|
| CHECK_EQ(0, elem_in0 - elem_start); |
| CHECK_EQ(kIntSize, elem_in1 - elem_start); |
| CHECK_EQ(2 * kIntSize, elem_out - elem_start); |
| + CHECK_EQ(3 * kIntSize, elem_uout - elem_start); |
| } |
| #endif |
| // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12]. |
| - __ lea(ecx, Operand(ecx, ecx, times_2, 0)); |
| + __ lea(ecx, Operand(ecx, ecx, times_4, 0)); |
| __ lea(ecx, Operand(eax, ecx, times_4, 0)); |
| // Check if cache matches: Double value is stored in uint32_t[2] array. |
| NearLabel cache_miss; |
| @@ -2751,35 +2767,33 @@ |
| __ cmp(edx, Operand(ecx, kIntSize)); |
| __ j(not_equal, &cache_miss); |
| // Cache hit! |
| - __ mov(eax, Operand(ecx, 2 * kIntSize)); |
| - __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
| + __ movdbl(xmm1, Operand(ecx, 3 * kIntSize)); |
| __ Ret(); |
| __ bind(&cache_miss); |
| // Update cache with new value. |
| // We are short on registers, so use no_reg as scratch. |
| // This gives slightly larger code. |
| - __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); |
| - __ sub(Operand(esp), Immediate(sizeof(double))); |
| + __ sub(Operand(esp), Immediate(kDoubleSize)); |
| __ movdbl(Operand(esp, 0), xmm1); |
| __ fld_d(Operand(esp, 0)); |
| - __ add(Operand(esp), Immediate(sizeof(double))); |
| + __ add(Operand(esp), Immediate(kDoubleSize)); |
| GenerateOperation(masm); |
| __ mov(Operand(ecx, 0), ebx); |
| __ mov(Operand(ecx, kIntSize), edx); |
| - __ mov(Operand(ecx, 2 * kIntSize), eax); |
| - __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| - __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
| + __ mov(Operand(ecx, 2 * kIntSize), Immediate(0)); // No tagged cached value. |
| + __ fst_d(Operand(ecx, 3 * kIntSize)); |
| + __ movdbl(xmm1, Operand(ecx, 3 * kIntSize)); |
| __ Ret(); |
| __ bind(&skip_cache); |
| - __ sub(Operand(esp), Immediate(2 * kPointerSize)); |
| + __ sub(Operand(esp), Immediate(kDoubleSize)); |
| __ movdbl(Operand(esp, 0), xmm1); |
| __ fld_d(Operand(esp, 0)); |
| GenerateOperation(masm); |
| __ fstp_d(Operand(esp, 0)); |
| __ movdbl(xmm1, Operand(esp, 0)); |
| - __ add(Operand(esp), Immediate(2 * kPointerSize)); |
| + __ add(Operand(esp), Immediate(kDoubleSize)); |
| __ Ret(); |
| __ bind(&call_runtime); |