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