Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 2103733003: [turbofan] Introduce Float64Pow and NumberPow operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE on ARM64 bug fix. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/arm64/code-stubs-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 __ mov(r0, Operand(ExternalReference::isolate_address(isolate()))); 687 __ mov(r0, Operand(ExternalReference::isolate_address(isolate())));
688 __ CallCFunction( 688 __ CallCFunction(
689 ExternalReference::store_buffer_overflow_function(isolate()), 689 ExternalReference::store_buffer_overflow_function(isolate()),
690 argument_count); 690 argument_count);
691 if (save_doubles()) { 691 if (save_doubles()) {
692 __ RestoreFPRegs(sp, scratch); 692 __ RestoreFPRegs(sp, scratch);
693 } 693 }
694 __ ldm(ia_w, sp, kCallerSaved | pc.bit()); // Also pop pc to get Ret(0). 694 __ ldm(ia_w, sp, kCallerSaved | pc.bit()); // Also pop pc to get Ret(0).
695 } 695 }
696 696
697
698 void MathPowStub::Generate(MacroAssembler* masm) { 697 void MathPowStub::Generate(MacroAssembler* masm) {
699 const Register base = r1;
700 const Register exponent = MathPowTaggedDescriptor::exponent(); 698 const Register exponent = MathPowTaggedDescriptor::exponent();
701 DCHECK(exponent.is(r2)); 699 DCHECK(exponent.is(r2));
702 const Register heapnumbermap = r5;
703 const Register heapnumber = r0;
704 const DwVfpRegister double_base = d0; 700 const DwVfpRegister double_base = d0;
705 const DwVfpRegister double_exponent = d1; 701 const DwVfpRegister double_exponent = d1;
706 const DwVfpRegister double_result = d2; 702 const DwVfpRegister double_result = d2;
707 const DwVfpRegister double_scratch = d3; 703 const DwVfpRegister double_scratch = d3;
708 const SwVfpRegister single_scratch = s6; 704 const SwVfpRegister single_scratch = s6;
709 const Register scratch = r9; 705 const Register scratch = r9;
710 const Register scratch2 = r4; 706 const Register scratch2 = r4;
711 707
712 Label call_runtime, done, int_exponent; 708 Label call_runtime, done, int_exponent;
713 if (exponent_type() == ON_STACK) { 709 if (exponent_type() == TAGGED) {
714 Label base_is_smi, unpack_exponent;
715 // The exponent and base are supplied as arguments on the stack.
716 // This can only happen if the stub is called from non-optimized code.
717 // Load input parameters from stack to double registers.
718 __ ldr(base, MemOperand(sp, 1 * kPointerSize));
719 __ ldr(exponent, MemOperand(sp, 0 * kPointerSize));
720
721 __ LoadRoot(heapnumbermap, Heap::kHeapNumberMapRootIndex);
722
723 __ UntagAndJumpIfSmi(scratch, base, &base_is_smi);
724 __ ldr(scratch, FieldMemOperand(base, JSObject::kMapOffset));
725 __ cmp(scratch, heapnumbermap);
726 __ b(ne, &call_runtime);
727
728 __ vldr(double_base, FieldMemOperand(base, HeapNumber::kValueOffset));
729 __ jmp(&unpack_exponent);
730
731 __ bind(&base_is_smi);
732 __ vmov(single_scratch, scratch);
733 __ vcvt_f64_s32(double_base, single_scratch);
734 __ bind(&unpack_exponent);
735
736 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent);
737
738 __ ldr(scratch, FieldMemOperand(exponent, JSObject::kMapOffset));
739 __ cmp(scratch, heapnumbermap);
740 __ b(ne, &call_runtime);
741 __ vldr(double_exponent,
742 FieldMemOperand(exponent, HeapNumber::kValueOffset));
743 } else if (exponent_type() == TAGGED) {
744 // Base is already in double_base. 710 // Base is already in double_base.
745 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent); 711 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent);
746 712
747 __ vldr(double_exponent, 713 __ vldr(double_exponent,
748 FieldMemOperand(exponent, HeapNumber::kValueOffset)); 714 FieldMemOperand(exponent, HeapNumber::kValueOffset));
749 } 715 }
750 716
751 if (exponent_type() != INTEGER) { 717 if (exponent_type() != INTEGER) {
752 Label int_exponent_convert; 718 Label int_exponent_convert;
753 // Detect integer exponents stored as double. 719 // Detect integer exponents stored as double.
754 __ vcvt_u32_f64(single_scratch, double_exponent); 720 __ vcvt_u32_f64(single_scratch, double_exponent);
755 // We do not check for NaN or Infinity here because comparing numbers on 721 // We do not check for NaN or Infinity here because comparing numbers on
756 // ARM correctly distinguishes NaNs. We end up calling the built-in. 722 // ARM correctly distinguishes NaNs. We end up calling the built-in.
757 __ vcvt_f64_u32(double_scratch, single_scratch); 723 __ vcvt_f64_u32(double_scratch, single_scratch);
758 __ VFPCompareAndSetFlags(double_scratch, double_exponent); 724 __ VFPCompareAndSetFlags(double_scratch, double_exponent);
759 __ b(eq, &int_exponent_convert); 725 __ b(eq, &int_exponent_convert);
760 726
761 if (exponent_type() == ON_STACK) {
762 // Detect square root case. Crankshaft detects constant +/-0.5 at
763 // compile time and uses DoMathPowHalf instead. We then skip this check
764 // for non-constant cases of +/-0.5 as these hardly occur.
765 Label not_plus_half;
766
767 // Test for 0.5.
768 __ vmov(double_scratch, 0.5, scratch);
769 __ VFPCompareAndSetFlags(double_exponent, double_scratch);
770 __ b(ne, &not_plus_half);
771
772 // Calculates square root of base. Check for the special case of
773 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
774 __ vmov(double_scratch, -V8_INFINITY, scratch);
775 __ VFPCompareAndSetFlags(double_base, double_scratch);
776 __ vneg(double_result, double_scratch, eq);
777 __ b(eq, &done);
778
779 // Add +0 to convert -0 to +0.
780 __ vadd(double_scratch, double_base, kDoubleRegZero);
781 __ vsqrt(double_result, double_scratch);
782 __ jmp(&done);
783
784 __ bind(&not_plus_half);
785 __ vmov(double_scratch, -0.5, scratch);
786 __ VFPCompareAndSetFlags(double_exponent, double_scratch);
787 __ b(ne, &call_runtime);
788
789 // Calculates square root of base. Check for the special case of
790 // Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
791 __ vmov(double_scratch, -V8_INFINITY, scratch);
792 __ VFPCompareAndSetFlags(double_base, double_scratch);
793 __ vmov(double_result, kDoubleRegZero, eq);
794 __ b(eq, &done);
795
796 // Add +0 to convert -0 to +0.
797 __ vadd(double_scratch, double_base, kDoubleRegZero);
798 __ vmov(double_result, 1.0, scratch);
799 __ vsqrt(double_scratch, double_scratch);
800 __ vdiv(double_result, double_result, double_scratch);
801 __ jmp(&done);
802 }
803
804 __ push(lr); 727 __ push(lr);
805 { 728 {
806 AllowExternalCallThatCantCauseGC scope(masm); 729 AllowExternalCallThatCantCauseGC scope(masm);
807 __ PrepareCallCFunction(0, 2, scratch); 730 __ PrepareCallCFunction(0, 2, scratch);
808 __ MovToFloatParameters(double_base, double_exponent); 731 __ MovToFloatParameters(double_base, double_exponent);
809 __ CallCFunction( 732 __ CallCFunction(
810 ExternalReference::power_double_double_function(isolate()), 733 ExternalReference::power_double_double_function(isolate()), 0, 2);
811 0, 2);
812 } 734 }
813 __ pop(lr); 735 __ pop(lr);
814 __ MovFromFloatResult(double_result); 736 __ MovFromFloatResult(double_result);
815 __ jmp(&done); 737 __ jmp(&done);
816 738
817 __ bind(&int_exponent_convert); 739 __ bind(&int_exponent_convert);
818 __ vcvt_u32_f64(single_scratch, double_exponent); 740 __ vcvt_u32_f64(single_scratch, double_exponent);
819 __ vmov(scratch, single_scratch); 741 __ vmov(scratch, single_scratch);
820 } 742 }
821 743
(...skipping 29 matching lines...) Expand all
851 // Test whether result is zero. Bail out to check for subnormal result. 773 // Test whether result is zero. Bail out to check for subnormal result.
852 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. 774 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
853 __ VFPCompareAndSetFlags(double_result, 0.0); 775 __ VFPCompareAndSetFlags(double_result, 0.0);
854 __ b(ne, &done); 776 __ b(ne, &done);
855 // double_exponent may not containe the exponent value if the input was a 777 // double_exponent may not containe the exponent value if the input was a
856 // smi. We set it with exponent value before bailing out. 778 // smi. We set it with exponent value before bailing out.
857 __ vmov(single_scratch, exponent); 779 __ vmov(single_scratch, exponent);
858 __ vcvt_f64_s32(double_exponent, single_scratch); 780 __ vcvt_f64_s32(double_exponent, single_scratch);
859 781
860 // Returning or bailing out. 782 // Returning or bailing out.
861 if (exponent_type() == ON_STACK) { 783 __ push(lr);
862 // The arguments are still on the stack. 784 {
863 __ bind(&call_runtime); 785 AllowExternalCallThatCantCauseGC scope(masm);
864 __ TailCallRuntime(Runtime::kMathPowRT); 786 __ PrepareCallCFunction(0, 2, scratch);
787 __ MovToFloatParameters(double_base, double_exponent);
788 __ CallCFunction(ExternalReference::power_double_double_function(isolate()),
789 0, 2);
790 }
791 __ pop(lr);
792 __ MovFromFloatResult(double_result);
865 793
866 // The stub is called from non-optimized code, which expects the result 794 __ bind(&done);
867 // as heap number in exponent. 795 __ Ret();
868 __ bind(&done);
869 __ AllocateHeapNumber(
870 heapnumber, scratch, scratch2, heapnumbermap, &call_runtime);
871 __ vstr(double_result,
872 FieldMemOperand(heapnumber, HeapNumber::kValueOffset));
873 DCHECK(heapnumber.is(r0));
874 __ Ret(2);
875 } else {
876 __ push(lr);
877 {
878 AllowExternalCallThatCantCauseGC scope(masm);
879 __ PrepareCallCFunction(0, 2, scratch);
880 __ MovToFloatParameters(double_base, double_exponent);
881 __ CallCFunction(
882 ExternalReference::power_double_double_function(isolate()),
883 0, 2);
884 }
885 __ pop(lr);
886 __ MovFromFloatResult(double_result);
887
888 __ bind(&done);
889 __ Ret();
890 }
891 } 796 }
892 797
893
894 bool CEntryStub::NeedsImmovableCode() { 798 bool CEntryStub::NeedsImmovableCode() {
895 return true; 799 return true;
896 } 800 }
897 801
898 802
899 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { 803 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
900 CEntryStub::GenerateAheadOfTime(isolate); 804 CEntryStub::GenerateAheadOfTime(isolate);
901 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); 805 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
902 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); 806 StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
903 CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate); 807 CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
(...skipping 4435 matching lines...) Expand 10 before | Expand all | Expand 10 after
5339 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, 5243 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
5340 kStackUnwindSpace, NULL, return_value_operand, NULL); 5244 kStackUnwindSpace, NULL, return_value_operand, NULL);
5341 } 5245 }
5342 5246
5343 #undef __ 5247 #undef __
5344 5248
5345 } // namespace internal 5249 } // namespace internal
5346 } // namespace v8 5250 } // namespace v8
5347 5251
5348 #endif // V8_TARGET_ARCH_ARM 5252 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/code-stubs-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698