OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 FPRegister scratch0_double = d7; | 1041 FPRegister scratch0_double = d7; |
1042 | 1042 |
1043 // A fast-path for integer exponents. | 1043 // A fast-path for integer exponents. |
1044 Label exponent_is_smi, exponent_is_integer; | 1044 Label exponent_is_smi, exponent_is_integer; |
1045 // Bail out to runtime. | 1045 // Bail out to runtime. |
1046 Label call_runtime; | 1046 Label call_runtime; |
1047 // Allocate a heap number for the result, and return it. | 1047 // Allocate a heap number for the result, and return it. |
1048 Label done; | 1048 Label done; |
1049 | 1049 |
1050 // Unpack the inputs. | 1050 // Unpack the inputs. |
1051 if (exponent_type_ == ON_STACK) { | 1051 if (exponent_type() == ON_STACK) { |
1052 Label base_is_smi; | 1052 Label base_is_smi; |
1053 Label unpack_exponent; | 1053 Label unpack_exponent; |
1054 | 1054 |
1055 __ Pop(exponent_tagged, base_tagged); | 1055 __ Pop(exponent_tagged, base_tagged); |
1056 | 1056 |
1057 __ JumpIfSmi(base_tagged, &base_is_smi); | 1057 __ JumpIfSmi(base_tagged, &base_is_smi); |
1058 __ JumpIfNotHeapNumber(base_tagged, &call_runtime); | 1058 __ JumpIfNotHeapNumber(base_tagged, &call_runtime); |
1059 // base_tagged is a heap number, so load its double value. | 1059 // base_tagged is a heap number, so load its double value. |
1060 __ Ldr(base_double, FieldMemOperand(base_tagged, HeapNumber::kValueOffset)); | 1060 __ Ldr(base_double, FieldMemOperand(base_tagged, HeapNumber::kValueOffset)); |
1061 __ B(&unpack_exponent); | 1061 __ B(&unpack_exponent); |
1062 __ Bind(&base_is_smi); | 1062 __ Bind(&base_is_smi); |
1063 // base_tagged is a SMI, so untag it and convert it to a double. | 1063 // base_tagged is a SMI, so untag it and convert it to a double. |
1064 __ SmiUntagToDouble(base_double, base_tagged); | 1064 __ SmiUntagToDouble(base_double, base_tagged); |
1065 | 1065 |
1066 __ Bind(&unpack_exponent); | 1066 __ Bind(&unpack_exponent); |
1067 // x10 base_tagged The tagged base (input). | 1067 // x10 base_tagged The tagged base (input). |
1068 // x11 exponent_tagged The tagged exponent (input). | 1068 // x11 exponent_tagged The tagged exponent (input). |
1069 // d1 base_double The base as a double. | 1069 // d1 base_double The base as a double. |
1070 __ JumpIfSmi(exponent_tagged, &exponent_is_smi); | 1070 __ JumpIfSmi(exponent_tagged, &exponent_is_smi); |
1071 __ JumpIfNotHeapNumber(exponent_tagged, &call_runtime); | 1071 __ JumpIfNotHeapNumber(exponent_tagged, &call_runtime); |
1072 // exponent_tagged is a heap number, so load its double value. | 1072 // exponent_tagged is a heap number, so load its double value. |
1073 __ Ldr(exponent_double, | 1073 __ Ldr(exponent_double, |
1074 FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset)); | 1074 FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset)); |
1075 } else if (exponent_type_ == TAGGED) { | 1075 } else if (exponent_type() == TAGGED) { |
1076 __ JumpIfSmi(exponent_tagged, &exponent_is_smi); | 1076 __ JumpIfSmi(exponent_tagged, &exponent_is_smi); |
1077 __ Ldr(exponent_double, | 1077 __ Ldr(exponent_double, |
1078 FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset)); | 1078 FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset)); |
1079 } | 1079 } |
1080 | 1080 |
1081 // Handle double (heap number) exponents. | 1081 // Handle double (heap number) exponents. |
1082 if (exponent_type_ != INTEGER) { | 1082 if (exponent_type() != INTEGER) { |
1083 // Detect integer exponents stored as doubles and handle those in the | 1083 // Detect integer exponents stored as doubles and handle those in the |
1084 // integer fast-path. | 1084 // integer fast-path. |
1085 __ TryRepresentDoubleAsInt64(exponent_integer, exponent_double, | 1085 __ TryRepresentDoubleAsInt64(exponent_integer, exponent_double, |
1086 scratch0_double, &exponent_is_integer); | 1086 scratch0_double, &exponent_is_integer); |
1087 | 1087 |
1088 if (exponent_type_ == ON_STACK) { | 1088 if (exponent_type() == ON_STACK) { |
1089 FPRegister half_double = d3; | 1089 FPRegister half_double = d3; |
1090 FPRegister minus_half_double = d4; | 1090 FPRegister minus_half_double = d4; |
1091 // Detect square root case. Crankshaft detects constant +/-0.5 at compile | 1091 // Detect square root case. Crankshaft detects constant +/-0.5 at compile |
1092 // time and uses DoMathPowHalf instead. We then skip this check for | 1092 // time and uses DoMathPowHalf instead. We then skip this check for |
1093 // non-constant cases of +/-0.5 as these hardly occur. | 1093 // non-constant cases of +/-0.5 as these hardly occur. |
1094 | 1094 |
1095 __ Fmov(minus_half_double, -0.5); | 1095 __ Fmov(minus_half_double, -0.5); |
1096 __ Fmov(half_double, 0.5); | 1096 __ Fmov(half_double, 0.5); |
1097 __ Fcmp(minus_half_double, exponent_double); | 1097 __ Fcmp(minus_half_double, exponent_double); |
1098 __ Fccmp(half_double, exponent_double, NZFlag, ne); | 1098 __ Fccmp(half_double, exponent_double, NZFlag, ne); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 __ Fdiv(result_double, scratch0_double, result_double); | 1229 __ Fdiv(result_double, scratch0_double, result_double); |
1230 // ECMA-262 only requires Math.pow to return an 'implementation-dependent | 1230 // ECMA-262 only requires Math.pow to return an 'implementation-dependent |
1231 // approximation' of base^exponent. However, mjsunit/math-pow uses Math.pow | 1231 // approximation' of base^exponent. However, mjsunit/math-pow uses Math.pow |
1232 // to calculate the subnormal value 2^-1074. This method of calculating | 1232 // to calculate the subnormal value 2^-1074. This method of calculating |
1233 // negative powers doesn't work because 2^1074 overflows to infinity. To | 1233 // negative powers doesn't work because 2^1074 overflows to infinity. To |
1234 // catch this corner-case, we bail out if the result was 0. (This can only | 1234 // catch this corner-case, we bail out if the result was 0. (This can only |
1235 // occur if the divisor is infinity or the base is zero.) | 1235 // occur if the divisor is infinity or the base is zero.) |
1236 __ Fcmp(result_double, 0.0); | 1236 __ Fcmp(result_double, 0.0); |
1237 __ B(&done, ne); | 1237 __ B(&done, ne); |
1238 | 1238 |
1239 if (exponent_type_ == ON_STACK) { | 1239 if (exponent_type() == ON_STACK) { |
1240 // Bail out to runtime code. | 1240 // Bail out to runtime code. |
1241 __ Bind(&call_runtime); | 1241 __ Bind(&call_runtime); |
1242 // Put the arguments back on the stack. | 1242 // Put the arguments back on the stack. |
1243 __ Push(base_tagged, exponent_tagged); | 1243 __ Push(base_tagged, exponent_tagged); |
1244 __ TailCallRuntime(Runtime::kMathPowRT, 2, 1); | 1244 __ TailCallRuntime(Runtime::kMathPowRT, 2, 1); |
1245 | 1245 |
1246 // Return. | 1246 // Return. |
1247 __ Bind(&done); | 1247 __ Bind(&done); |
1248 __ AllocateHeapNumber(result_tagged, &call_runtime, scratch0, scratch1, | 1248 __ AllocateHeapNumber(result_tagged, &call_runtime, scratch0, scratch1, |
1249 result_double); | 1249 result_double); |
(...skipping 1890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3140 | 3140 |
3141 if (call_as_method) { | 3141 if (call_as_method) { |
3142 __ Bind(&wrap); | 3142 __ Bind(&wrap); |
3143 EmitWrapCase(masm, argc, &cont); | 3143 EmitWrapCase(masm, argc, &cont); |
3144 } | 3144 } |
3145 } | 3145 } |
3146 | 3146 |
3147 | 3147 |
3148 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3148 void CallFunctionStub::Generate(MacroAssembler* masm) { |
3149 ASM_LOCATION("CallFunctionStub::Generate"); | 3149 ASM_LOCATION("CallFunctionStub::Generate"); |
3150 CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod()); | 3150 CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod()); |
3151 } | 3151 } |
3152 | 3152 |
3153 | 3153 |
3154 void CallConstructStub::Generate(MacroAssembler* masm) { | 3154 void CallConstructStub::Generate(MacroAssembler* masm) { |
3155 ASM_LOCATION("CallConstructStub::Generate"); | 3155 ASM_LOCATION("CallConstructStub::Generate"); |
3156 // x0 : number of arguments | 3156 // x0 : number of arguments |
3157 // x1 : the function to call | 3157 // x1 : the function to call |
3158 // x2 : feedback vector | 3158 // x2 : feedback vector |
3159 // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol) | 3159 // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol) |
3160 Register function = x1; | 3160 Register function = x1; |
(...skipping 1422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4583 __ Ret(); | 4583 __ Ret(); |
4584 } | 4584 } |
4585 | 4585 |
4586 | 4586 |
4587 void StubFailureTrampolineStub::Generate(MacroAssembler* masm) { | 4587 void StubFailureTrampolineStub::Generate(MacroAssembler* masm) { |
4588 CEntryStub ces(isolate(), 1, kSaveFPRegs); | 4588 CEntryStub ces(isolate(), 1, kSaveFPRegs); |
4589 __ Call(ces.GetCode(), RelocInfo::CODE_TARGET); | 4589 __ Call(ces.GetCode(), RelocInfo::CODE_TARGET); |
4590 int parameter_count_offset = | 4590 int parameter_count_offset = |
4591 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; | 4591 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; |
4592 __ Ldr(x1, MemOperand(fp, parameter_count_offset)); | 4592 __ Ldr(x1, MemOperand(fp, parameter_count_offset)); |
4593 if (function_mode_ == JS_FUNCTION_STUB_MODE) { | 4593 if (function_mode() == JS_FUNCTION_STUB_MODE) { |
4594 __ Add(x1, x1, 1); | 4594 __ Add(x1, x1, 1); |
4595 } | 4595 } |
4596 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 4596 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
4597 __ Drop(x1); | 4597 __ Drop(x1); |
4598 // Return to IC Miss stub, continuation still on stack. | 4598 // Return to IC Miss stub, continuation still on stack. |
4599 __ Ret(); | 4599 __ Ret(); |
4600 } | 4600 } |
4601 | 4601 |
4602 | 4602 |
4603 static unsigned int GetProfileEntryHookCallSize(MacroAssembler* masm) { | 4603 static unsigned int GetProfileEntryHookCallSize(MacroAssembler* masm) { |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5108 InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]); | 5108 InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]); |
5109 stubh3.GetCode(); | 5109 stubh3.GetCode(); |
5110 } | 5110 } |
5111 } | 5111 } |
5112 | 5112 |
5113 | 5113 |
5114 void ArrayConstructorStub::GenerateDispatchToArrayStub( | 5114 void ArrayConstructorStub::GenerateDispatchToArrayStub( |
5115 MacroAssembler* masm, | 5115 MacroAssembler* masm, |
5116 AllocationSiteOverrideMode mode) { | 5116 AllocationSiteOverrideMode mode) { |
5117 Register argc = x0; | 5117 Register argc = x0; |
5118 if (argument_count_ == ANY) { | 5118 if (argument_count() == ANY) { |
5119 Label zero_case, n_case; | 5119 Label zero_case, n_case; |
5120 __ Cbz(argc, &zero_case); | 5120 __ Cbz(argc, &zero_case); |
5121 __ Cmp(argc, 1); | 5121 __ Cmp(argc, 1); |
5122 __ B(ne, &n_case); | 5122 __ B(ne, &n_case); |
5123 | 5123 |
5124 // One argument. | 5124 // One argument. |
5125 CreateArrayDispatchOneArgument(masm, mode); | 5125 CreateArrayDispatchOneArgument(masm, mode); |
5126 | 5126 |
5127 __ Bind(&zero_case); | 5127 __ Bind(&zero_case); |
5128 // No arguments. | 5128 // No arguments. |
5129 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); | 5129 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); |
5130 | 5130 |
5131 __ Bind(&n_case); | 5131 __ Bind(&n_case); |
5132 // N arguments. | 5132 // N arguments. |
5133 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); | 5133 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
5134 | 5134 |
5135 } else if (argument_count_ == NONE) { | 5135 } else if (argument_count() == NONE) { |
5136 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); | 5136 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); |
5137 } else if (argument_count_ == ONE) { | 5137 } else if (argument_count() == ONE) { |
5138 CreateArrayDispatchOneArgument(masm, mode); | 5138 CreateArrayDispatchOneArgument(masm, mode); |
5139 } else if (argument_count_ == MORE_THAN_ONE) { | 5139 } else if (argument_count() == MORE_THAN_ONE) { |
5140 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); | 5140 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
5141 } else { | 5141 } else { |
5142 UNREACHABLE(); | 5142 UNREACHABLE(); |
5143 } | 5143 } |
5144 } | 5144 } |
5145 | 5145 |
5146 | 5146 |
5147 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 5147 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
5148 ASM_LOCATION("ArrayConstructorStub::Generate"); | 5148 ASM_LOCATION("ArrayConstructorStub::Generate"); |
5149 // ----------- S t a t e ------------- | 5149 // ----------- S t a t e ------------- |
5150 // -- x0 : argc (only if argument_count_ == ANY) | 5150 // -- x0 : argc (only if argument_count() == ANY) |
5151 // -- x1 : constructor | 5151 // -- x1 : constructor |
5152 // -- x2 : AllocationSite or undefined | 5152 // -- x2 : AllocationSite or undefined |
5153 // -- sp[0] : return address | 5153 // -- sp[0] : return address |
5154 // -- sp[4] : last argument | 5154 // -- sp[4] : last argument |
5155 // ----------------------------------- | 5155 // ----------------------------------- |
5156 Register constructor = x1; | 5156 Register constructor = x1; |
5157 Register allocation_site = x2; | 5157 Register allocation_site = x2; |
5158 | 5158 |
5159 if (FLAG_debug_code) { | 5159 if (FLAG_debug_code) { |
5160 // The array construct code is only set for the global and natives | 5160 // The array construct code is only set for the global and natives |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5292 // -- sp[(argc - 1) * 8] : first argument | 5292 // -- sp[(argc - 1) * 8] : first argument |
5293 // -- sp[argc * 8] : receiver | 5293 // -- sp[argc * 8] : receiver |
5294 // ----------------------------------- | 5294 // ----------------------------------- |
5295 | 5295 |
5296 Register callee = x0; | 5296 Register callee = x0; |
5297 Register call_data = x4; | 5297 Register call_data = x4; |
5298 Register holder = x2; | 5298 Register holder = x2; |
5299 Register api_function_address = x1; | 5299 Register api_function_address = x1; |
5300 Register context = cp; | 5300 Register context = cp; |
5301 | 5301 |
5302 int argc = ArgumentBits::decode(bit_field_); | 5302 int argc = this->argc(); |
5303 bool is_store = IsStoreBits::decode(bit_field_); | 5303 bool is_store = this->is_store(); |
5304 bool call_data_undefined = CallDataUndefinedBits::decode(bit_field_); | 5304 bool call_data_undefined = this->call_data_undefined(); |
5305 | 5305 |
5306 typedef FunctionCallbackArguments FCA; | 5306 typedef FunctionCallbackArguments FCA; |
5307 | 5307 |
5308 STATIC_ASSERT(FCA::kContextSaveIndex == 6); | 5308 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
5309 STATIC_ASSERT(FCA::kCalleeIndex == 5); | 5309 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
5310 STATIC_ASSERT(FCA::kDataIndex == 4); | 5310 STATIC_ASSERT(FCA::kDataIndex == 4); |
5311 STATIC_ASSERT(FCA::kReturnValueOffset == 3); | 5311 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
5312 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); | 5312 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
5313 STATIC_ASSERT(FCA::kIsolateIndex == 1); | 5313 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
5314 STATIC_ASSERT(FCA::kHolderIndex == 0); | 5314 STATIC_ASSERT(FCA::kHolderIndex == 0); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5423 MemOperand(fp, 6 * kPointerSize), | 5423 MemOperand(fp, 6 * kPointerSize), |
5424 NULL); | 5424 NULL); |
5425 } | 5425 } |
5426 | 5426 |
5427 | 5427 |
5428 #undef __ | 5428 #undef __ |
5429 | 5429 |
5430 } } // namespace v8::internal | 5430 } } // namespace v8::internal |
5431 | 5431 |
5432 #endif // V8_TARGET_ARCH_ARM64 | 5432 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |