| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. | 606 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. |
| 607 __ xorps(double_scratch2, double_scratch2); | 607 __ xorps(double_scratch2, double_scratch2); |
| 608 __ ucomisd(double_scratch2, double_result); // Result cannot be NaN. | 608 __ ucomisd(double_scratch2, double_result); // Result cannot be NaN. |
| 609 // double_exponent aliased as double_scratch2 has already been overwritten | 609 // double_exponent aliased as double_scratch2 has already been overwritten |
| 610 // and may not have contained the exponent value in the first place when the | 610 // and may not have contained the exponent value in the first place when the |
| 611 // exponent is a smi. We reset it with exponent value before bailing out. | 611 // exponent is a smi. We reset it with exponent value before bailing out. |
| 612 __ j(not_equal, &done); | 612 __ j(not_equal, &done); |
| 613 __ Cvtsi2sd(double_exponent, exponent); | 613 __ Cvtsi2sd(double_exponent, exponent); |
| 614 | 614 |
| 615 // Returning or bailing out. | 615 // Returning or bailing out. |
| 616 Counters* counters = isolate()->counters(); | |
| 617 if (exponent_type() == ON_STACK) { | 616 if (exponent_type() == ON_STACK) { |
| 618 // The arguments are still on the stack. | 617 // The arguments are still on the stack. |
| 619 __ bind(&call_runtime); | 618 __ bind(&call_runtime); |
| 620 __ TailCallRuntime(Runtime::kMathPowRT); | 619 __ TailCallRuntime(Runtime::kMathPowRT); |
| 621 | 620 |
| 622 // The stub is called from non-optimized code, which expects the result | 621 // The stub is called from non-optimized code, which expects the result |
| 623 // as heap number in exponent. | 622 // as heap number in exponent. |
| 624 __ bind(&done); | 623 __ bind(&done); |
| 625 __ AllocateHeapNumber(eax, scratch, base, &call_runtime); | 624 __ AllocateHeapNumber(eax, scratch, base, &call_runtime); |
| 626 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result); | 625 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result); |
| 627 __ IncrementCounter(counters->math_pow(), 1); | |
| 628 __ ret(2 * kPointerSize); | 626 __ ret(2 * kPointerSize); |
| 629 } else { | 627 } else { |
| 630 __ bind(&call_runtime); | 628 __ bind(&call_runtime); |
| 631 { | 629 { |
| 632 AllowExternalCallThatCantCauseGC scope(masm); | 630 AllowExternalCallThatCantCauseGC scope(masm); |
| 633 __ PrepareCallCFunction(4, scratch); | 631 __ PrepareCallCFunction(4, scratch); |
| 634 __ movsd(Operand(esp, 0 * kDoubleSize), double_base); | 632 __ movsd(Operand(esp, 0 * kDoubleSize), double_base); |
| 635 __ movsd(Operand(esp, 1 * kDoubleSize), double_exponent); | 633 __ movsd(Operand(esp, 1 * kDoubleSize), double_exponent); |
| 636 __ CallCFunction( | 634 __ CallCFunction( |
| 637 ExternalReference::power_double_double_function(isolate()), 4); | 635 ExternalReference::power_double_double_function(isolate()), 4); |
| 638 } | 636 } |
| 639 // Return value is in st(0) on ia32. | 637 // Return value is in st(0) on ia32. |
| 640 // Store it into the (fixed) result register. | 638 // Store it into the (fixed) result register. |
| 641 __ sub(esp, Immediate(kDoubleSize)); | 639 __ sub(esp, Immediate(kDoubleSize)); |
| 642 __ fstp_d(Operand(esp, 0)); | 640 __ fstp_d(Operand(esp, 0)); |
| 643 __ movsd(double_result, Operand(esp, 0)); | 641 __ movsd(double_result, Operand(esp, 0)); |
| 644 __ add(esp, Immediate(kDoubleSize)); | 642 __ add(esp, Immediate(kDoubleSize)); |
| 645 | 643 |
| 646 __ bind(&done); | 644 __ bind(&done); |
| 647 __ IncrementCounter(counters->math_pow(), 1); | |
| 648 __ ret(0); | 645 __ ret(0); |
| 649 } | 646 } |
| 650 } | 647 } |
| 651 | 648 |
| 652 | 649 |
| 653 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { | 650 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { |
| 654 Label miss; | 651 Label miss; |
| 655 Register receiver = LoadDescriptor::ReceiverRegister(); | 652 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 656 // With careful management, we won't have to save slot and vector on | 653 // With careful management, we won't have to save slot and vector on |
| 657 // the stack. Simply handle the possibly missing case first. | 654 // the stack. Simply handle the possibly missing case first. |
| (...skipping 5089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5747 return_value_operand, NULL); | 5744 return_value_operand, NULL); |
| 5748 } | 5745 } |
| 5749 | 5746 |
| 5750 | 5747 |
| 5751 #undef __ | 5748 #undef __ |
| 5752 | 5749 |
| 5753 } // namespace internal | 5750 } // namespace internal |
| 5754 } // namespace v8 | 5751 } // namespace v8 |
| 5755 | 5752 |
| 5756 #endif // V8_TARGET_ARCH_IA32 | 5753 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |