| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2559 __ test(eax, Operand(eax)); | 2559 __ test(eax, Operand(eax)); |
| 2560 __ j(zero, &runtime_call_clear_stack); | 2560 __ j(zero, &runtime_call_clear_stack); |
| 2561 #ifdef DEBUG | 2561 #ifdef DEBUG |
| 2562 // Check that the layout of cache elements match expectations. | 2562 // Check that the layout of cache elements match expectations. |
| 2563 { TranscendentalCache::Element test_elem[2]; | 2563 { TranscendentalCache::Element test_elem[2]; |
| 2564 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); | 2564 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); |
| 2565 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); | 2565 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); |
| 2566 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); | 2566 char* elem_in0 = reinterpret_cast<char*>(&(test_elem[0].in[0])); |
| 2567 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); | 2567 char* elem_in1 = reinterpret_cast<char*>(&(test_elem[0].in[1])); |
| 2568 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); | 2568 char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output)); |
| 2569 CHECK_EQ(12, elem2_start - elem_start); // Two uint_32's and a pointer. | 2569 char* elem_uout = reinterpret_cast<char*>(&(test_elem[0].untagged_output)); |
| 2570 CHECK_EQ(20, elem2_start - elem_start); // Two uint_32's and a pointer. |
| 2570 CHECK_EQ(0, elem_in0 - elem_start); | 2571 CHECK_EQ(0, elem_in0 - elem_start); |
| 2571 CHECK_EQ(kIntSize, elem_in1 - elem_start); | 2572 CHECK_EQ(kIntSize, elem_in1 - elem_start); |
| 2572 CHECK_EQ(2 * kIntSize, elem_out - elem_start); | 2573 CHECK_EQ(2 * kIntSize, elem_out - elem_start); |
| 2574 CHECK_EQ(3 * kIntSize, elem_uout - elem_start); |
| 2573 } | 2575 } |
| 2574 #endif | 2576 #endif |
| 2575 // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12]. | 2577 // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*20]. |
| 2576 __ lea(ecx, Operand(ecx, ecx, times_2, 0)); | 2578 __ lea(ecx, Operand(ecx, ecx, times_4, 0)); |
| 2577 __ lea(ecx, Operand(eax, ecx, times_4, 0)); | 2579 __ lea(ecx, Operand(eax, ecx, times_4, 0)); |
| 2578 // Check if cache matches: Double value is stored in uint32_t[2] array. | 2580 // Check if cache matches: Double value is stored in uint32_t[2] array. |
| 2579 NearLabel cache_miss; | 2581 NearLabel cache_miss, allocate_cached_answer; |
| 2580 __ cmp(ebx, Operand(ecx, 0)); | 2582 __ cmp(ebx, Operand(ecx, 0)); |
| 2581 __ j(not_equal, &cache_miss); | 2583 __ j(not_equal, &cache_miss); |
| 2582 __ cmp(edx, Operand(ecx, kIntSize)); | 2584 __ cmp(edx, Operand(ecx, kIntSize)); |
| 2583 __ j(not_equal, &cache_miss); | 2585 __ j(not_equal, &cache_miss); |
| 2584 // Cache hit! | 2586 // Cache hit! |
| 2585 __ mov(eax, Operand(ecx, 2 * kIntSize)); | |
| 2586 if (tagged) { | 2587 if (tagged) { |
| 2588 __ mov(eax, Operand(ecx, 2 * kIntSize)); |
| 2587 __ fstp(0); | 2589 __ fstp(0); |
| 2590 __ test(eax, Operand(eax)); |
| 2591 __ j(zero, &allocate_cached_answer); // The answer is cached as untagged. |
| 2588 __ ret(kPointerSize); | 2592 __ ret(kPointerSize); |
| 2589 } else { // UNTAGGED. | 2593 } else { // UNTAGGED. |
| 2590 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 2594 __ movdbl(xmm1, Operand(ecx, 3 * kIntSize)); |
| 2591 __ Ret(); | 2595 __ Ret(); |
| 2592 } | 2596 } |
| 2593 | 2597 |
| 2598 __ bind(&allocate_cached_answer); |
| 2599 __ AllocateHeapNumber(eax, edi, edx, &runtime_call); |
| 2600 __ mov(ebx, Operand(ecx, 3 * kIntSize)); |
| 2601 __ mov(FieldOperand(eax, HeapNumber::kValueOffset), ebx); |
| 2602 __ mov(ebx, Operand(ecx, 4 * kIntSize)); |
| 2603 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx); |
| 2604 __ mov(Operand(ecx, 2 * kIntSize), eax); |
| 2605 __ ret(kPointerSize); |
| 2606 |
| 2594 __ bind(&cache_miss); | 2607 __ bind(&cache_miss); |
| 2595 // Update cache with new value. | 2608 // Update cache with new value. |
| 2596 // We are short on registers, so use no_reg as scratch. | 2609 // We are short on registers, so use no_reg as scratch. |
| 2597 // This gives slightly larger code. | 2610 // This gives slightly larger code. |
| 2598 if (tagged) { | 2611 if (tagged) { |
| 2599 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); | 2612 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); |
| 2600 } else { // UNTAGGED. | 2613 } else { // UNTAGGED. |
| 2601 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); | |
| 2602 __ sub(Operand(esp), Immediate(kDoubleSize)); | 2614 __ sub(Operand(esp), Immediate(kDoubleSize)); |
| 2603 __ movdbl(Operand(esp, 0), xmm1); | 2615 __ movdbl(Operand(esp, 0), xmm1); |
| 2604 __ fld_d(Operand(esp, 0)); | 2616 __ fld_d(Operand(esp, 0)); |
| 2605 __ add(Operand(esp), Immediate(kDoubleSize)); | 2617 __ add(Operand(esp), Immediate(kDoubleSize)); |
| 2606 } | 2618 } |
| 2607 GenerateOperation(masm); | 2619 GenerateOperation(masm); |
| 2608 __ mov(Operand(ecx, 0), ebx); | 2620 __ mov(Operand(ecx, 0), ebx); |
| 2609 __ mov(Operand(ecx, kIntSize), edx); | 2621 __ mov(Operand(ecx, kIntSize), edx); |
| 2610 __ mov(Operand(ecx, 2 * kIntSize), eax); | |
| 2611 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | |
| 2612 if (tagged) { | 2622 if (tagged) { |
| 2623 __ fst_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 2624 __ mov(Operand(ecx, 2 * kIntSize), eax); |
| 2625 __ fstp_d(Operand(ecx, 3 * kIntSize)); |
| 2613 __ ret(kPointerSize); | 2626 __ ret(kPointerSize); |
| 2614 } else { // UNTAGGED. | 2627 } else { // UNTAGGED. |
| 2615 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 2628 __ fstp_d(Operand(ecx, 3 * kIntSize)); |
| 2629 __ movdbl(xmm1, Operand(ecx, 3 * kIntSize)); |
| 2616 __ Ret(); | 2630 __ Ret(); |
| 2617 | 2631 |
| 2618 // Skip cache and return answer directly, only in untagged case. | 2632 // Skip cache and return answer directly, only in untagged case. |
| 2619 __ bind(&skip_cache); | 2633 __ bind(&skip_cache); |
| 2620 __ sub(Operand(esp), Immediate(kDoubleSize)); | 2634 __ sub(Operand(esp), Immediate(kDoubleSize)); |
| 2621 __ movdbl(Operand(esp, 0), xmm1); | 2635 __ movdbl(Operand(esp, 0), xmm1); |
| 2622 __ fld_d(Operand(esp, 0)); | 2636 __ fld_d(Operand(esp, 0)); |
| 2623 GenerateOperation(masm); | 2637 GenerateOperation(masm); |
| 2624 __ fstp_d(Operand(esp, 0)); | 2638 __ fstp_d(Operand(esp, 0)); |
| 2625 __ movdbl(xmm1, Operand(esp, 0)); | 2639 __ movdbl(xmm1, Operand(esp, 0)); |
| (...skipping 3779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6405 // Do a tail call to the rewritten stub. | 6419 // Do a tail call to the rewritten stub. |
| 6406 __ jmp(Operand(edi)); | 6420 __ jmp(Operand(edi)); |
| 6407 } | 6421 } |
| 6408 | 6422 |
| 6409 | 6423 |
| 6410 #undef __ | 6424 #undef __ |
| 6411 | 6425 |
| 6412 } } // namespace v8::internal | 6426 } } // namespace v8::internal |
| 6413 | 6427 |
| 6414 #endif // V8_TARGET_ARCH_IA32 | 6428 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |