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

Side by Side Diff: src/ppc/lithium-ppc.cc

Issue 571173003: PowerPC specific sub-directories (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Updated ppc sub-dirs to current V8 code levels Created 6 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 //
3 // Copyright IBM Corp. 2012, 2013. All rights reserved.
4 //
2 // Use of this source code is governed by a BSD-style license that can be 5 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 6 // found in the LICENSE file.
4 7
5 #include "src/v8.h" 8 #include "src/v8.h"
6 9
7 #include "src/arm/lithium-codegen-arm.h"
8 #include "src/hydrogen-osr.h" 10 #include "src/hydrogen-osr.h"
9 #include "src/lithium-inl.h" 11 #include "src/lithium-inl.h"
12 #include "src/ppc/lithium-codegen-ppc.h"
10 13
11 namespace v8 { 14 namespace v8 {
12 namespace internal { 15 namespace internal {
13 16
14 #define DEFINE_COMPILE(type) \ 17 #define DEFINE_COMPILE(type) \
15 void L##type::CompileToNative(LCodeGen* generator) { \ 18 void L##type::CompileToNative(LCodeGen* generator) { \
16 generator->Do##type(this); \ 19 generator->Do##type(this); \
17 } 20 }
18 LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) 21 LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE)
19 #undef DEFINE_COMPILE 22 #undef DEFINE_COMPILE
20 23
21 #ifdef DEBUG 24 #ifdef DEBUG
22 void LInstruction::VerifyCall() { 25 void LInstruction::VerifyCall() {
23 // Call instructions can use only fixed registers as temporaries and 26 // Call instructions can use only fixed registers as temporaries and
24 // outputs because all registers are blocked by the calling convention. 27 // outputs because all registers are blocked by the calling convention.
25 // Inputs operands must use a fixed register or use-at-start policy or 28 // Inputs operands must use a fixed register or use-at-start policy or
26 // a non-register policy. 29 // a non-register policy.
27 DCHECK(Output() == NULL || 30 DCHECK(Output() == NULL || LUnallocated::cast(Output())->HasFixedPolicy() ||
28 LUnallocated::cast(Output())->HasFixedPolicy() ||
29 !LUnallocated::cast(Output())->HasRegisterPolicy()); 31 !LUnallocated::cast(Output())->HasRegisterPolicy());
30 for (UseIterator it(this); !it.Done(); it.Advance()) { 32 for (UseIterator it(this); !it.Done(); it.Advance()) {
31 LUnallocated* operand = LUnallocated::cast(it.Current()); 33 LUnallocated* operand = LUnallocated::cast(it.Current());
32 DCHECK(operand->HasFixedPolicy() || 34 DCHECK(operand->HasFixedPolicy() || operand->IsUsedAtStart());
33 operand->IsUsedAtStart());
34 } 35 }
35 for (TempIterator it(this); !it.Done(); it.Advance()) { 36 for (TempIterator it(this); !it.Done(); it.Advance()) {
36 LUnallocated* operand = LUnallocated::cast(it.Current()); 37 LUnallocated* operand = LUnallocated::cast(it.Current());
37 DCHECK(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); 38 DCHECK(operand->HasFixedPolicy() || !operand->HasRegisterPolicy());
38 } 39 }
39 } 40 }
40 #endif 41 #endif
41 42
42 43
43 void LInstruction::PrintTo(StringStream* stream) { 44 void LInstruction::PrintTo(StringStream* stream) {
44 stream->Add("%s ", this->Mnemonic()); 45 stream->Add("%s ", this->Mnemonic());
45 46
46 PrintOutputOperandTo(stream); 47 PrintOutputOperandTo(stream);
47 48
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 if (parallel_moves_[i] != NULL) { 104 if (parallel_moves_[i] != NULL) {
104 parallel_moves_[i]->PrintDataTo(stream); 105 parallel_moves_[i]->PrintDataTo(stream);
105 } 106 }
106 stream->Add(") "); 107 stream->Add(") ");
107 } 108 }
108 } 109 }
109 110
110 111
111 const char* LArithmeticD::Mnemonic() const { 112 const char* LArithmeticD::Mnemonic() const {
112 switch (op()) { 113 switch (op()) {
113 case Token::ADD: return "add-d"; 114 case Token::ADD:
114 case Token::SUB: return "sub-d"; 115 return "add-d";
115 case Token::MUL: return "mul-d"; 116 case Token::SUB:
116 case Token::DIV: return "div-d"; 117 return "sub-d";
117 case Token::MOD: return "mod-d"; 118 case Token::MUL:
119 return "mul-d";
120 case Token::DIV:
121 return "div-d";
122 case Token::MOD:
123 return "mod-d";
118 default: 124 default:
119 UNREACHABLE(); 125 UNREACHABLE();
120 return NULL; 126 return NULL;
121 } 127 }
122 } 128 }
123 129
124 130
125 const char* LArithmeticT::Mnemonic() const { 131 const char* LArithmeticT::Mnemonic() const {
126 switch (op()) { 132 switch (op()) {
127 case Token::ADD: return "add-t"; 133 case Token::ADD:
128 case Token::SUB: return "sub-t"; 134 return "add-t";
129 case Token::MUL: return "mul-t"; 135 case Token::SUB:
130 case Token::MOD: return "mod-t"; 136 return "sub-t";
131 case Token::DIV: return "div-t"; 137 case Token::MUL:
132 case Token::BIT_AND: return "bit-and-t"; 138 return "mul-t";
133 case Token::BIT_OR: return "bit-or-t"; 139 case Token::MOD:
134 case Token::BIT_XOR: return "bit-xor-t"; 140 return "mod-t";
135 case Token::ROR: return "ror-t"; 141 case Token::DIV:
136 case Token::SHL: return "shl-t"; 142 return "div-t";
137 case Token::SAR: return "sar-t"; 143 case Token::BIT_AND:
138 case Token::SHR: return "shr-t"; 144 return "bit-and-t";
145 case Token::BIT_OR:
146 return "bit-or-t";
147 case Token::BIT_XOR:
148 return "bit-xor-t";
149 case Token::ROR:
150 return "ror-t";
151 case Token::SHL:
152 return "shl-t";
153 case Token::SAR:
154 return "sar-t";
155 case Token::SHR:
156 return "shr-t";
139 default: 157 default:
140 UNREACHABLE(); 158 UNREACHABLE();
141 return NULL; 159 return NULL;
142 } 160 }
143 } 161 }
144 162
145 163
146 bool LGoto::HasInterestingComment(LCodeGen* gen) const { 164 bool LGoto::HasInterestingComment(LCodeGen* gen) const {
147 return !gen->IsNextEmittedBlock(block_id()); 165 return !gen->IsNextEmittedBlock(block_id());
148 } 166 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { 232 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
215 stream->Add("if has_cached_array_index("); 233 stream->Add("if has_cached_array_index(");
216 value()->PrintTo(stream); 234 value()->PrintTo(stream);
217 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 235 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
218 } 236 }
219 237
220 238
221 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { 239 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
222 stream->Add("if class_of_test("); 240 stream->Add("if class_of_test(");
223 value()->PrintTo(stream); 241 value()->PrintTo(stream);
224 stream->Add(", \"%o\") then B%d else B%d", 242 stream->Add(", \"%o\") then B%d else B%d", *hydrogen()->class_name(),
225 *hydrogen()->class_name(), 243 true_block_id(), false_block_id());
226 true_block_id(),
227 false_block_id());
228 } 244 }
229 245
230 246
231 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { 247 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
232 stream->Add("if typeof "); 248 stream->Add("if typeof ");
233 value()->PrintTo(stream); 249 value()->PrintTo(stream);
234 stream->Add(" == \"%s\" then B%d else B%d", 250 stream->Add(" == \"%s\" then B%d else B%d",
235 hydrogen()->type_literal()->ToCString().get(), 251 hydrogen()->type_literal()->ToCString().get(), true_block_id(),
236 true_block_id(), false_block_id()); 252 false_block_id());
237 } 253 }
238 254
239 255
240 void LStoreCodeEntry::PrintDataTo(StringStream* stream) { 256 void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
241 stream->Add(" = "); 257 stream->Add(" = ");
242 function()->PrintTo(stream); 258 function()->PrintTo(stream);
243 stream->Add(".code_entry = "); 259 stream->Add(".code_entry = ");
244 code_object()->PrintTo(stream); 260 code_object()->PrintTo(stream);
245 } 261 }
246 262
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 395 }
380 396
381 397
382 int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) { 398 int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) {
383 // Skip a slot if for a double-width slot. 399 // Skip a slot if for a double-width slot.
384 if (kind == DOUBLE_REGISTERS) spill_slot_count_++; 400 if (kind == DOUBLE_REGISTERS) spill_slot_count_++;
385 return spill_slot_count_++; 401 return spill_slot_count_++;
386 } 402 }
387 403
388 404
389 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { 405 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) {
390 int index = GetNextSpillIndex(kind); 406 int index = GetNextSpillIndex(kind);
391 if (kind == DOUBLE_REGISTERS) { 407 if (kind == DOUBLE_REGISTERS) {
392 return LDoubleStackSlot::Create(index, zone()); 408 return LDoubleStackSlot::Create(index, zone());
393 } else { 409 } else {
394 DCHECK(kind == GENERAL_REGISTERS); 410 DCHECK(kind == GENERAL_REGISTERS);
395 return LStackSlot::Create(index, zone()); 411 return LStackSlot::Create(index, zone());
396 } 412 }
397 } 413 }
398 414
399 415
400 LPlatformChunk* LChunkBuilder::Build() { 416 LPlatformChunk* LChunkBuilder::Build() {
401 DCHECK(is_unused()); 417 DCHECK(is_unused());
402 chunk_ = new(zone()) LPlatformChunk(info(), graph()); 418 chunk_ = new (zone()) LPlatformChunk(info(), graph());
403 LPhase phase("L_Building chunk", chunk_); 419 LPhase phase("L_Building chunk", chunk_);
404 status_ = BUILDING; 420 status_ = BUILDING;
405 421
406 // If compiling for OSR, reserve space for the unoptimized frame, 422 // If compiling for OSR, reserve space for the unoptimized frame,
407 // which will be subsumed into this frame. 423 // which will be subsumed into this frame.
408 if (graph()->has_osr()) { 424 if (graph()->has_osr()) {
409 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { 425 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) {
410 chunk_->GetNextSpillIndex(GENERAL_REGISTERS); 426 chunk_->GetNextSpillIndex(GENERAL_REGISTERS);
411 } 427 }
412 } 428 }
(...skipping 10 matching lines...) Expand all
423 } 439 }
424 440
425 441
426 void LChunkBuilder::Abort(BailoutReason reason) { 442 void LChunkBuilder::Abort(BailoutReason reason) {
427 info()->set_bailout_reason(reason); 443 info()->set_bailout_reason(reason);
428 status_ = ABORTED; 444 status_ = ABORTED;
429 } 445 }
430 446
431 447
432 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) { 448 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
433 return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER, 449 return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
434 Register::ToAllocationIndex(reg)); 450 Register::ToAllocationIndex(reg));
435 } 451 }
436 452
437 453
438 LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) { 454 LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) {
439 return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, 455 return new (zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
440 DoubleRegister::ToAllocationIndex(reg)); 456 DoubleRegister::ToAllocationIndex(reg));
441 } 457 }
442 458
443 459
444 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) { 460 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
445 return Use(value, ToUnallocated(fixed_register)); 461 return Use(value, ToUnallocated(fixed_register));
446 } 462 }
447 463
448 464
449 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, DoubleRegister reg) { 465 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, DoubleRegister reg) {
450 return Use(value, ToUnallocated(reg)); 466 return Use(value, ToUnallocated(reg));
451 } 467 }
452 468
453 469
454 LOperand* LChunkBuilder::UseRegister(HValue* value) { 470 LOperand* LChunkBuilder::UseRegister(HValue* value) {
455 return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); 471 return Use(value,
472 new (zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
456 } 473 }
457 474
458 475
459 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) { 476 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) {
460 return Use(value, 477 return Use(value, new (zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER,
461 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER, 478 LUnallocated::USED_AT_START));
462 LUnallocated::USED_AT_START));
463 } 479 }
464 480
465 481
466 LOperand* LChunkBuilder::UseTempRegister(HValue* value) { 482 LOperand* LChunkBuilder::UseTempRegister(HValue* value) {
467 return Use(value, new(zone()) LUnallocated(LUnallocated::WRITABLE_REGISTER)); 483 return Use(value, new (zone()) LUnallocated(LUnallocated::WRITABLE_REGISTER));
468 } 484 }
469 485
470 486
471 LOperand* LChunkBuilder::Use(HValue* value) { 487 LOperand* LChunkBuilder::Use(HValue* value) {
472 return Use(value, new(zone()) LUnallocated(LUnallocated::NONE)); 488 return Use(value, new (zone()) LUnallocated(LUnallocated::NONE));
473 } 489 }
474 490
475 491
476 LOperand* LChunkBuilder::UseAtStart(HValue* value) { 492 LOperand* LChunkBuilder::UseAtStart(HValue* value) {
477 return Use(value, new(zone()) LUnallocated(LUnallocated::NONE, 493 return Use(value, new (zone())
478 LUnallocated::USED_AT_START)); 494 LUnallocated(LUnallocated::NONE, LUnallocated::USED_AT_START));
479 } 495 }
480 496
481 497
482 LOperand* LChunkBuilder::UseOrConstant(HValue* value) { 498 LOperand* LChunkBuilder::UseOrConstant(HValue* value) {
483 return value->IsConstant() 499 return value->IsConstant()
484 ? chunk_->DefineConstantOperand(HConstant::cast(value)) 500 ? chunk_->DefineConstantOperand(HConstant::cast(value))
485 : Use(value); 501 : Use(value);
486 } 502 }
487 503
488 504
489 LOperand* LChunkBuilder::UseOrConstantAtStart(HValue* value) { 505 LOperand* LChunkBuilder::UseOrConstantAtStart(HValue* value) {
490 return value->IsConstant() 506 return value->IsConstant()
491 ? chunk_->DefineConstantOperand(HConstant::cast(value)) 507 ? chunk_->DefineConstantOperand(HConstant::cast(value))
492 : UseAtStart(value); 508 : UseAtStart(value);
493 } 509 }
494 510
495 511
496 LOperand* LChunkBuilder::UseRegisterOrConstant(HValue* value) { 512 LOperand* LChunkBuilder::UseRegisterOrConstant(HValue* value) {
497 return value->IsConstant() 513 return value->IsConstant()
498 ? chunk_->DefineConstantOperand(HConstant::cast(value)) 514 ? chunk_->DefineConstantOperand(HConstant::cast(value))
499 : UseRegister(value); 515 : UseRegister(value);
500 } 516 }
501 517
502 518
503 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) { 519 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
504 return value->IsConstant() 520 return value->IsConstant()
505 ? chunk_->DefineConstantOperand(HConstant::cast(value)) 521 ? chunk_->DefineConstantOperand(HConstant::cast(value))
506 : UseRegisterAtStart(value); 522 : UseRegisterAtStart(value);
507 } 523 }
508 524
509 525
510 LOperand* LChunkBuilder::UseConstant(HValue* value) { 526 LOperand* LChunkBuilder::UseConstant(HValue* value) {
511 return chunk_->DefineConstantOperand(HConstant::cast(value)); 527 return chunk_->DefineConstantOperand(HConstant::cast(value));
512 } 528 }
513 529
514 530
515 LOperand* LChunkBuilder::UseAny(HValue* value) { 531 LOperand* LChunkBuilder::UseAny(HValue* value) {
516 return value->IsConstant() 532 return value->IsConstant()
517 ? chunk_->DefineConstantOperand(HConstant::cast(value)) 533 ? chunk_->DefineConstantOperand(HConstant::cast(value))
518 : Use(value, new(zone()) LUnallocated(LUnallocated::ANY)); 534 : Use(value, new (zone()) LUnallocated(LUnallocated::ANY));
519 } 535 }
520 536
521 537
522 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { 538 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) {
523 if (value->EmitAtUses()) { 539 if (value->EmitAtUses()) {
524 HInstruction* instr = HInstruction::cast(value); 540 HInstruction* instr = HInstruction::cast(value);
525 VisitInstruction(instr); 541 VisitInstruction(instr);
526 } 542 }
527 operand->set_virtual_register(value->id()); 543 operand->set_virtual_register(value->id());
528 return operand; 544 return operand;
529 } 545 }
530 546
531 547
532 LInstruction* LChunkBuilder::Define(LTemplateResultInstruction<1>* instr, 548 LInstruction* LChunkBuilder::Define(LTemplateResultInstruction<1>* instr,
533 LUnallocated* result) { 549 LUnallocated* result) {
534 result->set_virtual_register(current_instruction_->id()); 550 result->set_virtual_register(current_instruction_->id());
535 instr->set_result(result); 551 instr->set_result(result);
536 return instr; 552 return instr;
537 } 553 }
538 554
539 555
540 LInstruction* LChunkBuilder::DefineAsRegister( 556 LInstruction* LChunkBuilder::DefineAsRegister(
541 LTemplateResultInstruction<1>* instr) { 557 LTemplateResultInstruction<1>* instr) {
542 return Define(instr, 558 return Define(instr,
543 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); 559 new (zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
544 } 560 }
545 561
546 562
547 LInstruction* LChunkBuilder::DefineAsSpilled( 563 LInstruction* LChunkBuilder::DefineAsSpilled(
548 LTemplateResultInstruction<1>* instr, int index) { 564 LTemplateResultInstruction<1>* instr, int index) {
549 return Define(instr, 565 return Define(instr,
550 new(zone()) LUnallocated(LUnallocated::FIXED_SLOT, index)); 566 new (zone()) LUnallocated(LUnallocated::FIXED_SLOT, index));
551 } 567 }
552 568
553 569
554 LInstruction* LChunkBuilder::DefineSameAsFirst( 570 LInstruction* LChunkBuilder::DefineSameAsFirst(
555 LTemplateResultInstruction<1>* instr) { 571 LTemplateResultInstruction<1>* instr) {
556 return Define(instr, 572 return Define(instr,
557 new(zone()) LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); 573 new (zone()) LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
558 } 574 }
559 575
560 576
561 LInstruction* LChunkBuilder::DefineFixed( 577 LInstruction* LChunkBuilder::DefineFixed(LTemplateResultInstruction<1>* instr,
562 LTemplateResultInstruction<1>* instr, Register reg) { 578 Register reg) {
563 return Define(instr, ToUnallocated(reg)); 579 return Define(instr, ToUnallocated(reg));
564 } 580 }
565 581
566 582
567 LInstruction* LChunkBuilder::DefineFixedDouble( 583 LInstruction* LChunkBuilder::DefineFixedDouble(
568 LTemplateResultInstruction<1>* instr, DoubleRegister reg) { 584 LTemplateResultInstruction<1>* instr, DoubleRegister reg) {
569 return Define(instr, ToUnallocated(reg)); 585 return Define(instr, ToUnallocated(reg));
570 } 586 }
571 587
572 588
573 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { 589 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
574 HEnvironment* hydrogen_env = current_block_->last_environment(); 590 HEnvironment* hydrogen_env = current_block_->last_environment();
575 int argument_index_accumulator = 0; 591 int argument_index_accumulator = 0;
576 ZoneList<HValue*> objects_to_materialize(0, zone()); 592 ZoneList<HValue*> objects_to_materialize(0, zone());
577 instr->set_environment(CreateEnvironment(hydrogen_env, 593 instr->set_environment(CreateEnvironment(
578 &argument_index_accumulator, 594 hydrogen_env, &argument_index_accumulator, &objects_to_materialize));
579 &objects_to_materialize));
580 return instr; 595 return instr;
581 } 596 }
582 597
583 598
584 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, 599 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
585 HInstruction* hinstr, 600 HInstruction* hinstr,
586 CanDeoptimize can_deoptimize) { 601 CanDeoptimize can_deoptimize) {
587 info()->MarkAsNonDeferredCalling(); 602 info()->MarkAsNonDeferredCalling();
588 #ifdef DEBUG 603 #ifdef DEBUG
589 instr->VerifyCall(); 604 instr->VerifyCall();
590 #endif 605 #endif
591 instr->MarkAsCall(); 606 instr->MarkAsCall();
592 instr = AssignPointerMap(instr); 607 instr = AssignPointerMap(instr);
593 608
594 // If instruction does not have side-effects lazy deoptimization 609 // If instruction does not have side-effects lazy deoptimization
595 // after the call will try to deoptimize to the point before the call. 610 // after the call will try to deoptimize to the point before the call.
596 // Thus we still need to attach environment to this call even if 611 // Thus we still need to attach environment to this call even if
597 // call sequence can not deoptimize eagerly. 612 // call sequence can not deoptimize eagerly.
598 bool needs_environment = 613 bool needs_environment = (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) ||
599 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || 614 !hinstr->HasObservableSideEffects();
600 !hinstr->HasObservableSideEffects();
601 if (needs_environment && !instr->HasEnvironment()) { 615 if (needs_environment && !instr->HasEnvironment()) {
602 instr = AssignEnvironment(instr); 616 instr = AssignEnvironment(instr);
603 // We can't really figure out if the environment is needed or not. 617 // We can't really figure out if the environment is needed or not.
604 instr->environment()->set_has_been_used(); 618 instr->environment()->set_has_been_used();
605 } 619 }
606 620
607 return instr; 621 return instr;
608 } 622 }
609 623
610 624
611 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { 625 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
612 DCHECK(!instr->HasPointerMap()); 626 DCHECK(!instr->HasPointerMap());
613 instr->set_pointer_map(new(zone()) LPointerMap(zone())); 627 instr->set_pointer_map(new (zone()) LPointerMap(zone()));
614 return instr; 628 return instr;
615 } 629 }
616 630
617 631
618 LUnallocated* LChunkBuilder::TempRegister() { 632 LUnallocated* LChunkBuilder::TempRegister() {
619 LUnallocated* operand = 633 LUnallocated* operand =
620 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); 634 new (zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
621 int vreg = allocator_->GetVirtualRegister(); 635 int vreg = allocator_->GetVirtualRegister();
622 if (!allocator_->AllocationOk()) { 636 if (!allocator_->AllocationOk()) {
623 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); 637 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister);
624 vreg = 0; 638 vreg = 0;
625 } 639 }
626 operand->set_virtual_register(vreg); 640 operand->set_virtual_register(vreg);
627 return operand; 641 return operand;
628 } 642 }
629 643
630 644
631 LUnallocated* LChunkBuilder::TempDoubleRegister() { 645 LUnallocated* LChunkBuilder::TempDoubleRegister() {
632 LUnallocated* operand = 646 LUnallocated* operand =
633 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_DOUBLE_REGISTER); 647 new (zone()) LUnallocated(LUnallocated::MUST_HAVE_DOUBLE_REGISTER);
634 int vreg = allocator_->GetVirtualRegister(); 648 int vreg = allocator_->GetVirtualRegister();
635 if (!allocator_->AllocationOk()) { 649 if (!allocator_->AllocationOk()) {
636 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); 650 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister);
637 vreg = 0; 651 vreg = 0;
638 } 652 }
639 operand->set_virtual_register(vreg); 653 operand->set_virtual_register(vreg);
640 return operand; 654 return operand;
641 } 655 }
642 656
643 657
644 LOperand* LChunkBuilder::FixedTemp(Register reg) { 658 LOperand* LChunkBuilder::FixedTemp(Register reg) {
645 LUnallocated* operand = ToUnallocated(reg); 659 LUnallocated* operand = ToUnallocated(reg);
646 DCHECK(operand->HasFixedPolicy()); 660 DCHECK(operand->HasFixedPolicy());
647 return operand; 661 return operand;
648 } 662 }
649 663
650 664
651 LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) { 665 LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) {
652 LUnallocated* operand = ToUnallocated(reg); 666 LUnallocated* operand = ToUnallocated(reg);
653 DCHECK(operand->HasFixedPolicy()); 667 DCHECK(operand->HasFixedPolicy());
654 return operand; 668 return operand;
655 } 669 }
656 670
657 671
658 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { 672 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
659 return new(zone()) LLabel(instr->block()); 673 return new (zone()) LLabel(instr->block());
660 } 674 }
661 675
662 676
663 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { 677 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
664 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); 678 return DefineAsRegister(new (zone()) LDummyUse(UseAny(instr->value())));
665 } 679 }
666 680
667 681
668 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) { 682 LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
669 UNREACHABLE(); 683 UNREACHABLE();
670 return NULL; 684 return NULL;
671 } 685 }
672 686
673 687
674 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { 688 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
675 return AssignEnvironment(new(zone()) LDeoptimize); 689 return AssignEnvironment(new (zone()) LDeoptimize);
676 } 690 }
677 691
678 692
679 LInstruction* LChunkBuilder::DoShift(Token::Value op, 693 LInstruction* LChunkBuilder::DoShift(Token::Value op,
680 HBitwiseBinaryOperation* instr) { 694 HBitwiseBinaryOperation* instr) {
681 if (instr->representation().IsSmiOrInteger32()) { 695 if (instr->representation().IsSmiOrInteger32()) {
682 DCHECK(instr->left()->representation().Equals(instr->representation())); 696 DCHECK(instr->left()->representation().Equals(instr->representation()));
683 DCHECK(instr->right()->representation().Equals(instr->representation())); 697 DCHECK(instr->right()->representation().Equals(instr->representation()));
684 LOperand* left = UseRegisterAtStart(instr->left()); 698 LOperand* left = UseRegisterAtStart(instr->left());
685 699
(...skipping 18 matching lines...) Expand all
704 // by 0 and the result cannot be truncated to int32. 718 // by 0 and the result cannot be truncated to int32.
705 if (op == Token::SHR && constant_value == 0) { 719 if (op == Token::SHR && constant_value == 0) {
706 if (FLAG_opt_safe_uint32_operations) { 720 if (FLAG_opt_safe_uint32_operations) {
707 does_deopt = !instr->CheckFlag(HInstruction::kUint32); 721 does_deopt = !instr->CheckFlag(HInstruction::kUint32);
708 } else { 722 } else {
709 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32); 723 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
710 } 724 }
711 } 725 }
712 726
713 LInstruction* result = 727 LInstruction* result =
714 DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); 728 DefineAsRegister(new (zone()) LShiftI(op, left, right, does_deopt));
715 return does_deopt ? AssignEnvironment(result) : result; 729 return does_deopt ? AssignEnvironment(result) : result;
716 } else { 730 } else {
717 return DoArithmeticT(op, instr); 731 return DoArithmeticT(op, instr);
718 } 732 }
719 } 733 }
720 734
721 735
722 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, 736 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
723 HArithmeticBinaryOperation* instr) { 737 HArithmeticBinaryOperation* instr) {
724 DCHECK(instr->representation().IsDouble()); 738 DCHECK(instr->representation().IsDouble());
725 DCHECK(instr->left()->representation().IsDouble()); 739 DCHECK(instr->left()->representation().IsDouble());
726 DCHECK(instr->right()->representation().IsDouble()); 740 DCHECK(instr->right()->representation().IsDouble());
727 if (op == Token::MOD) { 741 if (op == Token::MOD) {
728 LOperand* left = UseFixedDouble(instr->left(), d0); 742 LOperand* left = UseFixedDouble(instr->left(), d1);
729 LOperand* right = UseFixedDouble(instr->right(), d1); 743 LOperand* right = UseFixedDouble(instr->right(), d2);
730 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); 744 LArithmeticD* result = new (zone()) LArithmeticD(op, left, right);
731 return MarkAsCall(DefineFixedDouble(result, d0), instr); 745 // We call a C function for double modulo. It can't trigger a GC. We need
746 // to use fixed result register for the call.
747 // TODO(fschneider): Allow any register as input registers.
748 return MarkAsCall(DefineFixedDouble(result, d1), instr);
732 } else { 749 } else {
733 LOperand* left = UseRegisterAtStart(instr->left()); 750 LOperand* left = UseRegisterAtStart(instr->left());
734 LOperand* right = UseRegisterAtStart(instr->right()); 751 LOperand* right = UseRegisterAtStart(instr->right());
735 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); 752 LArithmeticD* result = new (zone()) LArithmeticD(op, left, right);
736 return DefineAsRegister(result); 753 return DefineAsRegister(result);
737 } 754 }
738 } 755 }
739 756
740 757
741 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, 758 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
742 HBinaryOperation* instr) { 759 HBinaryOperation* instr) {
743 HValue* left = instr->left(); 760 HValue* left = instr->left();
744 HValue* right = instr->right(); 761 HValue* right = instr->right();
745 DCHECK(left->representation().IsTagged()); 762 DCHECK(left->representation().IsTagged());
746 DCHECK(right->representation().IsTagged()); 763 DCHECK(right->representation().IsTagged());
747 LOperand* context = UseFixed(instr->context(), cp); 764 LOperand* context = UseFixed(instr->context(), cp);
748 LOperand* left_operand = UseFixed(left, r1); 765 LOperand* left_operand = UseFixed(left, r4);
749 LOperand* right_operand = UseFixed(right, r0); 766 LOperand* right_operand = UseFixed(right, r3);
750 LArithmeticT* result = 767 LArithmeticT* result =
751 new(zone()) LArithmeticT(op, context, left_operand, right_operand); 768 new (zone()) LArithmeticT(op, context, left_operand, right_operand);
752 return MarkAsCall(DefineFixed(result, r0), instr); 769 return MarkAsCall(DefineFixed(result, r3), instr);
753 } 770 }
754 771
755 772
756 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { 773 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
757 DCHECK(is_building()); 774 DCHECK(is_building());
758 current_block_ = block; 775 current_block_ = block;
759 next_block_ = next_block; 776 next_block_ = next_block;
760 if (block->IsStartBlock()) { 777 if (block->IsStartBlock()) {
761 block->UpdateEnvironment(graph_->start_environment()); 778 block->UpdateEnvironment(graph_->start_environment());
762 argument_count_ = 0; 779 argument_count_ = 0;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 } 837 }
821 838
822 839
823 void LChunkBuilder::VisitInstruction(HInstruction* current) { 840 void LChunkBuilder::VisitInstruction(HInstruction* current) {
824 HInstruction* old_current = current_instruction_; 841 HInstruction* old_current = current_instruction_;
825 current_instruction_ = current; 842 current_instruction_ = current;
826 843
827 LInstruction* instr = NULL; 844 LInstruction* instr = NULL;
828 if (current->CanReplaceWithDummyUses()) { 845 if (current->CanReplaceWithDummyUses()) {
829 if (current->OperandCount() == 0) { 846 if (current->OperandCount() == 0) {
830 instr = DefineAsRegister(new(zone()) LDummy()); 847 instr = DefineAsRegister(new (zone()) LDummy());
831 } else { 848 } else {
832 DCHECK(!current->OperandAt(0)->IsControlInstruction()); 849 DCHECK(!current->OperandAt(0)->IsControlInstruction());
833 instr = DefineAsRegister(new(zone()) 850 instr = DefineAsRegister(new (zone())
834 LDummyUse(UseAny(current->OperandAt(0)))); 851 LDummyUse(UseAny(current->OperandAt(0))));
835 } 852 }
836 for (int i = 1; i < current->OperandCount(); ++i) { 853 for (int i = 1; i < current->OperandCount(); ++i) {
837 if (current->OperandAt(i)->IsControlInstruction()) continue; 854 if (current->OperandAt(i)->IsControlInstruction()) continue;
838 LInstruction* dummy = 855 LInstruction* dummy =
839 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); 856 new (zone()) LDummyUse(UseAny(current->OperandAt(i)));
840 dummy->set_hydrogen_value(current); 857 dummy->set_hydrogen_value(current);
841 chunk_->AddInstruction(dummy, current_block_); 858 chunk_->AddInstruction(dummy, current_block_);
842 } 859 }
843 } else { 860 } else {
844 HBasicBlock* successor; 861 HBasicBlock* successor;
845 if (current->IsControlInstruction() && 862 if (current->IsControlInstruction() &&
846 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && 863 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) &&
847 successor != NULL) { 864 successor != NULL) {
848 instr = new(zone()) LGoto(successor); 865 instr = new (zone()) LGoto(successor);
849 } else { 866 } else {
850 instr = current->CompileToLithium(this); 867 instr = current->CompileToLithium(this);
851 } 868 }
852 } 869 }
853 870
854 argument_count_ += current->argument_delta(); 871 argument_count_ += current->argument_delta();
855 DCHECK(argument_count_ >= 0); 872 DCHECK(argument_count_ >= 0);
856 873
857 if (instr != NULL) { 874 if (instr != NULL) {
858 AddInstruction(instr, current); 875 AddInstruction(instr, current);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 925
909 if (instr->IsCall()) { 926 if (instr->IsCall()) {
910 HValue* hydrogen_value_for_lazy_bailout = hydrogen_val; 927 HValue* hydrogen_value_for_lazy_bailout = hydrogen_val;
911 LInstruction* instruction_needing_environment = NULL; 928 LInstruction* instruction_needing_environment = NULL;
912 if (hydrogen_val->HasObservableSideEffects()) { 929 if (hydrogen_val->HasObservableSideEffects()) {
913 HSimulate* sim = HSimulate::cast(hydrogen_val->next()); 930 HSimulate* sim = HSimulate::cast(hydrogen_val->next());
914 instruction_needing_environment = instr; 931 instruction_needing_environment = instr;
915 sim->ReplayEnvironment(current_block_->last_environment()); 932 sim->ReplayEnvironment(current_block_->last_environment());
916 hydrogen_value_for_lazy_bailout = sim; 933 hydrogen_value_for_lazy_bailout = sim;
917 } 934 }
918 LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout()); 935 LInstruction* bailout = AssignEnvironment(new (zone()) LLazyBailout());
919 bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout); 936 bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
920 chunk_->AddInstruction(bailout, current_block_); 937 chunk_->AddInstruction(bailout, current_block_);
921 if (instruction_needing_environment != NULL) { 938 if (instruction_needing_environment != NULL) {
922 // Store the lazy deopt environment with the instruction if needed. 939 // Store the lazy deopt environment with the instruction if needed.
923 // Right now it is only used for LInstanceOfKnownGlobal. 940 // Right now it is only used for LInstanceOfKnownGlobal.
924 instruction_needing_environment-> 941 instruction_needing_environment->SetDeferredLazyDeoptimizationEnvironment(
925 SetDeferredLazyDeoptimizationEnvironment(bailout->environment()); 942 bailout->environment());
926 } 943 }
927 } 944 }
928 } 945 }
929 946
930 947
931 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 948 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
932 return new(zone()) LGoto(instr->FirstSuccessor()); 949 return new (zone()) LGoto(instr->FirstSuccessor());
933 } 950 }
934 951
935 952
936 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { 953 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
937 HValue* value = instr->value(); 954 HValue* value = instr->value();
938 Representation r = value->representation(); 955 Representation r = value->representation();
939 HType type = value->type(); 956 HType type = value->type();
940 ToBooleanStub::Types expected = instr->expected_input_types(); 957 ToBooleanStub::Types expected = instr->expected_input_types();
941 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); 958 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
942 959
943 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || 960 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
944 type.IsJSArray() || type.IsHeapNumber() || type.IsString(); 961 type.IsJSArray() || type.IsHeapNumber() || type.IsString();
945 LInstruction* branch = new(zone()) LBranch(UseRegister(value)); 962 LInstruction* branch = new (zone()) LBranch(UseRegister(value));
946 if (!easy_case && 963 if (!easy_case &&
947 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || 964 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) ||
948 !expected.IsGeneric())) { 965 !expected.IsGeneric())) {
949 branch = AssignEnvironment(branch); 966 branch = AssignEnvironment(branch);
950 } 967 }
951 return branch; 968 return branch;
952 } 969 }
953 970
954 971
955 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { 972 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
956 return new(zone()) LDebugBreak(); 973 return new (zone()) LDebugBreak();
957 } 974 }
958 975
959 976
960 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { 977 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
961 DCHECK(instr->value()->representation().IsTagged()); 978 DCHECK(instr->value()->representation().IsTagged());
962 LOperand* value = UseRegisterAtStart(instr->value()); 979 LOperand* value = UseRegisterAtStart(instr->value());
963 LOperand* temp = TempRegister(); 980 LOperand* temp = TempRegister();
964 return new(zone()) LCmpMapAndBranch(value, temp); 981 return new (zone()) LCmpMapAndBranch(value, temp);
965 } 982 }
966 983
967 984
968 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* instr) { 985 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* instr) {
969 info()->MarkAsRequiresFrame(); 986 info()->MarkAsRequiresFrame();
970 LOperand* value = UseRegister(instr->value()); 987 LOperand* value = UseRegister(instr->value());
971 return DefineAsRegister(new(zone()) LArgumentsLength(value)); 988 return DefineAsRegister(new (zone()) LArgumentsLength(value));
972 } 989 }
973 990
974 991
975 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { 992 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
976 info()->MarkAsRequiresFrame(); 993 info()->MarkAsRequiresFrame();
977 return DefineAsRegister(new(zone()) LArgumentsElements); 994 return DefineAsRegister(new (zone()) LArgumentsElements);
978 } 995 }
979 996
980 997
981 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { 998 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
982 LOperand* context = UseFixed(instr->context(), cp); 999 LOperand* context = UseFixed(instr->context(), cp);
983 LInstanceOf* result = 1000 LInstanceOf* result = new (zone()) LInstanceOf(
984 new(zone()) LInstanceOf(context, UseFixed(instr->left(), r0), 1001 context, UseFixed(instr->left(), r3), UseFixed(instr->right(), r4));
985 UseFixed(instr->right(), r1)); 1002 return MarkAsCall(DefineFixed(result, r3), instr);
986 return MarkAsCall(DefineFixed(result, r0), instr);
987 } 1003 }
988 1004
989 1005
990 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( 1006 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
991 HInstanceOfKnownGlobal* instr) { 1007 HInstanceOfKnownGlobal* instr) {
992 LInstanceOfKnownGlobal* result = 1008 LInstanceOfKnownGlobal* result = new (zone())
993 new(zone()) LInstanceOfKnownGlobal( 1009 LInstanceOfKnownGlobal(UseFixed(instr->context(), cp),
994 UseFixed(instr->context(), cp), 1010 UseFixed(instr->left(), r3), FixedTemp(r7));
995 UseFixed(instr->left(), r0), 1011 return MarkAsCall(DefineFixed(result, r3), instr);
996 FixedTemp(r4));
997 return MarkAsCall(DefineFixed(result, r0), instr);
998 } 1012 }
999 1013
1000 1014
1001 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { 1015 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
1002 LOperand* receiver = UseRegisterAtStart(instr->receiver()); 1016 LOperand* receiver = UseRegisterAtStart(instr->receiver());
1003 LOperand* function = UseRegisterAtStart(instr->function()); 1017 LOperand* function = UseRegisterAtStart(instr->function());
1004 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); 1018 LWrapReceiver* result = new (zone()) LWrapReceiver(receiver, function);
1005 return AssignEnvironment(DefineAsRegister(result)); 1019 return AssignEnvironment(DefineAsRegister(result));
1006 } 1020 }
1007 1021
1008 1022
1009 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1023 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1010 LOperand* function = UseFixed(instr->function(), r1); 1024 LOperand* function = UseFixed(instr->function(), r4);
1011 LOperand* receiver = UseFixed(instr->receiver(), r0); 1025 LOperand* receiver = UseFixed(instr->receiver(), r3);
1012 LOperand* length = UseFixed(instr->length(), r2); 1026 LOperand* length = UseFixed(instr->length(), r5);
1013 LOperand* elements = UseFixed(instr->elements(), r3); 1027 LOperand* elements = UseFixed(instr->elements(), r6);
1014 LApplyArguments* result = new(zone()) LApplyArguments(function, 1028 LApplyArguments* result =
1015 receiver, 1029 new (zone()) LApplyArguments(function, receiver, length, elements);
1016 length, 1030 return MarkAsCall(DefineFixed(result, r3), instr, CAN_DEOPTIMIZE_EAGERLY);
1017 elements);
1018 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
1019 } 1031 }
1020 1032
1021 1033
1022 LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) { 1034 LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
1023 int argc = instr->OperandCount(); 1035 int argc = instr->OperandCount();
1024 for (int i = 0; i < argc; ++i) { 1036 for (int i = 0; i < argc; ++i) {
1025 LOperand* argument = Use(instr->argument(i)); 1037 LOperand* argument = Use(instr->argument(i));
1026 AddInstruction(new(zone()) LPushArgument(argument), instr); 1038 AddInstruction(new (zone()) LPushArgument(argument), instr);
1027 } 1039 }
1028 return NULL; 1040 return NULL;
1029 } 1041 }
1030 1042
1031 1043
1032 LInstruction* LChunkBuilder::DoStoreCodeEntry( 1044 LInstruction* LChunkBuilder::DoStoreCodeEntry(
1033 HStoreCodeEntry* store_code_entry) { 1045 HStoreCodeEntry* store_code_entry) {
1034 LOperand* function = UseRegister(store_code_entry->function()); 1046 LOperand* function = UseRegister(store_code_entry->function());
1035 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); 1047 LOperand* code_object = UseTempRegister(store_code_entry->code_object());
1036 return new(zone()) LStoreCodeEntry(function, code_object); 1048 return new (zone()) LStoreCodeEntry(function, code_object);
1037 } 1049 }
1038 1050
1039 1051
1040 LInstruction* LChunkBuilder::DoInnerAllocatedObject( 1052 LInstruction* LChunkBuilder::DoInnerAllocatedObject(
1041 HInnerAllocatedObject* instr) { 1053 HInnerAllocatedObject* instr) {
1042 LOperand* base_object = UseRegisterAtStart(instr->base_object()); 1054 LOperand* base_object = UseRegisterAtStart(instr->base_object());
1043 LOperand* offset = UseRegisterOrConstantAtStart(instr->offset()); 1055 LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
1044 return DefineAsRegister( 1056 return DefineAsRegister(new (zone())
1045 new(zone()) LInnerAllocatedObject(base_object, offset)); 1057 LInnerAllocatedObject(base_object, offset));
1046 } 1058 }
1047 1059
1048 1060
1049 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { 1061 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
1050 return instr->HasNoUses() 1062 return instr->HasNoUses() ? NULL
1051 ? NULL 1063 : DefineAsRegister(new (zone()) LThisFunction);
1052 : DefineAsRegister(new(zone()) LThisFunction);
1053 } 1064 }
1054 1065
1055 1066
1056 LInstruction* LChunkBuilder::DoContext(HContext* instr) { 1067 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1057 if (instr->HasNoUses()) return NULL; 1068 if (instr->HasNoUses()) return NULL;
1058 1069
1059 if (info()->IsStub()) { 1070 if (info()->IsStub()) {
1060 return DefineFixed(new(zone()) LContext, cp); 1071 return DefineFixed(new (zone()) LContext, cp);
1061 } 1072 }
1062 1073
1063 return DefineAsRegister(new(zone()) LContext); 1074 return DefineAsRegister(new (zone()) LContext);
1064 } 1075 }
1065 1076
1066 1077
1067 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { 1078 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
1068 LOperand* context = UseFixed(instr->context(), cp); 1079 LOperand* context = UseFixed(instr->context(), cp);
1069 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); 1080 return MarkAsCall(new (zone()) LDeclareGlobals(context), instr);
1070 } 1081 }
1071 1082
1072 1083
1073 LInstruction* LChunkBuilder::DoCallJSFunction( 1084 LInstruction* LChunkBuilder::DoCallJSFunction(HCallJSFunction* instr) {
1074 HCallJSFunction* instr) { 1085 LOperand* function = UseFixed(instr->function(), r4);
1075 LOperand* function = UseFixed(instr->function(), r1);
1076 1086
1077 LCallJSFunction* result = new(zone()) LCallJSFunction(function); 1087 LCallJSFunction* result = new (zone()) LCallJSFunction(function);
1078 1088
1079 return MarkAsCall(DefineFixed(result, r0), instr); 1089 return MarkAsCall(DefineFixed(result, r3), instr);
1080 } 1090 }
1081 1091
1082 1092
1083 LInstruction* LChunkBuilder::DoCallWithDescriptor( 1093 LInstruction* LChunkBuilder::DoCallWithDescriptor(HCallWithDescriptor* instr) {
1084 HCallWithDescriptor* instr) {
1085 CallInterfaceDescriptor descriptor = instr->descriptor(); 1094 CallInterfaceDescriptor descriptor = instr->descriptor();
1086 1095
1087 LOperand* target = UseRegisterOrConstantAtStart(instr->target()); 1096 LOperand* target = UseRegisterOrConstantAtStart(instr->target());
1088 ZoneList<LOperand*> ops(instr->OperandCount(), zone()); 1097 ZoneList<LOperand*> ops(instr->OperandCount(), zone());
1089 ops.Add(target, zone()); 1098 ops.Add(target, zone());
1090 for (int i = 1; i < instr->OperandCount(); i++) { 1099 for (int i = 1; i < instr->OperandCount(); i++) {
1091 LOperand* op = 1100 LOperand* op =
1092 UseFixed(instr->OperandAt(i), descriptor.GetParameterRegister(i - 1)); 1101 UseFixed(instr->OperandAt(i), descriptor.GetParameterRegister(i - 1));
1093 ops.Add(op, zone()); 1102 ops.Add(op, zone());
1094 } 1103 }
1095 1104
1096 LCallWithDescriptor* result = new(zone()) LCallWithDescriptor( 1105 LCallWithDescriptor* result =
1097 descriptor, ops, zone()); 1106 new (zone()) LCallWithDescriptor(descriptor, ops, zone());
1098 return MarkAsCall(DefineFixed(result, r0), instr); 1107 return MarkAsCall(DefineFixed(result, r3), instr);
1099 } 1108 }
1100 1109
1101 1110
1102 LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache( 1111 LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
1103 HTailCallThroughMegamorphicCache* instr) { 1112 HTailCallThroughMegamorphicCache* instr) {
1104 LOperand* context = UseFixed(instr->context(), cp); 1113 LOperand* context = UseFixed(instr->context(), cp);
1105 LOperand* receiver_register = 1114 LOperand* receiver_register =
1106 UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister()); 1115 UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
1107 LOperand* name_register = 1116 LOperand* name_register =
1108 UseFixed(instr->name(), LoadDescriptor::NameRegister()); 1117 UseFixed(instr->name(), LoadDescriptor::NameRegister());
1109 // Not marked as call. It can't deoptimize, and it never returns. 1118 // Not marked as call. It can't deoptimize, and it never returns.
1110 return new (zone()) LTailCallThroughMegamorphicCache( 1119 return new (zone()) LTailCallThroughMegamorphicCache(
1111 context, receiver_register, name_register); 1120 context, receiver_register, name_register);
1112 } 1121 }
1113 1122
1114 1123
1115 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { 1124 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1116 LOperand* context = UseFixed(instr->context(), cp); 1125 LOperand* context = UseFixed(instr->context(), cp);
1117 LOperand* function = UseFixed(instr->function(), r1); 1126 LOperand* function = UseFixed(instr->function(), r4);
1118 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); 1127 LInvokeFunction* result = new (zone()) LInvokeFunction(context, function);
1119 return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY); 1128 return MarkAsCall(DefineFixed(result, r3), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1120 } 1129 }
1121 1130
1122 1131
1123 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1132 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1124 switch (instr->op()) { 1133 switch (instr->op()) {
1125 case kMathFloor: 1134 case kMathFloor:
1126 return DoMathFloor(instr); 1135 return DoMathFloor(instr);
1127 case kMathRound: 1136 case kMathRound:
1128 return DoMathRound(instr); 1137 return DoMathRound(instr);
1129 case kMathFround: 1138 case kMathFround:
(...skipping 12 matching lines...) Expand all
1142 return DoMathClz32(instr); 1151 return DoMathClz32(instr);
1143 default: 1152 default:
1144 UNREACHABLE(); 1153 UNREACHABLE();
1145 return NULL; 1154 return NULL;
1146 } 1155 }
1147 } 1156 }
1148 1157
1149 1158
1150 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { 1159 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
1151 LOperand* input = UseRegister(instr->value()); 1160 LOperand* input = UseRegister(instr->value());
1152 LMathFloor* result = new(zone()) LMathFloor(input); 1161 LMathFloor* result = new (zone()) LMathFloor(input);
1153 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1162 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1154 } 1163 }
1155 1164
1156 1165
1157 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { 1166 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
1158 LOperand* input = UseRegister(instr->value()); 1167 LOperand* input = UseRegister(instr->value());
1159 LOperand* temp = TempDoubleRegister(); 1168 LOperand* temp = TempDoubleRegister();
1160 LMathRound* result = new(zone()) LMathRound(input, temp); 1169 LMathRound* result = new (zone()) LMathRound(input, temp);
1161 return AssignEnvironment(DefineAsRegister(result)); 1170 return AssignEnvironment(DefineAsRegister(result));
1162 } 1171 }
1163 1172
1164 1173
1165 LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) { 1174 LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
1166 LOperand* input = UseRegister(instr->value()); 1175 LOperand* input = UseRegister(instr->value());
1167 LMathFround* result = new (zone()) LMathFround(input); 1176 LMathFround* result = new (zone()) LMathFround(input);
1168 return DefineAsRegister(result); 1177 return DefineAsRegister(result);
1169 } 1178 }
1170 1179
1171 1180
1172 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { 1181 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1173 Representation r = instr->value()->representation(); 1182 Representation r = instr->value()->representation();
1174 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32()) 1183 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32())
1175 ? NULL 1184 ? NULL
1176 : UseFixed(instr->context(), cp); 1185 : UseFixed(instr->context(), cp);
1177 LOperand* input = UseRegister(instr->value()); 1186 LOperand* input = UseRegister(instr->value());
1178 LInstruction* result = 1187 LInstruction* result =
1179 DefineAsRegister(new(zone()) LMathAbs(context, input)); 1188 DefineAsRegister(new (zone()) LMathAbs(context, input));
1180 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); 1189 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
1181 if (!r.IsDouble()) result = AssignEnvironment(result); 1190 if (!r.IsDouble()) result = AssignEnvironment(result);
1182 return result; 1191 return result;
1183 } 1192 }
1184 1193
1185 1194
1186 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { 1195 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
1187 DCHECK(instr->representation().IsDouble()); 1196 DCHECK(instr->representation().IsDouble());
1188 DCHECK(instr->value()->representation().IsDouble()); 1197 DCHECK(instr->value()->representation().IsDouble());
1189 LOperand* input = UseFixedDouble(instr->value(), d0); 1198 LOperand* input = UseFixedDouble(instr->value(), d1);
1190 return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), d0), instr); 1199 return MarkAsCall(DefineFixedDouble(new (zone()) LMathLog(input), d1), instr);
1191 } 1200 }
1192 1201
1193 1202
1194 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { 1203 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
1195 LOperand* input = UseRegisterAtStart(instr->value()); 1204 LOperand* input = UseRegisterAtStart(instr->value());
1196 LMathClz32* result = new(zone()) LMathClz32(input); 1205 LMathClz32* result = new (zone()) LMathClz32(input);
1197 return DefineAsRegister(result); 1206 return DefineAsRegister(result);
1198 } 1207 }
1199 1208
1200 1209
1201 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { 1210 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
1202 DCHECK(instr->representation().IsDouble()); 1211 DCHECK(instr->representation().IsDouble());
1203 DCHECK(instr->value()->representation().IsDouble()); 1212 DCHECK(instr->value()->representation().IsDouble());
1204 LOperand* input = UseRegister(instr->value()); 1213 LOperand* input = UseRegister(instr->value());
1205 LOperand* temp1 = TempRegister(); 1214 LOperand* temp1 = TempRegister();
1206 LOperand* temp2 = TempRegister(); 1215 LOperand* temp2 = TempRegister();
1207 LOperand* double_temp = TempDoubleRegister(); 1216 LOperand* double_temp = TempDoubleRegister();
1208 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); 1217 LMathExp* result = new (zone()) LMathExp(input, double_temp, temp1, temp2);
1209 return DefineAsRegister(result); 1218 return DefineAsRegister(result);
1210 } 1219 }
1211 1220
1212 1221
1213 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { 1222 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
1214 LOperand* input = UseRegisterAtStart(instr->value()); 1223 LOperand* input = UseRegisterAtStart(instr->value());
1215 LMathSqrt* result = new(zone()) LMathSqrt(input); 1224 LMathSqrt* result = new (zone()) LMathSqrt(input);
1216 return DefineAsRegister(result); 1225 return DefineAsRegister(result);
1217 } 1226 }
1218 1227
1219 1228
1220 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { 1229 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
1221 LOperand* input = UseRegisterAtStart(instr->value()); 1230 LOperand* input = UseRegisterAtStart(instr->value());
1222 LMathPowHalf* result = new(zone()) LMathPowHalf(input); 1231 LMathPowHalf* result = new (zone()) LMathPowHalf(input);
1223 return DefineAsRegister(result); 1232 return DefineAsRegister(result);
1224 } 1233 }
1225 1234
1226 1235
1227 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { 1236 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1228 LOperand* context = UseFixed(instr->context(), cp); 1237 LOperand* context = UseFixed(instr->context(), cp);
1229 LOperand* constructor = UseFixed(instr->constructor(), r1); 1238 LOperand* constructor = UseFixed(instr->constructor(), r4);
1230 LCallNew* result = new(zone()) LCallNew(context, constructor); 1239 LCallNew* result = new (zone()) LCallNew(context, constructor);
1231 return MarkAsCall(DefineFixed(result, r0), instr); 1240 return MarkAsCall(DefineFixed(result, r3), instr);
1232 } 1241 }
1233 1242
1234 1243
1235 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { 1244 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1236 LOperand* context = UseFixed(instr->context(), cp); 1245 LOperand* context = UseFixed(instr->context(), cp);
1237 LOperand* constructor = UseFixed(instr->constructor(), r1); 1246 LOperand* constructor = UseFixed(instr->constructor(), r4);
1238 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); 1247 LCallNewArray* result = new (zone()) LCallNewArray(context, constructor);
1239 return MarkAsCall(DefineFixed(result, r0), instr); 1248 return MarkAsCall(DefineFixed(result, r3), instr);
1240 } 1249 }
1241 1250
1242 1251
1243 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { 1252 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1244 LOperand* context = UseFixed(instr->context(), cp); 1253 LOperand* context = UseFixed(instr->context(), cp);
1245 LOperand* function = UseFixed(instr->function(), r1); 1254 LOperand* function = UseFixed(instr->function(), r4);
1246 LCallFunction* call = new(zone()) LCallFunction(context, function); 1255 LCallFunction* call = new (zone()) LCallFunction(context, function);
1247 return MarkAsCall(DefineFixed(call, r0), instr); 1256 return MarkAsCall(DefineFixed(call, r3), instr);
1248 } 1257 }
1249 1258
1250 1259
1251 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { 1260 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1252 LOperand* context = UseFixed(instr->context(), cp); 1261 LOperand* context = UseFixed(instr->context(), cp);
1253 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), r0), instr); 1262 return MarkAsCall(DefineFixed(new (zone()) LCallRuntime(context), r3), instr);
1254 } 1263 }
1255 1264
1256 1265
1257 LInstruction* LChunkBuilder::DoRor(HRor* instr) { 1266 LInstruction* LChunkBuilder::DoRor(HRor* instr) {
1258 return DoShift(Token::ROR, instr); 1267 return DoShift(Token::ROR, instr);
1259 } 1268 }
1260 1269
1261 1270
1262 LInstruction* LChunkBuilder::DoShr(HShr* instr) { 1271 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1263 return DoShift(Token::SHR, instr); 1272 return DoShift(Token::SHR, instr);
(...skipping 11 matching lines...) Expand all
1275 1284
1276 1285
1277 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { 1286 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
1278 if (instr->representation().IsSmiOrInteger32()) { 1287 if (instr->representation().IsSmiOrInteger32()) {
1279 DCHECK(instr->left()->representation().Equals(instr->representation())); 1288 DCHECK(instr->left()->representation().Equals(instr->representation()));
1280 DCHECK(instr->right()->representation().Equals(instr->representation())); 1289 DCHECK(instr->right()->representation().Equals(instr->representation()));
1281 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32)); 1290 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32));
1282 1291
1283 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); 1292 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1284 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); 1293 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1285 return DefineAsRegister(new(zone()) LBitI(left, right)); 1294 return DefineAsRegister(new (zone()) LBitI(left, right));
1286 } else { 1295 } else {
1287 return DoArithmeticT(instr->op(), instr); 1296 return DoArithmeticT(instr->op(), instr);
1288 } 1297 }
1289 } 1298 }
1290 1299
1291 1300
1292 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { 1301 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
1293 DCHECK(instr->representation().IsSmiOrInteger32()); 1302 DCHECK(instr->representation().IsSmiOrInteger32());
1294 DCHECK(instr->left()->representation().Equals(instr->representation())); 1303 DCHECK(instr->left()->representation().Equals(instr->representation()));
1295 DCHECK(instr->right()->representation().Equals(instr->representation())); 1304 DCHECK(instr->right()->representation().Equals(instr->representation()));
1296 LOperand* dividend = UseRegister(instr->left()); 1305 LOperand* dividend = UseRegister(instr->left());
1297 int32_t divisor = instr->right()->GetInteger32Constant(); 1306 int32_t divisor = instr->right()->GetInteger32Constant();
1298 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( 1307 LInstruction* result =
1299 dividend, divisor)); 1308 DefineAsRegister(new (zone()) LDivByPowerOf2I(dividend, divisor));
1300 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || 1309 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1301 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || 1310 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
1302 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1311 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1303 divisor != 1 && divisor != -1)) { 1312 divisor != 1 && divisor != -1)) {
1304 result = AssignEnvironment(result); 1313 result = AssignEnvironment(result);
1305 } 1314 }
1306 return result; 1315 return result;
1307 } 1316 }
1308 1317
1309 1318
1310 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { 1319 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
1311 DCHECK(instr->representation().IsInteger32()); 1320 DCHECK(instr->representation().IsInteger32());
1312 DCHECK(instr->left()->representation().Equals(instr->representation())); 1321 DCHECK(instr->left()->representation().Equals(instr->representation()));
1313 DCHECK(instr->right()->representation().Equals(instr->representation())); 1322 DCHECK(instr->right()->representation().Equals(instr->representation()));
1314 LOperand* dividend = UseRegister(instr->left()); 1323 LOperand* dividend = UseRegister(instr->left());
1315 int32_t divisor = instr->right()->GetInteger32Constant(); 1324 int32_t divisor = instr->right()->GetInteger32Constant();
1316 LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI( 1325 LInstruction* result =
1317 dividend, divisor)); 1326 DefineAsRegister(new (zone()) LDivByConstI(dividend, divisor));
1318 if (divisor == 0 || 1327 if (divisor == 0 ||
1319 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || 1328 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1320 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1329 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1321 result = AssignEnvironment(result); 1330 result = AssignEnvironment(result);
1322 } 1331 }
1323 return result; 1332 return result;
1324 } 1333 }
1325 1334
1326 1335
1327 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { 1336 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
1328 DCHECK(instr->representation().IsSmiOrInteger32()); 1337 DCHECK(instr->representation().IsSmiOrInteger32());
1329 DCHECK(instr->left()->representation().Equals(instr->representation())); 1338 DCHECK(instr->left()->representation().Equals(instr->representation()));
1330 DCHECK(instr->right()->representation().Equals(instr->representation())); 1339 DCHECK(instr->right()->representation().Equals(instr->representation()));
1331 LOperand* dividend = UseRegister(instr->left()); 1340 LOperand* dividend = UseRegister(instr->left());
1332 LOperand* divisor = UseRegister(instr->right()); 1341 LOperand* divisor = UseRegister(instr->right());
1333 LOperand* temp =
1334 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister();
1335 LInstruction* result = 1342 LInstruction* result =
1336 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); 1343 DefineAsRegister(new (zone()) LDivI(dividend, divisor));
1337 if (instr->CheckFlag(HValue::kCanBeDivByZero) || 1344 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1338 instr->CheckFlag(HValue::kBailoutOnMinusZero) || 1345 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1339 (instr->CheckFlag(HValue::kCanOverflow) && 1346 (instr->CheckFlag(HValue::kCanOverflow) &&
1340 (!CpuFeatures::IsSupported(SUDIV) || 1347 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) ||
1341 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) ||
1342 (!instr->IsMathFloorOfDiv() && 1348 (!instr->IsMathFloorOfDiv() &&
1343 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) { 1349 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
1344 result = AssignEnvironment(result); 1350 result = AssignEnvironment(result);
1345 } 1351 }
1346 return result; 1352 return result;
1347 } 1353 }
1348 1354
1349 1355
1350 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1356 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1351 if (instr->representation().IsSmiOrInteger32()) { 1357 if (instr->representation().IsSmiOrInteger32()) {
1352 if (instr->RightIsPowerOf2()) { 1358 if (instr->RightIsPowerOf2()) {
1353 return DoDivByPowerOf2I(instr); 1359 return DoDivByPowerOf2I(instr);
1354 } else if (instr->right()->IsConstant()) { 1360 } else if (instr->right()->IsConstant()) {
1355 return DoDivByConstI(instr); 1361 return DoDivByConstI(instr);
1356 } else { 1362 } else {
1357 return DoDivI(instr); 1363 return DoDivI(instr);
1358 } 1364 }
1359 } else if (instr->representation().IsDouble()) { 1365 } else if (instr->representation().IsDouble()) {
1360 return DoArithmeticD(Token::DIV, instr); 1366 return DoArithmeticD(Token::DIV, instr);
1361 } else { 1367 } else {
1362 return DoArithmeticT(Token::DIV, instr); 1368 return DoArithmeticT(Token::DIV, instr);
1363 } 1369 }
1364 } 1370 }
1365 1371
1366 1372
1367 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) { 1373 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1368 LOperand* dividend = UseRegisterAtStart(instr->left()); 1374 LOperand* dividend = UseRegisterAtStart(instr->left());
1369 int32_t divisor = instr->right()->GetInteger32Constant(); 1375 int32_t divisor = instr->right()->GetInteger32Constant();
1370 LInstruction* result = DefineAsRegister(new(zone()) LFlooringDivByPowerOf2I( 1376 LInstruction* result =
1371 dividend, divisor)); 1377 DefineAsRegister(new (zone()) LFlooringDivByPowerOf2I(dividend, divisor));
1372 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || 1378 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1373 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { 1379 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
1374 result = AssignEnvironment(result); 1380 result = AssignEnvironment(result);
1375 } 1381 }
1376 return result; 1382 return result;
1377 } 1383 }
1378 1384
1379 1385
1380 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { 1386 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1381 DCHECK(instr->representation().IsInteger32()); 1387 DCHECK(instr->representation().IsInteger32());
1382 DCHECK(instr->left()->representation().Equals(instr->representation())); 1388 DCHECK(instr->left()->representation().Equals(instr->representation()));
1383 DCHECK(instr->right()->representation().Equals(instr->representation())); 1389 DCHECK(instr->right()->representation().Equals(instr->representation()));
1384 LOperand* dividend = UseRegister(instr->left()); 1390 LOperand* dividend = UseRegister(instr->left());
1385 int32_t divisor = instr->right()->GetInteger32Constant(); 1391 int32_t divisor = instr->right()->GetInteger32Constant();
1386 LOperand* temp = 1392 LOperand* temp =
1387 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || 1393 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
1388 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? 1394 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive)))
1389 NULL : TempRegister(); 1395 ? NULL
1396 : TempRegister();
1390 LInstruction* result = DefineAsRegister( 1397 LInstruction* result = DefineAsRegister(
1391 new(zone()) LFlooringDivByConstI(dividend, divisor, temp)); 1398 new (zone()) LFlooringDivByConstI(dividend, divisor, temp));
1392 if (divisor == 0 || 1399 if (divisor == 0 ||
1393 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { 1400 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
1394 result = AssignEnvironment(result); 1401 result = AssignEnvironment(result);
1395 } 1402 }
1396 return result; 1403 return result;
1397 } 1404 }
1398 1405
1399 1406
1400 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { 1407 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
1401 DCHECK(instr->representation().IsSmiOrInteger32()); 1408 DCHECK(instr->representation().IsSmiOrInteger32());
1402 DCHECK(instr->left()->representation().Equals(instr->representation())); 1409 DCHECK(instr->left()->representation().Equals(instr->representation()));
1403 DCHECK(instr->right()->representation().Equals(instr->representation())); 1410 DCHECK(instr->right()->representation().Equals(instr->representation()));
1404 LOperand* dividend = UseRegister(instr->left()); 1411 LOperand* dividend = UseRegister(instr->left());
1405 LOperand* divisor = UseRegister(instr->right()); 1412 LOperand* divisor = UseRegister(instr->right());
1406 LOperand* temp = 1413 LFlooringDivI* div = new (zone()) LFlooringDivI(dividend, divisor);
1407 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister();
1408 LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor, temp);
1409 return AssignEnvironment(DefineAsRegister(div)); 1414 return AssignEnvironment(DefineAsRegister(div));
1410 } 1415 }
1411 1416
1412 1417
1413 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { 1418 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1414 if (instr->RightIsPowerOf2()) { 1419 if (instr->RightIsPowerOf2()) {
1415 return DoFlooringDivByPowerOf2I(instr); 1420 return DoFlooringDivByPowerOf2I(instr);
1416 } else if (instr->right()->IsConstant()) { 1421 } else if (instr->right()->IsConstant()) {
1417 return DoFlooringDivByConstI(instr); 1422 return DoFlooringDivByConstI(instr);
1418 } else { 1423 } else {
1419 return DoFlooringDivI(instr); 1424 return DoFlooringDivI(instr);
1420 } 1425 }
1421 } 1426 }
1422 1427
1423 1428
1424 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { 1429 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
1425 DCHECK(instr->representation().IsSmiOrInteger32()); 1430 DCHECK(instr->representation().IsSmiOrInteger32());
1426 DCHECK(instr->left()->representation().Equals(instr->representation())); 1431 DCHECK(instr->left()->representation().Equals(instr->representation()));
1427 DCHECK(instr->right()->representation().Equals(instr->representation())); 1432 DCHECK(instr->right()->representation().Equals(instr->representation()));
1428 LOperand* dividend = UseRegisterAtStart(instr->left()); 1433 LOperand* dividend = UseRegisterAtStart(instr->left());
1429 int32_t divisor = instr->right()->GetInteger32Constant(); 1434 int32_t divisor = instr->right()->GetInteger32Constant();
1430 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( 1435 LInstruction* result =
1431 dividend, divisor)); 1436 DefineSameAsFirst(new (zone()) LModByPowerOf2I(dividend, divisor));
1432 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && 1437 if (instr->CheckFlag(HValue::kLeftCanBeNegative) &&
1433 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1438 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1434 result = AssignEnvironment(result); 1439 result = AssignEnvironment(result);
1435 } 1440 }
1436 return result; 1441 return result;
1437 } 1442 }
1438 1443
1439 1444
1440 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { 1445 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
1441 DCHECK(instr->representation().IsSmiOrInteger32()); 1446 DCHECK(instr->representation().IsSmiOrInteger32());
1442 DCHECK(instr->left()->representation().Equals(instr->representation())); 1447 DCHECK(instr->left()->representation().Equals(instr->representation()));
1443 DCHECK(instr->right()->representation().Equals(instr->representation())); 1448 DCHECK(instr->right()->representation().Equals(instr->representation()));
1444 LOperand* dividend = UseRegister(instr->left()); 1449 LOperand* dividend = UseRegister(instr->left());
1445 int32_t divisor = instr->right()->GetInteger32Constant(); 1450 int32_t divisor = instr->right()->GetInteger32Constant();
1446 LInstruction* result = DefineAsRegister(new(zone()) LModByConstI( 1451 LInstruction* result =
1447 dividend, divisor)); 1452 DefineAsRegister(new (zone()) LModByConstI(dividend, divisor));
1448 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1453 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1449 result = AssignEnvironment(result); 1454 result = AssignEnvironment(result);
1450 } 1455 }
1451 return result; 1456 return result;
1452 } 1457 }
1453 1458
1454 1459
1455 LInstruction* LChunkBuilder::DoModI(HMod* instr) { 1460 LInstruction* LChunkBuilder::DoModI(HMod* instr) {
1456 DCHECK(instr->representation().IsSmiOrInteger32()); 1461 DCHECK(instr->representation().IsSmiOrInteger32());
1457 DCHECK(instr->left()->representation().Equals(instr->representation())); 1462 DCHECK(instr->left()->representation().Equals(instr->representation()));
1458 DCHECK(instr->right()->representation().Equals(instr->representation())); 1463 DCHECK(instr->right()->representation().Equals(instr->representation()));
1459 LOperand* dividend = UseRegister(instr->left()); 1464 LOperand* dividend = UseRegister(instr->left());
1460 LOperand* divisor = UseRegister(instr->right()); 1465 LOperand* divisor = UseRegister(instr->right());
1461 LOperand* temp = 1466 LInstruction* result =
1462 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); 1467 DefineAsRegister(new (zone()) LModI(dividend, divisor));
1463 LOperand* temp2 =
1464 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister();
1465 LInstruction* result = DefineAsRegister(new(zone()) LModI(
1466 dividend, divisor, temp, temp2));
1467 if (instr->CheckFlag(HValue::kCanBeDivByZero) || 1468 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1468 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1469 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1469 result = AssignEnvironment(result); 1470 result = AssignEnvironment(result);
1470 } 1471 }
1471 return result; 1472 return result;
1472 } 1473 }
1473 1474
1474 1475
1475 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1476 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1476 if (instr->representation().IsSmiOrInteger32()) { 1477 if (instr->representation().IsSmiOrInteger32()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 right_op = UseRegister(right); 1518 right_op = UseRegister(right);
1518 } 1519 }
1519 } else { 1520 } else {
1520 if (bailout_on_minus_zero) { 1521 if (bailout_on_minus_zero) {
1521 left_op = UseRegister(left); 1522 left_op = UseRegister(left);
1522 } else { 1523 } else {
1523 left_op = UseRegisterAtStart(left); 1524 left_op = UseRegisterAtStart(left);
1524 } 1525 }
1525 right_op = UseRegister(right); 1526 right_op = UseRegister(right);
1526 } 1527 }
1527 LMulI* mul = new(zone()) LMulI(left_op, right_op); 1528 LMulI* mul = new (zone()) LMulI(left_op, right_op);
1528 if (can_overflow || bailout_on_minus_zero) { 1529 if (can_overflow || bailout_on_minus_zero) {
1529 AssignEnvironment(mul); 1530 AssignEnvironment(mul);
1530 } 1531 }
1531 return DefineAsRegister(mul); 1532 return DefineAsRegister(mul);
1532 1533
1533 } else if (instr->representation().IsDouble()) { 1534 } else if (instr->representation().IsDouble()) {
1534 if (instr->HasOneUse() && (instr->uses().value()->IsAdd() || 1535 if (instr->HasOneUse() &&
1535 instr->uses().value()->IsSub())) { 1536 (instr->uses().value()->IsAdd() || instr->uses().value()->IsSub())) {
1536 HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value()); 1537 HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value());
1537 1538
1538 if (use->IsAdd() && instr == use->left()) { 1539 if (use->IsAdd() && instr == use->left()) {
1539 // This mul is the lhs of an add. The add and mul will be folded into a 1540 // This mul is the lhs of an add. The add and mul will be folded into a
1540 // multiply-add in DoAdd. 1541 // multiply-add in DoAdd.
1541 return NULL; 1542 return NULL;
1542 } 1543 }
1543 if (instr == use->right() && use->IsAdd() && !use->left()->IsMul()) { 1544 if (instr == use->right() && use->IsAdd() &&
1545 !(use->left()->IsMul() && use->left()->HasOneUse())) {
1544 // This mul is the rhs of an add, where the lhs is not another mul. 1546 // This mul is the rhs of an add, where the lhs is not another mul.
1545 // The add and mul will be folded into a multiply-add in DoAdd. 1547 // The add and mul will be folded into a multiply-add in DoAdd.
1546 return NULL; 1548 return NULL;
1547 } 1549 }
1548 if (instr == use->right() && use->IsSub()) { 1550 if (instr == use->left() && use->IsSub()) {
1549 // This mul is the rhs of a sub. The sub and mul will be folded into a 1551 // This mul is the lhs of a sub. The mul and sub will be folded into a
1550 // multiply-sub in DoSub. 1552 // multiply-sub in DoSub.
1551 return NULL; 1553 return NULL;
1552 } 1554 }
1553 } 1555 }
1554 1556
1555 return DoArithmeticD(Token::MUL, instr); 1557 return DoArithmeticD(Token::MUL, instr);
1556 } else { 1558 } else {
1557 return DoArithmeticT(Token::MUL, instr); 1559 return DoArithmeticT(Token::MUL, instr);
1558 } 1560 }
1559 } 1561 }
1560 1562
1561 1563
1562 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 1564 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1563 if (instr->representation().IsSmiOrInteger32()) { 1565 if (instr->representation().IsSmiOrInteger32()) {
1564 DCHECK(instr->left()->representation().Equals(instr->representation())); 1566 DCHECK(instr->left()->representation().Equals(instr->representation()));
1565 DCHECK(instr->right()->representation().Equals(instr->representation())); 1567 DCHECK(instr->right()->representation().Equals(instr->representation()));
1566 1568
1567 if (instr->left()->IsConstant()) { 1569 if (instr->left()->IsConstant() &&
1570 !instr->CheckFlag(HValue::kCanOverflow)) {
1568 // If lhs is constant, do reverse subtraction instead. 1571 // If lhs is constant, do reverse subtraction instead.
1569 return DoRSub(instr); 1572 return DoRSub(instr);
1570 } 1573 }
1571 1574
1572 LOperand* left = UseRegisterAtStart(instr->left()); 1575 LOperand* left = UseRegisterAtStart(instr->left());
1573 LOperand* right = UseOrConstantAtStart(instr->right()); 1576 LOperand* right = UseOrConstantAtStart(instr->right());
1574 LSubI* sub = new(zone()) LSubI(left, right); 1577 LSubI* sub = new (zone()) LSubI(left, right);
1575 LInstruction* result = DefineAsRegister(sub); 1578 LInstruction* result = DefineAsRegister(sub);
1576 if (instr->CheckFlag(HValue::kCanOverflow)) { 1579 if (instr->CheckFlag(HValue::kCanOverflow)) {
1577 result = AssignEnvironment(result); 1580 result = AssignEnvironment(result);
1578 } 1581 }
1579 return result; 1582 return result;
1580 } else if (instr->representation().IsDouble()) { 1583 } else if (instr->representation().IsDouble()) {
1581 if (instr->right()->IsMul() && instr->right()->HasOneUse()) { 1584 if (instr->left()->IsMul() && instr->left()->HasOneUse()) {
1582 return DoMultiplySub(instr->left(), HMul::cast(instr->right())); 1585 return DoMultiplySub(instr->right(), HMul::cast(instr->left()));
1583 } 1586 }
1584 1587
1585 return DoArithmeticD(Token::SUB, instr); 1588 return DoArithmeticD(Token::SUB, instr);
1586 } else { 1589 } else {
1587 return DoArithmeticT(Token::SUB, instr); 1590 return DoArithmeticT(Token::SUB, instr);
1588 } 1591 }
1589 } 1592 }
1590 1593
1591 1594
1592 LInstruction* LChunkBuilder::DoRSub(HSub* instr) { 1595 LInstruction* LChunkBuilder::DoRSub(HSub* instr) {
1593 DCHECK(instr->representation().IsSmiOrInteger32()); 1596 DCHECK(instr->representation().IsSmiOrInteger32());
1594 DCHECK(instr->left()->representation().Equals(instr->representation())); 1597 DCHECK(instr->left()->representation().Equals(instr->representation()));
1595 DCHECK(instr->right()->representation().Equals(instr->representation())); 1598 DCHECK(instr->right()->representation().Equals(instr->representation()));
1599 DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
1596 1600
1597 // Note: The lhs of the subtraction becomes the rhs of the 1601 // Note: The lhs of the subtraction becomes the rhs of the
1598 // reverse-subtraction. 1602 // reverse-subtraction.
1599 LOperand* left = UseRegisterAtStart(instr->right()); 1603 LOperand* left = UseRegisterAtStart(instr->right());
1600 LOperand* right = UseOrConstantAtStart(instr->left()); 1604 LOperand* right = UseOrConstantAtStart(instr->left());
1601 LRSubI* rsb = new(zone()) LRSubI(left, right); 1605 LRSubI* rsb = new (zone()) LRSubI(left, right);
1602 LInstruction* result = DefineAsRegister(rsb); 1606 LInstruction* result = DefineAsRegister(rsb);
1603 if (instr->CheckFlag(HValue::kCanOverflow)) {
1604 result = AssignEnvironment(result);
1605 }
1606 return result; 1607 return result;
1607 } 1608 }
1608 1609
1609 1610
1610 LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) { 1611 LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) {
1611 LOperand* multiplier_op = UseRegisterAtStart(mul->left()); 1612 LOperand* multiplier_op = UseRegisterAtStart(mul->left());
1612 LOperand* multiplicand_op = UseRegisterAtStart(mul->right()); 1613 LOperand* multiplicand_op = UseRegisterAtStart(mul->right());
1613 LOperand* addend_op = UseRegisterAtStart(addend); 1614 LOperand* addend_op = UseRegisterAtStart(addend);
1614 return DefineSameAsFirst(new(zone()) LMultiplyAddD(addend_op, multiplier_op, 1615 return DefineSameAsFirst(
1615 multiplicand_op)); 1616 new (zone()) LMultiplyAddD(addend_op, multiplier_op, multiplicand_op));
1616 } 1617 }
1617 1618
1618 1619
1619 LInstruction* LChunkBuilder::DoMultiplySub(HValue* minuend, HMul* mul) { 1620 LInstruction* LChunkBuilder::DoMultiplySub(HValue* minuend, HMul* mul) {
1620 LOperand* minuend_op = UseRegisterAtStart(minuend); 1621 LOperand* minuend_op = UseRegisterAtStart(minuend);
1621 LOperand* multiplier_op = UseRegisterAtStart(mul->left()); 1622 LOperand* multiplier_op = UseRegisterAtStart(mul->left());
1622 LOperand* multiplicand_op = UseRegisterAtStart(mul->right()); 1623 LOperand* multiplicand_op = UseRegisterAtStart(mul->right());
1623 1624
1624 return DefineSameAsFirst(new(zone()) LMultiplySubD(minuend_op, 1625 return DefineSameAsFirst(
1625 multiplier_op, 1626 new (zone()) LMultiplySubD(minuend_op, multiplier_op, multiplicand_op));
1626 multiplicand_op));
1627 } 1627 }
1628 1628
1629 1629
1630 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { 1630 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1631 if (instr->representation().IsSmiOrInteger32()) { 1631 if (instr->representation().IsSmiOrInteger32()) {
1632 DCHECK(instr->left()->representation().Equals(instr->representation())); 1632 DCHECK(instr->left()->representation().Equals(instr->representation()));
1633 DCHECK(instr->right()->representation().Equals(instr->representation())); 1633 DCHECK(instr->right()->representation().Equals(instr->representation()));
1634 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); 1634 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1635 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); 1635 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1636 LAddI* add = new(zone()) LAddI(left, right); 1636 LAddI* add = new (zone()) LAddI(left, right);
1637 LInstruction* result = DefineAsRegister(add); 1637 LInstruction* result = DefineAsRegister(add);
1638 if (instr->CheckFlag(HValue::kCanOverflow)) { 1638 if (instr->CheckFlag(HValue::kCanOverflow)) {
1639 result = AssignEnvironment(result); 1639 result = AssignEnvironment(result);
1640 } 1640 }
1641 return result; 1641 return result;
1642 } else if (instr->representation().IsExternal()) { 1642 } else if (instr->representation().IsExternal()) {
1643 DCHECK(instr->left()->representation().IsExternal()); 1643 DCHECK(instr->left()->representation().IsExternal());
1644 DCHECK(instr->right()->representation().IsInteger32()); 1644 DCHECK(instr->right()->representation().IsInteger32());
1645 DCHECK(!instr->CheckFlag(HValue::kCanOverflow)); 1645 DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
1646 LOperand* left = UseRegisterAtStart(instr->left()); 1646 LOperand* left = UseRegisterAtStart(instr->left());
1647 LOperand* right = UseOrConstantAtStart(instr->right()); 1647 LOperand* right = UseOrConstantAtStart(instr->right());
1648 LAddI* add = new(zone()) LAddI(left, right); 1648 LAddI* add = new (zone()) LAddI(left, right);
1649 LInstruction* result = DefineAsRegister(add); 1649 LInstruction* result = DefineAsRegister(add);
1650 return result; 1650 return result;
1651 } else if (instr->representation().IsDouble()) { 1651 } else if (instr->representation().IsDouble()) {
1652 if (instr->left()->IsMul() && instr->left()->HasOneUse()) { 1652 if (instr->left()->IsMul() && instr->left()->HasOneUse()) {
1653 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right()); 1653 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
1654 } 1654 }
1655 1655
1656 if (instr->right()->IsMul() && instr->right()->HasOneUse()) { 1656 if (instr->right()->IsMul() && instr->right()->HasOneUse()) {
1657 DCHECK(!instr->left()->IsMul() || !instr->left()->HasOneUse()); 1657 DCHECK(!instr->left()->IsMul() || !instr->left()->HasOneUse());
1658 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left()); 1658 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left());
(...skipping 14 matching lines...) Expand all
1673 DCHECK(instr->right()->representation().Equals(instr->representation())); 1673 DCHECK(instr->right()->representation().Equals(instr->representation()));
1674 left = UseRegisterAtStart(instr->BetterLeftOperand()); 1674 left = UseRegisterAtStart(instr->BetterLeftOperand());
1675 right = UseOrConstantAtStart(instr->BetterRightOperand()); 1675 right = UseOrConstantAtStart(instr->BetterRightOperand());
1676 } else { 1676 } else {
1677 DCHECK(instr->representation().IsDouble()); 1677 DCHECK(instr->representation().IsDouble());
1678 DCHECK(instr->left()->representation().IsDouble()); 1678 DCHECK(instr->left()->representation().IsDouble());
1679 DCHECK(instr->right()->representation().IsDouble()); 1679 DCHECK(instr->right()->representation().IsDouble());
1680 left = UseRegisterAtStart(instr->left()); 1680 left = UseRegisterAtStart(instr->left());
1681 right = UseRegisterAtStart(instr->right()); 1681 right = UseRegisterAtStart(instr->right());
1682 } 1682 }
1683 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); 1683 return DefineAsRegister(new (zone()) LMathMinMax(left, right));
1684 } 1684 }
1685 1685
1686 1686
1687 LInstruction* LChunkBuilder::DoPower(HPower* instr) { 1687 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1688 DCHECK(instr->representation().IsDouble()); 1688 DCHECK(instr->representation().IsDouble());
1689 // We call a C function for double power. It can't trigger a GC. 1689 // We call a C function for double power. It can't trigger a GC.
1690 // We need to use fixed result register for the call. 1690 // We need to use fixed result register for the call.
1691 Representation exponent_type = instr->right()->representation(); 1691 Representation exponent_type = instr->right()->representation();
1692 DCHECK(instr->left()->representation().IsDouble()); 1692 DCHECK(instr->left()->representation().IsDouble());
1693 LOperand* left = UseFixedDouble(instr->left(), d0); 1693 LOperand* left = UseFixedDouble(instr->left(), d1);
1694 LOperand* right = 1694 LOperand* right =
1695 exponent_type.IsDouble() 1695 exponent_type.IsDouble()
1696 ? UseFixedDouble(instr->right(), d1) 1696 ? UseFixedDouble(instr->right(), d2)
1697 : UseFixed(instr->right(), MathPowTaggedDescriptor::exponent()); 1697 : UseFixed(instr->right(), MathPowTaggedDescriptor::exponent());
1698 LPower* result = new(zone()) LPower(left, right); 1698 LPower* result = new (zone()) LPower(left, right);
1699 return MarkAsCall(DefineFixedDouble(result, d2), 1699 return MarkAsCall(DefineFixedDouble(result, d3), instr,
1700 instr,
1701 CAN_DEOPTIMIZE_EAGERLY); 1700 CAN_DEOPTIMIZE_EAGERLY);
1702 } 1701 }
1703 1702
1704 1703
1705 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { 1704 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1706 DCHECK(instr->left()->representation().IsTagged()); 1705 DCHECK(instr->left()->representation().IsTagged());
1707 DCHECK(instr->right()->representation().IsTagged()); 1706 DCHECK(instr->right()->representation().IsTagged());
1708 LOperand* context = UseFixed(instr->context(), cp); 1707 LOperand* context = UseFixed(instr->context(), cp);
1709 LOperand* left = UseFixed(instr->left(), r1); 1708 LOperand* left = UseFixed(instr->left(), r4);
1710 LOperand* right = UseFixed(instr->right(), r0); 1709 LOperand* right = UseFixed(instr->right(), r3);
1711 LCmpT* result = new(zone()) LCmpT(context, left, right); 1710 LCmpT* result = new (zone()) LCmpT(context, left, right);
1712 return MarkAsCall(DefineFixed(result, r0), instr); 1711 return MarkAsCall(DefineFixed(result, r3), instr);
1713 } 1712 }
1714 1713
1715 1714
1716 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( 1715 LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
1717 HCompareNumericAndBranch* instr) { 1716 HCompareNumericAndBranch* instr) {
1718 Representation r = instr->representation(); 1717 Representation r = instr->representation();
1719 if (r.IsSmiOrInteger32()) { 1718 if (r.IsSmiOrInteger32()) {
1720 DCHECK(instr->left()->representation().Equals(r)); 1719 DCHECK(instr->left()->representation().Equals(r));
1721 DCHECK(instr->right()->representation().Equals(r)); 1720 DCHECK(instr->right()->representation().Equals(r));
1722 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); 1721 LOperand* left = UseRegisterOrConstantAtStart(instr->left());
1723 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); 1722 LOperand* right = UseRegisterOrConstantAtStart(instr->right());
1724 return new(zone()) LCompareNumericAndBranch(left, right); 1723 return new (zone()) LCompareNumericAndBranch(left, right);
1725 } else { 1724 } else {
1726 DCHECK(r.IsDouble()); 1725 DCHECK(r.IsDouble());
1727 DCHECK(instr->left()->representation().IsDouble()); 1726 DCHECK(instr->left()->representation().IsDouble());
1728 DCHECK(instr->right()->representation().IsDouble()); 1727 DCHECK(instr->right()->representation().IsDouble());
1729 LOperand* left = UseRegisterAtStart(instr->left()); 1728 LOperand* left = UseRegisterAtStart(instr->left());
1730 LOperand* right = UseRegisterAtStart(instr->right()); 1729 LOperand* right = UseRegisterAtStart(instr->right());
1731 return new(zone()) LCompareNumericAndBranch(left, right); 1730 return new (zone()) LCompareNumericAndBranch(left, right);
1732 } 1731 }
1733 } 1732 }
1734 1733
1735 1734
1736 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( 1735 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
1737 HCompareObjectEqAndBranch* instr) { 1736 HCompareObjectEqAndBranch* instr) {
1738 LOperand* left = UseRegisterAtStart(instr->left()); 1737 LOperand* left = UseRegisterAtStart(instr->left());
1739 LOperand* right = UseRegisterAtStart(instr->right()); 1738 LOperand* right = UseRegisterAtStart(instr->right());
1740 return new(zone()) LCmpObjectEqAndBranch(left, right); 1739 return new (zone()) LCmpObjectEqAndBranch(left, right);
1741 } 1740 }
1742 1741
1743 1742
1744 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( 1743 LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
1745 HCompareHoleAndBranch* instr) { 1744 HCompareHoleAndBranch* instr) {
1746 LOperand* value = UseRegisterAtStart(instr->value()); 1745 LOperand* value = UseRegisterAtStart(instr->value());
1747 return new(zone()) LCmpHoleAndBranch(value); 1746 return new (zone()) LCmpHoleAndBranch(value);
1748 } 1747 }
1749 1748
1750 1749
1751 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( 1750 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
1752 HCompareMinusZeroAndBranch* instr) { 1751 HCompareMinusZeroAndBranch* instr) {
1753 LOperand* value = UseRegister(instr->value()); 1752 LOperand* value = UseRegister(instr->value());
1754 LOperand* scratch = TempRegister(); 1753 LOperand* scratch = TempRegister();
1755 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); 1754 return new (zone()) LCompareMinusZeroAndBranch(value, scratch);
1756 } 1755 }
1757 1756
1758 1757
1759 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { 1758 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1760 DCHECK(instr->value()->representation().IsTagged()); 1759 DCHECK(instr->value()->representation().IsTagged());
1761 LOperand* value = UseRegisterAtStart(instr->value()); 1760 LOperand* value = UseRegisterAtStart(instr->value());
1762 LOperand* temp = TempRegister(); 1761 LOperand* temp = TempRegister();
1763 return new(zone()) LIsObjectAndBranch(value, temp); 1762 return new (zone()) LIsObjectAndBranch(value, temp);
1764 } 1763 }
1765 1764
1766 1765
1767 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { 1766 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1768 DCHECK(instr->value()->representation().IsTagged()); 1767 DCHECK(instr->value()->representation().IsTagged());
1769 LOperand* value = UseRegisterAtStart(instr->value()); 1768 LOperand* value = UseRegisterAtStart(instr->value());
1770 LOperand* temp = TempRegister(); 1769 LOperand* temp = TempRegister();
1771 return new(zone()) LIsStringAndBranch(value, temp); 1770 return new (zone()) LIsStringAndBranch(value, temp);
1772 } 1771 }
1773 1772
1774 1773
1775 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { 1774 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1776 DCHECK(instr->value()->representation().IsTagged()); 1775 DCHECK(instr->value()->representation().IsTagged());
1777 return new(zone()) LIsSmiAndBranch(Use(instr->value())); 1776 return new (zone()) LIsSmiAndBranch(Use(instr->value()));
1778 } 1777 }
1779 1778
1780 1779
1781 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( 1780 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
1782 HIsUndetectableAndBranch* instr) { 1781 HIsUndetectableAndBranch* instr) {
1783 DCHECK(instr->value()->representation().IsTagged()); 1782 DCHECK(instr->value()->representation().IsTagged());
1784 LOperand* value = UseRegisterAtStart(instr->value()); 1783 LOperand* value = UseRegisterAtStart(instr->value());
1785 return new(zone()) LIsUndetectableAndBranch(value, TempRegister()); 1784 return new (zone()) LIsUndetectableAndBranch(value, TempRegister());
1786 } 1785 }
1787 1786
1788 1787
1789 LInstruction* LChunkBuilder::DoStringCompareAndBranch( 1788 LInstruction* LChunkBuilder::DoStringCompareAndBranch(
1790 HStringCompareAndBranch* instr) { 1789 HStringCompareAndBranch* instr) {
1791 DCHECK(instr->left()->representation().IsTagged()); 1790 DCHECK(instr->left()->representation().IsTagged());
1792 DCHECK(instr->right()->representation().IsTagged()); 1791 DCHECK(instr->right()->representation().IsTagged());
1793 LOperand* context = UseFixed(instr->context(), cp); 1792 LOperand* context = UseFixed(instr->context(), cp);
1794 LOperand* left = UseFixed(instr->left(), r1); 1793 LOperand* left = UseFixed(instr->left(), r4);
1795 LOperand* right = UseFixed(instr->right(), r0); 1794 LOperand* right = UseFixed(instr->right(), r3);
1796 LStringCompareAndBranch* result = 1795 LStringCompareAndBranch* result =
1797 new(zone()) LStringCompareAndBranch(context, left, right); 1796 new (zone()) LStringCompareAndBranch(context, left, right);
1798 return MarkAsCall(result, instr); 1797 return MarkAsCall(result, instr);
1799 } 1798 }
1800 1799
1801 1800
1802 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( 1801 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
1803 HHasInstanceTypeAndBranch* instr) { 1802 HHasInstanceTypeAndBranch* instr) {
1804 DCHECK(instr->value()->representation().IsTagged()); 1803 DCHECK(instr->value()->representation().IsTagged());
1805 LOperand* value = UseRegisterAtStart(instr->value()); 1804 LOperand* value = UseRegisterAtStart(instr->value());
1806 return new(zone()) LHasInstanceTypeAndBranch(value); 1805 return new (zone()) LHasInstanceTypeAndBranch(value);
1807 } 1806 }
1808 1807
1809 1808
1810 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( 1809 LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1811 HGetCachedArrayIndex* instr) { 1810 HGetCachedArrayIndex* instr) {
1812 DCHECK(instr->value()->representation().IsTagged()); 1811 DCHECK(instr->value()->representation().IsTagged());
1813 LOperand* value = UseRegisterAtStart(instr->value()); 1812 LOperand* value = UseRegisterAtStart(instr->value());
1814 1813
1815 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); 1814 return DefineAsRegister(new (zone()) LGetCachedArrayIndex(value));
1816 } 1815 }
1817 1816
1818 1817
1819 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( 1818 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
1820 HHasCachedArrayIndexAndBranch* instr) { 1819 HHasCachedArrayIndexAndBranch* instr) {
1821 DCHECK(instr->value()->representation().IsTagged()); 1820 DCHECK(instr->value()->representation().IsTagged());
1822 return new(zone()) LHasCachedArrayIndexAndBranch( 1821 return new (zone())
1823 UseRegisterAtStart(instr->value())); 1822 LHasCachedArrayIndexAndBranch(UseRegisterAtStart(instr->value()));
1824 } 1823 }
1825 1824
1826 1825
1827 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( 1826 LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
1828 HClassOfTestAndBranch* instr) { 1827 HClassOfTestAndBranch* instr) {
1829 DCHECK(instr->value()->representation().IsTagged()); 1828 DCHECK(instr->value()->representation().IsTagged());
1830 LOperand* value = UseRegister(instr->value()); 1829 LOperand* value = UseRegister(instr->value());
1831 return new(zone()) LClassOfTestAndBranch(value, TempRegister()); 1830 return new (zone()) LClassOfTestAndBranch(value, TempRegister());
1832 } 1831 }
1833 1832
1834 1833
1835 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { 1834 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
1836 LOperand* map = UseRegisterAtStart(instr->value()); 1835 LOperand* map = UseRegisterAtStart(instr->value());
1837 return DefineAsRegister(new(zone()) LMapEnumLength(map)); 1836 return DefineAsRegister(new (zone()) LMapEnumLength(map));
1838 } 1837 }
1839 1838
1840 1839
1841 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { 1840 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
1842 LOperand* object = UseFixed(instr->value(), r0); 1841 LOperand* object = UseFixed(instr->value(), r3);
1843 LDateField* result = 1842 LDateField* result =
1844 new(zone()) LDateField(object, FixedTemp(r1), instr->index()); 1843 new (zone()) LDateField(object, FixedTemp(r4), instr->index());
1845 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 1844 return MarkAsCall(DefineFixed(result, r3), instr, CAN_DEOPTIMIZE_EAGERLY);
1846 } 1845 }
1847 1846
1848 1847
1849 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) { 1848 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
1850 LOperand* string = UseRegisterAtStart(instr->string()); 1849 LOperand* string = UseRegisterAtStart(instr->string());
1851 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); 1850 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1852 return DefineAsRegister(new(zone()) LSeqStringGetChar(string, index)); 1851 return DefineAsRegister(new (zone()) LSeqStringGetChar(string, index));
1853 } 1852 }
1854 1853
1855 1854
1856 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { 1855 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
1857 LOperand* string = UseRegisterAtStart(instr->string()); 1856 LOperand* string = UseRegisterAtStart(instr->string());
1858 LOperand* index = FLAG_debug_code 1857 LOperand* index = FLAG_debug_code
1859 ? UseRegisterAtStart(instr->index()) 1858 ? UseRegisterAtStart(instr->index())
1860 : UseRegisterOrConstantAtStart(instr->index()); 1859 : UseRegisterOrConstantAtStart(instr->index());
1861 LOperand* value = UseRegisterAtStart(instr->value()); 1860 LOperand* value = UseRegisterAtStart(instr->value());
1862 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL; 1861 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL;
1863 return new(zone()) LSeqStringSetChar(context, string, index, value); 1862 return new (zone()) LSeqStringSetChar(context, string, index, value);
1864 } 1863 }
1865 1864
1866 1865
1867 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1866 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1868 if (!FLAG_debug_code && instr->skip_check()) return NULL; 1867 if (!FLAG_debug_code && instr->skip_check()) return NULL;
1869 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); 1868 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1870 LOperand* length = !index->IsConstantOperand() 1869 LOperand* length = !index->IsConstantOperand()
1871 ? UseRegisterOrConstantAtStart(instr->length()) 1870 ? UseRegisterOrConstantAtStart(instr->length())
1872 : UseRegisterAtStart(instr->length()); 1871 : UseRegisterAtStart(instr->length());
1873 LInstruction* result = new(zone()) LBoundsCheck(index, length); 1872 LInstruction* result = new (zone()) LBoundsCheck(index, length);
1874 if (!FLAG_debug_code || !instr->skip_check()) { 1873 if (!FLAG_debug_code || !instr->skip_check()) {
1875 result = AssignEnvironment(result); 1874 result = AssignEnvironment(result);
1876 } 1875 }
1877 return result; 1876 return result;
1878 } 1877 }
1879 1878
1880 1879
1881 LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation( 1880 LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation(
1882 HBoundsCheckBaseIndexInformation* instr) { 1881 HBoundsCheckBaseIndexInformation* instr) {
1883 UNREACHABLE(); 1882 UNREACHABLE();
1884 return NULL; 1883 return NULL;
1885 } 1884 }
1886 1885
1887 1886
1888 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { 1887 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1889 // The control instruction marking the end of a block that completed 1888 // The control instruction marking the end of a block that completed
1890 // abruptly (e.g., threw an exception). There is nothing specific to do. 1889 // abruptly (e.g., threw an exception). There is nothing specific to do.
1891 return NULL; 1890 return NULL;
1892 } 1891 }
1893 1892
1894 1893
1895 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { 1894 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { return NULL; }
1896 return NULL;
1897 }
1898 1895
1899 1896
1900 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { 1897 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
1901 // All HForceRepresentation instructions should be eliminated in the 1898 // All HForceRepresentation instructions should be eliminated in the
1902 // representation change phase of Hydrogen. 1899 // representation change phase of Hydrogen.
1903 UNREACHABLE(); 1900 UNREACHABLE();
1904 return NULL; 1901 return NULL;
1905 } 1902 }
1906 1903
1907 1904
1908 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1905 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1909 Representation from = instr->from(); 1906 Representation from = instr->from();
1910 Representation to = instr->to(); 1907 Representation to = instr->to();
1911 HValue* val = instr->value(); 1908 HValue* val = instr->value();
1912 if (from.IsSmi()) { 1909 if (from.IsSmi()) {
1913 if (to.IsTagged()) { 1910 if (to.IsTagged()) {
1914 LOperand* value = UseRegister(val); 1911 LOperand* value = UseRegister(val);
1915 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1912 return DefineSameAsFirst(new (zone()) LDummyUse(value));
1916 } 1913 }
1917 from = Representation::Tagged(); 1914 from = Representation::Tagged();
1918 } 1915 }
1919 if (from.IsTagged()) { 1916 if (from.IsTagged()) {
1920 if (to.IsDouble()) { 1917 if (to.IsDouble()) {
1921 LOperand* value = UseRegister(val); 1918 LOperand* value = UseRegister(val);
1922 LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value)); 1919 LInstruction* result =
1920 DefineAsRegister(new (zone()) LNumberUntagD(value));
1923 if (!val->representation().IsSmi()) result = AssignEnvironment(result); 1921 if (!val->representation().IsSmi()) result = AssignEnvironment(result);
1924 return result; 1922 return result;
1925 } else if (to.IsSmi()) { 1923 } else if (to.IsSmi()) {
1926 LOperand* value = UseRegister(val); 1924 LOperand* value = UseRegister(val);
1927 if (val->type().IsSmi()) { 1925 if (val->type().IsSmi()) {
1928 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1926 return DefineSameAsFirst(new (zone()) LDummyUse(value));
1929 } 1927 }
1930 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); 1928 return AssignEnvironment(
1929 DefineSameAsFirst(new (zone()) LCheckSmi(value)));
1931 } else { 1930 } else {
1932 DCHECK(to.IsInteger32()); 1931 DCHECK(to.IsInteger32());
1933 if (val->type().IsSmi() || val->representation().IsSmi()) { 1932 if (val->type().IsSmi() || val->representation().IsSmi()) {
1934 LOperand* value = UseRegisterAtStart(val); 1933 LOperand* value = UseRegisterAtStart(val);
1935 return DefineAsRegister(new(zone()) LSmiUntag(value, false)); 1934 return DefineAsRegister(new (zone()) LSmiUntag(value, false));
1936 } else { 1935 } else {
1937 LOperand* value = UseRegister(val); 1936 LOperand* value = UseRegister(val);
1938 LOperand* temp1 = TempRegister(); 1937 LOperand* temp1 = TempRegister();
1939 LOperand* temp2 = TempDoubleRegister(); 1938 LOperand* temp2 = TempDoubleRegister();
1940 LInstruction* result = 1939 LInstruction* result =
1941 DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2)); 1940 DefineSameAsFirst(new (zone()) LTaggedToI(value, temp1, temp2));
1942 if (!val->representation().IsSmi()) result = AssignEnvironment(result); 1941 if (!val->representation().IsSmi()) result = AssignEnvironment(result);
1943 return result; 1942 return result;
1944 } 1943 }
1945 } 1944 }
1946 } else if (from.IsDouble()) { 1945 } else if (from.IsDouble()) {
1947 if (to.IsTagged()) { 1946 if (to.IsTagged()) {
1948 info()->MarkAsDeferredCalling(); 1947 info()->MarkAsDeferredCalling();
1949 LOperand* value = UseRegister(val); 1948 LOperand* value = UseRegister(val);
1950 LOperand* temp1 = TempRegister(); 1949 LOperand* temp1 = TempRegister();
1951 LOperand* temp2 = TempRegister(); 1950 LOperand* temp2 = TempRegister();
1952 LUnallocated* result_temp = TempRegister(); 1951 LUnallocated* result_temp = TempRegister();
1953 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); 1952 LNumberTagD* result = new (zone()) LNumberTagD(value, temp1, temp2);
1954 return AssignPointerMap(Define(result, result_temp)); 1953 return AssignPointerMap(Define(result, result_temp));
1955 } else if (to.IsSmi()) { 1954 } else if (to.IsSmi()) {
1956 LOperand* value = UseRegister(val); 1955 LOperand* value = UseRegister(val);
1957 return AssignEnvironment( 1956 return AssignEnvironment(
1958 DefineAsRegister(new(zone()) LDoubleToSmi(value))); 1957 DefineAsRegister(new (zone()) LDoubleToSmi(value)));
1959 } else { 1958 } else {
1960 DCHECK(to.IsInteger32()); 1959 DCHECK(to.IsInteger32());
1961 LOperand* value = UseRegister(val); 1960 LOperand* value = UseRegister(val);
1962 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value)); 1961 LInstruction* result = DefineAsRegister(new (zone()) LDoubleToI(value));
1963 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result); 1962 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
1964 return result; 1963 return result;
1965 } 1964 }
1966 } else if (from.IsInteger32()) { 1965 } else if (from.IsInteger32()) {
1967 info()->MarkAsDeferredCalling(); 1966 info()->MarkAsDeferredCalling();
1968 if (to.IsTagged()) { 1967 if (to.IsTagged()) {
1969 if (!instr->CheckFlag(HValue::kCanOverflow)) { 1968 if (!instr->CheckFlag(HValue::kCanOverflow)) {
1970 LOperand* value = UseRegisterAtStart(val); 1969 LOperand* value = UseRegisterAtStart(val);
1971 return DefineAsRegister(new(zone()) LSmiTag(value)); 1970 return DefineAsRegister(new (zone()) LSmiTag(value));
1972 } else if (val->CheckFlag(HInstruction::kUint32)) { 1971 } else if (val->CheckFlag(HInstruction::kUint32)) {
1973 LOperand* value = UseRegisterAtStart(val); 1972 LOperand* value = UseRegisterAtStart(val);
1974 LOperand* temp1 = TempRegister(); 1973 LOperand* temp1 = TempRegister();
1975 LOperand* temp2 = TempRegister(); 1974 LOperand* temp2 = TempRegister();
1976 LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2); 1975 LNumberTagU* result = new (zone()) LNumberTagU(value, temp1, temp2);
1977 return AssignPointerMap(DefineAsRegister(result)); 1976 return AssignPointerMap(DefineAsRegister(result));
1978 } else { 1977 } else {
1979 LOperand* value = UseRegisterAtStart(val); 1978 LOperand* value = UseRegisterAtStart(val);
1980 LOperand* temp1 = TempRegister(); 1979 LOperand* temp1 = TempRegister();
1981 LOperand* temp2 = TempRegister(); 1980 LOperand* temp2 = TempRegister();
1982 LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2); 1981 LNumberTagI* result = new (zone()) LNumberTagI(value, temp1, temp2);
1983 return AssignPointerMap(DefineAsRegister(result)); 1982 return AssignPointerMap(DefineAsRegister(result));
1984 } 1983 }
1985 } else if (to.IsSmi()) { 1984 } else if (to.IsSmi()) {
1986 LOperand* value = UseRegister(val); 1985 LOperand* value = UseRegister(val);
1987 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); 1986 LInstruction* result = DefineAsRegister(new (zone()) LSmiTag(value));
1988 if (instr->CheckFlag(HValue::kCanOverflow)) { 1987 if (instr->CheckFlag(HValue::kCanOverflow)) {
1989 result = AssignEnvironment(result); 1988 result = AssignEnvironment(result);
1990 } 1989 }
1991 return result; 1990 return result;
1992 } else { 1991 } else {
1993 DCHECK(to.IsDouble()); 1992 DCHECK(to.IsDouble());
1994 if (val->CheckFlag(HInstruction::kUint32)) { 1993 if (val->CheckFlag(HInstruction::kUint32)) {
1995 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); 1994 return DefineAsRegister(new (zone()) LUint32ToDouble(UseRegister(val)));
1996 } else { 1995 } else {
1997 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val))); 1996 return DefineAsRegister(new (zone()) LInteger32ToDouble(Use(val)));
1998 } 1997 }
1999 } 1998 }
2000 } 1999 }
2001 UNREACHABLE(); 2000 UNREACHABLE();
2002 return NULL; 2001 return NULL;
2003 } 2002 }
2004 2003
2005 2004
2006 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { 2005 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
2007 LOperand* value = UseRegisterAtStart(instr->value()); 2006 LOperand* value = UseRegisterAtStart(instr->value());
2008 LInstruction* result = new(zone()) LCheckNonSmi(value); 2007 LInstruction* result = new (zone()) LCheckNonSmi(value);
2009 if (!instr->value()->type().IsHeapObject()) { 2008 if (!instr->value()->type().IsHeapObject()) {
2010 result = AssignEnvironment(result); 2009 result = AssignEnvironment(result);
2011 } 2010 }
2012 return result; 2011 return result;
2013 } 2012 }
2014 2013
2015 2014
2016 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { 2015 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
2017 LOperand* value = UseRegisterAtStart(instr->value()); 2016 LOperand* value = UseRegisterAtStart(instr->value());
2018 return AssignEnvironment(new(zone()) LCheckSmi(value)); 2017 return AssignEnvironment(new (zone()) LCheckSmi(value));
2019 } 2018 }
2020 2019
2021 2020
2022 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { 2021 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
2023 LOperand* value = UseRegisterAtStart(instr->value()); 2022 LOperand* value = UseRegisterAtStart(instr->value());
2024 LInstruction* result = new(zone()) LCheckInstanceType(value); 2023 LInstruction* result = new (zone()) LCheckInstanceType(value);
2025 return AssignEnvironment(result); 2024 return AssignEnvironment(result);
2026 } 2025 }
2027 2026
2028 2027
2029 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) { 2028 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
2030 LOperand* value = UseRegisterAtStart(instr->value()); 2029 LOperand* value = UseRegisterAtStart(instr->value());
2031 return AssignEnvironment(new(zone()) LCheckValue(value)); 2030 return AssignEnvironment(new (zone()) LCheckValue(value));
2032 } 2031 }
2033 2032
2034 2033
2035 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { 2034 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
2036 if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps; 2035 if (instr->IsStabilityCheck()) return new (zone()) LCheckMaps;
2037 LOperand* value = UseRegisterAtStart(instr->value()); 2036 LOperand* value = UseRegisterAtStart(instr->value());
2038 LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value)); 2037 LInstruction* result = AssignEnvironment(new (zone()) LCheckMaps(value));
2039 if (instr->HasMigrationTarget()) { 2038 if (instr->HasMigrationTarget()) {
2040 info()->MarkAsDeferredCalling(); 2039 info()->MarkAsDeferredCalling();
2041 result = AssignPointerMap(result); 2040 result = AssignPointerMap(result);
2042 } 2041 }
2043 return result; 2042 return result;
2044 } 2043 }
2045 2044
2046 2045
2047 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { 2046 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
2048 HValue* value = instr->value(); 2047 HValue* value = instr->value();
2049 Representation input_rep = value->representation(); 2048 Representation input_rep = value->representation();
2050 LOperand* reg = UseRegister(value); 2049 LOperand* reg = UseRegister(value);
2051 if (input_rep.IsDouble()) { 2050 if (input_rep.IsDouble()) {
2052 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); 2051 return DefineAsRegister(new (zone()) LClampDToUint8(reg));
2053 } else if (input_rep.IsInteger32()) { 2052 } else if (input_rep.IsInteger32()) {
2054 return DefineAsRegister(new(zone()) LClampIToUint8(reg)); 2053 return DefineAsRegister(new (zone()) LClampIToUint8(reg));
2055 } else { 2054 } else {
2056 DCHECK(input_rep.IsSmiOrTagged()); 2055 DCHECK(input_rep.IsSmiOrTagged());
2057 // Register allocator doesn't (yet) support allocation of double
2058 // temps. Reserve d1 explicitly.
2059 LClampTToUint8* result = 2056 LClampTToUint8* result =
2060 new(zone()) LClampTToUint8(reg, TempDoubleRegister()); 2057 new (zone()) LClampTToUint8(reg, TempDoubleRegister());
2061 return AssignEnvironment(DefineAsRegister(result)); 2058 return AssignEnvironment(DefineAsRegister(result));
2062 } 2059 }
2063 } 2060 }
2064 2061
2065 2062
2066 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { 2063 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
2067 HValue* value = instr->value(); 2064 HValue* value = instr->value();
2068 DCHECK(value->representation().IsDouble()); 2065 DCHECK(value->representation().IsDouble());
2069 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); 2066 return DefineAsRegister(new (zone()) LDoubleBits(UseRegister(value)));
2070 } 2067 }
2071 2068
2072 2069
2073 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { 2070 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
2074 LOperand* lo = UseRegister(instr->lo()); 2071 LOperand* lo = UseRegister(instr->lo());
2075 LOperand* hi = UseRegister(instr->hi()); 2072 LOperand* hi = UseRegister(instr->hi());
2076 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); 2073 return DefineAsRegister(new (zone()) LConstructDouble(hi, lo));
2077 } 2074 }
2078 2075
2079 2076
2080 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 2077 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
2081 LOperand* context = info()->IsStub() 2078 LOperand* context = info()->IsStub() ? UseFixed(instr->context(), cp) : NULL;
2082 ? UseFixed(instr->context(), cp)
2083 : NULL;
2084 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); 2079 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
2085 return new(zone()) LReturn(UseFixed(instr->value(), r0), context, 2080 return new (zone())
2086 parameter_count); 2081 LReturn(UseFixed(instr->value(), r3), context, parameter_count);
2087 } 2082 }
2088 2083
2089 2084
2090 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 2085 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
2091 Representation r = instr->representation(); 2086 Representation r = instr->representation();
2092 if (r.IsSmi()) { 2087 if (r.IsSmi()) {
2093 return DefineAsRegister(new(zone()) LConstantS); 2088 return DefineAsRegister(new (zone()) LConstantS);
2094 } else if (r.IsInteger32()) { 2089 } else if (r.IsInteger32()) {
2095 return DefineAsRegister(new(zone()) LConstantI); 2090 return DefineAsRegister(new (zone()) LConstantI);
2096 } else if (r.IsDouble()) { 2091 } else if (r.IsDouble()) {
2097 return DefineAsRegister(new(zone()) LConstantD); 2092 return DefineAsRegister(new (zone()) LConstantD);
2098 } else if (r.IsExternal()) { 2093 } else if (r.IsExternal()) {
2099 return DefineAsRegister(new(zone()) LConstantE); 2094 return DefineAsRegister(new (zone()) LConstantE);
2100 } else if (r.IsTagged()) { 2095 } else if (r.IsTagged()) {
2101 return DefineAsRegister(new(zone()) LConstantT); 2096 return DefineAsRegister(new (zone()) LConstantT);
2102 } else { 2097 } else {
2103 UNREACHABLE(); 2098 UNREACHABLE();
2104 return NULL; 2099 return NULL;
2105 } 2100 }
2106 } 2101 }
2107 2102
2108 2103
2109 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { 2104 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
2110 LLoadGlobalCell* result = new(zone()) LLoadGlobalCell; 2105 LLoadGlobalCell* result = new (zone()) LLoadGlobalCell;
2111 return instr->RequiresHoleCheck() 2106 return instr->RequiresHoleCheck()
2112 ? AssignEnvironment(DefineAsRegister(result)) 2107 ? AssignEnvironment(DefineAsRegister(result))
2113 : DefineAsRegister(result); 2108 : DefineAsRegister(result);
2114 } 2109 }
2115 2110
2116 2111
2117 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { 2112 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
2118 LOperand* context = UseFixed(instr->context(), cp); 2113 LOperand* context = UseFixed(instr->context(), cp);
2119 LOperand* global_object = 2114 LOperand* global_object =
2120 UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister()); 2115 UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
2121 LOperand* vector = NULL; 2116 LOperand* vector = NULL;
2122 if (FLAG_vector_ics) { 2117 if (FLAG_vector_ics) {
2123 vector = FixedTemp(VectorLoadICDescriptor::VectorRegister()); 2118 vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
2124 } 2119 }
2125 LLoadGlobalGeneric* result = 2120 LLoadGlobalGeneric* result =
2126 new(zone()) LLoadGlobalGeneric(context, global_object, vector); 2121 new (zone()) LLoadGlobalGeneric(context, global_object, vector);
2127 return MarkAsCall(DefineFixed(result, r0), instr); 2122 return MarkAsCall(DefineFixed(result, r3), instr);
2128 } 2123 }
2129 2124
2130 2125
2131 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { 2126 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
2132 LOperand* value = UseRegister(instr->value()); 2127 LOperand* value = UseRegister(instr->value());
2133 // Use a temp to check the value in the cell in the case where we perform 2128 // Use a temp to check the value in the cell in the case where we perform
2134 // a hole check. 2129 // a hole check.
2135 return instr->RequiresHoleCheck() 2130 return instr->RequiresHoleCheck()
2136 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) 2131 ? AssignEnvironment(new (zone())
2137 : new(zone()) LStoreGlobalCell(value, NULL); 2132 LStoreGlobalCell(value, TempRegister()))
2133 : new (zone()) LStoreGlobalCell(value, NULL);
2138 } 2134 }
2139 2135
2140 2136
2141 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 2137 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
2142 LOperand* context = UseRegisterAtStart(instr->value()); 2138 LOperand* context = UseRegisterAtStart(instr->value());
2143 LInstruction* result = 2139 LInstruction* result =
2144 DefineAsRegister(new(zone()) LLoadContextSlot(context)); 2140 DefineAsRegister(new (zone()) LLoadContextSlot(context));
2145 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) { 2141 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2146 result = AssignEnvironment(result); 2142 result = AssignEnvironment(result);
2147 } 2143 }
2148 return result; 2144 return result;
2149 } 2145 }
2150 2146
2151 2147
2152 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { 2148 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2153 LOperand* context; 2149 LOperand* context;
2154 LOperand* value; 2150 LOperand* value;
2155 if (instr->NeedsWriteBarrier()) { 2151 if (instr->NeedsWriteBarrier()) {
2156 context = UseTempRegister(instr->context()); 2152 context = UseTempRegister(instr->context());
2157 value = UseTempRegister(instr->value()); 2153 value = UseTempRegister(instr->value());
2158 } else { 2154 } else {
2159 context = UseRegister(instr->context()); 2155 context = UseRegister(instr->context());
2160 value = UseRegister(instr->value()); 2156 value = UseRegister(instr->value());
2161 } 2157 }
2162 LInstruction* result = new(zone()) LStoreContextSlot(context, value); 2158 LInstruction* result = new (zone()) LStoreContextSlot(context, value);
2163 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) { 2159 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2164 result = AssignEnvironment(result); 2160 result = AssignEnvironment(result);
2165 } 2161 }
2166 return result; 2162 return result;
2167 } 2163 }
2168 2164
2169 2165
2170 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 2166 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2171 LOperand* obj = UseRegisterAtStart(instr->object()); 2167 LOperand* obj = UseRegisterAtStart(instr->object());
2172 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); 2168 return DefineAsRegister(new (zone()) LLoadNamedField(obj));
2173 } 2169 }
2174 2170
2175 2171
2176 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { 2172 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
2177 LOperand* context = UseFixed(instr->context(), cp); 2173 LOperand* context = UseFixed(instr->context(), cp);
2178 LOperand* object = 2174 LOperand* object =
2179 UseFixed(instr->object(), LoadDescriptor::ReceiverRegister()); 2175 UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
2180 LOperand* vector = NULL; 2176 LOperand* vector = NULL;
2181 if (FLAG_vector_ics) { 2177 if (FLAG_vector_ics) {
2182 vector = FixedTemp(VectorLoadICDescriptor::VectorRegister()); 2178 vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
2183 } 2179 }
2184 2180
2185 LInstruction* result = 2181 LInstruction* result =
2186 DefineFixed(new(zone()) LLoadNamedGeneric(context, object, vector), r0); 2182 DefineFixed(new (zone()) LLoadNamedGeneric(context, object, vector), r3);
2187 return MarkAsCall(result, instr); 2183 return MarkAsCall(result, instr);
2188 } 2184 }
2189 2185
2190 2186
2191 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( 2187 LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
2192 HLoadFunctionPrototype* instr) { 2188 HLoadFunctionPrototype* instr) {
2193 return AssignEnvironment(DefineAsRegister( 2189 return AssignEnvironment(DefineAsRegister(
2194 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); 2190 new (zone()) LLoadFunctionPrototype(UseRegister(instr->function()))));
2195 } 2191 }
2196 2192
2197 2193
2198 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { 2194 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2199 return DefineAsRegister(new(zone()) LLoadRoot); 2195 return DefineAsRegister(new (zone()) LLoadRoot);
2200 } 2196 }
2201 2197
2202 2198
2203 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { 2199 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2204 DCHECK(instr->key()->representation().IsSmiOrInteger32()); 2200 DCHECK(instr->key()->representation().IsSmiOrInteger32());
2205 ElementsKind elements_kind = instr->elements_kind(); 2201 ElementsKind elements_kind = instr->elements_kind();
2206 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2202 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2207 LInstruction* result = NULL; 2203 LInstruction* result = NULL;
2208 2204
2209 if (!instr->is_typed_elements()) { 2205 if (!instr->is_typed_elements()) {
2210 LOperand* obj = NULL; 2206 LOperand* obj = NULL;
2211 if (instr->representation().IsDouble()) { 2207 if (instr->representation().IsDouble()) {
2212 obj = UseRegister(instr->elements()); 2208 obj = UseRegister(instr->elements());
2213 } else { 2209 } else {
2214 DCHECK(instr->representation().IsSmiOrTagged());
2215 obj = UseRegisterAtStart(instr->elements()); 2210 obj = UseRegisterAtStart(instr->elements());
2216 } 2211 }
2217 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); 2212 result = DefineAsRegister(new (zone()) LLoadKeyed(obj, key));
2218 } else { 2213 } else {
2219 DCHECK( 2214 DCHECK((instr->representation().IsInteger32() &&
2220 (instr->representation().IsInteger32() && 2215 !IsDoubleOrFloatElementsKind(elements_kind)) ||
2221 !IsDoubleOrFloatElementsKind(elements_kind)) || 2216 (instr->representation().IsDouble() &&
2222 (instr->representation().IsDouble() && 2217 IsDoubleOrFloatElementsKind(elements_kind)));
2223 IsDoubleOrFloatElementsKind(elements_kind)));
2224 LOperand* backing_store = UseRegister(instr->elements()); 2218 LOperand* backing_store = UseRegister(instr->elements());
2225 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); 2219 result = DefineAsRegister(new (zone()) LLoadKeyed(backing_store, key));
2226 } 2220 }
2227 2221
2228 if ((instr->is_external() || instr->is_fixed_typed_array()) ? 2222 if ((instr->is_external() || instr->is_fixed_typed_array())
2229 // see LCodeGen::DoLoadKeyedExternalArray 2223 ?
2230 ((elements_kind == EXTERNAL_UINT32_ELEMENTS || 2224 // see LCodeGen::DoLoadKeyedExternalArray
2231 elements_kind == UINT32_ELEMENTS) && 2225 ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
2232 !instr->CheckFlag(HInstruction::kUint32)) : 2226 elements_kind == UINT32_ELEMENTS) &&
2233 // see LCodeGen::DoLoadKeyedFixedDoubleArray and 2227 !instr->CheckFlag(HInstruction::kUint32))
2234 // LCodeGen::DoLoadKeyedFixedArray 2228 :
2235 instr->RequiresHoleCheck()) { 2229 // see LCodeGen::DoLoadKeyedFixedDoubleArray and
2230 // LCodeGen::DoLoadKeyedFixedArray
2231 instr->RequiresHoleCheck()) {
2236 result = AssignEnvironment(result); 2232 result = AssignEnvironment(result);
2237 } 2233 }
2238 return result; 2234 return result;
2239 } 2235 }
2240 2236
2241 2237
2242 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 2238 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2243 LOperand* context = UseFixed(instr->context(), cp); 2239 LOperand* context = UseFixed(instr->context(), cp);
2244 LOperand* object = 2240 LOperand* object =
2245 UseFixed(instr->object(), LoadDescriptor::ReceiverRegister()); 2241 UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
2246 LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister()); 2242 LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
2247 LOperand* vector = NULL; 2243 LOperand* vector = NULL;
2248 if (FLAG_vector_ics) { 2244 if (FLAG_vector_ics) {
2249 vector = FixedTemp(VectorLoadICDescriptor::VectorRegister()); 2245 vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
2250 } 2246 }
2251 2247
2252 LInstruction* result = 2248 LInstruction* result = DefineFixed(
2253 DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key, vector), 2249 new (zone()) LLoadKeyedGeneric(context, object, key, vector), r3);
2254 r0);
2255 return MarkAsCall(result, instr); 2250 return MarkAsCall(result, instr);
2256 } 2251 }
2257 2252
2258 2253
2259 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { 2254 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2260 if (!instr->is_typed_elements()) { 2255 if (!instr->is_typed_elements()) {
2261 DCHECK(instr->elements()->representation().IsTagged()); 2256 DCHECK(instr->elements()->representation().IsTagged());
2262 bool needs_write_barrier = instr->NeedsWriteBarrier(); 2257 bool needs_write_barrier = instr->NeedsWriteBarrier();
2263 LOperand* object = NULL; 2258 LOperand* object = NULL;
2264 LOperand* key = NULL; 2259 LOperand* key = NULL;
2265 LOperand* val = NULL; 2260 LOperand* val = NULL;
2266 2261
2267 if (instr->value()->representation().IsDouble()) { 2262 if (instr->value()->representation().IsDouble()) {
2268 object = UseRegisterAtStart(instr->elements()); 2263 object = UseRegisterAtStart(instr->elements());
2269 val = UseRegister(instr->value()); 2264 val = UseRegister(instr->value());
2270 key = UseRegisterOrConstantAtStart(instr->key()); 2265 key = UseRegisterOrConstantAtStart(instr->key());
2271 } else { 2266 } else {
2272 DCHECK(instr->value()->representation().IsSmiOrTagged());
2273 if (needs_write_barrier) { 2267 if (needs_write_barrier) {
2274 object = UseTempRegister(instr->elements()); 2268 object = UseTempRegister(instr->elements());
2275 val = UseTempRegister(instr->value()); 2269 val = UseTempRegister(instr->value());
2276 key = UseTempRegister(instr->key()); 2270 key = UseTempRegister(instr->key());
2277 } else { 2271 } else {
2278 object = UseRegisterAtStart(instr->elements()); 2272 object = UseRegisterAtStart(instr->elements());
2279 val = UseRegisterAtStart(instr->value()); 2273 val = UseRegisterAtStart(instr->value());
2280 key = UseRegisterOrConstantAtStart(instr->key()); 2274 key = UseRegisterOrConstantAtStart(instr->key());
2281 } 2275 }
2282 } 2276 }
2283 2277
2284 return new(zone()) LStoreKeyed(object, key, val); 2278 return new (zone()) LStoreKeyed(object, key, val);
2285 } 2279 }
2286 2280
2287 DCHECK( 2281 DCHECK((instr->value()->representation().IsInteger32() &&
2288 (instr->value()->representation().IsInteger32() && 2282 !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
2289 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || 2283 (instr->value()->representation().IsDouble() &&
2290 (instr->value()->representation().IsDouble() && 2284 IsDoubleOrFloatElementsKind(instr->elements_kind())));
2291 IsDoubleOrFloatElementsKind(instr->elements_kind())));
2292 DCHECK((instr->is_fixed_typed_array() && 2285 DCHECK((instr->is_fixed_typed_array() &&
2293 instr->elements()->representation().IsTagged()) || 2286 instr->elements()->representation().IsTagged()) ||
2294 (instr->is_external() && 2287 (instr->is_external() &&
2295 instr->elements()->representation().IsExternal())); 2288 instr->elements()->representation().IsExternal()));
2296 LOperand* val = UseRegister(instr->value()); 2289 LOperand* val = UseRegister(instr->value());
2297 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2290 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2298 LOperand* backing_store = UseRegister(instr->elements()); 2291 LOperand* backing_store = UseRegister(instr->elements());
2299 return new(zone()) LStoreKeyed(backing_store, key, val); 2292 return new (zone()) LStoreKeyed(backing_store, key, val);
2300 } 2293 }
2301 2294
2302 2295
2303 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { 2296 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2304 LOperand* context = UseFixed(instr->context(), cp); 2297 LOperand* context = UseFixed(instr->context(), cp);
2305 LOperand* obj = 2298 LOperand* obj =
2306 UseFixed(instr->object(), StoreDescriptor::ReceiverRegister()); 2299 UseFixed(instr->object(), StoreDescriptor::ReceiverRegister());
2307 LOperand* key = UseFixed(instr->key(), StoreDescriptor::NameRegister()); 2300 LOperand* key = UseFixed(instr->key(), StoreDescriptor::NameRegister());
2308 LOperand* val = UseFixed(instr->value(), StoreDescriptor::ValueRegister()); 2301 LOperand* val = UseFixed(instr->value(), StoreDescriptor::ValueRegister());
2309 2302
2310 DCHECK(instr->object()->representation().IsTagged()); 2303 DCHECK(instr->object()->representation().IsTagged());
2311 DCHECK(instr->key()->representation().IsTagged()); 2304 DCHECK(instr->key()->representation().IsTagged());
2312 DCHECK(instr->value()->representation().IsTagged()); 2305 DCHECK(instr->value()->representation().IsTagged());
2313 2306
2314 return MarkAsCall( 2307 return MarkAsCall(new (zone()) LStoreKeyedGeneric(context, obj, key, val),
2315 new(zone()) LStoreKeyedGeneric(context, obj, key, val), instr); 2308 instr);
2316 } 2309 }
2317 2310
2318 2311
2319 LInstruction* LChunkBuilder::DoTransitionElementsKind( 2312 LInstruction* LChunkBuilder::DoTransitionElementsKind(
2320 HTransitionElementsKind* instr) { 2313 HTransitionElementsKind* instr) {
2321 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { 2314 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
2322 LOperand* object = UseRegister(instr->object()); 2315 LOperand* object = UseRegister(instr->object());
2323 LOperand* new_map_reg = TempRegister(); 2316 LOperand* new_map_reg = TempRegister();
2324 LTransitionElementsKind* result = 2317 LTransitionElementsKind* result =
2325 new(zone()) LTransitionElementsKind(object, NULL, new_map_reg); 2318 new (zone()) LTransitionElementsKind(object, NULL, new_map_reg);
2326 return result; 2319 return result;
2327 } else { 2320 } else {
2328 LOperand* object = UseFixed(instr->object(), r0); 2321 LOperand* object = UseFixed(instr->object(), r3);
2329 LOperand* context = UseFixed(instr->context(), cp); 2322 LOperand* context = UseFixed(instr->context(), cp);
2330 LTransitionElementsKind* result = 2323 LTransitionElementsKind* result =
2331 new(zone()) LTransitionElementsKind(object, context, NULL); 2324 new (zone()) LTransitionElementsKind(object, context, NULL);
2332 return MarkAsCall(result, instr); 2325 return MarkAsCall(result, instr);
2333 } 2326 }
2334 } 2327 }
2335 2328
2336 2329
2337 LInstruction* LChunkBuilder::DoTrapAllocationMemento( 2330 LInstruction* LChunkBuilder::DoTrapAllocationMemento(
2338 HTrapAllocationMemento* instr) { 2331 HTrapAllocationMemento* instr) {
2339 LOperand* object = UseRegister(instr->object()); 2332 LOperand* object = UseRegister(instr->object());
2340 LOperand* temp = TempRegister(); 2333 LOperand* temp = TempRegister();
2341 LTrapAllocationMemento* result = 2334 LTrapAllocationMemento* result =
2342 new(zone()) LTrapAllocationMemento(object, temp); 2335 new (zone()) LTrapAllocationMemento(object, temp);
2343 return AssignEnvironment(result); 2336 return AssignEnvironment(result);
2344 } 2337 }
2345 2338
2346 2339
2347 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { 2340 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2348 bool is_in_object = instr->access().IsInobject(); 2341 bool is_in_object = instr->access().IsInobject();
2349 bool needs_write_barrier = instr->NeedsWriteBarrier(); 2342 bool needs_write_barrier = instr->NeedsWriteBarrier();
2350 bool needs_write_barrier_for_map = instr->has_transition() && 2343 bool needs_write_barrier_for_map =
2351 instr->NeedsWriteBarrierForMap(); 2344 instr->has_transition() && instr->NeedsWriteBarrierForMap();
2352 2345
2353 LOperand* obj; 2346 LOperand* obj;
2354 if (needs_write_barrier) { 2347 if (needs_write_barrier) {
2355 obj = is_in_object 2348 obj = is_in_object ? UseRegister(instr->object())
2356 ? UseRegister(instr->object()) 2349 : UseTempRegister(instr->object());
2357 : UseTempRegister(instr->object());
2358 } else { 2350 } else {
2359 obj = needs_write_barrier_for_map 2351 obj = needs_write_barrier_for_map ? UseRegister(instr->object())
2360 ? UseRegister(instr->object()) 2352 : UseRegisterAtStart(instr->object());
2361 : UseRegisterAtStart(instr->object());
2362 } 2353 }
2363 2354
2364 LOperand* val; 2355 LOperand* val;
2365 if (needs_write_barrier || instr->field_representation().IsSmi()) { 2356 if (needs_write_barrier) {
2366 val = UseTempRegister(instr->value()); 2357 val = UseTempRegister(instr->value());
2367 } else if (instr->field_representation().IsDouble()) { 2358 } else if (instr->field_representation().IsDouble()) {
2368 val = UseRegisterAtStart(instr->value()); 2359 val = UseRegisterAtStart(instr->value());
2369 } else { 2360 } else {
2370 val = UseRegister(instr->value()); 2361 val = UseRegister(instr->value());
2371 } 2362 }
2372 2363
2373 // We need a temporary register for write barrier of the map field. 2364 // We need a temporary register for write barrier of the map field.
2374 LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL; 2365 LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
2375 2366
2376 return new(zone()) LStoreNamedField(obj, val, temp); 2367 return new (zone()) LStoreNamedField(obj, val, temp);
2377 } 2368 }
2378 2369
2379 2370
2380 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 2371 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2381 LOperand* context = UseFixed(instr->context(), cp); 2372 LOperand* context = UseFixed(instr->context(), cp);
2382 LOperand* obj = 2373 LOperand* obj =
2383 UseFixed(instr->object(), StoreDescriptor::ReceiverRegister()); 2374 UseFixed(instr->object(), StoreDescriptor::ReceiverRegister());
2384 LOperand* val = UseFixed(instr->value(), StoreDescriptor::ValueRegister()); 2375 LOperand* val = UseFixed(instr->value(), StoreDescriptor::ValueRegister());
2385 2376
2386 LInstruction* result = new(zone()) LStoreNamedGeneric(context, obj, val); 2377 LInstruction* result = new (zone()) LStoreNamedGeneric(context, obj, val);
2387 return MarkAsCall(result, instr); 2378 return MarkAsCall(result, instr);
2388 } 2379 }
2389 2380
2390 2381
2391 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { 2382 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2392 LOperand* context = UseFixed(instr->context(), cp); 2383 LOperand* context = UseFixed(instr->context(), cp);
2393 LOperand* left = UseFixed(instr->left(), r1); 2384 LOperand* left = UseFixed(instr->left(), r4);
2394 LOperand* right = UseFixed(instr->right(), r0); 2385 LOperand* right = UseFixed(instr->right(), r3);
2395 return MarkAsCall( 2386 return MarkAsCall(
2396 DefineFixed(new(zone()) LStringAdd(context, left, right), r0), 2387 DefineFixed(new (zone()) LStringAdd(context, left, right), r3), instr);
2397 instr);
2398 } 2388 }
2399 2389
2400 2390
2401 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { 2391 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2402 LOperand* string = UseTempRegister(instr->string()); 2392 LOperand* string = UseTempRegister(instr->string());
2403 LOperand* index = UseTempRegister(instr->index()); 2393 LOperand* index = UseTempRegister(instr->index());
2404 LOperand* context = UseAny(instr->context()); 2394 LOperand* context = UseAny(instr->context());
2405 LStringCharCodeAt* result = 2395 LStringCharCodeAt* result =
2406 new(zone()) LStringCharCodeAt(context, string, index); 2396 new (zone()) LStringCharCodeAt(context, string, index);
2407 return AssignPointerMap(DefineAsRegister(result)); 2397 return AssignPointerMap(DefineAsRegister(result));
2408 } 2398 }
2409 2399
2410 2400
2411 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { 2401 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2412 LOperand* char_code = UseRegister(instr->value()); 2402 LOperand* char_code = UseRegister(instr->value());
2413 LOperand* context = UseAny(instr->context()); 2403 LOperand* context = UseAny(instr->context());
2414 LStringCharFromCode* result = 2404 LStringCharFromCode* result =
2415 new(zone()) LStringCharFromCode(context, char_code); 2405 new (zone()) LStringCharFromCode(context, char_code);
2416 return AssignPointerMap(DefineAsRegister(result)); 2406 return AssignPointerMap(DefineAsRegister(result));
2417 } 2407 }
2418 2408
2419 2409
2420 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { 2410 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
2421 info()->MarkAsDeferredCalling(); 2411 info()->MarkAsDeferredCalling();
2422 LOperand* context = UseAny(instr->context()); 2412 LOperand* context = UseAny(instr->context());
2423 LOperand* size = UseRegisterOrConstant(instr->size()); 2413 LOperand* size = UseRegisterOrConstant(instr->size());
2424 LOperand* temp1 = TempRegister(); 2414 LOperand* temp1 = TempRegister();
2425 LOperand* temp2 = TempRegister(); 2415 LOperand* temp2 = TempRegister();
2426 LAllocate* result = new(zone()) LAllocate(context, size, temp1, temp2); 2416 LAllocate* result = new (zone()) LAllocate(context, size, temp1, temp2);
2427 return AssignPointerMap(DefineAsRegister(result)); 2417 return AssignPointerMap(DefineAsRegister(result));
2428 } 2418 }
2429 2419
2430 2420
2431 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { 2421 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2432 LOperand* context = UseFixed(instr->context(), cp); 2422 LOperand* context = UseFixed(instr->context(), cp);
2433 return MarkAsCall( 2423 return MarkAsCall(DefineFixed(new (zone()) LRegExpLiteral(context), r3),
2434 DefineFixed(new(zone()) LRegExpLiteral(context), r0), instr); 2424 instr);
2435 } 2425 }
2436 2426
2437 2427
2438 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { 2428 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
2439 LOperand* context = UseFixed(instr->context(), cp); 2429 LOperand* context = UseFixed(instr->context(), cp);
2440 return MarkAsCall( 2430 return MarkAsCall(DefineFixed(new (zone()) LFunctionLiteral(context), r3),
2441 DefineFixed(new(zone()) LFunctionLiteral(context), r0), instr); 2431 instr);
2442 } 2432 }
2443 2433
2444 2434
2445 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { 2435 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2446 DCHECK(argument_count_ == 0); 2436 DCHECK(argument_count_ == 0);
2447 allocator_->MarkAsOsrEntry(); 2437 allocator_->MarkAsOsrEntry();
2448 current_block_->last_environment()->set_ast_id(instr->ast_id()); 2438 current_block_->last_environment()->set_ast_id(instr->ast_id());
2449 return AssignEnvironment(new(zone()) LOsrEntry); 2439 return AssignEnvironment(new (zone()) LOsrEntry);
2450 } 2440 }
2451 2441
2452 2442
2453 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { 2443 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2454 LParameter* result = new(zone()) LParameter; 2444 LParameter* result = new (zone()) LParameter;
2455 if (instr->kind() == HParameter::STACK_PARAMETER) { 2445 if (instr->kind() == HParameter::STACK_PARAMETER) {
2456 int spill_index = chunk()->GetParameterStackSlot(instr->index()); 2446 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2457 return DefineAsSpilled(result, spill_index); 2447 return DefineAsSpilled(result, spill_index);
2458 } else { 2448 } else {
2459 DCHECK(info()->IsStub()); 2449 DCHECK(info()->IsStub());
2460 CallInterfaceDescriptor descriptor = 2450 CallInterfaceDescriptor descriptor =
2461 info()->code_stub()->GetCallInterfaceDescriptor(); 2451 info()->code_stub()->GetCallInterfaceDescriptor();
2462 int index = static_cast<int>(instr->index()); 2452 int index = static_cast<int>(instr->index());
2463 Register reg = descriptor.GetEnvironmentParameterRegister(index); 2453 Register reg = descriptor.GetEnvironmentParameterRegister(index);
2464 return DefineFixed(result, reg); 2454 return DefineFixed(result, reg);
2465 } 2455 }
2466 } 2456 }
2467 2457
2468 2458
2469 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { 2459 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2470 // Use an index that corresponds to the location in the unoptimized frame, 2460 // Use an index that corresponds to the location in the unoptimized frame,
2471 // which the optimized frame will subsume. 2461 // which the optimized frame will subsume.
2472 int env_index = instr->index(); 2462 int env_index = instr->index();
2473 int spill_index = 0; 2463 int spill_index = 0;
2474 if (instr->environment()->is_parameter_index(env_index)) { 2464 if (instr->environment()->is_parameter_index(env_index)) {
2475 spill_index = chunk()->GetParameterStackSlot(env_index); 2465 spill_index = chunk()->GetParameterStackSlot(env_index);
2476 } else { 2466 } else {
2477 spill_index = env_index - instr->environment()->first_local_index(); 2467 spill_index = env_index - instr->environment()->first_local_index();
2478 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { 2468 if (spill_index > LUnallocated::kMaxFixedSlotIndex) {
2479 Abort(kTooManySpillSlotsNeededForOSR); 2469 Abort(kTooManySpillSlotsNeededForOSR);
2480 spill_index = 0; 2470 spill_index = 0;
2481 } 2471 }
2482 } 2472 }
2483 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); 2473 return DefineAsSpilled(new (zone()) LUnknownOSRValue, spill_index);
2484 } 2474 }
2485 2475
2486 2476
2487 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { 2477 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2488 LOperand* context = UseFixed(instr->context(), cp); 2478 LOperand* context = UseFixed(instr->context(), cp);
2489 return MarkAsCall(DefineFixed(new(zone()) LCallStub(context), r0), instr); 2479 return MarkAsCall(DefineFixed(new (zone()) LCallStub(context), r3), instr);
2490 } 2480 }
2491 2481
2492 2482
2493 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { 2483 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2494 // There are no real uses of the arguments object. 2484 // There are no real uses of the arguments object.
2495 // arguments.length and element access are supported directly on 2485 // arguments.length and element access are supported directly on
2496 // stack arguments, and any real arguments object use causes a bailout. 2486 // stack arguments, and any real arguments object use causes a bailout.
2497 // So this value is never used. 2487 // So this value is never used.
2498 return NULL; 2488 return NULL;
2499 } 2489 }
2500 2490
2501 2491
2502 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) { 2492 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
2503 instr->ReplayEnvironment(current_block_->last_environment()); 2493 instr->ReplayEnvironment(current_block_->last_environment());
2504 2494
2505 // There are no real uses of a captured object. 2495 // There are no real uses of a captured object.
2506 return NULL; 2496 return NULL;
2507 } 2497 }
2508 2498
2509 2499
2510 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 2500 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2511 info()->MarkAsRequiresFrame(); 2501 info()->MarkAsRequiresFrame();
2512 LOperand* args = UseRegister(instr->arguments()); 2502 LOperand* args = UseRegister(instr->arguments());
2513 LOperand* length = UseRegisterOrConstantAtStart(instr->length()); 2503 LOperand* length = UseRegisterOrConstantAtStart(instr->length());
2514 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); 2504 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
2515 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index)); 2505 return DefineAsRegister(new (zone()) LAccessArgumentsAt(args, length, index));
2516 } 2506 }
2517 2507
2518 2508
2519 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { 2509 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2520 LOperand* object = UseFixed(instr->value(), r0); 2510 LOperand* object = UseFixed(instr->value(), r3);
2521 LToFastProperties* result = new(zone()) LToFastProperties(object); 2511 LToFastProperties* result = new (zone()) LToFastProperties(object);
2522 return MarkAsCall(DefineFixed(result, r0), instr); 2512 return MarkAsCall(DefineFixed(result, r3), instr);
2523 } 2513 }
2524 2514
2525 2515
2526 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 2516 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2527 LOperand* context = UseFixed(instr->context(), cp); 2517 LOperand* context = UseFixed(instr->context(), cp);
2528 LTypeof* result = new(zone()) LTypeof(context, UseFixed(instr->value(), r0)); 2518 LTypeof* result = new (zone()) LTypeof(context, UseFixed(instr->value(), r3));
2529 return MarkAsCall(DefineFixed(result, r0), instr); 2519 return MarkAsCall(DefineFixed(result, r3), instr);
2530 } 2520 }
2531 2521
2532 2522
2533 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { 2523 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2534 return new(zone()) LTypeofIsAndBranch(UseRegister(instr->value())); 2524 return new (zone()) LTypeofIsAndBranch(UseRegister(instr->value()));
2535 } 2525 }
2536 2526
2537 2527
2538 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( 2528 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
2539 HIsConstructCallAndBranch* instr) { 2529 HIsConstructCallAndBranch* instr) {
2540 return new(zone()) LIsConstructCallAndBranch(TempRegister()); 2530 return new (zone()) LIsConstructCallAndBranch(TempRegister());
2541 } 2531 }
2542 2532
2543 2533
2544 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 2534 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2545 instr->ReplayEnvironment(current_block_->last_environment()); 2535 instr->ReplayEnvironment(current_block_->last_environment());
2546 return NULL; 2536 return NULL;
2547 } 2537 }
2548 2538
2549 2539
2550 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 2540 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2551 if (instr->is_function_entry()) { 2541 if (instr->is_function_entry()) {
2552 LOperand* context = UseFixed(instr->context(), cp); 2542 LOperand* context = UseFixed(instr->context(), cp);
2553 return MarkAsCall(new(zone()) LStackCheck(context), instr); 2543 return MarkAsCall(new (zone()) LStackCheck(context), instr);
2554 } else { 2544 } else {
2555 DCHECK(instr->is_backwards_branch()); 2545 DCHECK(instr->is_backwards_branch());
2556 LOperand* context = UseAny(instr->context()); 2546 LOperand* context = UseAny(instr->context());
2557 return AssignEnvironment( 2547 return AssignEnvironment(
2558 AssignPointerMap(new(zone()) LStackCheck(context))); 2548 AssignPointerMap(new (zone()) LStackCheck(context)));
2559 } 2549 }
2560 } 2550 }
2561 2551
2562 2552
2563 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { 2553 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2564 HEnvironment* outer = current_block_->last_environment(); 2554 HEnvironment* outer = current_block_->last_environment();
2565 outer->set_ast_id(instr->ReturnId()); 2555 outer->set_ast_id(instr->ReturnId());
2566 HConstant* undefined = graph()->GetConstantUndefined(); 2556 HConstant* undefined = graph()->GetConstantUndefined();
2567 HEnvironment* inner = outer->CopyForInlining(instr->closure(), 2557 HEnvironment* inner = outer->CopyForInlining(
2568 instr->arguments_count(), 2558 instr->closure(), instr->arguments_count(), instr->function(), undefined,
2569 instr->function(), 2559 instr->inlining_kind());
2570 undefined,
2571 instr->inlining_kind());
2572 // Only replay binding of arguments object if it wasn't removed from graph. 2560 // Only replay binding of arguments object if it wasn't removed from graph.
2573 if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) { 2561 if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
2574 inner->Bind(instr->arguments_var(), instr->arguments_object()); 2562 inner->Bind(instr->arguments_var(), instr->arguments_object());
2575 } 2563 }
2576 inner->BindContext(instr->closure_context()); 2564 inner->BindContext(instr->closure_context());
2577 inner->set_entry(instr); 2565 inner->set_entry(instr);
2578 current_block_->UpdateEnvironment(inner); 2566 current_block_->UpdateEnvironment(inner);
2579 chunk_->AddInlinedClosure(instr->closure()); 2567 chunk_->AddInlinedClosure(instr->closure());
2580 return NULL; 2568 return NULL;
2581 } 2569 }
2582 2570
2583 2571
2584 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2572 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2585 LInstruction* pop = NULL; 2573 LInstruction* pop = NULL;
2586 2574
2587 HEnvironment* env = current_block_->last_environment(); 2575 HEnvironment* env = current_block_->last_environment();
2588 2576
2589 if (env->entry()->arguments_pushed()) { 2577 if (env->entry()->arguments_pushed()) {
2590 int argument_count = env->arguments_environment()->parameter_count(); 2578 int argument_count = env->arguments_environment()->parameter_count();
2591 pop = new(zone()) LDrop(argument_count); 2579 pop = new (zone()) LDrop(argument_count);
2592 DCHECK(instr->argument_delta() == -argument_count); 2580 DCHECK(instr->argument_delta() == -argument_count);
2593 } 2581 }
2594 2582
2595 HEnvironment* outer = current_block_->last_environment()-> 2583 HEnvironment* outer =
2596 DiscardInlined(false); 2584 current_block_->last_environment()->DiscardInlined(false);
2597 current_block_->UpdateEnvironment(outer); 2585 current_block_->UpdateEnvironment(outer);
2598 2586
2599 return pop; 2587 return pop;
2600 } 2588 }
2601 2589
2602 2590
2603 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { 2591 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
2604 LOperand* context = UseFixed(instr->context(), cp); 2592 LOperand* context = UseFixed(instr->context(), cp);
2605 LOperand* object = UseFixed(instr->enumerable(), r0); 2593 LOperand* object = UseFixed(instr->enumerable(), r3);
2606 LForInPrepareMap* result = new(zone()) LForInPrepareMap(context, object); 2594 LForInPrepareMap* result = new (zone()) LForInPrepareMap(context, object);
2607 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 2595 return MarkAsCall(DefineFixed(result, r3), instr, CAN_DEOPTIMIZE_EAGERLY);
2608 } 2596 }
2609 2597
2610 2598
2611 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) { 2599 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
2612 LOperand* map = UseRegister(instr->map()); 2600 LOperand* map = UseRegister(instr->map());
2613 return AssignEnvironment(DefineAsRegister(new(zone()) LForInCacheArray(map))); 2601 return AssignEnvironment(
2602 DefineAsRegister(new (zone()) LForInCacheArray(map)));
2614 } 2603 }
2615 2604
2616 2605
2617 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) { 2606 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
2618 LOperand* value = UseRegisterAtStart(instr->value()); 2607 LOperand* value = UseRegisterAtStart(instr->value());
2619 LOperand* map = UseRegisterAtStart(instr->map()); 2608 LOperand* map = UseRegisterAtStart(instr->map());
2620 return AssignEnvironment(new(zone()) LCheckMapValue(value, map)); 2609 return AssignEnvironment(new (zone()) LCheckMapValue(value, map));
2621 } 2610 }
2622 2611
2623 2612
2624 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2613 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2625 LOperand* object = UseRegister(instr->object()); 2614 LOperand* object = UseRegister(instr->object());
2626 LOperand* index = UseTempRegister(instr->index()); 2615 LOperand* index = UseTempRegister(instr->index());
2627 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); 2616 LLoadFieldByIndex* load = new (zone()) LLoadFieldByIndex(object, index);
2628 LInstruction* result = DefineSameAsFirst(load); 2617 LInstruction* result = DefineSameAsFirst(load);
2629 return AssignPointerMap(result); 2618 return AssignPointerMap(result);
2630 } 2619 }
2631 2620
2632 2621
2633 LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) { 2622 LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) {
2634 LOperand* context = UseRegisterAtStart(instr->context()); 2623 LOperand* context = UseRegisterAtStart(instr->context());
2635 return new(zone()) LStoreFrameContext(context); 2624 return new (zone()) LStoreFrameContext(context);
2636 } 2625 }
2637 2626
2638 2627
2639 LInstruction* LChunkBuilder::DoAllocateBlockContext( 2628 LInstruction* LChunkBuilder::DoAllocateBlockContext(
2640 HAllocateBlockContext* instr) { 2629 HAllocateBlockContext* instr) {
2641 LOperand* context = UseFixed(instr->context(), cp); 2630 LOperand* context = UseFixed(instr->context(), cp);
2642 LOperand* function = UseRegisterAtStart(instr->function()); 2631 LOperand* function = UseRegisterAtStart(instr->function());
2643 LAllocateBlockContext* result = 2632 LAllocateBlockContext* result =
2644 new(zone()) LAllocateBlockContext(context, function); 2633 new (zone()) LAllocateBlockContext(context, function);
2645 return MarkAsCall(DefineFixed(result, cp), instr); 2634 return MarkAsCall(DefineFixed(result, cp), instr);
2646 } 2635 }
2647 2636 }
2648 } } // namespace v8::internal 2637 } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698