OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_S390 | 5 #if V8_TARGET_ARCH_S390 |
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 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 __ PushSafepointRegisters(); | 704 __ PushSafepointRegisters(); |
705 __ b(r14); | 705 __ b(r14); |
706 } | 706 } |
707 | 707 |
708 void RestoreRegistersStateStub::Generate(MacroAssembler* masm) { | 708 void RestoreRegistersStateStub::Generate(MacroAssembler* masm) { |
709 __ PopSafepointRegisters(); | 709 __ PopSafepointRegisters(); |
710 __ b(r14); | 710 __ b(r14); |
711 } | 711 } |
712 | 712 |
713 void MathPowStub::Generate(MacroAssembler* masm) { | 713 void MathPowStub::Generate(MacroAssembler* masm) { |
714 const Register base = r3; | |
715 const Register exponent = MathPowTaggedDescriptor::exponent(); | 714 const Register exponent = MathPowTaggedDescriptor::exponent(); |
716 DCHECK(exponent.is(r4)); | 715 DCHECK(exponent.is(r4)); |
717 const Register heapnumbermap = r7; | |
718 const Register heapnumber = r2; | |
719 const DoubleRegister double_base = d1; | 716 const DoubleRegister double_base = d1; |
720 const DoubleRegister double_exponent = d2; | 717 const DoubleRegister double_exponent = d2; |
721 const DoubleRegister double_result = d3; | 718 const DoubleRegister double_result = d3; |
722 const DoubleRegister double_scratch = d0; | 719 const DoubleRegister double_scratch = d0; |
723 const Register scratch = r1; | 720 const Register scratch = r1; |
724 const Register scratch2 = r9; | 721 const Register scratch2 = r9; |
725 | 722 |
726 Label call_runtime, done, int_exponent; | 723 Label call_runtime, done, int_exponent; |
727 if (exponent_type() == ON_STACK) { | 724 if (exponent_type() == TAGGED) { |
728 Label base_is_smi, unpack_exponent; | |
729 // The exponent and base are supplied as arguments on the stack. | |
730 // This can only happen if the stub is called from non-optimized code. | |
731 // Load input parameters from stack to double registers. | |
732 __ LoadP(base, MemOperand(sp, 1 * kPointerSize)); | |
733 __ LoadP(exponent, MemOperand(sp, 0 * kPointerSize)); | |
734 | |
735 __ LoadRoot(heapnumbermap, Heap::kHeapNumberMapRootIndex); | |
736 | |
737 __ UntagAndJumpIfSmi(scratch, base, &base_is_smi); | |
738 __ LoadP(scratch, FieldMemOperand(base, JSObject::kMapOffset)); | |
739 __ CmpP(scratch, heapnumbermap); | |
740 __ bne(&call_runtime); | |
741 | |
742 __ LoadDouble(double_base, FieldMemOperand(base, HeapNumber::kValueOffset)); | |
743 __ b(&unpack_exponent, Label::kNear); | |
744 | |
745 __ bind(&base_is_smi); | |
746 __ ConvertIntToDouble(scratch, double_base); | |
747 __ bind(&unpack_exponent); | |
748 | |
749 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent); | |
750 __ LoadP(scratch, FieldMemOperand(exponent, JSObject::kMapOffset)); | |
751 __ CmpP(scratch, heapnumbermap); | |
752 __ bne(&call_runtime); | |
753 | |
754 __ LoadDouble(double_exponent, | |
755 FieldMemOperand(exponent, HeapNumber::kValueOffset)); | |
756 } else if (exponent_type() == TAGGED) { | |
757 // Base is already in double_base. | 725 // Base is already in double_base. |
758 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent); | 726 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent); |
759 | 727 |
760 __ LoadDouble(double_exponent, | 728 __ LoadDouble(double_exponent, |
761 FieldMemOperand(exponent, HeapNumber::kValueOffset)); | 729 FieldMemOperand(exponent, HeapNumber::kValueOffset)); |
762 } | 730 } |
763 | 731 |
764 if (exponent_type() != INTEGER) { | 732 if (exponent_type() != INTEGER) { |
765 // Detect integer exponents stored as double. | 733 // Detect integer exponents stored as double. |
766 __ TryDoubleToInt32Exact(scratch, double_exponent, scratch2, | 734 __ TryDoubleToInt32Exact(scratch, double_exponent, scratch2, |
767 double_scratch); | 735 double_scratch); |
768 __ beq(&int_exponent, Label::kNear); | 736 __ beq(&int_exponent, Label::kNear); |
769 | 737 |
770 if (exponent_type() == ON_STACK) { | |
771 // Detect square root case. Crankshaft detects constant +/-0.5 at | |
772 // compile time and uses DoMathPowHalf instead. We then skip this check | |
773 // for non-constant cases of +/-0.5 as these hardly occur. | |
774 Label not_plus_half, not_minus_inf1, not_minus_inf2; | |
775 | |
776 // Test for 0.5. | |
777 __ LoadDoubleLiteral(double_scratch, 0.5, scratch); | |
778 __ cdbr(double_exponent, double_scratch); | |
779 __ bne(¬_plus_half, Label::kNear); | |
780 | |
781 // Calculates square root of base. Check for the special case of | |
782 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13). | |
783 __ LoadDoubleLiteral(double_scratch, -V8_INFINITY, scratch); | |
784 __ cdbr(double_base, double_scratch); | |
785 __ bne(¬_minus_inf1, Label::kNear); | |
786 __ lcdbr(double_result, double_scratch); | |
787 __ b(&done); | |
788 __ bind(¬_minus_inf1); | |
789 | |
790 // Add +0 to convert -0 to +0. | |
791 __ ldr(double_scratch, double_base); | |
792 __ lzdr(kDoubleRegZero); | |
793 __ adbr(double_scratch, kDoubleRegZero); | |
794 __ sqdbr(double_result, double_scratch); | |
795 __ b(&done); | |
796 | |
797 __ bind(¬_plus_half); | |
798 __ LoadDoubleLiteral(double_scratch, -0.5, scratch); | |
799 __ cdbr(double_exponent, double_scratch); | |
800 __ bne(&call_runtime); | |
801 | |
802 // Calculates square root of base. Check for the special case of | |
803 // Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13). | |
804 __ LoadDoubleLiteral(double_scratch, -V8_INFINITY, scratch); | |
805 __ cdbr(double_base, double_scratch); | |
806 __ bne(¬_minus_inf2, Label::kNear); | |
807 __ ldr(double_result, kDoubleRegZero); | |
808 __ b(&done); | |
809 __ bind(¬_minus_inf2); | |
810 | |
811 // Add +0 to convert -0 to +0. | |
812 __ ldr(double_scratch, double_base); | |
813 __ lzdr(kDoubleRegZero); | |
814 __ adbr(double_scratch, kDoubleRegZero); | |
815 __ LoadDoubleLiteral(double_result, 1.0, scratch); | |
816 __ sqdbr(double_scratch, double_scratch); | |
817 __ ddbr(double_result, double_scratch); | |
818 __ b(&done); | |
819 } | |
820 | |
821 __ push(r14); | 738 __ push(r14); |
822 { | 739 { |
823 AllowExternalCallThatCantCauseGC scope(masm); | 740 AllowExternalCallThatCantCauseGC scope(masm); |
824 __ PrepareCallCFunction(0, 2, scratch); | 741 __ PrepareCallCFunction(0, 2, scratch); |
825 __ MovToFloatParameters(double_base, double_exponent); | 742 __ MovToFloatParameters(double_base, double_exponent); |
826 __ CallCFunction( | 743 __ CallCFunction( |
827 ExternalReference::power_double_double_function(isolate()), 0, 2); | 744 ExternalReference::power_double_double_function(isolate()), 0, 2); |
828 } | 745 } |
829 __ pop(r14); | 746 __ pop(r14); |
830 __ MovFromFloatResult(double_result); | 747 __ MovFromFloatResult(double_result); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 // Test whether result is zero. Bail out to check for subnormal result. | 794 // Test whether result is zero. Bail out to check for subnormal result. |
878 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. | 795 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. |
879 __ lzdr(kDoubleRegZero); | 796 __ lzdr(kDoubleRegZero); |
880 __ cdbr(double_result, kDoubleRegZero); | 797 __ cdbr(double_result, kDoubleRegZero); |
881 __ bne(&done, Label::kNear); | 798 __ bne(&done, Label::kNear); |
882 // double_exponent may not containe the exponent value if the input was a | 799 // double_exponent may not containe the exponent value if the input was a |
883 // smi. We set it with exponent value before bailing out. | 800 // smi. We set it with exponent value before bailing out. |
884 __ ConvertIntToDouble(exponent, double_exponent); | 801 __ ConvertIntToDouble(exponent, double_exponent); |
885 | 802 |
886 // Returning or bailing out. | 803 // Returning or bailing out. |
887 if (exponent_type() == ON_STACK) { | 804 __ push(r14); |
888 // The arguments are still on the stack. | 805 { |
889 __ bind(&call_runtime); | 806 AllowExternalCallThatCantCauseGC scope(masm); |
890 __ TailCallRuntime(Runtime::kMathPowRT); | 807 __ PrepareCallCFunction(0, 2, scratch); |
| 808 __ MovToFloatParameters(double_base, double_exponent); |
| 809 __ CallCFunction( |
| 810 ExternalReference::power_double_double_function(isolate()), 0, 2); |
| 811 } |
| 812 __ pop(r14); |
| 813 __ MovFromFloatResult(double_result); |
891 | 814 |
892 // The stub is called from non-optimized code, which expects the result | 815 __ bind(&done); |
893 // as heap number in exponent. | 816 __ Ret(); |
894 __ bind(&done); | |
895 __ AllocateHeapNumber(heapnumber, scratch, scratch2, heapnumbermap, | |
896 &call_runtime); | |
897 __ StoreDouble(double_result, | |
898 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); | |
899 DCHECK(heapnumber.is(r2)); | |
900 __ Ret(2); | |
901 } else { | |
902 __ push(r14); | |
903 { | |
904 AllowExternalCallThatCantCauseGC scope(masm); | |
905 __ PrepareCallCFunction(0, 2, scratch); | |
906 __ MovToFloatParameters(double_base, double_exponent); | |
907 __ CallCFunction( | |
908 ExternalReference::power_double_double_function(isolate()), 0, 2); | |
909 } | |
910 __ pop(r14); | |
911 __ MovFromFloatResult(double_result); | |
912 | |
913 __ bind(&done); | |
914 __ Ret(); | |
915 } | |
916 } | 817 } |
917 | 818 |
918 bool CEntryStub::NeedsImmovableCode() { return true; } | 819 bool CEntryStub::NeedsImmovableCode() { return true; } |
919 | 820 |
920 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 821 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
921 CEntryStub::GenerateAheadOfTime(isolate); | 822 CEntryStub::GenerateAheadOfTime(isolate); |
922 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); | 823 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); |
923 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); | 824 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); |
924 CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate); | 825 CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate); |
925 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); | 826 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); |
(...skipping 4570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5496 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 5397 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |
5497 kStackUnwindSpace, NULL, return_value_operand, NULL); | 5398 kStackUnwindSpace, NULL, return_value_operand, NULL); |
5498 } | 5399 } |
5499 | 5400 |
5500 #undef __ | 5401 #undef __ |
5501 | 5402 |
5502 } // namespace internal | 5403 } // namespace internal |
5503 } // namespace v8 | 5404 } // namespace v8 |
5504 | 5405 |
5505 #endif // V8_TARGET_ARCH_S390 | 5406 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |