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

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

Issue 132373011: A64: Synchronize with r17635. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months 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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 Isolate* isolate, 295 Isolate* isolate,
296 CodeStubInterfaceDescriptor* descriptor) { 296 CodeStubInterfaceDescriptor* descriptor) {
297 static Register registers[] = { rax, rbx, rcx, rdx }; 297 static Register registers[] = { rax, rbx, rcx, rdx };
298 descriptor->register_param_count_ = 4; 298 descriptor->register_param_count_ = 4;
299 descriptor->register_params_ = registers; 299 descriptor->register_params_ = registers;
300 descriptor->deoptimization_handler_ = 300 descriptor->deoptimization_handler_ =
301 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss); 301 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
302 } 302 }
303 303
304 304
305 void NewStringAddStub::InitializeInterfaceDescriptor(
306 Isolate* isolate,
307 CodeStubInterfaceDescriptor* descriptor) {
308 static Register registers[] = { rdx, rax };
309 descriptor->register_param_count_ = 2;
310 descriptor->register_params_ = registers;
311 descriptor->deoptimization_handler_ =
312 Runtime::FunctionForId(Runtime::kStringAdd)->entry;
313 }
314
315
305 #define __ ACCESS_MASM(masm) 316 #define __ ACCESS_MASM(masm)
306 317
307 318
308 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { 319 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
309 // Update the static counter each time a new code stub is generated. 320 // Update the static counter each time a new code stub is generated.
310 Isolate* isolate = masm->isolate(); 321 Isolate* isolate = masm->isolate();
311 isolate->counters()->code_stubs()->Increment(); 322 isolate->counters()->code_stubs()->Increment();
312 323
313 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); 324 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate);
314 int param_count = descriptor->register_param_count_; 325 int param_count = descriptor->register_param_count_;
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 __ xorl(rax, rdi); 635 __ xorl(rax, rdi);
625 __ xorl(rcx, rax); 636 __ xorl(rcx, rax);
626 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); 637 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize));
627 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1)); 638 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1));
628 639
629 // ST[0] == double value. 640 // ST[0] == double value.
630 // rbx = bits of double value. 641 // rbx = bits of double value.
631 // rcx = TranscendentalCache::hash(double value). 642 // rcx = TranscendentalCache::hash(double value).
632 ExternalReference cache_array = 643 ExternalReference cache_array =
633 ExternalReference::transcendental_cache_array_address(masm->isolate()); 644 ExternalReference::transcendental_cache_array_address(masm->isolate());
634 __ movq(rax, cache_array); 645 __ Move(rax, cache_array);
635 int cache_array_index = 646 int cache_array_index =
636 type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]); 647 type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]);
637 __ movq(rax, Operand(rax, cache_array_index)); 648 __ movq(rax, Operand(rax, cache_array_index));
638 // rax points to the cache for the type type_. 649 // rax points to the cache for the type type_.
639 // If NULL, the cache hasn't been initialized yet, so go through runtime. 650 // If NULL, the cache hasn't been initialized yet, so go through runtime.
640 __ testq(rax, rax); 651 __ testq(rax, rax);
641 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED. 652 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED.
642 #ifdef DEBUG 653 #ifdef DEBUG
643 // Check that the layout of cache elements match expectations. 654 // Check that the layout of cache elements match expectations.
644 { // NOLINT - doesn't like a single brace on a line. 655 { // 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)); 963 __ cmpl(exponent, Immediate(0x80000000u));
953 __ j(equal, &call_runtime); 964 __ j(equal, &call_runtime);
954 965
955 if (exponent_type_ == ON_STACK) { 966 if (exponent_type_ == ON_STACK) {
956 // Detect square root case. Crankshaft detects constant +/-0.5 at 967 // Detect square root case. Crankshaft detects constant +/-0.5 at
957 // compile time and uses DoMathPowHalf instead. We then skip this check 968 // compile time and uses DoMathPowHalf instead. We then skip this check
958 // for non-constant cases of +/-0.5 as these hardly occur. 969 // for non-constant cases of +/-0.5 as these hardly occur.
959 Label continue_sqrt, continue_rsqrt, not_plus_half; 970 Label continue_sqrt, continue_rsqrt, not_plus_half;
960 // Test for 0.5. 971 // Test for 0.5.
961 // Load double_scratch with 0.5. 972 // Load double_scratch with 0.5.
962 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000), RelocInfo::NONE64); 973 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000));
963 __ movq(double_scratch, scratch); 974 __ movq(double_scratch, scratch);
964 // Already ruled out NaNs for exponent. 975 // Already ruled out NaNs for exponent.
965 __ ucomisd(double_scratch, double_exponent); 976 __ ucomisd(double_scratch, double_exponent);
966 __ j(not_equal, &not_plus_half, Label::kNear); 977 __ j(not_equal, &not_plus_half, Label::kNear);
967 978
968 // Calculates square root of base. Check for the special case of 979 // Calculates square root of base. Check for the special case of
969 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13). 980 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
970 // According to IEEE-754, double-precision -Infinity has the highest 981 // According to IEEE-754, double-precision -Infinity has the highest
971 // 12 bits set and the lowest 52 bits cleared. 982 // 12 bits set and the lowest 52 bits cleared.
972 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000), RelocInfo::NONE64); 983 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000));
973 __ movq(double_scratch, scratch); 984 __ movq(double_scratch, scratch);
974 __ ucomisd(double_scratch, double_base); 985 __ ucomisd(double_scratch, double_base);
975 // Comparing -Infinity with NaN results in "unordered", which sets the 986 // 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. 987 // zero flag as if both were equal. However, it also sets the carry flag.
977 __ j(not_equal, &continue_sqrt, Label::kNear); 988 __ j(not_equal, &continue_sqrt, Label::kNear);
978 __ j(carry, &continue_sqrt, Label::kNear); 989 __ j(carry, &continue_sqrt, Label::kNear);
979 990
980 // Set result to Infinity in the special case. 991 // Set result to Infinity in the special case.
981 __ xorps(double_result, double_result); 992 __ xorps(double_result, double_result);
982 __ subsd(double_result, double_scratch); 993 __ subsd(double_result, double_scratch);
(...skipping 11 matching lines...) Expand all
994 // Load double_scratch with -0.5 by substracting 1. 1005 // Load double_scratch with -0.5 by substracting 1.
995 __ subsd(double_scratch, double_result); 1006 __ subsd(double_scratch, double_result);
996 // Already ruled out NaNs for exponent. 1007 // Already ruled out NaNs for exponent.
997 __ ucomisd(double_scratch, double_exponent); 1008 __ ucomisd(double_scratch, double_exponent);
998 __ j(not_equal, &fast_power, Label::kNear); 1009 __ j(not_equal, &fast_power, Label::kNear);
999 1010
1000 // Calculates reciprocal of square root of base. Check for the special 1011 // 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). 1012 // 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 1013 // According to IEEE-754, double-precision -Infinity has the highest
1003 // 12 bits set and the lowest 52 bits cleared. 1014 // 12 bits set and the lowest 52 bits cleared.
1004 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000), RelocInfo::NONE64); 1015 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000));
1005 __ movq(double_scratch, scratch); 1016 __ movq(double_scratch, scratch);
1006 __ ucomisd(double_scratch, double_base); 1017 __ ucomisd(double_scratch, double_base);
1007 // Comparing -Infinity with NaN results in "unordered", which sets the 1018 // 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. 1019 // zero flag as if both were equal. However, it also sets the carry flag.
1009 __ j(not_equal, &continue_rsqrt, Label::kNear); 1020 __ j(not_equal, &continue_rsqrt, Label::kNear);
1010 __ j(carry, &continue_rsqrt, Label::kNear); 1021 __ j(carry, &continue_rsqrt, Label::kNear);
1011 1022
1012 // Set result to 0 in the special case. 1023 // Set result to 0 in the special case.
1013 __ xorps(double_result, double_result); 1024 __ xorps(double_result, double_result);
1014 __ jmp(&done); 1025 __ jmp(&done);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 __ movsd(xmm0, double_base); 1140 __ movsd(xmm0, double_base);
1130 ASSERT(double_exponent.is(xmm1)); 1141 ASSERT(double_exponent.is(xmm1));
1131 { 1142 {
1132 AllowExternalCallThatCantCauseGC scope(masm); 1143 AllowExternalCallThatCantCauseGC scope(masm);
1133 __ PrepareCallCFunction(2); 1144 __ PrepareCallCFunction(2);
1134 __ CallCFunction( 1145 __ CallCFunction(
1135 ExternalReference::power_double_double_function(masm->isolate()), 2); 1146 ExternalReference::power_double_double_function(masm->isolate()), 2);
1136 } 1147 }
1137 // Return value is in xmm0. 1148 // Return value is in xmm0.
1138 __ movsd(double_result, xmm0); 1149 __ movsd(double_result, xmm0);
1139 // Restore context register.
1140 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1141 1150
1142 __ bind(&done); 1151 __ bind(&done);
1143 __ IncrementCounter(counters->math_pow(), 1); 1152 __ IncrementCounter(counters->math_pow(), 1);
1144 __ ret(0); 1153 __ ret(0);
1145 } 1154 }
1146 } 1155 }
1147 1156
1148 1157
1149 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { 1158 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
1150 Label miss; 1159 Label miss;
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
1866 __ LoadAddress(kScratchRegister, 1875 __ LoadAddress(kScratchRegister,
1867 ExternalReference::isolate_address(masm->isolate())); 1876 ExternalReference::isolate_address(masm->isolate()));
1868 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), 1877 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
1869 kScratchRegister); 1878 kScratchRegister);
1870 1879
1871 // Argument 8: Indicate that this is a direct call from JavaScript. 1880 // Argument 8: Indicate that this is a direct call from JavaScript.
1872 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize), 1881 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize),
1873 Immediate(1)); 1882 Immediate(1));
1874 1883
1875 // Argument 7: Start (high end) of backtracking stack memory area. 1884 // Argument 7: Start (high end) of backtracking stack memory area.
1876 __ movq(kScratchRegister, address_of_regexp_stack_memory_address); 1885 __ Move(kScratchRegister, address_of_regexp_stack_memory_address);
1877 __ movq(r9, Operand(kScratchRegister, 0)); 1886 __ movq(r9, Operand(kScratchRegister, 0));
1878 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); 1887 __ Move(kScratchRegister, address_of_regexp_stack_memory_size);
1879 __ addq(r9, Operand(kScratchRegister, 0)); 1888 __ addq(r9, Operand(kScratchRegister, 0));
1880 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9); 1889 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9);
1881 1890
1882 // Argument 6: Set the number of capture registers to zero to force global 1891 // 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. 1892 // 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. 1893 // Argument 6 is passed in r9 on Linux and on the stack on Windows.
1885 #ifdef _WIN64 1894 #ifdef _WIN64
1886 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), 1895 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize),
1887 Immediate(0)); 1896 Immediate(0));
1888 #else 1897 #else
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
2215 2224
2216 static void CheckInputType(MacroAssembler* masm, 2225 static void CheckInputType(MacroAssembler* masm,
2217 Register input, 2226 Register input,
2218 CompareIC::State expected, 2227 CompareIC::State expected,
2219 Label* fail) { 2228 Label* fail) {
2220 Label ok; 2229 Label ok;
2221 if (expected == CompareIC::SMI) { 2230 if (expected == CompareIC::SMI) {
2222 __ JumpIfNotSmi(input, fail); 2231 __ JumpIfNotSmi(input, fail);
2223 } else if (expected == CompareIC::NUMBER) { 2232 } else if (expected == CompareIC::NUMBER) {
2224 __ JumpIfSmi(input, &ok); 2233 __ JumpIfSmi(input, &ok);
2225 __ CompareMap(input, masm->isolate()->factory()->heap_number_map(), NULL); 2234 __ CompareMap(input, masm->isolate()->factory()->heap_number_map());
2226 __ j(not_equal, fail); 2235 __ j(not_equal, fail);
2227 } 2236 }
2228 // We could be strict about internalized/non-internalized here, but as long as 2237 // 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. 2238 // hydrogen doesn't care, the stub doesn't have to care either.
2230 __ bind(&ok); 2239 __ bind(&ok);
2231 } 2240 }
2232 2241
2233 2242
2234 static void BranchIfNotInternalizedString(MacroAssembler* masm, 2243 static void BranchIfNotInternalizedString(MacroAssembler* masm,
2235 Label* label, 2244 Label* label,
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
2803 // Check stack alignment. 2812 // Check stack alignment.
2804 if (FLAG_debug_code) { 2813 if (FLAG_debug_code) {
2805 __ CheckStackAlignment(); 2814 __ CheckStackAlignment();
2806 } 2815 }
2807 2816
2808 if (do_gc) { 2817 if (do_gc) {
2809 // Pass failure code returned from last attempt as first argument to 2818 // Pass failure code returned from last attempt as first argument to
2810 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the 2819 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
2811 // stack is known to be aligned. This function takes one argument which is 2820 // stack is known to be aligned. This function takes one argument which is
2812 // passed in register. 2821 // passed in register.
2813 __ movq(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); 2822 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate()));
2814 __ movq(arg_reg_1, rax); 2823 __ movq(arg_reg_1, rax);
2815 __ movq(kScratchRegister, 2824 __ Move(kScratchRegister,
2816 ExternalReference::perform_gc_function(masm->isolate())); 2825 ExternalReference::perform_gc_function(masm->isolate()));
2817 __ call(kScratchRegister); 2826 __ call(kScratchRegister);
2818 } 2827 }
2819 2828
2820 ExternalReference scope_depth = 2829 ExternalReference scope_depth =
2821 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); 2830 ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
2822 if (always_allocate_scope) { 2831 if (always_allocate_scope) {
2823 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); 2832 Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
2824 __ incl(scope_depth_operand); 2833 __ incl(scope_depth_operand);
2825 } 2834 }
2826 2835
2827 // Call C function. 2836 // Call C function.
2828 #ifdef _WIN64 2837 #ifdef _WIN64
2829 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. 2838 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9.
2830 // Pass argv and argc as two parameters. The arguments object will 2839 // Pass argv and argc as two parameters. The arguments object will
2831 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). 2840 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION().
2832 if (result_size_ < 2) { 2841 if (result_size_ < 2) {
2833 // Pass a pointer to the Arguments object as the first argument. 2842 // Pass a pointer to the Arguments object as the first argument.
2834 // Return result in single register (rax). 2843 // Return result in single register (rax).
2835 __ movq(rcx, r14); // argc. 2844 __ movq(rcx, r14); // argc.
2836 __ movq(rdx, r15); // argv. 2845 __ movq(rdx, r15); // argv.
2837 __ movq(r8, ExternalReference::isolate_address(masm->isolate())); 2846 __ Move(r8, ExternalReference::isolate_address(masm->isolate()));
2838 } else { 2847 } else {
2839 ASSERT_EQ(2, result_size_); 2848 ASSERT_EQ(2, result_size_);
2840 // Pass a pointer to the result location as the first argument. 2849 // Pass a pointer to the result location as the first argument.
2841 __ lea(rcx, StackSpaceOperand(2)); 2850 __ lea(rcx, StackSpaceOperand(2));
2842 // Pass a pointer to the Arguments object as the second argument. 2851 // Pass a pointer to the Arguments object as the second argument.
2843 __ movq(rdx, r14); // argc. 2852 __ movq(rdx, r14); // argc.
2844 __ movq(r8, r15); // argv. 2853 __ movq(r8, r15); // argv.
2845 __ movq(r9, ExternalReference::isolate_address(masm->isolate())); 2854 __ Move(r9, ExternalReference::isolate_address(masm->isolate()));
2846 } 2855 }
2847 2856
2848 #else // _WIN64 2857 #else // _WIN64
2849 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. 2858 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
2850 __ movq(rdi, r14); // argc. 2859 __ movq(rdi, r14); // argc.
2851 __ movq(rsi, r15); // argv. 2860 __ movq(rsi, r15); // argv.
2852 __ movq(rdx, ExternalReference::isolate_address(masm->isolate())); 2861 __ Move(rdx, ExternalReference::isolate_address(masm->isolate()));
2853 #endif 2862 #endif
2854 __ call(rbx); 2863 __ call(rbx);
2855 // Result is in rax - do not destroy this register! 2864 // Result is in rax - do not destroy this register!
2856 2865
2857 if (always_allocate_scope) { 2866 if (always_allocate_scope) {
2858 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); 2867 Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
2859 __ decl(scope_depth_operand); 2868 __ decl(scope_depth_operand);
2860 } 2869 }
2861 2870
2862 // Check for failure result. 2871 // Check for failure result.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
3023 MacroAssembler::NoRootArrayScope uninitialized_root_register(masm); 3032 MacroAssembler::NoRootArrayScope uninitialized_root_register(masm);
3024 // Set up frame. 3033 // Set up frame.
3025 __ push(rbp); 3034 __ push(rbp);
3026 __ movq(rbp, rsp); 3035 __ movq(rbp, rsp);
3027 3036
3028 // Push the stack frame type marker twice. 3037 // Push the stack frame type marker twice.
3029 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; 3038 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
3030 // Scratch register is neither callee-save, nor an argument register on any 3039 // Scratch register is neither callee-save, nor an argument register on any
3031 // platform. It's free to use at this point. 3040 // platform. It's free to use at this point.
3032 // Cannot use smi-register for loading yet. 3041 // Cannot use smi-register for loading yet.
3033 __ movq(kScratchRegister, 3042 __ movq(kScratchRegister, Smi::FromInt(marker), RelocInfo::NONE64);
3034 reinterpret_cast<uint64_t>(Smi::FromInt(marker)),
3035 RelocInfo::NONE64);
3036 __ push(kScratchRegister); // context slot 3043 __ push(kScratchRegister); // context slot
3037 __ push(kScratchRegister); // function slot 3044 __ push(kScratchRegister); // function slot
3038 // Save callee-saved registers (X64/Win64 calling conventions). 3045 // Save callee-saved registers (X64/Win64 calling conventions).
3039 __ push(r12); 3046 __ push(r12);
3040 __ push(r13); 3047 __ push(r13);
3041 __ push(r14); 3048 __ push(r14);
3042 __ push(r15); 3049 __ push(r15);
3043 #ifdef _WIN64 3050 #ifdef _WIN64
3044 __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI. 3051 __ 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. 3052 __ 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); 3139 __ call(kScratchRegister);
3133 3140
3134 // Unlink this frame from the handler chain. 3141 // Unlink this frame from the handler chain.
3135 __ PopTryHandler(); 3142 __ PopTryHandler();
3136 3143
3137 __ bind(&exit); 3144 __ bind(&exit);
3138 // Check if the current stack frame is marked as the outermost JS frame. 3145 // Check if the current stack frame is marked as the outermost JS frame.
3139 __ pop(rbx); 3146 __ pop(rbx);
3140 __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)); 3147 __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME));
3141 __ j(not_equal, &not_outermost_js_2); 3148 __ j(not_equal, &not_outermost_js_2);
3142 __ movq(kScratchRegister, js_entry_sp); 3149 __ Move(kScratchRegister, js_entry_sp);
3143 __ movq(Operand(kScratchRegister, 0), Immediate(0)); 3150 __ movq(Operand(kScratchRegister, 0), Immediate(0));
3144 __ bind(&not_outermost_js_2); 3151 __ bind(&not_outermost_js_2);
3145 3152
3146 // Restore the top frame descriptor from the stack. 3153 // Restore the top frame descriptor from the stack.
3147 { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp); 3154 { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
3148 __ pop(c_entry_fp_operand); 3155 __ pop(c_entry_fp_operand);
3149 } 3156 }
3150 3157
3151 // Restore callee-saved registers (X64 conventions). 3158 // Restore callee-saved registers (X64 conventions).
3152 #ifdef _WIN64 3159 #ifdef _WIN64
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3201 static const int kOffsetToResultValue = 18; 3208 static const int kOffsetToResultValue = 18;
3202 // The last 4 bytes of the instruction sequence 3209 // The last 4 bytes of the instruction sequence
3203 // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset)) 3210 // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset))
3204 // Move(kScratchRegister, Factory::the_hole_value()) 3211 // Move(kScratchRegister, Factory::the_hole_value())
3205 // in front of the hole value address. 3212 // in front of the hole value address.
3206 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78; 3213 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78;
3207 // The last 4 bytes of the instruction sequence 3214 // The last 4 bytes of the instruction sequence
3208 // __ j(not_equal, &cache_miss); 3215 // __ j(not_equal, &cache_miss);
3209 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); 3216 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
3210 // before the offset of the hole value in the root array. 3217 // before the offset of the hole value in the root array.
3211 static const unsigned int kWordBeforeResultValue = 0x458B4909; 3218 static const unsigned int kWordBeforeResultValue = 0x458B4906;
3212 // Only the inline check flag is supported on X64. 3219 // Only the inline check flag is supported on X64.
3213 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck()); 3220 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck());
3214 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0; 3221 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0;
3215 3222
3216 // Get the object - go slow case if it's a smi. 3223 // Get the object - go slow case if it's a smi.
3217 Label slow; 3224 Label slow;
3218 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset, 3225 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset,
3219 ARGUMENTS_DONT_CONTAIN_RECEIVER); 3226 ARGUMENTS_DONT_CONTAIN_RECEIVER);
3220 __ movq(rax, args.GetArgumentOperand(0)); 3227 __ movq(rax, args.GetArgumentOperand(0));
3221 __ JumpIfSmi(rax, &slow); 3228 __ JumpIfSmi(rax, &slow);
(...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after
4538 if (left_ == CompareIC::SMI) { 4545 if (left_ == CompareIC::SMI) {
4539 __ JumpIfNotSmi(rdx, &miss); 4546 __ JumpIfNotSmi(rdx, &miss);
4540 } 4547 }
4541 if (right_ == CompareIC::SMI) { 4548 if (right_ == CompareIC::SMI) {
4542 __ JumpIfNotSmi(rax, &miss); 4549 __ JumpIfNotSmi(rax, &miss);
4543 } 4550 }
4544 4551
4545 // Load left and right operand. 4552 // Load left and right operand.
4546 Label done, left, left_smi, right_smi; 4553 Label done, left, left_smi, right_smi;
4547 __ JumpIfSmi(rax, &right_smi, Label::kNear); 4554 __ JumpIfSmi(rax, &right_smi, Label::kNear);
4548 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map(), NULL); 4555 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map());
4549 __ j(not_equal, &maybe_undefined1, Label::kNear); 4556 __ j(not_equal, &maybe_undefined1, Label::kNear);
4550 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); 4557 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
4551 __ jmp(&left, Label::kNear); 4558 __ jmp(&left, Label::kNear);
4552 __ bind(&right_smi); 4559 __ bind(&right_smi);
4553 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet. 4560 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet.
4554 __ Cvtlsi2sd(xmm1, rcx); 4561 __ Cvtlsi2sd(xmm1, rcx);
4555 4562
4556 __ bind(&left); 4563 __ bind(&left);
4557 __ JumpIfSmi(rdx, &left_smi, Label::kNear); 4564 __ JumpIfSmi(rdx, &left_smi, Label::kNear);
4558 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map(), NULL); 4565 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map());
4559 __ j(not_equal, &maybe_undefined2, Label::kNear); 4566 __ j(not_equal, &maybe_undefined2, Label::kNear);
4560 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); 4567 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
4561 __ jmp(&done); 4568 __ jmp(&done);
4562 __ bind(&left_smi); 4569 __ bind(&left_smi);
4563 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet. 4570 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet.
4564 __ Cvtlsi2sd(xmm0, rcx); 4571 __ Cvtlsi2sd(xmm0, rcx);
4565 4572
4566 __ bind(&done); 4573 __ bind(&done);
4567 // Compare operands 4574 // Compare operands
4568 __ ucomisd(xmm0, xmm1); 4575 __ ucomisd(xmm0, xmm1);
(...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after
5815 __ bind(&fast_elements_case); 5822 __ bind(&fast_elements_case);
5816 GenerateCase(masm, FAST_ELEMENTS); 5823 GenerateCase(masm, FAST_ELEMENTS);
5817 } 5824 }
5818 5825
5819 5826
5820 #undef __ 5827 #undef __
5821 5828
5822 } } // namespace v8::internal 5829 } } // namespace v8::internal
5823 5830
5824 #endif // V8_TARGET_ARCH_X64 5831 #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