OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2478 // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12]. | 2478 // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12]. |
2479 __ lea(ecx, Operand(ecx, ecx, times_2, 0)); | 2479 __ lea(ecx, Operand(ecx, ecx, times_2, 0)); |
2480 __ lea(ecx, Operand(eax, ecx, times_4, 0)); | 2480 __ lea(ecx, Operand(eax, ecx, times_4, 0)); |
2481 // Check if cache matches: Double value is stored in uint32_t[2] array. | 2481 // Check if cache matches: Double value is stored in uint32_t[2] array. |
2482 Label cache_miss; | 2482 Label cache_miss; |
2483 __ cmp(ebx, Operand(ecx, 0)); | 2483 __ cmp(ebx, Operand(ecx, 0)); |
2484 __ j(not_equal, &cache_miss, Label::kNear); | 2484 __ j(not_equal, &cache_miss, Label::kNear); |
2485 __ cmp(edx, Operand(ecx, kIntSize)); | 2485 __ cmp(edx, Operand(ecx, kIntSize)); |
2486 __ j(not_equal, &cache_miss, Label::kNear); | 2486 __ j(not_equal, &cache_miss, Label::kNear); |
2487 // Cache hit! | 2487 // Cache hit! |
| 2488 Counters* counters = masm->isolate()->counters(); |
| 2489 __ IncrementCounter(counters->transcendental_cache_hit(), 1); |
2488 __ mov(eax, Operand(ecx, 2 * kIntSize)); | 2490 __ mov(eax, Operand(ecx, 2 * kIntSize)); |
2489 if (tagged) { | 2491 if (tagged) { |
2490 __ fstp(0); | 2492 __ fstp(0); |
2491 __ ret(kPointerSize); | 2493 __ ret(kPointerSize); |
2492 } else { // UNTAGGED. | 2494 } else { // UNTAGGED. |
2493 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 2495 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
2494 __ Ret(); | 2496 __ Ret(); |
2495 } | 2497 } |
2496 | 2498 |
2497 __ bind(&cache_miss); | 2499 __ bind(&cache_miss); |
| 2500 __ IncrementCounter(counters->transcendental_cache_miss(), 1); |
2498 // Update cache with new value. | 2501 // Update cache with new value. |
2499 // We are short on registers, so use no_reg as scratch. | 2502 // We are short on registers, so use no_reg as scratch. |
2500 // This gives slightly larger code. | 2503 // This gives slightly larger code. |
2501 if (tagged) { | 2504 if (tagged) { |
2502 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); | 2505 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); |
2503 } else { // UNTAGGED. | 2506 } else { // UNTAGGED. |
2504 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); | 2507 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); |
2505 __ sub(esp, Immediate(kDoubleSize)); | 2508 __ sub(esp, Immediate(kDoubleSize)); |
2506 __ movdbl(Operand(esp, 0), xmm1); | 2509 __ movdbl(Operand(esp, 0), xmm1); |
2507 __ fld_d(Operand(esp, 0)); | 2510 __ fld_d(Operand(esp, 0)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2559 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 2562 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |
2560 __ Ret(); | 2563 __ Ret(); |
2561 } | 2564 } |
2562 } | 2565 } |
2563 | 2566 |
2564 | 2567 |
2565 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { | 2568 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { |
2566 switch (type_) { | 2569 switch (type_) { |
2567 case TranscendentalCache::SIN: return Runtime::kMath_sin; | 2570 case TranscendentalCache::SIN: return Runtime::kMath_sin; |
2568 case TranscendentalCache::COS: return Runtime::kMath_cos; | 2571 case TranscendentalCache::COS: return Runtime::kMath_cos; |
| 2572 case TranscendentalCache::TAN: return Runtime::kMath_tan; |
2569 case TranscendentalCache::LOG: return Runtime::kMath_log; | 2573 case TranscendentalCache::LOG: return Runtime::kMath_log; |
2570 default: | 2574 default: |
2571 UNIMPLEMENTED(); | 2575 UNIMPLEMENTED(); |
2572 return Runtime::kAbort; | 2576 return Runtime::kAbort; |
2573 } | 2577 } |
2574 } | 2578 } |
2575 | 2579 |
2576 | 2580 |
2577 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { | 2581 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { |
2578 // Only free register is edi. | 2582 // Only free register is edi. |
2579 // Input value is on FP stack, and also in ebx/edx. | 2583 // Input value is on FP stack, and also in ebx/edx. |
2580 // Input value is possibly in xmm1. | 2584 // Input value is possibly in xmm1. |
2581 // Address of result (a newly allocated HeapNumber) may be in eax. | 2585 // Address of result (a newly allocated HeapNumber) may be in eax. |
2582 if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) { | 2586 if (type_ == TranscendentalCache::SIN || |
| 2587 type_ == TranscendentalCache::COS || |
| 2588 type_ == TranscendentalCache::TAN) { |
2583 // Both fsin and fcos require arguments in the range +/-2^63 and | 2589 // Both fsin and fcos require arguments in the range +/-2^63 and |
2584 // return NaN for infinities and NaN. They can share all code except | 2590 // return NaN for infinities and NaN. They can share all code except |
2585 // the actual fsin/fcos operation. | 2591 // the actual fsin/fcos operation. |
2586 Label in_range, done; | 2592 Label in_range, done; |
2587 // If argument is outside the range -2^63..2^63, fsin/cos doesn't | 2593 // If argument is outside the range -2^63..2^63, fsin/cos doesn't |
2588 // work. We must reduce it to the appropriate range. | 2594 // work. We must reduce it to the appropriate range. |
2589 __ mov(edi, edx); | 2595 __ mov(edi, edx); |
2590 __ and_(edi, Immediate(0x7ff00000)); // Exponent only. | 2596 __ and_(edi, Immediate(0x7ff00000)); // Exponent only. |
2591 int supported_exponent_limit = | 2597 int supported_exponent_limit = |
2592 (63 + HeapNumber::kExponentBias) << HeapNumber::kExponentShift; | 2598 (63 + HeapNumber::kExponentBias) << HeapNumber::kExponentShift; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2643 | 2649 |
2644 // FPU Stack: input % 2*pi | 2650 // FPU Stack: input % 2*pi |
2645 __ bind(&in_range); | 2651 __ bind(&in_range); |
2646 switch (type_) { | 2652 switch (type_) { |
2647 case TranscendentalCache::SIN: | 2653 case TranscendentalCache::SIN: |
2648 __ fsin(); | 2654 __ fsin(); |
2649 break; | 2655 break; |
2650 case TranscendentalCache::COS: | 2656 case TranscendentalCache::COS: |
2651 __ fcos(); | 2657 __ fcos(); |
2652 break; | 2658 break; |
| 2659 case TranscendentalCache::TAN: |
| 2660 // FPTAN computes tangent onto st(0) and pushes 1.0 onto the FP stack. |
| 2661 __ fptan(); |
| 2662 __ ffree(); |
| 2663 __ fincstp(); |
| 2664 break; |
2653 default: | 2665 default: |
2654 UNREACHABLE(); | 2666 UNREACHABLE(); |
2655 } | 2667 } |
2656 __ bind(&done); | 2668 __ bind(&done); |
2657 } else { | 2669 } else { |
2658 ASSERT(type_ == TranscendentalCache::LOG); | 2670 ASSERT(type_ == TranscendentalCache::LOG); |
2659 __ fldln2(); | 2671 __ fldln2(); |
2660 __ fxch(); | 2672 __ fxch(); |
2661 __ fyl2x(); | 2673 __ fyl2x(); |
2662 } | 2674 } |
(...skipping 4469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7132 false); | 7144 false); |
7133 __ pop(edx); | 7145 __ pop(edx); |
7134 __ ret(0); | 7146 __ ret(0); |
7135 } | 7147 } |
7136 | 7148 |
7137 #undef __ | 7149 #undef __ |
7138 | 7150 |
7139 } } // namespace v8::internal | 7151 } } // namespace v8::internal |
7140 | 7152 |
7141 #endif // V8_TARGET_ARCH_IA32 | 7153 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |