| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 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 2492 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2503   // This gives slightly larger code. |  2503   // This gives slightly larger code. | 
|  2504   if (tagged) { |  2504   if (tagged) { | 
|  2505     __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); |  2505     __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); | 
|  2506   } else {  // UNTAGGED. |  2506   } else {  // UNTAGGED. | 
|  2507     __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); |  2507     __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); | 
|  2508     __ sub(esp, Immediate(kDoubleSize)); |  2508     __ sub(esp, Immediate(kDoubleSize)); | 
|  2509     __ movdbl(Operand(esp, 0), xmm1); |  2509     __ movdbl(Operand(esp, 0), xmm1); | 
|  2510     __ fld_d(Operand(esp, 0)); |  2510     __ fld_d(Operand(esp, 0)); | 
|  2511     __ add(esp, Immediate(kDoubleSize)); |  2511     __ add(esp, Immediate(kDoubleSize)); | 
|  2512   } |  2512   } | 
|  2513   GenerateOperation(masm); |  2513   GenerateOperation(masm, type_); | 
|  2514   __ mov(Operand(ecx, 0), ebx); |  2514   __ mov(Operand(ecx, 0), ebx); | 
|  2515   __ mov(Operand(ecx, kIntSize), edx); |  2515   __ mov(Operand(ecx, kIntSize), edx); | 
|  2516   __ mov(Operand(ecx, 2 * kIntSize), eax); |  2516   __ mov(Operand(ecx, 2 * kIntSize), eax); | 
|  2517   __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |  2517   __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 
|  2518   if (tagged) { |  2518   if (tagged) { | 
|  2519     __ ret(kPointerSize); |  2519     __ ret(kPointerSize); | 
|  2520   } else {  // UNTAGGED. |  2520   } else {  // UNTAGGED. | 
|  2521     __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); |  2521     __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); | 
|  2522     __ Ret(); |  2522     __ Ret(); | 
|  2523  |  2523  | 
|  2524     // Skip cache and return answer directly, only in untagged case. |  2524     // Skip cache and return answer directly, only in untagged case. | 
|  2525     __ bind(&skip_cache); |  2525     __ bind(&skip_cache); | 
|  2526     __ sub(esp, Immediate(kDoubleSize)); |  2526     __ sub(esp, Immediate(kDoubleSize)); | 
|  2527     __ movdbl(Operand(esp, 0), xmm1); |  2527     __ movdbl(Operand(esp, 0), xmm1); | 
|  2528     __ fld_d(Operand(esp, 0)); |  2528     __ fld_d(Operand(esp, 0)); | 
|  2529     GenerateOperation(masm); |  2529     GenerateOperation(masm, type_); | 
|  2530     __ fstp_d(Operand(esp, 0)); |  2530     __ fstp_d(Operand(esp, 0)); | 
|  2531     __ movdbl(xmm1, Operand(esp, 0)); |  2531     __ movdbl(xmm1, Operand(esp, 0)); | 
|  2532     __ add(esp, Immediate(kDoubleSize)); |  2532     __ add(esp, Immediate(kDoubleSize)); | 
|  2533     // We return the value in xmm1 without adding it to the cache, but |  2533     // We return the value in xmm1 without adding it to the cache, but | 
|  2534     // we cause a scavenging GC so that future allocations will succeed. |  2534     // we cause a scavenging GC so that future allocations will succeed. | 
|  2535     { |  2535     { | 
|  2536       FrameScope scope(masm, StackFrame::INTERNAL); |  2536       FrameScope scope(masm, StackFrame::INTERNAL); | 
|  2537       // Allocate an unused object bigger than a HeapNumber. |  2537       // Allocate an unused object bigger than a HeapNumber. | 
|  2538       __ push(Immediate(Smi::FromInt(2 * kDoubleSize))); |  2538       __ push(Immediate(Smi::FromInt(2 * kDoubleSize))); | 
|  2539       __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); |  2539       __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2571     case TranscendentalCache::COS: return Runtime::kMath_cos; |  2571     case TranscendentalCache::COS: return Runtime::kMath_cos; | 
|  2572     case TranscendentalCache::TAN: return Runtime::kMath_tan; |  2572     case TranscendentalCache::TAN: return Runtime::kMath_tan; | 
|  2573     case TranscendentalCache::LOG: return Runtime::kMath_log; |  2573     case TranscendentalCache::LOG: return Runtime::kMath_log; | 
|  2574     default: |  2574     default: | 
|  2575       UNIMPLEMENTED(); |  2575       UNIMPLEMENTED(); | 
|  2576       return Runtime::kAbort; |  2576       return Runtime::kAbort; | 
|  2577   } |  2577   } | 
|  2578 } |  2578 } | 
|  2579  |  2579  | 
|  2580  |  2580  | 
|  2581 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { |  2581 void TranscendentalCacheStub::GenerateOperation( | 
 |  2582     MacroAssembler* masm, TranscendentalCache::Type type) { | 
|  2582   // Only free register is edi. |  2583   // Only free register is edi. | 
|  2583   // Input value is on FP stack, and also in ebx/edx. |  2584   // Input value is on FP stack, and also in ebx/edx. | 
|  2584   // Input value is possibly in xmm1. |  2585   // Input value is possibly in xmm1. | 
|  2585   // Address of result (a newly allocated HeapNumber) may be in eax. |  2586   // Address of result (a newly allocated HeapNumber) may be in eax. | 
|  2586   if (type_ == TranscendentalCache::SIN || |  2587   if (type == TranscendentalCache::SIN || | 
|  2587       type_ == TranscendentalCache::COS || |  2588       type == TranscendentalCache::COS || | 
|  2588       type_ == TranscendentalCache::TAN) { |  2589       type == TranscendentalCache::TAN) { | 
|  2589     // Both fsin and fcos require arguments in the range +/-2^63 and |  2590     // Both fsin and fcos require arguments in the range +/-2^63 and | 
|  2590     // return NaN for infinities and NaN. They can share all code except |  2591     // return NaN for infinities and NaN. They can share all code except | 
|  2591     // the actual fsin/fcos operation. |  2592     // the actual fsin/fcos operation. | 
|  2592     Label in_range, done; |  2593     Label in_range, done; | 
|  2593     // If argument is outside the range -2^63..2^63, fsin/cos doesn't |  2594     // If argument is outside the range -2^63..2^63, fsin/cos doesn't | 
|  2594     // work. We must reduce it to the appropriate range. |  2595     // work. We must reduce it to the appropriate range. | 
|  2595     __ mov(edi, edx); |  2596     __ mov(edi, edx); | 
|  2596     __ and_(edi, Immediate(0x7ff00000));  // Exponent only. |  2597     __ and_(edi, Immediate(0x7ff00000));  // Exponent only. | 
|  2597     int supported_exponent_limit = |  2598     int supported_exponent_limit = | 
|  2598         (63 + HeapNumber::kExponentBias) << HeapNumber::kExponentShift; |  2599         (63 + HeapNumber::kExponentBias) << HeapNumber::kExponentShift; | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2642       // continue computation. |  2643       // continue computation. | 
|  2643       __ j(not_zero, &partial_remainder_loop); |  2644       __ j(not_zero, &partial_remainder_loop); | 
|  2644     } |  2645     } | 
|  2645     // FPU Stack: input, 2*pi, input % 2*pi |  2646     // FPU Stack: input, 2*pi, input % 2*pi | 
|  2646     __ fstp(2); |  2647     __ fstp(2); | 
|  2647     __ fstp(0); |  2648     __ fstp(0); | 
|  2648     __ mov(eax, edi);  // Restore eax (allocated HeapNumber pointer). |  2649     __ mov(eax, edi);  // Restore eax (allocated HeapNumber pointer). | 
|  2649  |  2650  | 
|  2650     // FPU Stack: input % 2*pi |  2651     // FPU Stack: input % 2*pi | 
|  2651     __ bind(&in_range); |  2652     __ bind(&in_range); | 
|  2652     switch (type_) { |  2653     switch (type) { | 
|  2653       case TranscendentalCache::SIN: |  2654       case TranscendentalCache::SIN: | 
|  2654         __ fsin(); |  2655         __ fsin(); | 
|  2655         break; |  2656         break; | 
|  2656       case TranscendentalCache::COS: |  2657       case TranscendentalCache::COS: | 
|  2657         __ fcos(); |  2658         __ fcos(); | 
|  2658         break; |  2659         break; | 
|  2659       case TranscendentalCache::TAN: |  2660       case TranscendentalCache::TAN: | 
|  2660         // FPTAN calculates tangent onto st(0) and pushes 1.0 onto the |  2661         // FPTAN calculates tangent onto st(0) and pushes 1.0 onto the | 
|  2661         // FP register stack. |  2662         // FP register stack. | 
|  2662         __ fptan(); |  2663         __ fptan(); | 
|  2663         __ fstp(0);  // Pop FP register stack. |  2664         __ fstp(0);  // Pop FP register stack. | 
|  2664         break; |  2665         break; | 
|  2665       default: |  2666       default: | 
|  2666         UNREACHABLE(); |  2667         UNREACHABLE(); | 
|  2667     } |  2668     } | 
|  2668     __ bind(&done); |  2669     __ bind(&done); | 
|  2669   } else { |  2670   } else { | 
|  2670     ASSERT(type_ == TranscendentalCache::LOG); |  2671     ASSERT(type == TranscendentalCache::LOG); | 
|  2671     __ fldln2(); |  2672     __ fldln2(); | 
|  2672     __ fxch(); |  2673     __ fxch(); | 
|  2673     __ fyl2x(); |  2674     __ fyl2x(); | 
|  2674   } |  2675   } | 
|  2675 } |  2676 } | 
|  2676  |  2677  | 
|  2677  |  2678  | 
|  2678 // Input: edx, eax are the left and right objects of a bit op. |  2679 // Input: edx, eax are the left and right objects of a bit op. | 
|  2679 // Output: eax, ecx are left and right integers for a bit op. |  2680 // Output: eax, ecx are left and right integers for a bit op. | 
|  2680 void FloatingPointHelper::LoadUnknownsAsIntegers(MacroAssembler* masm, |  2681 void FloatingPointHelper::LoadUnknownsAsIntegers(MacroAssembler* masm, | 
| (...skipping 4718 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  7399                                  false); |  7400                                  false); | 
|  7400   __ pop(edx); |  7401   __ pop(edx); | 
|  7401   __ ret(0); |  7402   __ ret(0); | 
|  7402 } |  7403 } | 
|  7403  |  7404  | 
|  7404 #undef __ |  7405 #undef __ | 
|  7405  |  7406  | 
|  7406 } }  // namespace v8::internal |  7407 } }  // namespace v8::internal | 
|  7407  |  7408  | 
|  7408 #endif  // V8_TARGET_ARCH_IA32 |  7409 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |