| 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 |