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

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

Issue 39973003: Merge bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: again Created 7 years, 2 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/lithium-codegen-x64.h ('k') | src/x64/lithium-gap-resolver-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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 136 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
137 __ movq(args.GetReceiverOperand(), kScratchRegister); 137 __ movq(args.GetReceiverOperand(), kScratchRegister);
138 __ bind(&ok); 138 __ bind(&ok);
139 } 139 }
140 } 140 }
141 141
142 info()->set_prologue_offset(masm_->pc_offset()); 142 info()->set_prologue_offset(masm_->pc_offset());
143 if (NeedsEagerFrame()) { 143 if (NeedsEagerFrame()) {
144 ASSERT(!frame_is_built_); 144 ASSERT(!frame_is_built_);
145 frame_is_built_ = true; 145 frame_is_built_ = true;
146 __ push(rbp); // Caller's frame pointer. 146 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
147 __ movq(rbp, rsp);
148 __ push(rsi); // Callee's context.
149 if (info()->IsStub()) {
150 __ Push(Smi::FromInt(StackFrame::STUB));
151 } else {
152 __ push(rdi); // Callee's JS function.
153 }
154 info()->AddNoFrameRange(0, masm_->pc_offset()); 147 info()->AddNoFrameRange(0, masm_->pc_offset());
155 } 148 }
156 149
157 // Reserve space for the stack slots needed by the code. 150 // Reserve space for the stack slots needed by the code.
158 int slots = GetStackSlotCount(); 151 int slots = GetStackSlotCount();
159 if (slots > 0) { 152 if (slots > 0) {
160 if (FLAG_debug_code) { 153 if (FLAG_debug_code) {
161 __ subq(rsp, Immediate(slots * kPointerSize)); 154 __ subq(rsp, Immediate(slots * kPointerSize));
162 #ifdef _MSC_VER 155 #ifdef _MSC_VER
163 MakeSureStackPagesMapped(slots * kPointerSize); 156 MakeSureStackPagesMapped(slots * kPointerSize);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 return !is_aborted(); 285 return !is_aborted();
293 } 286 }
294 287
295 288
296 bool LCodeGen::GenerateDeferredCode() { 289 bool LCodeGen::GenerateDeferredCode() {
297 ASSERT(is_generating()); 290 ASSERT(is_generating());
298 if (deferred_.length() > 0) { 291 if (deferred_.length() > 0) {
299 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 292 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
300 LDeferredCode* code = deferred_[i]; 293 LDeferredCode* code = deferred_[i];
301 294
302 int pos = instructions_->at(code->instruction_index())->position(); 295 HValue* value =
303 RecordAndUpdatePosition(pos); 296 instructions_->at(code->instruction_index())->hydrogen_value();
297 RecordAndWritePosition(value->position());
304 298
305 Comment(";;; <@%d,#%d> " 299 Comment(";;; <@%d,#%d> "
306 "-------------------- Deferred %s --------------------", 300 "-------------------- Deferred %s --------------------",
307 code->instruction_index(), 301 code->instruction_index(),
308 code->instr()->hydrogen_value()->id(), 302 code->instr()->hydrogen_value()->id(),
309 code->instr()->Mnemonic()); 303 code->instr()->Mnemonic());
310 __ bind(code->entry()); 304 __ bind(code->entry());
311 if (NeedsDeferredFrame()) { 305 if (NeedsDeferredFrame()) {
312 Comment(";;; Build frame"); 306 Comment(";;; Build frame");
313 ASSERT(!frame_is_built_); 307 ASSERT(!frame_is_built_);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 } 550 }
557 551
558 552
559 void LCodeGen::CallCodeGeneric(Handle<Code> code, 553 void LCodeGen::CallCodeGeneric(Handle<Code> code,
560 RelocInfo::Mode mode, 554 RelocInfo::Mode mode,
561 LInstruction* instr, 555 LInstruction* instr,
562 SafepointMode safepoint_mode, 556 SafepointMode safepoint_mode,
563 int argc) { 557 int argc) {
564 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size() - masm()->CallSize(code)); 558 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size() - masm()->CallSize(code));
565 ASSERT(instr != NULL); 559 ASSERT(instr != NULL);
566 LPointerMap* pointers = instr->pointer_map();
567 RecordPosition(pointers->position());
568 __ call(code, mode); 560 __ call(code, mode);
569 RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc); 561 RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc);
570 562
571 // Signal that we don't inline smi code before these stubs in the 563 // Signal that we don't inline smi code before these stubs in the
572 // optimizing code generator. 564 // optimizing code generator.
573 if (code->kind() == Code::BINARY_OP_IC || 565 if (code->kind() == Code::BINARY_OP_IC ||
574 code->kind() == Code::COMPARE_IC) { 566 code->kind() == Code::COMPARE_IC) {
575 __ nop(); 567 __ nop();
576 } 568 }
577 } 569 }
578 570
579 571
580 void LCodeGen::CallCode(Handle<Code> code, 572 void LCodeGen::CallCode(Handle<Code> code,
581 RelocInfo::Mode mode, 573 RelocInfo::Mode mode,
582 LInstruction* instr) { 574 LInstruction* instr) {
583 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0); 575 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0);
584 } 576 }
585 577
586 578
587 void LCodeGen::CallRuntime(const Runtime::Function* function, 579 void LCodeGen::CallRuntime(const Runtime::Function* function,
588 int num_arguments, 580 int num_arguments,
589 LInstruction* instr, 581 LInstruction* instr,
590 SaveFPRegsMode save_doubles) { 582 SaveFPRegsMode save_doubles) {
591 ASSERT(instr != NULL); 583 ASSERT(instr != NULL);
592 ASSERT(instr->HasPointerMap()); 584 ASSERT(instr->HasPointerMap());
593 LPointerMap* pointers = instr->pointer_map();
594 RecordPosition(pointers->position());
595 585
596 __ CallRuntime(function, num_arguments, save_doubles); 586 __ CallRuntime(function, num_arguments, save_doubles);
597 587
598 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); 588 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
599 } 589 }
600 590
601 591
602 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 592 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
603 int argc, 593 int argc,
604 LInstruction* instr) { 594 LInstruction* instr) {
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 } 823 }
834 824
835 825
836 void LCodeGen::RecordSafepoint(LPointerMap* pointers, 826 void LCodeGen::RecordSafepoint(LPointerMap* pointers,
837 Safepoint::DeoptMode deopt_mode) { 827 Safepoint::DeoptMode deopt_mode) {
838 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); 828 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode);
839 } 829 }
840 830
841 831
842 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { 832 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) {
843 LPointerMap empty_pointers(RelocInfo::kNoPosition, zone()); 833 LPointerMap empty_pointers(zone());
844 RecordSafepoint(&empty_pointers, deopt_mode); 834 RecordSafepoint(&empty_pointers, deopt_mode);
845 } 835 }
846 836
847 837
848 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 838 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
849 int arguments, 839 int arguments,
850 Safepoint::DeoptMode deopt_mode) { 840 Safepoint::DeoptMode deopt_mode) {
851 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, deopt_mode); 841 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, deopt_mode);
852 } 842 }
853 843
854 844
855 void LCodeGen::RecordPosition(int position) { 845 void LCodeGen::RecordAndWritePosition(int position) {
856 if (position == RelocInfo::kNoPosition) return; 846 if (position == RelocInfo::kNoPosition) return;
857 masm()->positions_recorder()->RecordPosition(position); 847 masm()->positions_recorder()->RecordPosition(position);
848 masm()->positions_recorder()->WriteRecordedPositions();
858 } 849 }
859 850
860 851
861 void LCodeGen::RecordAndUpdatePosition(int position) {
862 if (position >= 0 && position != old_position_) {
863 masm()->positions_recorder()->RecordPosition(position);
864 old_position_ = position;
865 }
866 }
867
868
869 static const char* LabelType(LLabel* label) { 852 static const char* LabelType(LLabel* label) {
870 if (label->is_loop_header()) return " (loop header)"; 853 if (label->is_loop_header()) return " (loop header)";
871 if (label->is_osr_entry()) return " (OSR entry)"; 854 if (label->is_osr_entry()) return " (OSR entry)";
872 return ""; 855 return "";
873 } 856 }
874 857
875 858
876 void LCodeGen::DoLabel(LLabel* label) { 859 void LCodeGen::DoLabel(LLabel* label) {
877 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", 860 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------",
878 current_instruction_, 861 current_instruction_,
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 } 1542 }
1560 1543
1561 1544
1562 void LCodeGen::DoConstantE(LConstantE* instr) { 1545 void LCodeGen::DoConstantE(LConstantE* instr) {
1563 __ LoadAddress(ToRegister(instr->result()), instr->value()); 1546 __ LoadAddress(ToRegister(instr->result()), instr->value());
1564 } 1547 }
1565 1548
1566 1549
1567 void LCodeGen::DoConstantT(LConstantT* instr) { 1550 void LCodeGen::DoConstantT(LConstantT* instr) {
1568 Handle<Object> value = instr->value(isolate()); 1551 Handle<Object> value = instr->value(isolate());
1569 AllowDeferredHandleDereference smi_check; 1552 __ Move(ToRegister(instr->result()), value);
1570 __ LoadObject(ToRegister(instr->result()), value);
1571 } 1553 }
1572 1554
1573 1555
1574 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1556 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1575 Register result = ToRegister(instr->result()); 1557 Register result = ToRegister(instr->result());
1576 Register map = ToRegister(instr->value()); 1558 Register map = ToRegister(instr->value());
1577 __ EnumLength(result, map); 1559 __ EnumLength(result, map);
1578 } 1560 }
1579 1561
1580 1562
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
2041 } 2023 }
2042 2024
2043 2025
2044 inline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 2026 inline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
2045 Condition cond = no_condition; 2027 Condition cond = no_condition;
2046 switch (op) { 2028 switch (op) {
2047 case Token::EQ: 2029 case Token::EQ:
2048 case Token::EQ_STRICT: 2030 case Token::EQ_STRICT:
2049 cond = equal; 2031 cond = equal;
2050 break; 2032 break;
2033 case Token::NE:
2034 case Token::NE_STRICT:
2035 cond = not_equal;
2036 break;
2051 case Token::LT: 2037 case Token::LT:
2052 cond = is_unsigned ? below : less; 2038 cond = is_unsigned ? below : less;
2053 break; 2039 break;
2054 case Token::GT: 2040 case Token::GT:
2055 cond = is_unsigned ? above : greater; 2041 cond = is_unsigned ? above : greater;
2056 break; 2042 break;
2057 case Token::LTE: 2043 case Token::LTE:
2058 cond = is_unsigned ? below_equal : less_equal; 2044 cond = is_unsigned ? below_equal : less_equal;
2059 break; 2045 break;
2060 case Token::GTE: 2046 case Token::GTE:
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2128 EmitBranch(instr, cc); 2114 EmitBranch(instr, cc);
2129 } 2115 }
2130 } 2116 }
2131 2117
2132 2118
2133 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2119 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2134 Register left = ToRegister(instr->left()); 2120 Register left = ToRegister(instr->left());
2135 2121
2136 if (instr->right()->IsConstantOperand()) { 2122 if (instr->right()->IsConstantOperand()) {
2137 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); 2123 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2138 __ CmpObject(left, right); 2124 __ Cmp(left, right);
2139 } else { 2125 } else {
2140 Register right = ToRegister(instr->right()); 2126 Register right = ToRegister(instr->right());
2141 __ cmpq(left, right); 2127 __ cmpq(left, right);
2142 } 2128 }
2143 EmitBranch(instr, equal); 2129 EmitBranch(instr, equal);
2144 } 2130 }
2145 2131
2146 2132
2147 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) { 2133 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2148 if (instr->hydrogen()->representation().IsTagged()) { 2134 if (instr->hydrogen()->representation().IsTagged()) {
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
2496 2482
2497 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 2483 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
2498 Label* map_check) { 2484 Label* map_check) {
2499 { 2485 {
2500 PushSafepointRegistersScope scope(this); 2486 PushSafepointRegistersScope scope(this);
2501 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( 2487 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
2502 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); 2488 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck);
2503 InstanceofStub stub(flags); 2489 InstanceofStub stub(flags);
2504 2490
2505 __ push(ToRegister(instr->value())); 2491 __ push(ToRegister(instr->value()));
2506 __ PushHeapObject(instr->function()); 2492 __ Push(instr->function());
2507 2493
2508 static const int kAdditionalDelta = 10; 2494 static const int kAdditionalDelta = 10;
2509 int delta = 2495 int delta =
2510 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 2496 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
2511 ASSERT(delta >= 0); 2497 ASSERT(delta >= 0);
2512 __ push_imm32(delta); 2498 __ push_imm32(delta);
2513 2499
2514 // We are pushing three values on the stack but recording a 2500 // We are pushing three values on the stack but recording a
2515 // safepoint with two arguments because stub is going to 2501 // safepoint with two arguments because stub is going to
2516 // remove the third argument from the stack before jumping 2502 // remove the third argument from the stack before jumping
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
3165 StackArgumentsAccessor args(elements, length, 3151 StackArgumentsAccessor args(elements, length,
3166 ARGUMENTS_DONT_CONTAIN_RECEIVER); 3152 ARGUMENTS_DONT_CONTAIN_RECEIVER);
3167 __ push(args.GetArgumentOperand(0)); 3153 __ push(args.GetArgumentOperand(0));
3168 __ decl(length); 3154 __ decl(length);
3169 __ j(not_zero, &loop); 3155 __ j(not_zero, &loop);
3170 3156
3171 // Invoke the function. 3157 // Invoke the function.
3172 __ bind(&invoke); 3158 __ bind(&invoke);
3173 ASSERT(instr->HasPointerMap()); 3159 ASSERT(instr->HasPointerMap());
3174 LPointerMap* pointers = instr->pointer_map(); 3160 LPointerMap* pointers = instr->pointer_map();
3175 RecordPosition(pointers->position());
3176 SafepointGenerator safepoint_generator( 3161 SafepointGenerator safepoint_generator(
3177 this, pointers, Safepoint::kLazyDeopt); 3162 this, pointers, Safepoint::kLazyDeopt);
3178 ParameterCount actual(rax); 3163 ParameterCount actual(rax);
3179 __ InvokeFunction(function, actual, CALL_FUNCTION, 3164 __ InvokeFunction(function, actual, CALL_FUNCTION,
3180 safepoint_generator, CALL_AS_METHOD); 3165 safepoint_generator, CALL_AS_METHOD);
3181 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3166 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3182 } 3167 }
3183 3168
3184 3169
3185 void LCodeGen::DoPushArgument(LPushArgument* instr) { 3170 void LCodeGen::DoPushArgument(LPushArgument* instr) {
(...skipping 22 matching lines...) Expand all
3208 void LCodeGen::DoOuterContext(LOuterContext* instr) { 3193 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3209 Register context = ToRegister(instr->context()); 3194 Register context = ToRegister(instr->context());
3210 Register result = ToRegister(instr->result()); 3195 Register result = ToRegister(instr->result());
3211 __ movq(result, 3196 __ movq(result,
3212 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); 3197 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3213 } 3198 }
3214 3199
3215 3200
3216 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3201 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3217 __ push(rsi); // The context is the first argument. 3202 __ push(rsi); // The context is the first argument.
3218 __ PushHeapObject(instr->hydrogen()->pairs()); 3203 __ Push(instr->hydrogen()->pairs());
3219 __ Push(Smi::FromInt(instr->hydrogen()->flags())); 3204 __ Push(Smi::FromInt(instr->hydrogen()->flags()));
3220 CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3205 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3221 } 3206 }
3222 3207
3223 3208
3224 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 3209 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3225 Register result = ToRegister(instr->result()); 3210 Register result = ToRegister(instr->result());
3226 __ movq(result, GlobalObjectOperand()); 3211 __ movq(result, GlobalObjectOperand());
3227 } 3212 }
3228 3213
(...skipping 10 matching lines...) Expand all
3239 int arity, 3224 int arity,
3240 LInstruction* instr, 3225 LInstruction* instr,
3241 CallKind call_kind, 3226 CallKind call_kind,
3242 RDIState rdi_state) { 3227 RDIState rdi_state) {
3243 bool dont_adapt_arguments = 3228 bool dont_adapt_arguments =
3244 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 3229 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3245 bool can_invoke_directly = 3230 bool can_invoke_directly =
3246 dont_adapt_arguments || formal_parameter_count == arity; 3231 dont_adapt_arguments || formal_parameter_count == arity;
3247 3232
3248 LPointerMap* pointers = instr->pointer_map(); 3233 LPointerMap* pointers = instr->pointer_map();
3249 RecordPosition(pointers->position());
3250 3234
3251 if (can_invoke_directly) { 3235 if (can_invoke_directly) {
3252 if (rdi_state == RDI_UNINITIALIZED) { 3236 if (rdi_state == RDI_UNINITIALIZED) {
3253 __ LoadHeapObject(rdi, function); 3237 __ Move(rdi, function);
3254 } 3238 }
3255 3239
3256 // Change context. 3240 // Change context.
3257 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 3241 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
3258 3242
3259 // Set rax to arguments count if adaption is not needed. Assumes that rax 3243 // Set rax to arguments count if adaption is not needed. Assumes that rax
3260 // is available to write to at this point. 3244 // is available to write to at this point.
3261 if (dont_adapt_arguments) { 3245 if (dont_adapt_arguments) {
3262 __ Set(rax, arity); 3246 __ Set(rax, arity);
3263 } 3247 }
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
3662 XMMRegister result = ToDoubleRegister(instr->result()); 3646 XMMRegister result = ToDoubleRegister(instr->result());
3663 XMMRegister temp0 = double_scratch0(); 3647 XMMRegister temp0 = double_scratch0();
3664 Register temp1 = ToRegister(instr->temp1()); 3648 Register temp1 = ToRegister(instr->temp1());
3665 Register temp2 = ToRegister(instr->temp2()); 3649 Register temp2 = ToRegister(instr->temp2());
3666 3650
3667 MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2); 3651 MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2);
3668 } 3652 }
3669 3653
3670 3654
3671 void LCodeGen::DoMathLog(LMathLog* instr) { 3655 void LCodeGen::DoMathLog(LMathLog* instr) {
3672 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3656 ASSERT(instr->value()->Equals(instr->result()));
3673 TranscendentalCacheStub stub(TranscendentalCache::LOG, 3657 XMMRegister input_reg = ToDoubleRegister(instr->value());
3674 TranscendentalCacheStub::UNTAGGED); 3658 XMMRegister xmm_scratch = double_scratch0();
3675 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3659 Label positive, done, zero;
3660 __ xorps(xmm_scratch, xmm_scratch);
3661 __ ucomisd(input_reg, xmm_scratch);
3662 __ j(above, &positive, Label::kNear);
3663 __ j(equal, &zero, Label::kNear);
3664 ExternalReference nan =
3665 ExternalReference::address_of_canonical_non_hole_nan();
3666 Operand nan_operand = masm()->ExternalOperand(nan);
3667 __ movsd(input_reg, nan_operand);
3668 __ jmp(&done, Label::kNear);
3669 __ bind(&zero);
3670 ExternalReference ninf =
3671 ExternalReference::address_of_negative_infinity();
3672 Operand ninf_operand = masm()->ExternalOperand(ninf);
3673 __ movsd(input_reg, ninf_operand);
3674 __ jmp(&done, Label::kNear);
3675 __ bind(&positive);
3676 __ fldln2();
3677 __ subq(rsp, Immediate(kDoubleSize));
3678 __ movsd(Operand(rsp, 0), input_reg);
3679 __ fld_d(Operand(rsp, 0));
3680 __ fyl2x();
3681 __ fstp_d(Operand(rsp, 0));
3682 __ movsd(input_reg, Operand(rsp, 0));
3683 __ addq(rsp, Immediate(kDoubleSize));
3684 __ bind(&done);
3676 } 3685 }
3677 3686
3678 3687
3679 void LCodeGen::DoMathTan(LMathTan* instr) { 3688 void LCodeGen::DoMathTan(LMathTan* instr) {
3680 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3689 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3681 TranscendentalCacheStub stub(TranscendentalCache::TAN, 3690 TranscendentalCacheStub stub(TranscendentalCache::TAN,
3682 TranscendentalCacheStub::UNTAGGED); 3691 TranscendentalCacheStub::UNTAGGED);
3683 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3692 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3684 } 3693 }
3685 3694
(...skipping 14 matching lines...) Expand all
3700 } 3709 }
3701 3710
3702 3711
3703 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3712 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3704 ASSERT(ToRegister(instr->function()).is(rdi)); 3713 ASSERT(ToRegister(instr->function()).is(rdi));
3705 ASSERT(instr->HasPointerMap()); 3714 ASSERT(instr->HasPointerMap());
3706 3715
3707 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 3716 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3708 if (known_function.is_null()) { 3717 if (known_function.is_null()) {
3709 LPointerMap* pointers = instr->pointer_map(); 3718 LPointerMap* pointers = instr->pointer_map();
3710 RecordPosition(pointers->position());
3711 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3719 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3712 ParameterCount count(instr->arity()); 3720 ParameterCount count(instr->arity());
3713 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 3721 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
3714 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3722 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3715 } else { 3723 } else {
3716 CallKnownFunction(known_function, 3724 CallKnownFunction(known_function,
3717 instr->hydrogen()->formal_parameter_count(), 3725 instr->hydrogen()->formal_parameter_count(),
3718 instr->arity(), 3726 instr->arity(),
3719 instr, 3727 instr,
3720 CALL_AS_METHOD, 3728 CALL_AS_METHOD,
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
4250 RecordSafepointWithRegisters( 4258 RecordSafepointWithRegisters(
4251 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4259 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4252 } 4260 }
4253 __ bind(&not_applicable); 4261 __ bind(&not_applicable);
4254 } 4262 }
4255 4263
4256 4264
4257 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4265 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4258 Register object = ToRegister(instr->object()); 4266 Register object = ToRegister(instr->object());
4259 Register temp = ToRegister(instr->temp()); 4267 Register temp = ToRegister(instr->temp());
4260 __ TestJSArrayForAllocationMemento(object, temp); 4268 Label no_memento_found;
4269 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
4261 DeoptimizeIf(equal, instr->environment()); 4270 DeoptimizeIf(equal, instr->environment());
4271 __ bind(&no_memento_found);
4262 } 4272 }
4263 4273
4264 4274
4265 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4275 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4266 EmitPushTaggedOperand(instr->left()); 4276 EmitPushTaggedOperand(instr->left());
4267 EmitPushTaggedOperand(instr->right()); 4277 EmitPushTaggedOperand(instr->right());
4268 StringAddStub stub(instr->hydrogen()->flags()); 4278 StringAddStub stub(instr->hydrogen()->flags());
4269 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4279 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4270 } 4280 }
4271 4281
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
4605 4615
4606 // Smi to XMM conversion 4616 // Smi to XMM conversion
4607 __ bind(&load_smi); 4617 __ bind(&load_smi);
4608 __ SmiToInteger32(kScratchRegister, input_reg); 4618 __ SmiToInteger32(kScratchRegister, input_reg);
4609 __ Cvtlsi2sd(result_reg, kScratchRegister); 4619 __ Cvtlsi2sd(result_reg, kScratchRegister);
4610 __ bind(&done); 4620 __ bind(&done);
4611 } 4621 }
4612 4622
4613 4623
4614 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) { 4624 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
4615 Label heap_number;
4616 Register input_reg = ToRegister(instr->value()); 4625 Register input_reg = ToRegister(instr->value());
4617 4626
4627 if (instr->truncating()) {
4628 Label no_heap_number, check_bools, check_false;
4618 4629
4619 if (instr->truncating()) {
4620 // Heap number map check. 4630 // Heap number map check.
4621 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 4631 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
4622 Heap::kHeapNumberMapRootIndex); 4632 Heap::kHeapNumberMapRootIndex);
4623 __ j(equal, &heap_number, Label::kNear); 4633 __ j(not_equal, &no_heap_number, Label::kNear);
4624 // Check for undefined. Undefined is converted to zero for truncating 4634 __ TruncateHeapNumberToI(input_reg, input_reg);
4625 // conversions. 4635 __ jmp(done);
4636
4637 __ bind(&no_heap_number);
4638 // Check for Oddballs. Undefined/False is converted to zero and True to one
4639 // for truncating conversions.
4626 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); 4640 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
4641 __ j(not_equal, &check_bools, Label::kNear);
4642 __ Set(input_reg, 0);
4643 __ jmp(done);
4644
4645 __ bind(&check_bools);
4646 __ CompareRoot(input_reg, Heap::kTrueValueRootIndex);
4647 __ j(not_equal, &check_false, Label::kNear);
4648 __ Set(input_reg, 1);
4649 __ jmp(done);
4650
4651 __ bind(&check_false);
4652 __ CompareRoot(input_reg, Heap::kFalseValueRootIndex);
4653 __ RecordComment("Deferred TaggedToI: cannot truncate");
4627 DeoptimizeIf(not_equal, instr->environment()); 4654 DeoptimizeIf(not_equal, instr->environment());
4628 __ Set(input_reg, 0); 4655 __ Set(input_reg, 0);
4629 __ jmp(done); 4656 __ jmp(done);
4630
4631 __ bind(&heap_number);
4632 __ TruncateHeapNumberToI(input_reg, input_reg);
4633 } else { 4657 } else {
4634 Label bailout; 4658 Label bailout;
4635 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 4659 XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
4636 __ TaggedToI(input_reg, input_reg, xmm_temp, 4660 __ TaggedToI(input_reg, input_reg, xmm_temp,
4637 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); 4661 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
4638 4662
4639 __ jmp(done); 4663 __ jmp(done);
4640 __ bind(&bailout); 4664 __ bind(&bailout);
4641 DeoptimizeIf(no_condition, instr->environment()); 4665 DeoptimizeIf(no_condition, instr->environment());
4642 } 4666 }
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
4799 __ andb(kScratchRegister, Immediate(mask)); 4823 __ andb(kScratchRegister, Immediate(mask));
4800 __ cmpb(kScratchRegister, Immediate(tag)); 4824 __ cmpb(kScratchRegister, Immediate(tag));
4801 DeoptimizeIf(not_equal, instr->environment()); 4825 DeoptimizeIf(not_equal, instr->environment());
4802 } 4826 }
4803 } 4827 }
4804 } 4828 }
4805 4829
4806 4830
4807 void LCodeGen::DoCheckValue(LCheckValue* instr) { 4831 void LCodeGen::DoCheckValue(LCheckValue* instr) {
4808 Register reg = ToRegister(instr->value()); 4832 Register reg = ToRegister(instr->value());
4809 Handle<HeapObject> object = instr->hydrogen()->object().handle(); 4833 __ Cmp(reg, instr->hydrogen()->object().handle());
4810 __ CmpHeapObject(reg, object);
4811 DeoptimizeIf(not_equal, instr->environment()); 4834 DeoptimizeIf(not_equal, instr->environment());
4812 } 4835 }
4813 4836
4814 4837
4815 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 4838 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
4816 { 4839 {
4817 PushSafepointRegistersScope scope(this); 4840 PushSafepointRegistersScope scope(this);
4818 __ push(object); 4841 __ push(object);
4819 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr); 4842 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr);
4820 __ testq(rax, Immediate(kSmiTagMask)); 4843 __ testq(rax, Immediate(kSmiTagMask));
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
5027 5050
5028 5051
5029 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5052 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
5030 Label materialized; 5053 Label materialized;
5031 // Registers will be used as follows: 5054 // Registers will be used as follows:
5032 // rcx = literals array. 5055 // rcx = literals array.
5033 // rbx = regexp literal. 5056 // rbx = regexp literal.
5034 // rax = regexp literal clone. 5057 // rax = regexp literal clone.
5035 int literal_offset = 5058 int literal_offset =
5036 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); 5059 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
5037 __ LoadHeapObject(rcx, instr->hydrogen()->literals()); 5060 __ Move(rcx, instr->hydrogen()->literals());
5038 __ movq(rbx, FieldOperand(rcx, literal_offset)); 5061 __ movq(rbx, FieldOperand(rcx, literal_offset));
5039 __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); 5062 __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
5040 __ j(not_equal, &materialized, Label::kNear); 5063 __ j(not_equal, &materialized, Label::kNear);
5041 5064
5042 // Create regexp literal using runtime function 5065 // Create regexp literal using runtime function
5043 // Result will be in rax. 5066 // Result will be in rax.
5044 __ push(rcx); 5067 __ push(rcx);
5045 __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); 5068 __ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
5046 __ Push(instr->hydrogen()->pattern()); 5069 __ Push(instr->hydrogen()->pattern());
5047 __ Push(instr->hydrogen()->flags()); 5070 __ Push(instr->hydrogen()->flags());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5098 void LCodeGen::DoTypeof(LTypeof* instr) { 5121 void LCodeGen::DoTypeof(LTypeof* instr) {
5099 LOperand* input = instr->value(); 5122 LOperand* input = instr->value();
5100 EmitPushTaggedOperand(input); 5123 EmitPushTaggedOperand(input);
5101 CallRuntime(Runtime::kTypeof, 1, instr); 5124 CallRuntime(Runtime::kTypeof, 1, instr);
5102 } 5125 }
5103 5126
5104 5127
5105 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 5128 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
5106 ASSERT(!operand->IsDoubleRegister()); 5129 ASSERT(!operand->IsDoubleRegister());
5107 if (operand->IsConstantOperand()) { 5130 if (operand->IsConstantOperand()) {
5108 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); 5131 __ Push(ToHandle(LConstantOperand::cast(operand)));
5109 AllowDeferredHandleDereference smi_check;
5110 if (object->IsSmi()) {
5111 __ Push(Handle<Smi>::cast(object));
5112 } else {
5113 __ PushHeapObject(Handle<HeapObject>::cast(object));
5114 }
5115 } else if (operand->IsRegister()) { 5132 } else if (operand->IsRegister()) {
5116 __ push(ToRegister(operand)); 5133 __ push(ToRegister(operand));
5117 } else { 5134 } else {
5118 __ push(ToOperand(operand)); 5135 __ push(ToOperand(operand));
5119 } 5136 }
5120 } 5137 }
5121 5138
5122 5139
5123 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5140 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
5124 Register input = ToRegister(instr->value()); 5141 Register input = ToRegister(instr->value());
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
5218 5235
5219 void LCodeGen::EmitIsConstructCall(Register temp) { 5236 void LCodeGen::EmitIsConstructCall(Register temp) {
5220 // Get the frame pointer for the calling frame. 5237 // Get the frame pointer for the calling frame.
5221 __ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 5238 __ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
5222 5239
5223 // Skip the arguments adaptor frame if it exists. 5240 // Skip the arguments adaptor frame if it exists.
5224 Label check_frame_marker; 5241 Label check_frame_marker;
5225 __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset), 5242 __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset),
5226 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 5243 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
5227 __ j(not_equal, &check_frame_marker, Label::kNear); 5244 __ j(not_equal, &check_frame_marker, Label::kNear);
5228 __ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset)); 5245 __ movq(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
5229 5246
5230 // Check the marker in the calling frame. 5247 // Check the marker in the calling frame.
5231 __ bind(&check_frame_marker); 5248 __ bind(&check_frame_marker);
5232 __ Cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), 5249 __ Cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
5233 Smi::FromInt(StackFrame::CONSTRUCT)); 5250 Smi::FromInt(StackFrame::CONSTRUCT));
5234 } 5251 }
5235 5252
5236 5253
5237 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { 5254 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
5238 if (info()->IsStub()) return; 5255 if (info()->IsStub()) return;
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
5438 FixedArray::kHeaderSize - kPointerSize)); 5455 FixedArray::kHeaderSize - kPointerSize));
5439 __ bind(&done); 5456 __ bind(&done);
5440 } 5457 }
5441 5458
5442 5459
5443 #undef __ 5460 #undef __
5444 5461
5445 } } // namespace v8::internal 5462 } } // namespace v8::internal
5446 5463
5447 #endif // V8_TARGET_ARCH_X64 5464 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-gap-resolver-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698