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 |