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