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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 | 80 |
81 __ push(scratch); | 81 __ push(scratch); |
82 // Account for saved regs if input is sp. | 82 // Account for saved regs if input is sp. |
83 if (input_reg.is(sp)) double_offset += kPointerSize; | 83 if (input_reg.is(sp)) double_offset += kPointerSize; |
84 | 84 |
85 if (!skip_fastpath()) { | 85 if (!skip_fastpath()) { |
86 // Load double input. | 86 // Load double input. |
87 __ LoadDouble(double_scratch, MemOperand(input_reg, double_offset)); | 87 __ LoadDouble(double_scratch, MemOperand(input_reg, double_offset)); |
88 | 88 |
89 // Do fast-path convert from double to int. | 89 // Do fast-path convert from double to int. |
90 __ ConvertDoubleToInt64(double_scratch, | 90 __ ConvertDoubleToInt64(result_reg, double_scratch); |
91 #if !V8_TARGET_ARCH_S390X | |
92 scratch, | |
93 #endif | |
94 result_reg, d0); | |
95 | 91 |
96 // Test for overflow | 92 // Test for overflow |
97 #if V8_TARGET_ARCH_S390X | 93 __ TestIfInt32(result_reg); |
98 __ TestIfInt32(result_reg, r0); | |
99 #else | |
100 __ TestIfInt32(scratch, result_reg, r0); | |
101 #endif | |
102 __ beq(&fastpath_done, Label::kNear); | 94 __ beq(&fastpath_done, Label::kNear); |
103 } | 95 } |
104 | 96 |
105 __ Push(scratch_high, scratch_low); | 97 __ Push(scratch_high, scratch_low); |
106 // Account for saved regs if input is sp. | 98 // Account for saved regs if input is sp. |
107 if (input_reg.is(sp)) double_offset += 2 * kPointerSize; | 99 if (input_reg.is(sp)) double_offset += 2 * kPointerSize; |
108 | 100 |
109 __ LoadlW(scratch_high, | 101 __ LoadlW(scratch_high, |
110 MemOperand(input_reg, double_offset + Register::kExponentOffset)); | 102 MemOperand(input_reg, double_offset + Register::kExponentOffset)); |
111 __ LoadlW(scratch_low, | 103 __ LoadlW(scratch_low, |
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 | 731 |
740 // Get two copies of exponent in the registers scratch and exponent. | 732 // Get two copies of exponent in the registers scratch and exponent. |
741 if (exponent_type() == INTEGER) { | 733 if (exponent_type() == INTEGER) { |
742 __ LoadRR(scratch, exponent); | 734 __ LoadRR(scratch, exponent); |
743 } else { | 735 } else { |
744 // Exponent has previously been stored into scratch as untagged integer. | 736 // Exponent has previously been stored into scratch as untagged integer. |
745 __ LoadRR(exponent, scratch); | 737 __ LoadRR(exponent, scratch); |
746 } | 738 } |
747 __ ldr(double_scratch, double_base); // Back up base. | 739 __ ldr(double_scratch, double_base); // Back up base. |
748 __ LoadImmP(scratch2, Operand(1)); | 740 __ LoadImmP(scratch2, Operand(1)); |
749 __ ConvertIntToDouble(scratch2, double_result); | 741 __ ConvertIntToDouble(double_result, scratch2); |
750 | 742 |
751 // Get absolute value of exponent. | 743 // Get absolute value of exponent. |
752 Label positive_exponent; | 744 Label positive_exponent; |
753 __ CmpP(scratch, Operand::Zero()); | 745 __ CmpP(scratch, Operand::Zero()); |
754 __ bge(&positive_exponent, Label::kNear); | 746 __ bge(&positive_exponent, Label::kNear); |
755 __ LoadComplementRR(scratch, scratch); | 747 __ LoadComplementRR(scratch, scratch); |
756 __ bind(&positive_exponent); | 748 __ bind(&positive_exponent); |
757 | 749 |
758 Label while_true, no_carry, loop_end; | 750 Label while_true, no_carry, loop_end; |
759 __ bind(&while_true); | 751 __ bind(&while_true); |
760 __ mov(scratch2, Operand(1)); | 752 __ mov(scratch2, Operand(1)); |
761 __ AndP(scratch2, scratch); | 753 __ AndP(scratch2, scratch); |
762 __ beq(&no_carry, Label::kNear); | 754 __ beq(&no_carry, Label::kNear); |
763 __ mdbr(double_result, double_scratch); | 755 __ mdbr(double_result, double_scratch); |
764 __ bind(&no_carry); | 756 __ bind(&no_carry); |
765 __ ShiftRightP(scratch, scratch, Operand(1)); | 757 __ ShiftRightP(scratch, scratch, Operand(1)); |
766 __ LoadAndTestP(scratch, scratch); | 758 __ LoadAndTestP(scratch, scratch); |
767 __ beq(&loop_end, Label::kNear); | 759 __ beq(&loop_end, Label::kNear); |
768 __ mdbr(double_scratch, double_scratch); | 760 __ mdbr(double_scratch, double_scratch); |
769 __ b(&while_true); | 761 __ b(&while_true); |
770 __ bind(&loop_end); | 762 __ bind(&loop_end); |
771 | 763 |
772 __ CmpP(exponent, Operand::Zero()); | 764 __ CmpP(exponent, Operand::Zero()); |
773 __ bge(&done); | 765 __ bge(&done); |
774 | 766 |
775 // get 1/double_result: | 767 // get 1/double_result: |
776 __ ldr(double_scratch, double_result); | 768 __ ldr(double_scratch, double_result); |
777 __ LoadImmP(scratch2, Operand(1)); | 769 __ LoadImmP(scratch2, Operand(1)); |
778 __ ConvertIntToDouble(scratch2, double_result); | 770 __ ConvertIntToDouble(double_result, scratch2); |
779 __ ddbr(double_result, double_scratch); | 771 __ ddbr(double_result, double_scratch); |
780 | 772 |
781 // 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. |
782 // 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. |
783 __ lzdr(kDoubleRegZero); | 775 __ lzdr(kDoubleRegZero); |
784 __ cdbr(double_result, kDoubleRegZero); | 776 __ cdbr(double_result, kDoubleRegZero); |
785 __ bne(&done, Label::kNear); | 777 __ bne(&done, Label::kNear); |
786 // double_exponent may not containe the exponent value if the input was a | 778 // double_exponent may not containe the exponent value if the input was a |
787 // smi. We set it with exponent value before bailing out. | 779 // smi. We set it with exponent value before bailing out. |
788 __ ConvertIntToDouble(exponent, double_exponent); | 780 __ ConvertIntToDouble(double_exponent, exponent); |
789 | 781 |
790 // Returning or bailing out. | 782 // Returning or bailing out. |
791 __ push(r14); | 783 __ push(r14); |
792 { | 784 { |
793 AllowExternalCallThatCantCauseGC scope(masm); | 785 AllowExternalCallThatCantCauseGC scope(masm); |
794 __ PrepareCallCFunction(0, 2, scratch); | 786 __ PrepareCallCFunction(0, 2, scratch); |
795 __ MovToFloatParameters(double_base, double_exponent); | 787 __ MovToFloatParameters(double_base, double_exponent); |
796 __ CallCFunction( | 788 __ CallCFunction( |
797 ExternalReference::power_double_double_function(isolate()), 0, 2); | 789 ExternalReference::power_double_double_function(isolate()), 0, 2); |
798 } | 790 } |
(...skipping 2324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3123 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 3115 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |
3124 kStackUnwindSpace, NULL, return_value_operand, NULL); | 3116 kStackUnwindSpace, NULL, return_value_operand, NULL); |
3125 } | 3117 } |
3126 | 3118 |
3127 #undef __ | 3119 #undef __ |
3128 | 3120 |
3129 } // namespace internal | 3121 } // namespace internal |
3130 } // namespace v8 | 3122 } // namespace v8 |
3131 | 3123 |
3132 #endif // V8_TARGET_ARCH_S390 | 3124 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |