Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 71163006: Merge bleeding_edge r17376:17693. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Fix all.gyp Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 } 71 }
72 72
73 73
74 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( 74 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
75 Isolate* isolate, 75 Isolate* isolate,
76 CodeStubInterfaceDescriptor* descriptor) { 76 CodeStubInterfaceDescriptor* descriptor) {
77 static Register registers[] = { rax, rbx, rcx }; 77 static Register registers[] = { rax, rbx, rcx };
78 descriptor->register_param_count_ = 3; 78 descriptor->register_param_count_ = 3;
79 descriptor->register_params_ = registers; 79 descriptor->register_params_ = registers;
80 descriptor->deoptimization_handler_ = 80 descriptor->deoptimization_handler_ =
81 Runtime::FunctionForId(Runtime::kCreateArrayLiteralShallow)->entry; 81 Runtime::FunctionForId(Runtime::kCreateArrayLiteral)->entry;
82 } 82 }
83 83
84 84
85 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( 85 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
86 Isolate* isolate, 86 Isolate* isolate,
87 CodeStubInterfaceDescriptor* descriptor) { 87 CodeStubInterfaceDescriptor* descriptor) {
88 static Register registers[] = { rax, rbx, rcx, rdx }; 88 static Register registers[] = { rax, rbx, rcx, rdx };
89 descriptor->register_param_count_ = 4; 89 descriptor->register_param_count_ = 4;
90 descriptor->register_params_ = registers; 90 descriptor->register_params_ = registers;
91 descriptor->deoptimization_handler_ = 91 descriptor->deoptimization_handler_ =
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 169
170 170
171 static void InitializeArrayConstructorDescriptor( 171 static void InitializeArrayConstructorDescriptor(
172 Isolate* isolate, 172 Isolate* isolate,
173 CodeStubInterfaceDescriptor* descriptor, 173 CodeStubInterfaceDescriptor* descriptor,
174 int constant_stack_parameter_count) { 174 int constant_stack_parameter_count) {
175 // register state 175 // register state
176 // rax -- number of arguments 176 // rax -- number of arguments
177 // rdi -- function 177 // rdi -- function
178 // rbx -- type info cell with elements kind 178 // rbx -- type info cell with elements kind
179 static Register registers[] = { rdi, rbx }; 179 static Register registers_variable_args[] = { rdi, rbx, rax };
180 descriptor->register_param_count_ = 2; 180 static Register registers_no_args[] = { rdi, rbx };
181 if (constant_stack_parameter_count != 0) { 181
182 if (constant_stack_parameter_count == 0) {
183 descriptor->register_param_count_ = 2;
184 descriptor->register_params_ = registers_no_args;
185 } else {
182 // stack param count needs (constructor pointer, and single argument) 186 // stack param count needs (constructor pointer, and single argument)
187 descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
183 descriptor->stack_parameter_count_ = rax; 188 descriptor->stack_parameter_count_ = rax;
189 descriptor->register_param_count_ = 3;
190 descriptor->register_params_ = registers_variable_args;
184 } 191 }
192
185 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; 193 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
186 descriptor->register_params_ = registers;
187 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; 194 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
188 descriptor->deoptimization_handler_ = 195 descriptor->deoptimization_handler_ =
189 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; 196 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry;
190 } 197 }
191 198
192 199
193 static void InitializeInternalArrayConstructorDescriptor( 200 static void InitializeInternalArrayConstructorDescriptor(
194 Isolate* isolate, 201 Isolate* isolate,
195 CodeStubInterfaceDescriptor* descriptor, 202 CodeStubInterfaceDescriptor* descriptor,
196 int constant_stack_parameter_count) { 203 int constant_stack_parameter_count) {
197 // register state 204 // register state
198 // rax -- number of arguments 205 // rax -- number of arguments
199 // rdi -- constructor function 206 // rdi -- constructor function
200 static Register registers[] = { rdi }; 207 static Register registers_variable_args[] = { rdi, rax };
201 descriptor->register_param_count_ = 1; 208 static Register registers_no_args[] = { rdi };
202 209
203 if (constant_stack_parameter_count != 0) { 210 if (constant_stack_parameter_count == 0) {
211 descriptor->register_param_count_ = 1;
212 descriptor->register_params_ = registers_no_args;
213 } else {
204 // stack param count needs (constructor pointer, and single argument) 214 // stack param count needs (constructor pointer, and single argument)
215 descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
205 descriptor->stack_parameter_count_ = rax; 216 descriptor->stack_parameter_count_ = rax;
217 descriptor->register_param_count_ = 2;
218 descriptor->register_params_ = registers_variable_args;
206 } 219 }
220
207 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; 221 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
208 descriptor->register_params_ = registers;
209 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; 222 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
210 descriptor->deoptimization_handler_ = 223 descriptor->deoptimization_handler_ =
211 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; 224 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry;
212 } 225 }
213 226
214 227
215 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( 228 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
216 Isolate* isolate, 229 Isolate* isolate,
217 CodeStubInterfaceDescriptor* descriptor) { 230 CodeStubInterfaceDescriptor* descriptor) {
218 InitializeArrayConstructorDescriptor(isolate, descriptor, 0); 231 InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 Isolate* isolate, 308 Isolate* isolate,
296 CodeStubInterfaceDescriptor* descriptor) { 309 CodeStubInterfaceDescriptor* descriptor) {
297 static Register registers[] = { rax, rbx, rcx, rdx }; 310 static Register registers[] = { rax, rbx, rcx, rdx };
298 descriptor->register_param_count_ = 4; 311 descriptor->register_param_count_ = 4;
299 descriptor->register_params_ = registers; 312 descriptor->register_params_ = registers;
300 descriptor->deoptimization_handler_ = 313 descriptor->deoptimization_handler_ =
301 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss); 314 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
302 } 315 }
303 316
304 317
318 void NewStringAddStub::InitializeInterfaceDescriptor(
319 Isolate* isolate,
320 CodeStubInterfaceDescriptor* descriptor) {
321 static Register registers[] = { rdx, rax };
322 descriptor->register_param_count_ = 2;
323 descriptor->register_params_ = registers;
324 descriptor->deoptimization_handler_ =
325 Runtime::FunctionForId(Runtime::kStringAdd)->entry;
326 }
327
328
305 #define __ ACCESS_MASM(masm) 329 #define __ ACCESS_MASM(masm)
306 330
307 331
308 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { 332 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
309 // Update the static counter each time a new code stub is generated. 333 // Update the static counter each time a new code stub is generated.
310 Isolate* isolate = masm->isolate(); 334 Isolate* isolate = masm->isolate();
311 isolate->counters()->code_stubs()->Increment(); 335 isolate->counters()->code_stubs()->Increment();
312 336
313 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); 337 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate);
314 int param_count = descriptor->register_param_count_; 338 int param_count = descriptor->register_param_count_;
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 __ jmp(&loaded, Label::kNear); 611 __ jmp(&loaded, Label::kNear);
588 612
589 __ bind(&input_not_smi); 613 __ bind(&input_not_smi);
590 // Check if input is a HeapNumber. 614 // Check if input is a HeapNumber.
591 __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex); 615 __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex);
592 __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 616 __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
593 __ j(not_equal, &runtime_call); 617 __ j(not_equal, &runtime_call);
594 // Input is a HeapNumber. Push it on the FPU stack and load its 618 // Input is a HeapNumber. Push it on the FPU stack and load its
595 // bits into rbx. 619 // bits into rbx.
596 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); 620 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
597 __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset)); 621 __ MoveDouble(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
598 __ movq(rdx, rbx); 622 __ movq(rdx, rbx);
599 623
600 __ bind(&loaded); 624 __ bind(&loaded);
601 } else { // UNTAGGED. 625 } else { // UNTAGGED.
602 __ movq(rbx, xmm1); 626 __ movq(rbx, xmm1);
603 __ movq(rdx, xmm1); 627 __ movq(rdx, xmm1);
604 } 628 }
605 629
606 // ST[0] == double value, if TAGGED. 630 // ST[0] == double value, if TAGGED.
607 // rbx = bits of double value. 631 // rbx = bits of double value.
(...skipping 16 matching lines...) Expand all
624 __ xorl(rax, rdi); 648 __ xorl(rax, rdi);
625 __ xorl(rcx, rax); 649 __ xorl(rcx, rax);
626 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); 650 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize));
627 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1)); 651 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1));
628 652
629 // ST[0] == double value. 653 // ST[0] == double value.
630 // rbx = bits of double value. 654 // rbx = bits of double value.
631 // rcx = TranscendentalCache::hash(double value). 655 // rcx = TranscendentalCache::hash(double value).
632 ExternalReference cache_array = 656 ExternalReference cache_array =
633 ExternalReference::transcendental_cache_array_address(masm->isolate()); 657 ExternalReference::transcendental_cache_array_address(masm->isolate());
634 __ movq(rax, cache_array); 658 __ Move(rax, cache_array);
635 int cache_array_index = 659 int cache_array_index =
636 type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]); 660 type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]);
637 __ movq(rax, Operand(rax, cache_array_index)); 661 __ movq(rax, Operand(rax, cache_array_index));
638 // rax points to the cache for the type type_. 662 // rax points to the cache for the type type_.
639 // If NULL, the cache hasn't been initialized yet, so go through runtime. 663 // If NULL, the cache hasn't been initialized yet, so go through runtime.
640 __ testq(rax, rax); 664 __ testq(rax, rax);
641 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED. 665 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED.
642 #ifdef DEBUG 666 #ifdef DEBUG
643 // Check that the layout of cache elements match expectations. 667 // Check that the layout of cache elements match expectations.
644 { // NOLINT - doesn't like a single brace on a line. 668 { // NOLINT - doesn't like a single brace on a line.
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 __ cmpl(exponent, Immediate(0x80000000u)); 976 __ cmpl(exponent, Immediate(0x80000000u));
953 __ j(equal, &call_runtime); 977 __ j(equal, &call_runtime);
954 978
955 if (exponent_type_ == ON_STACK) { 979 if (exponent_type_ == ON_STACK) {
956 // Detect square root case. Crankshaft detects constant +/-0.5 at 980 // Detect square root case. Crankshaft detects constant +/-0.5 at
957 // compile time and uses DoMathPowHalf instead. We then skip this check 981 // compile time and uses DoMathPowHalf instead. We then skip this check
958 // for non-constant cases of +/-0.5 as these hardly occur. 982 // for non-constant cases of +/-0.5 as these hardly occur.
959 Label continue_sqrt, continue_rsqrt, not_plus_half; 983 Label continue_sqrt, continue_rsqrt, not_plus_half;
960 // Test for 0.5. 984 // Test for 0.5.
961 // Load double_scratch with 0.5. 985 // Load double_scratch with 0.5.
962 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000), RelocInfo::NONE64); 986 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000));
963 __ movq(double_scratch, scratch); 987 __ movq(double_scratch, scratch);
964 // Already ruled out NaNs for exponent. 988 // Already ruled out NaNs for exponent.
965 __ ucomisd(double_scratch, double_exponent); 989 __ ucomisd(double_scratch, double_exponent);
966 __ j(not_equal, &not_plus_half, Label::kNear); 990 __ j(not_equal, &not_plus_half, Label::kNear);
967 991
968 // Calculates square root of base. Check for the special case of 992 // Calculates square root of base. Check for the special case of
969 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13). 993 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
970 // According to IEEE-754, double-precision -Infinity has the highest 994 // According to IEEE-754, double-precision -Infinity has the highest
971 // 12 bits set and the lowest 52 bits cleared. 995 // 12 bits set and the lowest 52 bits cleared.
972 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000), RelocInfo::NONE64); 996 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000));
973 __ movq(double_scratch, scratch); 997 __ movq(double_scratch, scratch);
974 __ ucomisd(double_scratch, double_base); 998 __ ucomisd(double_scratch, double_base);
975 // Comparing -Infinity with NaN results in "unordered", which sets the 999 // Comparing -Infinity with NaN results in "unordered", which sets the
976 // zero flag as if both were equal. However, it also sets the carry flag. 1000 // zero flag as if both were equal. However, it also sets the carry flag.
977 __ j(not_equal, &continue_sqrt, Label::kNear); 1001 __ j(not_equal, &continue_sqrt, Label::kNear);
978 __ j(carry, &continue_sqrt, Label::kNear); 1002 __ j(carry, &continue_sqrt, Label::kNear);
979 1003
980 // Set result to Infinity in the special case. 1004 // Set result to Infinity in the special case.
981 __ xorps(double_result, double_result); 1005 __ xorps(double_result, double_result);
982 __ subsd(double_result, double_scratch); 1006 __ subsd(double_result, double_scratch);
(...skipping 11 matching lines...) Expand all
994 // Load double_scratch with -0.5 by substracting 1. 1018 // Load double_scratch with -0.5 by substracting 1.
995 __ subsd(double_scratch, double_result); 1019 __ subsd(double_scratch, double_result);
996 // Already ruled out NaNs for exponent. 1020 // Already ruled out NaNs for exponent.
997 __ ucomisd(double_scratch, double_exponent); 1021 __ ucomisd(double_scratch, double_exponent);
998 __ j(not_equal, &fast_power, Label::kNear); 1022 __ j(not_equal, &fast_power, Label::kNear);
999 1023
1000 // Calculates reciprocal of square root of base. Check for the special 1024 // Calculates reciprocal of square root of base. Check for the special
1001 // case of Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13). 1025 // case of Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
1002 // According to IEEE-754, double-precision -Infinity has the highest 1026 // According to IEEE-754, double-precision -Infinity has the highest
1003 // 12 bits set and the lowest 52 bits cleared. 1027 // 12 bits set and the lowest 52 bits cleared.
1004 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000), RelocInfo::NONE64); 1028 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000));
1005 __ movq(double_scratch, scratch); 1029 __ movq(double_scratch, scratch);
1006 __ ucomisd(double_scratch, double_base); 1030 __ ucomisd(double_scratch, double_base);
1007 // Comparing -Infinity with NaN results in "unordered", which sets the 1031 // Comparing -Infinity with NaN results in "unordered", which sets the
1008 // zero flag as if both were equal. However, it also sets the carry flag. 1032 // zero flag as if both were equal. However, it also sets the carry flag.
1009 __ j(not_equal, &continue_rsqrt, Label::kNear); 1033 __ j(not_equal, &continue_rsqrt, Label::kNear);
1010 __ j(carry, &continue_rsqrt, Label::kNear); 1034 __ j(carry, &continue_rsqrt, Label::kNear);
1011 1035
1012 // Set result to 0 in the special case. 1036 // Set result to 0 in the special case.
1013 __ xorps(double_result, double_result); 1037 __ xorps(double_result, double_result);
1014 __ jmp(&done); 1038 __ jmp(&done);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 __ movsd(xmm0, double_base); 1153 __ movsd(xmm0, double_base);
1130 ASSERT(double_exponent.is(xmm1)); 1154 ASSERT(double_exponent.is(xmm1));
1131 { 1155 {
1132 AllowExternalCallThatCantCauseGC scope(masm); 1156 AllowExternalCallThatCantCauseGC scope(masm);
1133 __ PrepareCallCFunction(2); 1157 __ PrepareCallCFunction(2);
1134 __ CallCFunction( 1158 __ CallCFunction(
1135 ExternalReference::power_double_double_function(masm->isolate()), 2); 1159 ExternalReference::power_double_double_function(masm->isolate()), 2);
1136 } 1160 }
1137 // Return value is in xmm0. 1161 // Return value is in xmm0.
1138 __ movsd(double_result, xmm0); 1162 __ movsd(double_result, xmm0);
1139 // Restore context register.
1140 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1141 1163
1142 __ bind(&done); 1164 __ bind(&done);
1143 __ IncrementCounter(counters->math_pow(), 1); 1165 __ IncrementCounter(counters->math_pow(), 1);
1144 __ ret(0); 1166 __ ret(0);
1145 } 1167 }
1146 } 1168 }
1147 1169
1148 1170
1149 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { 1171 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
1150 Label miss; 1172 Label miss;
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
1866 __ LoadAddress(kScratchRegister, 1888 __ LoadAddress(kScratchRegister,
1867 ExternalReference::isolate_address(masm->isolate())); 1889 ExternalReference::isolate_address(masm->isolate()));
1868 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), 1890 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
1869 kScratchRegister); 1891 kScratchRegister);
1870 1892
1871 // Argument 8: Indicate that this is a direct call from JavaScript. 1893 // Argument 8: Indicate that this is a direct call from JavaScript.
1872 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize), 1894 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize),
1873 Immediate(1)); 1895 Immediate(1));
1874 1896
1875 // Argument 7: Start (high end) of backtracking stack memory area. 1897 // Argument 7: Start (high end) of backtracking stack memory area.
1876 __ movq(kScratchRegister, address_of_regexp_stack_memory_address); 1898 __ Move(kScratchRegister, address_of_regexp_stack_memory_address);
1877 __ movq(r9, Operand(kScratchRegister, 0)); 1899 __ movq(r9, Operand(kScratchRegister, 0));
1878 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); 1900 __ Move(kScratchRegister, address_of_regexp_stack_memory_size);
1879 __ addq(r9, Operand(kScratchRegister, 0)); 1901 __ addq(r9, Operand(kScratchRegister, 0));
1880 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9); 1902 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9);
1881 1903
1882 // Argument 6: Set the number of capture registers to zero to force global 1904 // Argument 6: Set the number of capture registers to zero to force global
1883 // regexps to behave as non-global. This does not affect non-global regexps. 1905 // regexps to behave as non-global. This does not affect non-global regexps.
1884 // Argument 6 is passed in r9 on Linux and on the stack on Windows. 1906 // Argument 6 is passed in r9 on Linux and on the stack on Windows.
1885 #ifdef _WIN64 1907 #ifdef _WIN64
1886 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), 1908 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize),
1887 Immediate(0)); 1909 Immediate(0));
1888 #else 1910 #else
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
2215 2237
2216 static void CheckInputType(MacroAssembler* masm, 2238 static void CheckInputType(MacroAssembler* masm,
2217 Register input, 2239 Register input,
2218 CompareIC::State expected, 2240 CompareIC::State expected,
2219 Label* fail) { 2241 Label* fail) {
2220 Label ok; 2242 Label ok;
2221 if (expected == CompareIC::SMI) { 2243 if (expected == CompareIC::SMI) {
2222 __ JumpIfNotSmi(input, fail); 2244 __ JumpIfNotSmi(input, fail);
2223 } else if (expected == CompareIC::NUMBER) { 2245 } else if (expected == CompareIC::NUMBER) {
2224 __ JumpIfSmi(input, &ok); 2246 __ JumpIfSmi(input, &ok);
2225 __ CompareMap(input, masm->isolate()->factory()->heap_number_map(), NULL); 2247 __ CompareMap(input, masm->isolate()->factory()->heap_number_map());
2226 __ j(not_equal, fail); 2248 __ j(not_equal, fail);
2227 } 2249 }
2228 // We could be strict about internalized/non-internalized here, but as long as 2250 // We could be strict about internalized/non-internalized here, but as long as
2229 // hydrogen doesn't care, the stub doesn't have to care either. 2251 // hydrogen doesn't care, the stub doesn't have to care either.
2230 __ bind(&ok); 2252 __ bind(&ok);
2231 } 2253 }
2232 2254
2233 2255
2234 static void BranchIfNotInternalizedString(MacroAssembler* masm, 2256 static void BranchIfNotInternalizedString(MacroAssembler* masm,
2235 Label* label, 2257 Label* label,
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
2803 // Check stack alignment. 2825 // Check stack alignment.
2804 if (FLAG_debug_code) { 2826 if (FLAG_debug_code) {
2805 __ CheckStackAlignment(); 2827 __ CheckStackAlignment();
2806 } 2828 }
2807 2829
2808 if (do_gc) { 2830 if (do_gc) {
2809 // Pass failure code returned from last attempt as first argument to 2831 // Pass failure code returned from last attempt as first argument to
2810 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the 2832 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
2811 // stack is known to be aligned. This function takes one argument which is 2833 // stack is known to be aligned. This function takes one argument which is
2812 // passed in register. 2834 // passed in register.
2813 __ movq(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); 2835 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate()));
2814 __ movq(arg_reg_1, rax); 2836 __ movq(arg_reg_1, rax);
2815 __ movq(kScratchRegister, 2837 __ Move(kScratchRegister,
2816 ExternalReference::perform_gc_function(masm->isolate())); 2838 ExternalReference::perform_gc_function(masm->isolate()));
2817 __ call(kScratchRegister); 2839 __ call(kScratchRegister);
2818 } 2840 }
2819 2841
2820 ExternalReference scope_depth = 2842 ExternalReference scope_depth =
2821 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); 2843 ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
2822 if (always_allocate_scope) { 2844 if (always_allocate_scope) {
2823 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); 2845 Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
2824 __ incl(scope_depth_operand); 2846 __ incl(scope_depth_operand);
2825 } 2847 }
2826 2848
2827 // Call C function. 2849 // Call C function.
2828 #ifdef _WIN64 2850 #ifdef _WIN64
2829 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. 2851 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9.
2830 // Pass argv and argc as two parameters. The arguments object will 2852 // Pass argv and argc as two parameters. The arguments object will
2831 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). 2853 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION().
2832 if (result_size_ < 2) { 2854 if (result_size_ < 2) {
2833 // Pass a pointer to the Arguments object as the first argument. 2855 // Pass a pointer to the Arguments object as the first argument.
2834 // Return result in single register (rax). 2856 // Return result in single register (rax).
2835 __ movq(rcx, r14); // argc. 2857 __ movq(rcx, r14); // argc.
2836 __ movq(rdx, r15); // argv. 2858 __ movq(rdx, r15); // argv.
2837 __ movq(r8, ExternalReference::isolate_address(masm->isolate())); 2859 __ Move(r8, ExternalReference::isolate_address(masm->isolate()));
2838 } else { 2860 } else {
2839 ASSERT_EQ(2, result_size_); 2861 ASSERT_EQ(2, result_size_);
2840 // Pass a pointer to the result location as the first argument. 2862 // Pass a pointer to the result location as the first argument.
2841 __ lea(rcx, StackSpaceOperand(2)); 2863 __ lea(rcx, StackSpaceOperand(2));
2842 // Pass a pointer to the Arguments object as the second argument. 2864 // Pass a pointer to the Arguments object as the second argument.
2843 __ movq(rdx, r14); // argc. 2865 __ movq(rdx, r14); // argc.
2844 __ movq(r8, r15); // argv. 2866 __ movq(r8, r15); // argv.
2845 __ movq(r9, ExternalReference::isolate_address(masm->isolate())); 2867 __ Move(r9, ExternalReference::isolate_address(masm->isolate()));
2846 } 2868 }
2847 2869
2848 #else // _WIN64 2870 #else // _WIN64
2849 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. 2871 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
2850 __ movq(rdi, r14); // argc. 2872 __ movq(rdi, r14); // argc.
2851 __ movq(rsi, r15); // argv. 2873 __ movq(rsi, r15); // argv.
2852 __ movq(rdx, ExternalReference::isolate_address(masm->isolate())); 2874 __ Move(rdx, ExternalReference::isolate_address(masm->isolate()));
2853 #endif 2875 #endif
2854 __ call(rbx); 2876 __ call(rbx);
2855 // Result is in rax - do not destroy this register! 2877 // Result is in rax - do not destroy this register!
2856 2878
2857 if (always_allocate_scope) { 2879 if (always_allocate_scope) {
2858 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); 2880 Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
2859 __ decl(scope_depth_operand); 2881 __ decl(scope_depth_operand);
2860 } 2882 }
2861 2883
2862 // Check for failure result. 2884 // Check for failure result.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
3023 MacroAssembler::NoRootArrayScope uninitialized_root_register(masm); 3045 MacroAssembler::NoRootArrayScope uninitialized_root_register(masm);
3024 // Set up frame. 3046 // Set up frame.
3025 __ push(rbp); 3047 __ push(rbp);
3026 __ movq(rbp, rsp); 3048 __ movq(rbp, rsp);
3027 3049
3028 // Push the stack frame type marker twice. 3050 // Push the stack frame type marker twice.
3029 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; 3051 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
3030 // Scratch register is neither callee-save, nor an argument register on any 3052 // Scratch register is neither callee-save, nor an argument register on any
3031 // platform. It's free to use at this point. 3053 // platform. It's free to use at this point.
3032 // Cannot use smi-register for loading yet. 3054 // Cannot use smi-register for loading yet.
3033 __ movq(kScratchRegister, 3055 __ movq(kScratchRegister, Smi::FromInt(marker), RelocInfo::NONE64);
3034 reinterpret_cast<uint64_t>(Smi::FromInt(marker)),
3035 RelocInfo::NONE64);
3036 __ push(kScratchRegister); // context slot 3056 __ push(kScratchRegister); // context slot
3037 __ push(kScratchRegister); // function slot 3057 __ push(kScratchRegister); // function slot
3038 // Save callee-saved registers (X64/Win64 calling conventions). 3058 // Save callee-saved registers (X64/Win64 calling conventions).
3039 __ push(r12); 3059 __ push(r12);
3040 __ push(r13); 3060 __ push(r13);
3041 __ push(r14); 3061 __ push(r14);
3042 __ push(r15); 3062 __ push(r15);
3043 #ifdef _WIN64 3063 #ifdef _WIN64
3044 __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI. 3064 __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
3045 __ push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI. 3065 __ push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3132 __ call(kScratchRegister); 3152 __ call(kScratchRegister);
3133 3153
3134 // Unlink this frame from the handler chain. 3154 // Unlink this frame from the handler chain.
3135 __ PopTryHandler(); 3155 __ PopTryHandler();
3136 3156
3137 __ bind(&exit); 3157 __ bind(&exit);
3138 // Check if the current stack frame is marked as the outermost JS frame. 3158 // Check if the current stack frame is marked as the outermost JS frame.
3139 __ pop(rbx); 3159 __ pop(rbx);
3140 __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)); 3160 __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME));
3141 __ j(not_equal, &not_outermost_js_2); 3161 __ j(not_equal, &not_outermost_js_2);
3142 __ movq(kScratchRegister, js_entry_sp); 3162 __ Move(kScratchRegister, js_entry_sp);
3143 __ movq(Operand(kScratchRegister, 0), Immediate(0)); 3163 __ movq(Operand(kScratchRegister, 0), Immediate(0));
3144 __ bind(&not_outermost_js_2); 3164 __ bind(&not_outermost_js_2);
3145 3165
3146 // Restore the top frame descriptor from the stack. 3166 // Restore the top frame descriptor from the stack.
3147 { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp); 3167 { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
3148 __ pop(c_entry_fp_operand); 3168 __ pop(c_entry_fp_operand);
3149 } 3169 }
3150 3170
3151 // Restore callee-saved registers (X64 conventions). 3171 // Restore callee-saved registers (X64 conventions).
3152 #ifdef _WIN64 3172 #ifdef _WIN64
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3201 static const int kOffsetToResultValue = 18; 3221 static const int kOffsetToResultValue = 18;
3202 // The last 4 bytes of the instruction sequence 3222 // The last 4 bytes of the instruction sequence
3203 // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset)) 3223 // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset))
3204 // Move(kScratchRegister, Factory::the_hole_value()) 3224 // Move(kScratchRegister, Factory::the_hole_value())
3205 // in front of the hole value address. 3225 // in front of the hole value address.
3206 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78; 3226 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78;
3207 // The last 4 bytes of the instruction sequence 3227 // The last 4 bytes of the instruction sequence
3208 // __ j(not_equal, &cache_miss); 3228 // __ j(not_equal, &cache_miss);
3209 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); 3229 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
3210 // before the offset of the hole value in the root array. 3230 // before the offset of the hole value in the root array.
3211 static const unsigned int kWordBeforeResultValue = 0x458B4909; 3231 static const unsigned int kWordBeforeResultValue = 0x458B4906;
3212 // Only the inline check flag is supported on X64. 3232 // Only the inline check flag is supported on X64.
3213 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck()); 3233 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck());
3214 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0; 3234 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0;
3215 3235
3216 // Get the object - go slow case if it's a smi. 3236 // Get the object - go slow case if it's a smi.
3217 Label slow; 3237 Label slow;
3218 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset, 3238 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset,
3219 ARGUMENTS_DONT_CONTAIN_RECEIVER); 3239 ARGUMENTS_DONT_CONTAIN_RECEIVER);
3220 __ movq(rax, args.GetArgumentOperand(0)); 3240 __ movq(rax, args.GetArgumentOperand(0));
3221 __ JumpIfSmi(rax, &slow); 3241 __ JumpIfSmi(rax, &slow);
(...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after
4538 if (left_ == CompareIC::SMI) { 4558 if (left_ == CompareIC::SMI) {
4539 __ JumpIfNotSmi(rdx, &miss); 4559 __ JumpIfNotSmi(rdx, &miss);
4540 } 4560 }
4541 if (right_ == CompareIC::SMI) { 4561 if (right_ == CompareIC::SMI) {
4542 __ JumpIfNotSmi(rax, &miss); 4562 __ JumpIfNotSmi(rax, &miss);
4543 } 4563 }
4544 4564
4545 // Load left and right operand. 4565 // Load left and right operand.
4546 Label done, left, left_smi, right_smi; 4566 Label done, left, left_smi, right_smi;
4547 __ JumpIfSmi(rax, &right_smi, Label::kNear); 4567 __ JumpIfSmi(rax, &right_smi, Label::kNear);
4548 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map(), NULL); 4568 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map());
4549 __ j(not_equal, &maybe_undefined1, Label::kNear); 4569 __ j(not_equal, &maybe_undefined1, Label::kNear);
4550 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); 4570 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
4551 __ jmp(&left, Label::kNear); 4571 __ jmp(&left, Label::kNear);
4552 __ bind(&right_smi); 4572 __ bind(&right_smi);
4553 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet. 4573 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet.
4554 __ Cvtlsi2sd(xmm1, rcx); 4574 __ Cvtlsi2sd(xmm1, rcx);
4555 4575
4556 __ bind(&left); 4576 __ bind(&left);
4557 __ JumpIfSmi(rdx, &left_smi, Label::kNear); 4577 __ JumpIfSmi(rdx, &left_smi, Label::kNear);
4558 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map(), NULL); 4578 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map());
4559 __ j(not_equal, &maybe_undefined2, Label::kNear); 4579 __ j(not_equal, &maybe_undefined2, Label::kNear);
4560 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); 4580 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
4561 __ jmp(&done); 4581 __ jmp(&done);
4562 __ bind(&left_smi); 4582 __ bind(&left_smi);
4563 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet. 4583 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet.
4564 __ Cvtlsi2sd(xmm0, rcx); 4584 __ Cvtlsi2sd(xmm0, rcx);
4565 4585
4566 __ bind(&done); 4586 __ bind(&done);
4567 // Compare operands 4587 // Compare operands
4568 __ ucomisd(xmm0, xmm1); 4588 __ ucomisd(xmm0, xmm1);
(...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after
5815 __ bind(&fast_elements_case); 5835 __ bind(&fast_elements_case);
5816 GenerateCase(masm, FAST_ELEMENTS); 5836 GenerateCase(masm, FAST_ELEMENTS);
5817 } 5837 }
5818 5838
5819 5839
5820 #undef __ 5840 #undef __
5821 5841
5822 } } // namespace v8::internal 5842 } } // namespace v8::internal
5823 5843
5824 #endif // V8_TARGET_ARCH_X64 5844 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698