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

Side by Side Diff: src/x64/full-codegen-x64.cc

Issue 196893003: Introduce addp, idivp, imulp and subp for x64 port (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 __ movp(rcx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 1113 __ movp(rcx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset));
1114 1114
1115 // Set up the four remaining stack slots. 1115 // Set up the four remaining stack slots.
1116 __ Push(rax); // Map. 1116 __ Push(rax); // Map.
1117 __ Push(rcx); // Enumeration cache. 1117 __ Push(rcx); // Enumeration cache.
1118 __ Push(rdx); // Number of valid entries for the map in the enum cache. 1118 __ Push(rdx); // Number of valid entries for the map in the enum cache.
1119 __ Push(Smi::FromInt(0)); // Initial index. 1119 __ Push(Smi::FromInt(0)); // Initial index.
1120 __ jmp(&loop); 1120 __ jmp(&loop);
1121 1121
1122 __ bind(&no_descriptors); 1122 __ bind(&no_descriptors);
1123 __ addq(rsp, Immediate(kPointerSize)); 1123 __ addp(rsp, Immediate(kPointerSize));
1124 __ jmp(&exit); 1124 __ jmp(&exit);
1125 1125
1126 // We got a fixed array in register rax. Iterate through that. 1126 // We got a fixed array in register rax. Iterate through that.
1127 Label non_proxy; 1127 Label non_proxy;
1128 __ bind(&fixed_array); 1128 __ bind(&fixed_array);
1129 1129
1130 Handle<Object> feedback = Handle<Object>( 1130 Handle<Object> feedback = Handle<Object>(
1131 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker), 1131 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
1132 isolate()); 1132 isolate());
1133 StoreFeedbackVectorSlot(slot, feedback); 1133 StoreFeedbackVectorSlot(slot, feedback);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 // Generate code for going to the next element by incrementing the 1205 // Generate code for going to the next element by incrementing the
1206 // index (smi) stored on top of the stack. 1206 // index (smi) stored on top of the stack.
1207 __ bind(loop_statement.continue_label()); 1207 __ bind(loop_statement.continue_label());
1208 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); 1208 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1));
1209 1209
1210 EmitBackEdgeBookkeeping(stmt, &loop); 1210 EmitBackEdgeBookkeeping(stmt, &loop);
1211 __ jmp(&loop); 1211 __ jmp(&loop);
1212 1212
1213 // Remove the pointers stored on the stack. 1213 // Remove the pointers stored on the stack.
1214 __ bind(loop_statement.break_label()); 1214 __ bind(loop_statement.break_label());
1215 __ addq(rsp, Immediate(5 * kPointerSize)); 1215 __ addp(rsp, Immediate(5 * kPointerSize));
1216 1216
1217 // Exit and decrement the loop depth. 1217 // Exit and decrement the loop depth.
1218 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1218 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1219 __ bind(&exit); 1219 __ bind(&exit);
1220 decrement_loop_depth(); 1220 decrement_loop_depth();
1221 } 1221 }
1222 1222
1223 1223
1224 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 1224 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1225 Comment cmnt(masm_, "[ ForOfStatement"); 1225 Comment cmnt(masm_, "[ ForOfStatement");
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 // Store the subexpression value in the array's elements. 1827 // Store the subexpression value in the array's elements.
1828 __ Move(rcx, Smi::FromInt(i)); 1828 __ Move(rcx, Smi::FromInt(i));
1829 StoreArrayLiteralElementStub stub; 1829 StoreArrayLiteralElementStub stub;
1830 __ CallStub(&stub); 1830 __ CallStub(&stub);
1831 } 1831 }
1832 1832
1833 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1833 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1834 } 1834 }
1835 1835
1836 if (result_saved) { 1836 if (result_saved) {
1837 __ addq(rsp, Immediate(kPointerSize)); // literal index 1837 __ addp(rsp, Immediate(kPointerSize)); // literal index
1838 context()->PlugTOS(); 1838 context()->PlugTOS();
1839 } else { 1839 } else {
1840 context()->Plug(rax); 1840 context()->Plug(rax);
1841 } 1841 }
1842 } 1842 }
1843 1843
1844 1844
1845 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1845 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1846 ASSERT(expr->target()->IsValidLeftHandSide()); 1846 ASSERT(expr->target()->IsValidLeftHandSide());
1847 1847
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 __ Push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset)); 2131 __ Push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset));
2132 2132
2133 // Push holes for arguments to generator function. 2133 // Push holes for arguments to generator function.
2134 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 2134 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
2135 __ movsxlq(rdx, 2135 __ movsxlq(rdx,
2136 FieldOperand(rdx, 2136 FieldOperand(rdx,
2137 SharedFunctionInfo::kFormalParameterCountOffset)); 2137 SharedFunctionInfo::kFormalParameterCountOffset));
2138 __ LoadRoot(rcx, Heap::kTheHoleValueRootIndex); 2138 __ LoadRoot(rcx, Heap::kTheHoleValueRootIndex);
2139 Label push_argument_holes, push_frame; 2139 Label push_argument_holes, push_frame;
2140 __ bind(&push_argument_holes); 2140 __ bind(&push_argument_holes);
2141 __ subq(rdx, Immediate(1)); 2141 __ subp(rdx, Immediate(1));
2142 __ j(carry, &push_frame); 2142 __ j(carry, &push_frame);
2143 __ Push(rcx); 2143 __ Push(rcx);
2144 __ jmp(&push_argument_holes); 2144 __ jmp(&push_argument_holes);
2145 2145
2146 // Enter a new JavaScript frame, and initialize its slots as they were when 2146 // Enter a new JavaScript frame, and initialize its slots as they were when
2147 // the generator was suspended. 2147 // the generator was suspended.
2148 Label resume_frame; 2148 Label resume_frame;
2149 __ bind(&push_frame); 2149 __ bind(&push_frame);
2150 __ call(&resume_frame); 2150 __ call(&resume_frame);
2151 __ jmp(&done); 2151 __ jmp(&done);
(...skipping 10 matching lines...) Expand all
2162 2162
2163 // If we are sending a value and there is no operand stack, we can jump back 2163 // If we are sending a value and there is no operand stack, we can jump back
2164 // in directly. 2164 // in directly.
2165 if (resume_mode == JSGeneratorObject::NEXT) { 2165 if (resume_mode == JSGeneratorObject::NEXT) {
2166 Label slow_resume; 2166 Label slow_resume;
2167 __ cmpq(rdx, Immediate(0)); 2167 __ cmpq(rdx, Immediate(0));
2168 __ j(not_zero, &slow_resume); 2168 __ j(not_zero, &slow_resume);
2169 __ movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2169 __ movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2170 __ SmiToInteger64(rcx, 2170 __ SmiToInteger64(rcx,
2171 FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); 2171 FieldOperand(rbx, JSGeneratorObject::kContinuationOffset));
2172 __ addq(rdx, rcx); 2172 __ addp(rdx, rcx);
2173 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), 2173 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset),
2174 Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); 2174 Smi::FromInt(JSGeneratorObject::kGeneratorExecuting));
2175 __ jmp(rdx); 2175 __ jmp(rdx);
2176 __ bind(&slow_resume); 2176 __ bind(&slow_resume);
2177 } 2177 }
2178 2178
2179 // Otherwise, we push holes for the operand stack and call the runtime to fix 2179 // Otherwise, we push holes for the operand stack and call the runtime to fix
2180 // up the stack and the handlers. 2180 // up the stack and the handlers.
2181 Label push_operand_holes, call_resume; 2181 Label push_operand_holes, call_resume;
2182 __ bind(&push_operand_holes); 2182 __ bind(&push_operand_holes);
2183 __ subq(rdx, Immediate(1)); 2183 __ subp(rdx, Immediate(1));
2184 __ j(carry, &call_resume); 2184 __ j(carry, &call_resume);
2185 __ Push(rcx); 2185 __ Push(rcx);
2186 __ jmp(&push_operand_holes); 2186 __ jmp(&push_operand_holes);
2187 __ bind(&call_resume); 2187 __ bind(&call_resume);
2188 __ Push(rbx); 2188 __ Push(rbx);
2189 __ Push(result_register()); 2189 __ Push(result_register());
2190 __ Push(Smi::FromInt(resume_mode)); 2190 __ Push(Smi::FromInt(resume_mode));
2191 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2191 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2192 // Not reached: the runtime call returns elsewhere. 2192 // Not reached: the runtime call returns elsewhere.
2193 __ Abort(kGeneratorFailedToResume); 2193 __ Abort(kGeneratorFailedToResume);
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
2995 2995
2996 // Skip loop if no descriptors are valid. 2996 // Skip loop if no descriptors are valid.
2997 __ NumberOfOwnDescriptors(rcx, rbx); 2997 __ NumberOfOwnDescriptors(rcx, rbx);
2998 __ cmpq(rcx, Immediate(0)); 2998 __ cmpq(rcx, Immediate(0));
2999 __ j(equal, &done); 2999 __ j(equal, &done);
3000 3000
3001 __ LoadInstanceDescriptors(rbx, r8); 3001 __ LoadInstanceDescriptors(rbx, r8);
3002 // rbx: descriptor array. 3002 // rbx: descriptor array.
3003 // rcx: valid entries in the descriptor array. 3003 // rcx: valid entries in the descriptor array.
3004 // Calculate the end of the descriptor array. 3004 // Calculate the end of the descriptor array.
3005 __ imul(rcx, rcx, Immediate(DescriptorArray::kDescriptorSize)); 3005 __ imulp(rcx, rcx, Immediate(DescriptorArray::kDescriptorSize));
3006 SmiIndex index = masm_->SmiToIndex(rdx, rcx, kPointerSizeLog2); 3006 SmiIndex index = masm_->SmiToIndex(rdx, rcx, kPointerSizeLog2);
3007 __ lea(rcx, 3007 __ lea(rcx,
3008 Operand( 3008 Operand(
3009 r8, index.reg, index.scale, DescriptorArray::kFirstOffset)); 3009 r8, index.reg, index.scale, DescriptorArray::kFirstOffset));
3010 // Calculate location of the first key name. 3010 // Calculate location of the first key name.
3011 __ addq(r8, Immediate(DescriptorArray::kFirstOffset)); 3011 __ addp(r8, Immediate(DescriptorArray::kFirstOffset));
3012 // Loop through all the keys in the descriptor array. If one of these is the 3012 // Loop through all the keys in the descriptor array. If one of these is the
3013 // internalized string "valueOf" the result is false. 3013 // internalized string "valueOf" the result is false.
3014 __ jmp(&entry); 3014 __ jmp(&entry);
3015 __ bind(&loop); 3015 __ bind(&loop);
3016 __ movp(rdx, FieldOperand(r8, 0)); 3016 __ movp(rdx, FieldOperand(r8, 0));
3017 __ Cmp(rdx, isolate()->factory()->value_of_string()); 3017 __ Cmp(rdx, isolate()->factory()->value_of_string());
3018 __ j(equal, if_false); 3018 __ j(equal, if_false);
3019 __ addq(r8, Immediate(DescriptorArray::kDescriptorSize * kPointerSize)); 3019 __ addp(r8, Immediate(DescriptorArray::kDescriptorSize * kPointerSize));
3020 __ bind(&entry); 3020 __ bind(&entry);
3021 __ cmpq(r8, rcx); 3021 __ cmpq(r8, rcx);
3022 __ j(not_equal, &loop); 3022 __ j(not_equal, &loop);
3023 3023
3024 __ bind(&done); 3024 __ bind(&done);
3025 3025
3026 // Set the bit in the map to indicate that there is no local valueOf field. 3026 // Set the bit in the map to indicate that there is no local valueOf field.
3027 __ or_(FieldOperand(rbx, Map::kBitField2Offset), 3027 __ or_(FieldOperand(rbx, Map::kBitField2Offset),
3028 Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf)); 3028 Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
3029 3029
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after
3851 3851
3852 Register array_length = rdi; 3852 Register array_length = rdi;
3853 Register result_pos = no_reg; // Will be rdi. 3853 Register result_pos = no_reg; // Will be rdi.
3854 3854
3855 Operand separator_operand = Operand(rsp, 2 * kPointerSize); 3855 Operand separator_operand = Operand(rsp, 2 * kPointerSize);
3856 Operand result_operand = Operand(rsp, 1 * kPointerSize); 3856 Operand result_operand = Operand(rsp, 1 * kPointerSize);
3857 Operand array_length_operand = Operand(rsp, 0 * kPointerSize); 3857 Operand array_length_operand = Operand(rsp, 0 * kPointerSize);
3858 // Separator operand is already pushed. Make room for the two 3858 // Separator operand is already pushed. Make room for the two
3859 // other stack fields, and clear the direction flag in anticipation 3859 // other stack fields, and clear the direction flag in anticipation
3860 // of calling CopyBytes. 3860 // of calling CopyBytes.
3861 __ subq(rsp, Immediate(2 * kPointerSize)); 3861 __ subp(rsp, Immediate(2 * kPointerSize));
3862 __ cld(); 3862 __ cld();
3863 // Check that the array is a JSArray 3863 // Check that the array is a JSArray
3864 __ JumpIfSmi(array, &bailout); 3864 __ JumpIfSmi(array, &bailout);
3865 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch); 3865 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch);
3866 __ j(not_equal, &bailout); 3866 __ j(not_equal, &bailout);
3867 3867
3868 // Check that the array has fast elements. 3868 // Check that the array has fast elements.
3869 __ CheckFastElements(scratch, &bailout); 3869 __ CheckFastElements(scratch, &bailout);
3870 3870
3871 // Array has fast elements, so its length must be a smi. 3871 // Array has fast elements, so its length must be a smi.
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
4099 FieldOperand(string, SeqOneByteString::kHeaderSize)); 4099 FieldOperand(string, SeqOneByteString::kHeaderSize));
4100 __ CopyBytes(result_pos, string, string_length); 4100 __ CopyBytes(result_pos, string, string_length);
4101 __ incq(index); 4101 __ incq(index);
4102 __ j(not_equal, &loop_3); // Loop while (index < 0). 4102 __ j(not_equal, &loop_3); // Loop while (index < 0).
4103 4103
4104 __ bind(&done); 4104 __ bind(&done);
4105 __ movp(rax, result_operand); 4105 __ movp(rax, result_operand);
4106 4106
4107 __ bind(&return_result); 4107 __ bind(&return_result);
4108 // Drop temp values from the stack, and restore context register. 4108 // Drop temp values from the stack, and restore context register.
4109 __ addq(rsp, Immediate(3 * kPointerSize)); 4109 __ addp(rsp, Immediate(3 * kPointerSize));
4110 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 4110 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
4111 context()->Plug(rax); 4111 context()->Plug(rax);
4112 } 4112 }
4113 4113
4114 4114
4115 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 4115 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
4116 Handle<String> name = expr->name(); 4116 Handle<String> name = expr->name();
4117 if (name->length() > 0 && name->Get(0) == '_') { 4117 if (name->length() > 0 && name->Get(0) == '_') {
4118 Comment cmnt(masm_, "[ InlineRuntimeCall"); 4118 Comment cmnt(masm_, "[ InlineRuntimeCall");
4119 EmitInlineRuntimeCall(expr); 4119 EmitInlineRuntimeCall(expr);
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after
4730 // ---------------------------------------------------------------------------- 4730 // ----------------------------------------------------------------------------
4731 // Non-local control flow support. 4731 // Non-local control flow support.
4732 4732
4733 4733
4734 void FullCodeGenerator::EnterFinallyBlock() { 4734 void FullCodeGenerator::EnterFinallyBlock() {
4735 ASSERT(!result_register().is(rdx)); 4735 ASSERT(!result_register().is(rdx));
4736 ASSERT(!result_register().is(rcx)); 4736 ASSERT(!result_register().is(rcx));
4737 // Cook return address on top of stack (smi encoded Code* delta) 4737 // Cook return address on top of stack (smi encoded Code* delta)
4738 __ PopReturnAddressTo(rdx); 4738 __ PopReturnAddressTo(rdx);
4739 __ Move(rcx, masm_->CodeObject()); 4739 __ Move(rcx, masm_->CodeObject());
4740 __ subq(rdx, rcx); 4740 __ subp(rdx, rcx);
4741 __ Integer32ToSmi(rdx, rdx); 4741 __ Integer32ToSmi(rdx, rdx);
4742 __ Push(rdx); 4742 __ Push(rdx);
4743 4743
4744 // Store result register while executing finally block. 4744 // Store result register while executing finally block.
4745 __ Push(result_register()); 4745 __ Push(result_register());
4746 4746
4747 // Store pending message while executing finally block. 4747 // Store pending message while executing finally block.
4748 ExternalReference pending_message_obj = 4748 ExternalReference pending_message_obj =
4749 ExternalReference::address_of_pending_message_obj(isolate()); 4749 ExternalReference::address_of_pending_message_obj(isolate());
4750 __ Load(rdx, pending_message_obj); 4750 __ Load(rdx, pending_message_obj);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4783 ExternalReference::address_of_pending_message_obj(isolate()); 4783 ExternalReference::address_of_pending_message_obj(isolate());
4784 __ Store(pending_message_obj, rdx); 4784 __ Store(pending_message_obj, rdx);
4785 4785
4786 // Restore result register from stack. 4786 // Restore result register from stack.
4787 __ Pop(result_register()); 4787 __ Pop(result_register());
4788 4788
4789 // Uncook return address. 4789 // Uncook return address.
4790 __ Pop(rdx); 4790 __ Pop(rdx);
4791 __ SmiToInteger32(rdx, rdx); 4791 __ SmiToInteger32(rdx, rdx);
4792 __ Move(rcx, masm_->CodeObject()); 4792 __ Move(rcx, masm_->CodeObject());
4793 __ addq(rdx, rcx); 4793 __ addp(rdx, rcx);
4794 __ jmp(rdx); 4794 __ jmp(rdx);
4795 } 4795 }
4796 4796
4797 4797
4798 #undef __ 4798 #undef __
4799 4799
4800 #define __ ACCESS_MASM(masm()) 4800 #define __ ACCESS_MASM(masm())
4801 4801
4802 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( 4802 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
4803 int* stack_depth, 4803 int* stack_depth,
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
4900 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4900 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4901 Assembler::target_address_at(call_target_address, 4901 Assembler::target_address_at(call_target_address,
4902 unoptimized_code)); 4902 unoptimized_code));
4903 return OSR_AFTER_STACK_CHECK; 4903 return OSR_AFTER_STACK_CHECK;
4904 } 4904 }
4905 4905
4906 4906
4907 } } // namespace v8::internal 4907 } } // namespace v8::internal
4908 4908
4909 #endif // V8_TARGET_ARCH_X64 4909 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/x64/assembler-x64.h ('K') | « src/x64/deoptimizer-x64.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698