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

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

Issue 422063005: Contribution of PowerPC port. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: re-upload - catch up to 8/19 level Created 6 years, 3 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 const InterfaceDescriptor* descriptor = instr->descriptor(); 1094 const InterfaceDescriptor* 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 = UseFixed(instr->OperandAt(i), 1100 LOperand* op =
1092 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::DoInvokeFunction(HInvokeFunction* instr) { 1111 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1103 LOperand* context = UseFixed(instr->context(), cp); 1112 LOperand* context = UseFixed(instr->context(), cp);
1104 LOperand* function = UseFixed(instr->function(), r1); 1113 LOperand* function = UseFixed(instr->function(), r4);
1105 LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); 1114 LInvokeFunction* result = new (zone()) LInvokeFunction(context, function);
1106 return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY); 1115 return MarkAsCall(DefineFixed(result, r3), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1107 } 1116 }
1108 1117
1109 1118
1110 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1119 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1111 switch (instr->op()) { 1120 switch (instr->op()) {
1112 case kMathFloor: 1121 case kMathFloor:
1113 return DoMathFloor(instr); 1122 return DoMathFloor(instr);
1114 case kMathRound: 1123 case kMathRound:
1115 return DoMathRound(instr); 1124 return DoMathRound(instr);
1116 case kMathFround: 1125 case kMathFround:
(...skipping 12 matching lines...) Expand all
1129 return DoMathClz32(instr); 1138 return DoMathClz32(instr);
1130 default: 1139 default:
1131 UNREACHABLE(); 1140 UNREACHABLE();
1132 return NULL; 1141 return NULL;
1133 } 1142 }
1134 } 1143 }
1135 1144
1136 1145
1137 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { 1146 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
1138 LOperand* input = UseRegister(instr->value()); 1147 LOperand* input = UseRegister(instr->value());
1139 LMathFloor* result = new(zone()) LMathFloor(input); 1148 LMathFloor* result = new (zone()) LMathFloor(input);
1140 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1149 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1141 } 1150 }
1142 1151
1143 1152
1144 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { 1153 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
1145 LOperand* input = UseRegister(instr->value()); 1154 LOperand* input = UseRegister(instr->value());
1146 LOperand* temp = TempDoubleRegister(); 1155 LOperand* temp = TempDoubleRegister();
1147 LMathRound* result = new(zone()) LMathRound(input, temp); 1156 LMathRound* result = new (zone()) LMathRound(input, temp);
1148 return AssignEnvironment(DefineAsRegister(result)); 1157 return AssignEnvironment(DefineAsRegister(result));
1149 } 1158 }
1150 1159
1151 1160
1152 LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) { 1161 LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
1153 LOperand* input = UseRegister(instr->value()); 1162 LOperand* input = UseRegister(instr->value());
1154 LMathFround* result = new (zone()) LMathFround(input); 1163 LMathFround* result = new (zone()) LMathFround(input);
1155 return DefineAsRegister(result); 1164 return DefineAsRegister(result);
1156 } 1165 }
1157 1166
1158 1167
1159 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { 1168 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1160 Representation r = instr->value()->representation(); 1169 Representation r = instr->value()->representation();
1161 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32()) 1170 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32())
1162 ? NULL 1171 ? NULL
1163 : UseFixed(instr->context(), cp); 1172 : UseFixed(instr->context(), cp);
1164 LOperand* input = UseRegister(instr->value()); 1173 LOperand* input = UseRegister(instr->value());
1165 LInstruction* result = 1174 LInstruction* result =
1166 DefineAsRegister(new(zone()) LMathAbs(context, input)); 1175 DefineAsRegister(new (zone()) LMathAbs(context, input));
1167 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result); 1176 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
1168 if (!r.IsDouble()) result = AssignEnvironment(result); 1177 if (!r.IsDouble()) result = AssignEnvironment(result);
1169 return result; 1178 return result;
1170 } 1179 }
1171 1180
1172 1181
1173 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { 1182 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
1174 DCHECK(instr->representation().IsDouble()); 1183 DCHECK(instr->representation().IsDouble());
1175 DCHECK(instr->value()->representation().IsDouble()); 1184 DCHECK(instr->value()->representation().IsDouble());
1176 LOperand* input = UseFixedDouble(instr->value(), d0); 1185 LOperand* input = UseFixedDouble(instr->value(), d1);
1177 return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), d0), instr); 1186 return MarkAsCall(DefineFixedDouble(new (zone()) LMathLog(input), d1), instr);
1178 } 1187 }
1179 1188
1180 1189
1181 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { 1190 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
1182 LOperand* input = UseRegisterAtStart(instr->value()); 1191 LOperand* input = UseRegisterAtStart(instr->value());
1183 LMathClz32* result = new(zone()) LMathClz32(input); 1192 LMathClz32* result = new (zone()) LMathClz32(input);
1184 return DefineAsRegister(result); 1193 return DefineAsRegister(result);
1185 } 1194 }
1186 1195
1187 1196
1188 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { 1197 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
1189 DCHECK(instr->representation().IsDouble()); 1198 DCHECK(instr->representation().IsDouble());
1190 DCHECK(instr->value()->representation().IsDouble()); 1199 DCHECK(instr->value()->representation().IsDouble());
1191 LOperand* input = UseRegister(instr->value()); 1200 LOperand* input = UseRegister(instr->value());
1192 LOperand* temp1 = TempRegister(); 1201 LOperand* temp1 = TempRegister();
1193 LOperand* temp2 = TempRegister(); 1202 LOperand* temp2 = TempRegister();
1194 LOperand* double_temp = TempDoubleRegister(); 1203 LOperand* double_temp = TempDoubleRegister();
1195 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); 1204 LMathExp* result = new (zone()) LMathExp(input, double_temp, temp1, temp2);
1196 return DefineAsRegister(result); 1205 return DefineAsRegister(result);
1197 } 1206 }
1198 1207
1199 1208
1200 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { 1209 LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
1201 LOperand* input = UseRegisterAtStart(instr->value()); 1210 LOperand* input = UseRegisterAtStart(instr->value());
1202 LMathSqrt* result = new(zone()) LMathSqrt(input); 1211 LMathSqrt* result = new (zone()) LMathSqrt(input);
1203 return DefineAsRegister(result); 1212 return DefineAsRegister(result);
1204 } 1213 }
1205 1214
1206 1215
1207 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { 1216 LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
1208 LOperand* input = UseRegisterAtStart(instr->value()); 1217 LOperand* input = UseRegisterAtStart(instr->value());
1209 LMathPowHalf* result = new(zone()) LMathPowHalf(input); 1218 LMathPowHalf* result = new (zone()) LMathPowHalf(input);
1210 return DefineAsRegister(result); 1219 return DefineAsRegister(result);
1211 } 1220 }
1212 1221
1213 1222
1214 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { 1223 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1215 LOperand* context = UseFixed(instr->context(), cp); 1224 LOperand* context = UseFixed(instr->context(), cp);
1216 LOperand* constructor = UseFixed(instr->constructor(), r1); 1225 LOperand* constructor = UseFixed(instr->constructor(), r4);
1217 LCallNew* result = new(zone()) LCallNew(context, constructor); 1226 LCallNew* result = new (zone()) LCallNew(context, constructor);
1218 return MarkAsCall(DefineFixed(result, r0), instr); 1227 return MarkAsCall(DefineFixed(result, r3), instr);
1219 } 1228 }
1220 1229
1221 1230
1222 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { 1231 LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1223 LOperand* context = UseFixed(instr->context(), cp); 1232 LOperand* context = UseFixed(instr->context(), cp);
1224 LOperand* constructor = UseFixed(instr->constructor(), r1); 1233 LOperand* constructor = UseFixed(instr->constructor(), r4);
1225 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); 1234 LCallNewArray* result = new (zone()) LCallNewArray(context, constructor);
1226 return MarkAsCall(DefineFixed(result, r0), instr); 1235 return MarkAsCall(DefineFixed(result, r3), instr);
1227 } 1236 }
1228 1237
1229 1238
1230 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { 1239 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1231 LOperand* context = UseFixed(instr->context(), cp); 1240 LOperand* context = UseFixed(instr->context(), cp);
1232 LOperand* function = UseFixed(instr->function(), r1); 1241 LOperand* function = UseFixed(instr->function(), r4);
1233 LCallFunction* call = new(zone()) LCallFunction(context, function); 1242 LCallFunction* call = new (zone()) LCallFunction(context, function);
1234 return MarkAsCall(DefineFixed(call, r0), instr); 1243 return MarkAsCall(DefineFixed(call, r3), instr);
1235 } 1244 }
1236 1245
1237 1246
1238 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { 1247 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1239 LOperand* context = UseFixed(instr->context(), cp); 1248 LOperand* context = UseFixed(instr->context(), cp);
1240 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), r0), instr); 1249 return MarkAsCall(DefineFixed(new (zone()) LCallRuntime(context), r3), instr);
1241 } 1250 }
1242 1251
1243 1252
1244 LInstruction* LChunkBuilder::DoRor(HRor* instr) { 1253 LInstruction* LChunkBuilder::DoRor(HRor* instr) {
1245 return DoShift(Token::ROR, instr); 1254 return DoShift(Token::ROR, instr);
1246 } 1255 }
1247 1256
1248 1257
1249 LInstruction* LChunkBuilder::DoShr(HShr* instr) { 1258 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1250 return DoShift(Token::SHR, instr); 1259 return DoShift(Token::SHR, instr);
(...skipping 11 matching lines...) Expand all
1262 1271
1263 1272
1264 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { 1273 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
1265 if (instr->representation().IsSmiOrInteger32()) { 1274 if (instr->representation().IsSmiOrInteger32()) {
1266 DCHECK(instr->left()->representation().Equals(instr->representation())); 1275 DCHECK(instr->left()->representation().Equals(instr->representation()));
1267 DCHECK(instr->right()->representation().Equals(instr->representation())); 1276 DCHECK(instr->right()->representation().Equals(instr->representation()));
1268 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32)); 1277 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32));
1269 1278
1270 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); 1279 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1271 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); 1280 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1272 return DefineAsRegister(new(zone()) LBitI(left, right)); 1281 return DefineAsRegister(new (zone()) LBitI(left, right));
1273 } else { 1282 } else {
1274 return DoArithmeticT(instr->op(), instr); 1283 return DoArithmeticT(instr->op(), instr);
1275 } 1284 }
1276 } 1285 }
1277 1286
1278 1287
1279 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { 1288 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
1280 DCHECK(instr->representation().IsSmiOrInteger32()); 1289 DCHECK(instr->representation().IsSmiOrInteger32());
1281 DCHECK(instr->left()->representation().Equals(instr->representation())); 1290 DCHECK(instr->left()->representation().Equals(instr->representation()));
1282 DCHECK(instr->right()->representation().Equals(instr->representation())); 1291 DCHECK(instr->right()->representation().Equals(instr->representation()));
1283 LOperand* dividend = UseRegister(instr->left()); 1292 LOperand* dividend = UseRegister(instr->left());
1284 int32_t divisor = instr->right()->GetInteger32Constant(); 1293 int32_t divisor = instr->right()->GetInteger32Constant();
1285 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( 1294 LInstruction* result =
1286 dividend, divisor)); 1295 DefineAsRegister(new (zone()) LDivByPowerOf2I(dividend, divisor));
1287 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || 1296 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1288 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || 1297 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
1289 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1298 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1290 divisor != 1 && divisor != -1)) { 1299 divisor != 1 && divisor != -1)) {
1291 result = AssignEnvironment(result); 1300 result = AssignEnvironment(result);
1292 } 1301 }
1293 return result; 1302 return result;
1294 } 1303 }
1295 1304
1296 1305
1297 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { 1306 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
1298 DCHECK(instr->representation().IsInteger32()); 1307 DCHECK(instr->representation().IsInteger32());
1299 DCHECK(instr->left()->representation().Equals(instr->representation())); 1308 DCHECK(instr->left()->representation().Equals(instr->representation()));
1300 DCHECK(instr->right()->representation().Equals(instr->representation())); 1309 DCHECK(instr->right()->representation().Equals(instr->representation()));
1301 LOperand* dividend = UseRegister(instr->left()); 1310 LOperand* dividend = UseRegister(instr->left());
1302 int32_t divisor = instr->right()->GetInteger32Constant(); 1311 int32_t divisor = instr->right()->GetInteger32Constant();
1303 LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI( 1312 LInstruction* result =
1304 dividend, divisor)); 1313 DefineAsRegister(new (zone()) LDivByConstI(dividend, divisor));
1305 if (divisor == 0 || 1314 if (divisor == 0 ||
1306 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || 1315 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1307 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1316 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1308 result = AssignEnvironment(result); 1317 result = AssignEnvironment(result);
1309 } 1318 }
1310 return result; 1319 return result;
1311 } 1320 }
1312 1321
1313 1322
1314 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) { 1323 LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
1315 DCHECK(instr->representation().IsSmiOrInteger32()); 1324 DCHECK(instr->representation().IsSmiOrInteger32());
1316 DCHECK(instr->left()->representation().Equals(instr->representation())); 1325 DCHECK(instr->left()->representation().Equals(instr->representation()));
1317 DCHECK(instr->right()->representation().Equals(instr->representation())); 1326 DCHECK(instr->right()->representation().Equals(instr->representation()));
1318 LOperand* dividend = UseRegister(instr->left()); 1327 LOperand* dividend = UseRegister(instr->left());
1319 LOperand* divisor = UseRegister(instr->right()); 1328 LOperand* divisor = UseRegister(instr->right());
1320 LOperand* temp =
1321 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister();
1322 LInstruction* result = 1329 LInstruction* result =
1323 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); 1330 DefineAsRegister(new (zone()) LDivI(dividend, divisor));
1324 if (instr->CheckFlag(HValue::kCanBeDivByZero) || 1331 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1325 instr->CheckFlag(HValue::kBailoutOnMinusZero) || 1332 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1326 (instr->CheckFlag(HValue::kCanOverflow) && 1333 (instr->CheckFlag(HValue::kCanOverflow) &&
1327 (!CpuFeatures::IsSupported(SUDIV) || 1334 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) ||
1328 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) ||
1329 (!instr->IsMathFloorOfDiv() && 1335 (!instr->IsMathFloorOfDiv() &&
1330 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) { 1336 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
1331 result = AssignEnvironment(result); 1337 result = AssignEnvironment(result);
1332 } 1338 }
1333 return result; 1339 return result;
1334 } 1340 }
1335 1341
1336 1342
1337 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1343 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1338 if (instr->representation().IsSmiOrInteger32()) { 1344 if (instr->representation().IsSmiOrInteger32()) {
1339 if (instr->RightIsPowerOf2()) { 1345 if (instr->RightIsPowerOf2()) {
1340 return DoDivByPowerOf2I(instr); 1346 return DoDivByPowerOf2I(instr);
1341 } else if (instr->right()->IsConstant()) { 1347 } else if (instr->right()->IsConstant()) {
1342 return DoDivByConstI(instr); 1348 return DoDivByConstI(instr);
1343 } else { 1349 } else {
1344 return DoDivI(instr); 1350 return DoDivI(instr);
1345 } 1351 }
1346 } else if (instr->representation().IsDouble()) { 1352 } else if (instr->representation().IsDouble()) {
1347 return DoArithmeticD(Token::DIV, instr); 1353 return DoArithmeticD(Token::DIV, instr);
1348 } else { 1354 } else {
1349 return DoArithmeticT(Token::DIV, instr); 1355 return DoArithmeticT(Token::DIV, instr);
1350 } 1356 }
1351 } 1357 }
1352 1358
1353 1359
1354 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) { 1360 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
1355 LOperand* dividend = UseRegisterAtStart(instr->left()); 1361 LOperand* dividend = UseRegisterAtStart(instr->left());
1356 int32_t divisor = instr->right()->GetInteger32Constant(); 1362 int32_t divisor = instr->right()->GetInteger32Constant();
1357 LInstruction* result = DefineAsRegister(new(zone()) LFlooringDivByPowerOf2I( 1363 LInstruction* result =
1358 dividend, divisor)); 1364 DefineAsRegister(new (zone()) LFlooringDivByPowerOf2I(dividend, divisor));
1359 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || 1365 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
1360 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { 1366 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
1361 result = AssignEnvironment(result); 1367 result = AssignEnvironment(result);
1362 } 1368 }
1363 return result; 1369 return result;
1364 } 1370 }
1365 1371
1366 1372
1367 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { 1373 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
1368 DCHECK(instr->representation().IsInteger32()); 1374 DCHECK(instr->representation().IsInteger32());
1369 DCHECK(instr->left()->representation().Equals(instr->representation())); 1375 DCHECK(instr->left()->representation().Equals(instr->representation()));
1370 DCHECK(instr->right()->representation().Equals(instr->representation())); 1376 DCHECK(instr->right()->representation().Equals(instr->representation()));
1371 LOperand* dividend = UseRegister(instr->left()); 1377 LOperand* dividend = UseRegister(instr->left());
1372 int32_t divisor = instr->right()->GetInteger32Constant(); 1378 int32_t divisor = instr->right()->GetInteger32Constant();
1373 LOperand* temp = 1379 LOperand* temp =
1374 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || 1380 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
1375 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? 1381 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive)))
1376 NULL : TempRegister(); 1382 ? NULL
1383 : TempRegister();
1377 LInstruction* result = DefineAsRegister( 1384 LInstruction* result = DefineAsRegister(
1378 new(zone()) LFlooringDivByConstI(dividend, divisor, temp)); 1385 new (zone()) LFlooringDivByConstI(dividend, divisor, temp));
1379 if (divisor == 0 || 1386 if (divisor == 0 ||
1380 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { 1387 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
1381 result = AssignEnvironment(result); 1388 result = AssignEnvironment(result);
1382 } 1389 }
1383 return result; 1390 return result;
1384 } 1391 }
1385 1392
1386 1393
1387 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { 1394 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
1388 DCHECK(instr->representation().IsSmiOrInteger32()); 1395 DCHECK(instr->representation().IsSmiOrInteger32());
1389 DCHECK(instr->left()->representation().Equals(instr->representation())); 1396 DCHECK(instr->left()->representation().Equals(instr->representation()));
1390 DCHECK(instr->right()->representation().Equals(instr->representation())); 1397 DCHECK(instr->right()->representation().Equals(instr->representation()));
1391 LOperand* dividend = UseRegister(instr->left()); 1398 LOperand* dividend = UseRegister(instr->left());
1392 LOperand* divisor = UseRegister(instr->right()); 1399 LOperand* divisor = UseRegister(instr->right());
1393 LOperand* temp = 1400 LFlooringDivI* div = new (zone()) LFlooringDivI(dividend, divisor);
1394 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister();
1395 LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor, temp);
1396 return AssignEnvironment(DefineAsRegister(div)); 1401 return AssignEnvironment(DefineAsRegister(div));
1397 } 1402 }
1398 1403
1399 1404
1400 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { 1405 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1401 if (instr->RightIsPowerOf2()) { 1406 if (instr->RightIsPowerOf2()) {
1402 return DoFlooringDivByPowerOf2I(instr); 1407 return DoFlooringDivByPowerOf2I(instr);
1403 } else if (instr->right()->IsConstant()) { 1408 } else if (instr->right()->IsConstant()) {
1404 return DoFlooringDivByConstI(instr); 1409 return DoFlooringDivByConstI(instr);
1405 } else { 1410 } else {
1406 return DoFlooringDivI(instr); 1411 return DoFlooringDivI(instr);
1407 } 1412 }
1408 } 1413 }
1409 1414
1410 1415
1411 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { 1416 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
1412 DCHECK(instr->representation().IsSmiOrInteger32()); 1417 DCHECK(instr->representation().IsSmiOrInteger32());
1413 DCHECK(instr->left()->representation().Equals(instr->representation())); 1418 DCHECK(instr->left()->representation().Equals(instr->representation()));
1414 DCHECK(instr->right()->representation().Equals(instr->representation())); 1419 DCHECK(instr->right()->representation().Equals(instr->representation()));
1415 LOperand* dividend = UseRegisterAtStart(instr->left()); 1420 LOperand* dividend = UseRegisterAtStart(instr->left());
1416 int32_t divisor = instr->right()->GetInteger32Constant(); 1421 int32_t divisor = instr->right()->GetInteger32Constant();
1417 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( 1422 LInstruction* result =
1418 dividend, divisor)); 1423 DefineSameAsFirst(new (zone()) LModByPowerOf2I(dividend, divisor));
1419 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && 1424 if (instr->CheckFlag(HValue::kLeftCanBeNegative) &&
1420 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1425 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1421 result = AssignEnvironment(result); 1426 result = AssignEnvironment(result);
1422 } 1427 }
1423 return result; 1428 return result;
1424 } 1429 }
1425 1430
1426 1431
1427 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { 1432 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
1428 DCHECK(instr->representation().IsSmiOrInteger32()); 1433 DCHECK(instr->representation().IsSmiOrInteger32());
1429 DCHECK(instr->left()->representation().Equals(instr->representation())); 1434 DCHECK(instr->left()->representation().Equals(instr->representation()));
1430 DCHECK(instr->right()->representation().Equals(instr->representation())); 1435 DCHECK(instr->right()->representation().Equals(instr->representation()));
1431 LOperand* dividend = UseRegister(instr->left()); 1436 LOperand* dividend = UseRegister(instr->left());
1432 int32_t divisor = instr->right()->GetInteger32Constant(); 1437 int32_t divisor = instr->right()->GetInteger32Constant();
1433 LInstruction* result = DefineAsRegister(new(zone()) LModByConstI( 1438 LInstruction* result =
1434 dividend, divisor)); 1439 DefineAsRegister(new (zone()) LModByConstI(dividend, divisor));
1435 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1440 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1436 result = AssignEnvironment(result); 1441 result = AssignEnvironment(result);
1437 } 1442 }
1438 return result; 1443 return result;
1439 } 1444 }
1440 1445
1441 1446
1442 LInstruction* LChunkBuilder::DoModI(HMod* instr) { 1447 LInstruction* LChunkBuilder::DoModI(HMod* instr) {
1443 DCHECK(instr->representation().IsSmiOrInteger32()); 1448 DCHECK(instr->representation().IsSmiOrInteger32());
1444 DCHECK(instr->left()->representation().Equals(instr->representation())); 1449 DCHECK(instr->left()->representation().Equals(instr->representation()));
1445 DCHECK(instr->right()->representation().Equals(instr->representation())); 1450 DCHECK(instr->right()->representation().Equals(instr->representation()));
1446 LOperand* dividend = UseRegister(instr->left()); 1451 LOperand* dividend = UseRegister(instr->left());
1447 LOperand* divisor = UseRegister(instr->right()); 1452 LOperand* divisor = UseRegister(instr->right());
1448 LOperand* temp = 1453 LInstruction* result =
1449 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister(); 1454 DefineAsRegister(new (zone()) LModI(dividend, divisor));
1450 LOperand* temp2 =
1451 CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister();
1452 LInstruction* result = DefineAsRegister(new(zone()) LModI(
1453 dividend, divisor, temp, temp2));
1454 if (instr->CheckFlag(HValue::kCanBeDivByZero) || 1455 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1455 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1456 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1456 result = AssignEnvironment(result); 1457 result = AssignEnvironment(result);
1457 } 1458 }
1458 return result; 1459 return result;
1459 } 1460 }
1460 1461
1461 1462
1462 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1463 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1463 if (instr->representation().IsSmiOrInteger32()) { 1464 if (instr->representation().IsSmiOrInteger32()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 right_op = UseRegister(right); 1505 right_op = UseRegister(right);
1505 } 1506 }
1506 } else { 1507 } else {
1507 if (bailout_on_minus_zero) { 1508 if (bailout_on_minus_zero) {
1508 left_op = UseRegister(left); 1509 left_op = UseRegister(left);
1509 } else { 1510 } else {
1510 left_op = UseRegisterAtStart(left); 1511 left_op = UseRegisterAtStart(left);
1511 } 1512 }
1512 right_op = UseRegister(right); 1513 right_op = UseRegister(right);
1513 } 1514 }
1514 LMulI* mul = new(zone()) LMulI(left_op, right_op); 1515 LMulI* mul = new (zone()) LMulI(left_op, right_op);
1515 if (can_overflow || bailout_on_minus_zero) { 1516 if (can_overflow || bailout_on_minus_zero) {
1516 AssignEnvironment(mul); 1517 AssignEnvironment(mul);
1517 } 1518 }
1518 return DefineAsRegister(mul); 1519 return DefineAsRegister(mul);
1519 1520
1520 } else if (instr->representation().IsDouble()) { 1521 } else if (instr->representation().IsDouble()) {
1521 if (instr->HasOneUse() && (instr->uses().value()->IsAdd() || 1522 if (instr->HasOneUse() &&
1522 instr->uses().value()->IsSub())) { 1523 (instr->uses().value()->IsAdd() || instr->uses().value()->IsSub())) {
1523 HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value()); 1524 HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value());
1524 1525
1525 if (use->IsAdd() && instr == use->left()) { 1526 if (use->IsAdd() && instr == use->left()) {
1526 // This mul is the lhs of an add. The add and mul will be folded into a 1527 // This mul is the lhs of an add. The add and mul will be folded into a
1527 // multiply-add in DoAdd. 1528 // multiply-add in DoAdd.
1528 return NULL; 1529 return NULL;
1529 } 1530 }
1530 if (instr == use->right() && use->IsAdd() && !use->left()->IsMul()) { 1531 if (instr == use->right() && use->IsAdd() &&
1532 !(use->left()->IsMul() && use->left()->HasOneUse())) {
1531 // This mul is the rhs of an add, where the lhs is not another mul. 1533 // This mul is the rhs of an add, where the lhs is not another mul.
1532 // The add and mul will be folded into a multiply-add in DoAdd. 1534 // The add and mul will be folded into a multiply-add in DoAdd.
1533 return NULL; 1535 return NULL;
1534 } 1536 }
1535 if (instr == use->right() && use->IsSub()) { 1537 if (instr == use->left() && use->IsSub()) {
1536 // This mul is the rhs of a sub. The sub and mul will be folded into a 1538 // This mul is the lhs of a sub. The mul and sub will be folded into a
1537 // multiply-sub in DoSub. 1539 // multiply-sub in DoSub.
1538 return NULL; 1540 return NULL;
1539 } 1541 }
1540 } 1542 }
1541 1543
1542 return DoArithmeticD(Token::MUL, instr); 1544 return DoArithmeticD(Token::MUL, instr);
1543 } else { 1545 } else {
1544 return DoArithmeticT(Token::MUL, instr); 1546 return DoArithmeticT(Token::MUL, instr);
1545 } 1547 }
1546 } 1548 }
1547 1549
1548 1550
1549 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 1551 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1550 if (instr->representation().IsSmiOrInteger32()) { 1552 if (instr->representation().IsSmiOrInteger32()) {
1551 DCHECK(instr->left()->representation().Equals(instr->representation())); 1553 DCHECK(instr->left()->representation().Equals(instr->representation()));
1552 DCHECK(instr->right()->representation().Equals(instr->representation())); 1554 DCHECK(instr->right()->representation().Equals(instr->representation()));
1553 1555
1554 if (instr->left()->IsConstant()) { 1556 if (instr->left()->IsConstant() &&
1557 !instr->CheckFlag(HValue::kCanOverflow)) {
1555 // If lhs is constant, do reverse subtraction instead. 1558 // If lhs is constant, do reverse subtraction instead.
1556 return DoRSub(instr); 1559 return DoRSub(instr);
1557 } 1560 }
1558 1561
1559 LOperand* left = UseRegisterAtStart(instr->left()); 1562 LOperand* left = UseRegisterAtStart(instr->left());
1560 LOperand* right = UseOrConstantAtStart(instr->right()); 1563 LOperand* right = UseOrConstantAtStart(instr->right());
1561 LSubI* sub = new(zone()) LSubI(left, right); 1564 LSubI* sub = new (zone()) LSubI(left, right);
1562 LInstruction* result = DefineAsRegister(sub); 1565 LInstruction* result = DefineAsRegister(sub);
1563 if (instr->CheckFlag(HValue::kCanOverflow)) { 1566 if (instr->CheckFlag(HValue::kCanOverflow)) {
1564 result = AssignEnvironment(result); 1567 result = AssignEnvironment(result);
1565 } 1568 }
1566 return result; 1569 return result;
1567 } else if (instr->representation().IsDouble()) { 1570 } else if (instr->representation().IsDouble()) {
1568 if (instr->right()->IsMul() && instr->right()->HasOneUse()) { 1571 if (instr->left()->IsMul() && instr->left()->HasOneUse()) {
1569 return DoMultiplySub(instr->left(), HMul::cast(instr->right())); 1572 return DoMultiplySub(instr->right(), HMul::cast(instr->left()));
1570 } 1573 }
1571 1574
1572 return DoArithmeticD(Token::SUB, instr); 1575 return DoArithmeticD(Token::SUB, instr);
1573 } else { 1576 } else {
1574 return DoArithmeticT(Token::SUB, instr); 1577 return DoArithmeticT(Token::SUB, instr);
1575 } 1578 }
1576 } 1579 }
1577 1580
1578 1581
1579 LInstruction* LChunkBuilder::DoRSub(HSub* instr) { 1582 LInstruction* LChunkBuilder::DoRSub(HSub* instr) {
1580 DCHECK(instr->representation().IsSmiOrInteger32()); 1583 DCHECK(instr->representation().IsSmiOrInteger32());
1581 DCHECK(instr->left()->representation().Equals(instr->representation())); 1584 DCHECK(instr->left()->representation().Equals(instr->representation()));
1582 DCHECK(instr->right()->representation().Equals(instr->representation())); 1585 DCHECK(instr->right()->representation().Equals(instr->representation()));
1586 DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
1583 1587
1584 // Note: The lhs of the subtraction becomes the rhs of the 1588 // Note: The lhs of the subtraction becomes the rhs of the
1585 // reverse-subtraction. 1589 // reverse-subtraction.
1586 LOperand* left = UseRegisterAtStart(instr->right()); 1590 LOperand* left = UseRegisterAtStart(instr->right());
1587 LOperand* right = UseOrConstantAtStart(instr->left()); 1591 LOperand* right = UseOrConstantAtStart(instr->left());
1588 LRSubI* rsb = new(zone()) LRSubI(left, right); 1592 LRSubI* rsb = new (zone()) LRSubI(left, right);
1589 LInstruction* result = DefineAsRegister(rsb); 1593 LInstruction* result = DefineAsRegister(rsb);
1590 if (instr->CheckFlag(HValue::kCanOverflow)) {
1591 result = AssignEnvironment(result);
1592 }
1593 return result; 1594 return result;
1594 } 1595 }
1595 1596
1596 1597
1597 LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) { 1598 LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) {
1598 LOperand* multiplier_op = UseRegisterAtStart(mul->left()); 1599 LOperand* multiplier_op = UseRegisterAtStart(mul->left());
1599 LOperand* multiplicand_op = UseRegisterAtStart(mul->right()); 1600 LOperand* multiplicand_op = UseRegisterAtStart(mul->right());
1600 LOperand* addend_op = UseRegisterAtStart(addend); 1601 LOperand* addend_op = UseRegisterAtStart(addend);
1601 return DefineSameAsFirst(new(zone()) LMultiplyAddD(addend_op, multiplier_op, 1602 return DefineSameAsFirst(
1602 multiplicand_op)); 1603 new (zone()) LMultiplyAddD(addend_op, multiplier_op, multiplicand_op));
1603 } 1604 }
1604 1605
1605 1606
1606 LInstruction* LChunkBuilder::DoMultiplySub(HValue* minuend, HMul* mul) { 1607 LInstruction* LChunkBuilder::DoMultiplySub(HValue* minuend, HMul* mul) {
1607 LOperand* minuend_op = UseRegisterAtStart(minuend); 1608 LOperand* minuend_op = UseRegisterAtStart(minuend);
1608 LOperand* multiplier_op = UseRegisterAtStart(mul->left()); 1609 LOperand* multiplier_op = UseRegisterAtStart(mul->left());
1609 LOperand* multiplicand_op = UseRegisterAtStart(mul->right()); 1610 LOperand* multiplicand_op = UseRegisterAtStart(mul->right());
1610 1611
1611 return DefineSameAsFirst(new(zone()) LMultiplySubD(minuend_op, 1612 return DefineSameAsFirst(
1612 multiplier_op, 1613 new (zone()) LMultiplySubD(minuend_op, multiplier_op, multiplicand_op));
1613 multiplicand_op));
1614 } 1614 }
1615 1615
1616 1616
1617 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { 1617 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1618 if (instr->representation().IsSmiOrInteger32()) { 1618 if (instr->representation().IsSmiOrInteger32()) {
1619 DCHECK(instr->left()->representation().Equals(instr->representation())); 1619 DCHECK(instr->left()->representation().Equals(instr->representation()));
1620 DCHECK(instr->right()->representation().Equals(instr->representation())); 1620 DCHECK(instr->right()->representation().Equals(instr->representation()));
1621 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); 1621 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1622 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); 1622 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1623 LAddI* add = new(zone()) LAddI(left, right); 1623 LAddI* add = new (zone()) LAddI(left, right);
1624 LInstruction* result = DefineAsRegister(add); 1624 LInstruction* result = DefineAsRegister(add);
1625 if (instr->CheckFlag(HValue::kCanOverflow)) { 1625 if (instr->CheckFlag(HValue::kCanOverflow)) {
1626 result = AssignEnvironment(result); 1626 result = AssignEnvironment(result);
1627 } 1627 }
1628 return result; 1628 return result;
1629 } else if (instr->representation().IsExternal()) { 1629 } else if (instr->representation().IsExternal()) {
1630 DCHECK(instr->left()->representation().IsExternal()); 1630 DCHECK(instr->left()->representation().IsExternal());
1631 DCHECK(instr->right()->representation().IsInteger32()); 1631 DCHECK(instr->right()->representation().IsInteger32());
1632 DCHECK(!instr->CheckFlag(HValue::kCanOverflow)); 1632 DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
1633 LOperand* left = UseRegisterAtStart(instr->left()); 1633 LOperand* left = UseRegisterAtStart(instr->left());
1634 LOperand* right = UseOrConstantAtStart(instr->right()); 1634 LOperand* right = UseOrConstantAtStart(instr->right());
1635 LAddI* add = new(zone()) LAddI(left, right); 1635 LAddI* add = new (zone()) LAddI(left, right);
1636 LInstruction* result = DefineAsRegister(add); 1636 LInstruction* result = DefineAsRegister(add);
1637 return result; 1637 return result;
1638 } else if (instr->representation().IsDouble()) { 1638 } else if (instr->representation().IsDouble()) {
1639 if (instr->left()->IsMul() && instr->left()->HasOneUse()) { 1639 if (instr->left()->IsMul() && instr->left()->HasOneUse()) {
1640 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right()); 1640 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
1641 } 1641 }
1642 1642
1643 if (instr->right()->IsMul() && instr->right()->HasOneUse()) { 1643 if (instr->right()->IsMul() && instr->right()->HasOneUse()) {
1644 DCHECK(!instr->left()->IsMul() || !instr->left()->HasOneUse()); 1644 DCHECK(!instr->left()->IsMul() || !instr->left()->HasOneUse());
1645 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left()); 1645 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left());
(...skipping 14 matching lines...) Expand all
1660 DCHECK(instr->right()->representation().Equals(instr->representation())); 1660 DCHECK(instr->right()->representation().Equals(instr->representation()));
1661 left = UseRegisterAtStart(instr->BetterLeftOperand()); 1661 left = UseRegisterAtStart(instr->BetterLeftOperand());
1662 right = UseOrConstantAtStart(instr->BetterRightOperand()); 1662 right = UseOrConstantAtStart(instr->BetterRightOperand());
1663 } else { 1663 } else {
1664 DCHECK(instr->representation().IsDouble()); 1664 DCHECK(instr->representation().IsDouble());
1665 DCHECK(instr->left()->representation().IsDouble()); 1665 DCHECK(instr->left()->representation().IsDouble());
1666 DCHECK(instr->right()->representation().IsDouble()); 1666 DCHECK(instr->right()->representation().IsDouble());
1667 left = UseRegisterAtStart(instr->left()); 1667 left = UseRegisterAtStart(instr->left());
1668 right = UseRegisterAtStart(instr->right()); 1668 right = UseRegisterAtStart(instr->right());
1669 } 1669 }
1670 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); 1670 return DefineAsRegister(new (zone()) LMathMinMax(left, right));
1671 } 1671 }
1672 1672
1673 1673
1674 LInstruction* LChunkBuilder::DoPower(HPower* instr) { 1674 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1675 DCHECK(instr->representation().IsDouble()); 1675 DCHECK(instr->representation().IsDouble());
1676 // We call a C function for double power. It can't trigger a GC. 1676 // We call a C function for double power. It can't trigger a GC.
1677 // We need to use fixed result register for the call. 1677 // We need to use fixed result register for the call.
1678 Representation exponent_type = instr->right()->representation(); 1678 Representation exponent_type = instr->right()->representation();
1679 DCHECK(instr->left()->representation().IsDouble()); 1679 DCHECK(instr->left()->representation().IsDouble());
1680 LOperand* left = UseFixedDouble(instr->left(), d0); 1680 LOperand* left = UseFixedDouble(instr->left(), d1);
1681 LOperand* right = exponent_type.IsDouble() ? 1681 LOperand* right = exponent_type.IsDouble()
1682 UseFixedDouble(instr->right(), d1) : 1682 ? UseFixedDouble(instr->right(), d2)
1683 UseFixed(instr->right(), r2); 1683 : UseFixed(instr->right(), r5);
1684 LPower* result = new(zone()) LPower(left, right); 1684 LPower* result = new (zone()) LPower(left, right);
1685 return MarkAsCall(DefineFixedDouble(result, d2), 1685 return MarkAsCall(DefineFixedDouble(result, d3), instr,
1686 instr,
1687 CAN_DEOPTIMIZE_EAGERLY); 1686 CAN_DEOPTIMIZE_EAGERLY);
1688 } 1687 }
1689 1688
1690 1689
1691 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { 1690 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1692 DCHECK(instr->left()->representation().IsTagged()); 1691 DCHECK(instr->left()->representation().IsTagged());
1693 DCHECK(instr->right()->representation().IsTagged()); 1692 DCHECK(instr->right()->representation().IsTagged());
1694 LOperand* context = UseFixed(instr->context(), cp); 1693 LOperand* context = UseFixed(instr->context(), cp);
1695 LOperand* left = UseFixed(instr->left(), r1); 1694 LOperand* left = UseFixed(instr->left(), r4);
1696 LOperand* right = UseFixed(instr->right(), r0); 1695 LOperand* right = UseFixed(instr->right(), r3);
1697 LCmpT* result = new(zone()) LCmpT(context, left, right); 1696 LCmpT* result = new (zone()) LCmpT(context, left, right);
1698 return MarkAsCall(DefineFixed(result, r0), instr); 1697 return MarkAsCall(DefineFixed(result, r3), instr);
1699 } 1698 }
1700 1699
1701 1700
1702 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( 1701 LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
1703 HCompareNumericAndBranch* instr) { 1702 HCompareNumericAndBranch* instr) {
1704 Representation r = instr->representation(); 1703 Representation r = instr->representation();
1705 if (r.IsSmiOrInteger32()) { 1704 if (r.IsSmiOrInteger32()) {
1706 DCHECK(instr->left()->representation().Equals(r)); 1705 DCHECK(instr->left()->representation().Equals(r));
1707 DCHECK(instr->right()->representation().Equals(r)); 1706 DCHECK(instr->right()->representation().Equals(r));
1708 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); 1707 LOperand* left = UseRegisterOrConstantAtStart(instr->left());
1709 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); 1708 LOperand* right = UseRegisterOrConstantAtStart(instr->right());
1710 return new(zone()) LCompareNumericAndBranch(left, right); 1709 return new (zone()) LCompareNumericAndBranch(left, right);
1711 } else { 1710 } else {
1712 DCHECK(r.IsDouble()); 1711 DCHECK(r.IsDouble());
1713 DCHECK(instr->left()->representation().IsDouble()); 1712 DCHECK(instr->left()->representation().IsDouble());
1714 DCHECK(instr->right()->representation().IsDouble()); 1713 DCHECK(instr->right()->representation().IsDouble());
1715 LOperand* left = UseRegisterAtStart(instr->left()); 1714 LOperand* left = UseRegisterAtStart(instr->left());
1716 LOperand* right = UseRegisterAtStart(instr->right()); 1715 LOperand* right = UseRegisterAtStart(instr->right());
1717 return new(zone()) LCompareNumericAndBranch(left, right); 1716 return new (zone()) LCompareNumericAndBranch(left, right);
1718 } 1717 }
1719 } 1718 }
1720 1719
1721 1720
1722 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( 1721 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
1723 HCompareObjectEqAndBranch* instr) { 1722 HCompareObjectEqAndBranch* instr) {
1724 LOperand* left = UseRegisterAtStart(instr->left()); 1723 LOperand* left = UseRegisterAtStart(instr->left());
1725 LOperand* right = UseRegisterAtStart(instr->right()); 1724 LOperand* right = UseRegisterAtStart(instr->right());
1726 return new(zone()) LCmpObjectEqAndBranch(left, right); 1725 return new (zone()) LCmpObjectEqAndBranch(left, right);
1727 } 1726 }
1728 1727
1729 1728
1730 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( 1729 LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
1731 HCompareHoleAndBranch* instr) { 1730 HCompareHoleAndBranch* instr) {
1732 LOperand* value = UseRegisterAtStart(instr->value()); 1731 LOperand* value = UseRegisterAtStart(instr->value());
1733 return new(zone()) LCmpHoleAndBranch(value); 1732 return new (zone()) LCmpHoleAndBranch(value);
1734 } 1733 }
1735 1734
1736 1735
1737 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( 1736 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
1738 HCompareMinusZeroAndBranch* instr) { 1737 HCompareMinusZeroAndBranch* instr) {
1739 LOperand* value = UseRegister(instr->value()); 1738 LOperand* value = UseRegister(instr->value());
1740 LOperand* scratch = TempRegister(); 1739 LOperand* scratch = TempRegister();
1741 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); 1740 return new (zone()) LCompareMinusZeroAndBranch(value, scratch);
1742 } 1741 }
1743 1742
1744 1743
1745 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { 1744 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1746 DCHECK(instr->value()->representation().IsTagged()); 1745 DCHECK(instr->value()->representation().IsTagged());
1747 LOperand* value = UseRegisterAtStart(instr->value()); 1746 LOperand* value = UseRegisterAtStart(instr->value());
1748 LOperand* temp = TempRegister(); 1747 LOperand* temp = TempRegister();
1749 return new(zone()) LIsObjectAndBranch(value, temp); 1748 return new (zone()) LIsObjectAndBranch(value, temp);
1750 } 1749 }
1751 1750
1752 1751
1753 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { 1752 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1754 DCHECK(instr->value()->representation().IsTagged()); 1753 DCHECK(instr->value()->representation().IsTagged());
1755 LOperand* value = UseRegisterAtStart(instr->value()); 1754 LOperand* value = UseRegisterAtStart(instr->value());
1756 LOperand* temp = TempRegister(); 1755 LOperand* temp = TempRegister();
1757 return new(zone()) LIsStringAndBranch(value, temp); 1756 return new (zone()) LIsStringAndBranch(value, temp);
1758 } 1757 }
1759 1758
1760 1759
1761 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { 1760 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1762 DCHECK(instr->value()->representation().IsTagged()); 1761 DCHECK(instr->value()->representation().IsTagged());
1763 return new(zone()) LIsSmiAndBranch(Use(instr->value())); 1762 return new (zone()) LIsSmiAndBranch(Use(instr->value()));
1764 } 1763 }
1765 1764
1766 1765
1767 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( 1766 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
1768 HIsUndetectableAndBranch* instr) { 1767 HIsUndetectableAndBranch* instr) {
1769 DCHECK(instr->value()->representation().IsTagged()); 1768 DCHECK(instr->value()->representation().IsTagged());
1770 LOperand* value = UseRegisterAtStart(instr->value()); 1769 LOperand* value = UseRegisterAtStart(instr->value());
1771 return new(zone()) LIsUndetectableAndBranch(value, TempRegister()); 1770 return new (zone()) LIsUndetectableAndBranch(value, TempRegister());
1772 } 1771 }
1773 1772
1774 1773
1775 LInstruction* LChunkBuilder::DoStringCompareAndBranch( 1774 LInstruction* LChunkBuilder::DoStringCompareAndBranch(
1776 HStringCompareAndBranch* instr) { 1775 HStringCompareAndBranch* instr) {
1777 DCHECK(instr->left()->representation().IsTagged()); 1776 DCHECK(instr->left()->representation().IsTagged());
1778 DCHECK(instr->right()->representation().IsTagged()); 1777 DCHECK(instr->right()->representation().IsTagged());
1779 LOperand* context = UseFixed(instr->context(), cp); 1778 LOperand* context = UseFixed(instr->context(), cp);
1780 LOperand* left = UseFixed(instr->left(), r1); 1779 LOperand* left = UseFixed(instr->left(), r4);
1781 LOperand* right = UseFixed(instr->right(), r0); 1780 LOperand* right = UseFixed(instr->right(), r3);
1782 LStringCompareAndBranch* result = 1781 LStringCompareAndBranch* result =
1783 new(zone()) LStringCompareAndBranch(context, left, right); 1782 new (zone()) LStringCompareAndBranch(context, left, right);
1784 return MarkAsCall(result, instr); 1783 return MarkAsCall(result, instr);
1785 } 1784 }
1786 1785
1787 1786
1788 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( 1787 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
1789 HHasInstanceTypeAndBranch* instr) { 1788 HHasInstanceTypeAndBranch* instr) {
1790 DCHECK(instr->value()->representation().IsTagged()); 1789 DCHECK(instr->value()->representation().IsTagged());
1791 LOperand* value = UseRegisterAtStart(instr->value()); 1790 LOperand* value = UseRegisterAtStart(instr->value());
1792 return new(zone()) LHasInstanceTypeAndBranch(value); 1791 return new (zone()) LHasInstanceTypeAndBranch(value);
1793 } 1792 }
1794 1793
1795 1794
1796 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( 1795 LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1797 HGetCachedArrayIndex* instr) { 1796 HGetCachedArrayIndex* instr) {
1798 DCHECK(instr->value()->representation().IsTagged()); 1797 DCHECK(instr->value()->representation().IsTagged());
1799 LOperand* value = UseRegisterAtStart(instr->value()); 1798 LOperand* value = UseRegisterAtStart(instr->value());
1800 1799
1801 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); 1800 return DefineAsRegister(new (zone()) LGetCachedArrayIndex(value));
1802 } 1801 }
1803 1802
1804 1803
1805 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( 1804 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
1806 HHasCachedArrayIndexAndBranch* instr) { 1805 HHasCachedArrayIndexAndBranch* instr) {
1807 DCHECK(instr->value()->representation().IsTagged()); 1806 DCHECK(instr->value()->representation().IsTagged());
1808 return new(zone()) LHasCachedArrayIndexAndBranch( 1807 return new (zone())
1809 UseRegisterAtStart(instr->value())); 1808 LHasCachedArrayIndexAndBranch(UseRegisterAtStart(instr->value()));
1810 } 1809 }
1811 1810
1812 1811
1813 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( 1812 LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
1814 HClassOfTestAndBranch* instr) { 1813 HClassOfTestAndBranch* instr) {
1815 DCHECK(instr->value()->representation().IsTagged()); 1814 DCHECK(instr->value()->representation().IsTagged());
1816 LOperand* value = UseRegister(instr->value()); 1815 LOperand* value = UseRegister(instr->value());
1817 return new(zone()) LClassOfTestAndBranch(value, TempRegister()); 1816 return new (zone()) LClassOfTestAndBranch(value, TempRegister());
1818 } 1817 }
1819 1818
1820 1819
1821 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { 1820 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
1822 LOperand* map = UseRegisterAtStart(instr->value()); 1821 LOperand* map = UseRegisterAtStart(instr->value());
1823 return DefineAsRegister(new(zone()) LMapEnumLength(map)); 1822 return DefineAsRegister(new (zone()) LMapEnumLength(map));
1824 } 1823 }
1825 1824
1826 1825
1827 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { 1826 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
1828 LOperand* object = UseFixed(instr->value(), r0); 1827 LOperand* object = UseFixed(instr->value(), r3);
1829 LDateField* result = 1828 LDateField* result =
1830 new(zone()) LDateField(object, FixedTemp(r1), instr->index()); 1829 new (zone()) LDateField(object, FixedTemp(r4), instr->index());
1831 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 1830 return MarkAsCall(DefineFixed(result, r3), instr, CAN_DEOPTIMIZE_EAGERLY);
1832 } 1831 }
1833 1832
1834 1833
1835 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) { 1834 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
1836 LOperand* string = UseRegisterAtStart(instr->string()); 1835 LOperand* string = UseRegisterAtStart(instr->string());
1837 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); 1836 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1838 return DefineAsRegister(new(zone()) LSeqStringGetChar(string, index)); 1837 return DefineAsRegister(new (zone()) LSeqStringGetChar(string, index));
1839 } 1838 }
1840 1839
1841 1840
1842 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { 1841 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
1843 LOperand* string = UseRegisterAtStart(instr->string()); 1842 LOperand* string = UseRegisterAtStart(instr->string());
1844 LOperand* index = FLAG_debug_code 1843 LOperand* index = FLAG_debug_code
1845 ? UseRegisterAtStart(instr->index()) 1844 ? UseRegisterAtStart(instr->index())
1846 : UseRegisterOrConstantAtStart(instr->index()); 1845 : UseRegisterOrConstantAtStart(instr->index());
1847 LOperand* value = UseRegisterAtStart(instr->value()); 1846 LOperand* value = UseRegisterAtStart(instr->value());
1848 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL; 1847 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL;
1849 return new(zone()) LSeqStringSetChar(context, string, index, value); 1848 return new (zone()) LSeqStringSetChar(context, string, index, value);
1850 } 1849 }
1851 1850
1852 1851
1853 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1852 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1854 if (!FLAG_debug_code && instr->skip_check()) return NULL; 1853 if (!FLAG_debug_code && instr->skip_check()) return NULL;
1855 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); 1854 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
1856 LOperand* length = !index->IsConstantOperand() 1855 LOperand* length = !index->IsConstantOperand()
1857 ? UseRegisterOrConstantAtStart(instr->length()) 1856 ? UseRegisterOrConstantAtStart(instr->length())
1858 : UseRegisterAtStart(instr->length()); 1857 : UseRegisterAtStart(instr->length());
1859 LInstruction* result = new(zone()) LBoundsCheck(index, length); 1858 LInstruction* result = new (zone()) LBoundsCheck(index, length);
1860 if (!FLAG_debug_code || !instr->skip_check()) { 1859 if (!FLAG_debug_code || !instr->skip_check()) {
1861 result = AssignEnvironment(result); 1860 result = AssignEnvironment(result);
1862 } 1861 }
1863 return result; 1862 return result;
1864 } 1863 }
1865 1864
1866 1865
1867 LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation( 1866 LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation(
1868 HBoundsCheckBaseIndexInformation* instr) { 1867 HBoundsCheckBaseIndexInformation* instr) {
1869 UNREACHABLE(); 1868 UNREACHABLE();
1870 return NULL; 1869 return NULL;
1871 } 1870 }
1872 1871
1873 1872
1874 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { 1873 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1875 // The control instruction marking the end of a block that completed 1874 // The control instruction marking the end of a block that completed
1876 // abruptly (e.g., threw an exception). There is nothing specific to do. 1875 // abruptly (e.g., threw an exception). There is nothing specific to do.
1877 return NULL; 1876 return NULL;
1878 } 1877 }
1879 1878
1880 1879
1881 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { 1880 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { return NULL; }
1882 return NULL;
1883 }
1884 1881
1885 1882
1886 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { 1883 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
1887 // All HForceRepresentation instructions should be eliminated in the 1884 // All HForceRepresentation instructions should be eliminated in the
1888 // representation change phase of Hydrogen. 1885 // representation change phase of Hydrogen.
1889 UNREACHABLE(); 1886 UNREACHABLE();
1890 return NULL; 1887 return NULL;
1891 } 1888 }
1892 1889
1893 1890
1894 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1891 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1895 Representation from = instr->from(); 1892 Representation from = instr->from();
1896 Representation to = instr->to(); 1893 Representation to = instr->to();
1897 HValue* val = instr->value(); 1894 HValue* val = instr->value();
1898 if (from.IsSmi()) { 1895 if (from.IsSmi()) {
1899 if (to.IsTagged()) { 1896 if (to.IsTagged()) {
1900 LOperand* value = UseRegister(val); 1897 LOperand* value = UseRegister(val);
1901 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1898 return DefineSameAsFirst(new (zone()) LDummyUse(value));
1902 } 1899 }
1903 from = Representation::Tagged(); 1900 from = Representation::Tagged();
1904 } 1901 }
1905 if (from.IsTagged()) { 1902 if (from.IsTagged()) {
1906 if (to.IsDouble()) { 1903 if (to.IsDouble()) {
1907 LOperand* value = UseRegister(val); 1904 LOperand* value = UseRegister(val);
1908 LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value)); 1905 LInstruction* result =
1906 DefineAsRegister(new (zone()) LNumberUntagD(value));
1909 if (!val->representation().IsSmi()) result = AssignEnvironment(result); 1907 if (!val->representation().IsSmi()) result = AssignEnvironment(result);
1910 return result; 1908 return result;
1911 } else if (to.IsSmi()) { 1909 } else if (to.IsSmi()) {
1912 LOperand* value = UseRegister(val); 1910 LOperand* value = UseRegister(val);
1913 if (val->type().IsSmi()) { 1911 if (val->type().IsSmi()) {
1914 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1912 return DefineSameAsFirst(new (zone()) LDummyUse(value));
1915 } 1913 }
1916 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); 1914 return AssignEnvironment(
1915 DefineSameAsFirst(new (zone()) LCheckSmi(value)));
1917 } else { 1916 } else {
1918 DCHECK(to.IsInteger32()); 1917 DCHECK(to.IsInteger32());
1919 if (val->type().IsSmi() || val->representation().IsSmi()) { 1918 if (val->type().IsSmi() || val->representation().IsSmi()) {
1920 LOperand* value = UseRegisterAtStart(val); 1919 LOperand* value = UseRegisterAtStart(val);
1921 return DefineAsRegister(new(zone()) LSmiUntag(value, false)); 1920 return DefineAsRegister(new (zone()) LSmiUntag(value, false));
1922 } else { 1921 } else {
1923 LOperand* value = UseRegister(val); 1922 LOperand* value = UseRegister(val);
1924 LOperand* temp1 = TempRegister(); 1923 LOperand* temp1 = TempRegister();
1925 LOperand* temp2 = TempDoubleRegister(); 1924 LOperand* temp2 = TempDoubleRegister();
1926 LInstruction* result = 1925 LInstruction* result =
1927 DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2)); 1926 DefineSameAsFirst(new (zone()) LTaggedToI(value, temp1, temp2));
1928 if (!val->representation().IsSmi()) result = AssignEnvironment(result); 1927 if (!val->representation().IsSmi()) result = AssignEnvironment(result);
1929 return result; 1928 return result;
1930 } 1929 }
1931 } 1930 }
1932 } else if (from.IsDouble()) { 1931 } else if (from.IsDouble()) {
1933 if (to.IsTagged()) { 1932 if (to.IsTagged()) {
1934 info()->MarkAsDeferredCalling(); 1933 info()->MarkAsDeferredCalling();
1935 LOperand* value = UseRegister(val); 1934 LOperand* value = UseRegister(val);
1936 LOperand* temp1 = TempRegister(); 1935 LOperand* temp1 = TempRegister();
1937 LOperand* temp2 = TempRegister(); 1936 LOperand* temp2 = TempRegister();
1938 LUnallocated* result_temp = TempRegister(); 1937 LUnallocated* result_temp = TempRegister();
1939 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); 1938 LNumberTagD* result = new (zone()) LNumberTagD(value, temp1, temp2);
1940 return AssignPointerMap(Define(result, result_temp)); 1939 return AssignPointerMap(Define(result, result_temp));
1941 } else if (to.IsSmi()) { 1940 } else if (to.IsSmi()) {
1942 LOperand* value = UseRegister(val); 1941 LOperand* value = UseRegister(val);
1943 return AssignEnvironment( 1942 return AssignEnvironment(
1944 DefineAsRegister(new(zone()) LDoubleToSmi(value))); 1943 DefineAsRegister(new (zone()) LDoubleToSmi(value)));
1945 } else { 1944 } else {
1946 DCHECK(to.IsInteger32()); 1945 DCHECK(to.IsInteger32());
1947 LOperand* value = UseRegister(val); 1946 LOperand* value = UseRegister(val);
1948 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value)); 1947 LInstruction* result = DefineAsRegister(new (zone()) LDoubleToI(value));
1949 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result); 1948 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
1950 return result; 1949 return result;
1951 } 1950 }
1952 } else if (from.IsInteger32()) { 1951 } else if (from.IsInteger32()) {
1953 info()->MarkAsDeferredCalling(); 1952 info()->MarkAsDeferredCalling();
1954 if (to.IsTagged()) { 1953 if (to.IsTagged()) {
1955 if (!instr->CheckFlag(HValue::kCanOverflow)) { 1954 if (!instr->CheckFlag(HValue::kCanOverflow)) {
1956 LOperand* value = UseRegisterAtStart(val); 1955 LOperand* value = UseRegisterAtStart(val);
1957 return DefineAsRegister(new(zone()) LSmiTag(value)); 1956 return DefineAsRegister(new (zone()) LSmiTag(value));
1958 } else if (val->CheckFlag(HInstruction::kUint32)) { 1957 } else if (val->CheckFlag(HInstruction::kUint32)) {
1959 LOperand* value = UseRegisterAtStart(val); 1958 LOperand* value = UseRegisterAtStart(val);
1960 LOperand* temp1 = TempRegister(); 1959 LOperand* temp1 = TempRegister();
1961 LOperand* temp2 = TempRegister(); 1960 LOperand* temp2 = TempRegister();
1962 LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2); 1961 LNumberTagU* result = new (zone()) LNumberTagU(value, temp1, temp2);
1963 return AssignPointerMap(DefineAsRegister(result)); 1962 return AssignPointerMap(DefineAsRegister(result));
1964 } else { 1963 } else {
1965 LOperand* value = UseRegisterAtStart(val); 1964 LOperand* value = UseRegisterAtStart(val);
1966 LOperand* temp1 = TempRegister(); 1965 LOperand* temp1 = TempRegister();
1967 LOperand* temp2 = TempRegister(); 1966 LOperand* temp2 = TempRegister();
1968 LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2); 1967 LNumberTagI* result = new (zone()) LNumberTagI(value, temp1, temp2);
1969 return AssignPointerMap(DefineAsRegister(result)); 1968 return AssignPointerMap(DefineAsRegister(result));
1970 } 1969 }
1971 } else if (to.IsSmi()) { 1970 } else if (to.IsSmi()) {
1972 LOperand* value = UseRegister(val); 1971 LOperand* value = UseRegister(val);
1973 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); 1972 LInstruction* result = DefineAsRegister(new (zone()) LSmiTag(value));
1974 if (instr->CheckFlag(HValue::kCanOverflow)) { 1973 if (instr->CheckFlag(HValue::kCanOverflow)) {
1975 result = AssignEnvironment(result); 1974 result = AssignEnvironment(result);
1976 } 1975 }
1977 return result; 1976 return result;
1978 } else { 1977 } else {
1979 DCHECK(to.IsDouble()); 1978 DCHECK(to.IsDouble());
1980 if (val->CheckFlag(HInstruction::kUint32)) { 1979 if (val->CheckFlag(HInstruction::kUint32)) {
1981 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val))); 1980 return DefineAsRegister(new (zone()) LUint32ToDouble(UseRegister(val)));
1982 } else { 1981 } else {
1983 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val))); 1982 return DefineAsRegister(new (zone()) LInteger32ToDouble(Use(val)));
1984 } 1983 }
1985 } 1984 }
1986 } 1985 }
1987 UNREACHABLE(); 1986 UNREACHABLE();
1988 return NULL; 1987 return NULL;
1989 } 1988 }
1990 1989
1991 1990
1992 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { 1991 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
1993 LOperand* value = UseRegisterAtStart(instr->value()); 1992 LOperand* value = UseRegisterAtStart(instr->value());
1994 LInstruction* result = new(zone()) LCheckNonSmi(value); 1993 LInstruction* result = new (zone()) LCheckNonSmi(value);
1995 if (!instr->value()->type().IsHeapObject()) { 1994 if (!instr->value()->type().IsHeapObject()) {
1996 result = AssignEnvironment(result); 1995 result = AssignEnvironment(result);
1997 } 1996 }
1998 return result; 1997 return result;
1999 } 1998 }
2000 1999
2001 2000
2002 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { 2001 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
2003 LOperand* value = UseRegisterAtStart(instr->value()); 2002 LOperand* value = UseRegisterAtStart(instr->value());
2004 return AssignEnvironment(new(zone()) LCheckSmi(value)); 2003 return AssignEnvironment(new (zone()) LCheckSmi(value));
2005 } 2004 }
2006 2005
2007 2006
2008 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { 2007 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
2009 LOperand* value = UseRegisterAtStart(instr->value()); 2008 LOperand* value = UseRegisterAtStart(instr->value());
2010 LInstruction* result = new(zone()) LCheckInstanceType(value); 2009 LInstruction* result = new (zone()) LCheckInstanceType(value);
2011 return AssignEnvironment(result); 2010 return AssignEnvironment(result);
2012 } 2011 }
2013 2012
2014 2013
2015 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) { 2014 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
2016 LOperand* value = UseRegisterAtStart(instr->value()); 2015 LOperand* value = UseRegisterAtStart(instr->value());
2017 return AssignEnvironment(new(zone()) LCheckValue(value)); 2016 return AssignEnvironment(new (zone()) LCheckValue(value));
2018 } 2017 }
2019 2018
2020 2019
2021 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { 2020 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
2022 if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps; 2021 if (instr->IsStabilityCheck()) return new (zone()) LCheckMaps;
2023 LOperand* value = UseRegisterAtStart(instr->value()); 2022 LOperand* value = UseRegisterAtStart(instr->value());
2024 LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value)); 2023 LInstruction* result = AssignEnvironment(new (zone()) LCheckMaps(value));
2025 if (instr->HasMigrationTarget()) { 2024 if (instr->HasMigrationTarget()) {
2026 info()->MarkAsDeferredCalling(); 2025 info()->MarkAsDeferredCalling();
2027 result = AssignPointerMap(result); 2026 result = AssignPointerMap(result);
2028 } 2027 }
2029 return result; 2028 return result;
2030 } 2029 }
2031 2030
2032 2031
2033 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { 2032 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
2034 HValue* value = instr->value(); 2033 HValue* value = instr->value();
2035 Representation input_rep = value->representation(); 2034 Representation input_rep = value->representation();
2036 LOperand* reg = UseRegister(value); 2035 LOperand* reg = UseRegister(value);
2037 if (input_rep.IsDouble()) { 2036 if (input_rep.IsDouble()) {
2038 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); 2037 return DefineAsRegister(new (zone()) LClampDToUint8(reg));
2039 } else if (input_rep.IsInteger32()) { 2038 } else if (input_rep.IsInteger32()) {
2040 return DefineAsRegister(new(zone()) LClampIToUint8(reg)); 2039 return DefineAsRegister(new (zone()) LClampIToUint8(reg));
2041 } else { 2040 } else {
2042 DCHECK(input_rep.IsSmiOrTagged()); 2041 DCHECK(input_rep.IsSmiOrTagged());
2043 // Register allocator doesn't (yet) support allocation of double
2044 // temps. Reserve d1 explicitly.
2045 LClampTToUint8* result = 2042 LClampTToUint8* result =
2046 new(zone()) LClampTToUint8(reg, TempDoubleRegister()); 2043 new (zone()) LClampTToUint8(reg, TempDoubleRegister());
2047 return AssignEnvironment(DefineAsRegister(result)); 2044 return AssignEnvironment(DefineAsRegister(result));
2048 } 2045 }
2049 } 2046 }
2050 2047
2051 2048
2052 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { 2049 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
2053 HValue* value = instr->value(); 2050 HValue* value = instr->value();
2054 DCHECK(value->representation().IsDouble()); 2051 DCHECK(value->representation().IsDouble());
2055 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); 2052 return DefineAsRegister(new (zone()) LDoubleBits(UseRegister(value)));
2056 } 2053 }
2057 2054
2058 2055
2059 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { 2056 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
2060 LOperand* lo = UseRegister(instr->lo()); 2057 LOperand* lo = UseRegister(instr->lo());
2061 LOperand* hi = UseRegister(instr->hi()); 2058 LOperand* hi = UseRegister(instr->hi());
2062 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); 2059 return DefineAsRegister(new (zone()) LConstructDouble(hi, lo));
2063 } 2060 }
2064 2061
2065 2062
2066 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 2063 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
2067 LOperand* context = info()->IsStub() 2064 LOperand* context = info()->IsStub() ? UseFixed(instr->context(), cp) : NULL;
2068 ? UseFixed(instr->context(), cp)
2069 : NULL;
2070 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); 2065 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
2071 return new(zone()) LReturn(UseFixed(instr->value(), r0), context, 2066 return new (zone())
2072 parameter_count); 2067 LReturn(UseFixed(instr->value(), r3), context, parameter_count);
2073 } 2068 }
2074 2069
2075 2070
2076 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 2071 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
2077 Representation r = instr->representation(); 2072 Representation r = instr->representation();
2078 if (r.IsSmi()) { 2073 if (r.IsSmi()) {
2079 return DefineAsRegister(new(zone()) LConstantS); 2074 return DefineAsRegister(new (zone()) LConstantS);
2080 } else if (r.IsInteger32()) { 2075 } else if (r.IsInteger32()) {
2081 return DefineAsRegister(new(zone()) LConstantI); 2076 return DefineAsRegister(new (zone()) LConstantI);
2082 } else if (r.IsDouble()) { 2077 } else if (r.IsDouble()) {
2083 return DefineAsRegister(new(zone()) LConstantD); 2078 return DefineAsRegister(new (zone()) LConstantD);
2084 } else if (r.IsExternal()) { 2079 } else if (r.IsExternal()) {
2085 return DefineAsRegister(new(zone()) LConstantE); 2080 return DefineAsRegister(new (zone()) LConstantE);
2086 } else if (r.IsTagged()) { 2081 } else if (r.IsTagged()) {
2087 return DefineAsRegister(new(zone()) LConstantT); 2082 return DefineAsRegister(new (zone()) LConstantT);
2088 } else { 2083 } else {
2089 UNREACHABLE(); 2084 UNREACHABLE();
2090 return NULL; 2085 return NULL;
2091 } 2086 }
2092 } 2087 }
2093 2088
2094 2089
2095 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { 2090 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
2096 LLoadGlobalCell* result = new(zone()) LLoadGlobalCell; 2091 LLoadGlobalCell* result = new (zone()) LLoadGlobalCell;
2097 return instr->RequiresHoleCheck() 2092 return instr->RequiresHoleCheck()
2098 ? AssignEnvironment(DefineAsRegister(result)) 2093 ? AssignEnvironment(DefineAsRegister(result))
2099 : DefineAsRegister(result); 2094 : DefineAsRegister(result);
2100 } 2095 }
2101 2096
2102 2097
2103 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { 2098 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
2104 LOperand* context = UseFixed(instr->context(), cp); 2099 LOperand* context = UseFixed(instr->context(), cp);
2105 LOperand* global_object = UseFixed(instr->global_object(), 2100 LOperand* global_object =
2106 LoadIC::ReceiverRegister()); 2101 UseFixed(instr->global_object(), LoadIC::ReceiverRegister());
2107 LOperand* vector = NULL; 2102 LOperand* vector = NULL;
2108 if (FLAG_vector_ics) { 2103 if (FLAG_vector_ics) {
2109 vector = FixedTemp(LoadIC::VectorRegister()); 2104 vector = FixedTemp(LoadIC::VectorRegister());
2110 } 2105 }
2111 LLoadGlobalGeneric* result = 2106 LLoadGlobalGeneric* result =
2112 new(zone()) LLoadGlobalGeneric(context, global_object, vector); 2107 new (zone()) LLoadGlobalGeneric(context, global_object, vector);
2113 return MarkAsCall(DefineFixed(result, r0), instr); 2108 return MarkAsCall(DefineFixed(result, r3), instr);
2114 } 2109 }
2115 2110
2116 2111
2117 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { 2112 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
2118 LOperand* value = UseRegister(instr->value()); 2113 LOperand* value = UseRegister(instr->value());
2119 // Use a temp to check the value in the cell in the case where we perform 2114 // Use a temp to check the value in the cell in the case where we perform
2120 // a hole check. 2115 // a hole check.
2121 return instr->RequiresHoleCheck() 2116 return instr->RequiresHoleCheck()
2122 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) 2117 ? AssignEnvironment(new (zone())
2123 : new(zone()) LStoreGlobalCell(value, NULL); 2118 LStoreGlobalCell(value, TempRegister()))
2119 : new (zone()) LStoreGlobalCell(value, NULL);
2124 } 2120 }
2125 2121
2126 2122
2127 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 2123 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
2128 LOperand* context = UseRegisterAtStart(instr->value()); 2124 LOperand* context = UseRegisterAtStart(instr->value());
2129 LInstruction* result = 2125 LInstruction* result =
2130 DefineAsRegister(new(zone()) LLoadContextSlot(context)); 2126 DefineAsRegister(new (zone()) LLoadContextSlot(context));
2131 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) { 2127 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2132 result = AssignEnvironment(result); 2128 result = AssignEnvironment(result);
2133 } 2129 }
2134 return result; 2130 return result;
2135 } 2131 }
2136 2132
2137 2133
2138 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { 2134 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2139 LOperand* context; 2135 LOperand* context;
2140 LOperand* value; 2136 LOperand* value;
2141 if (instr->NeedsWriteBarrier()) { 2137 if (instr->NeedsWriteBarrier()) {
2142 context = UseTempRegister(instr->context()); 2138 context = UseTempRegister(instr->context());
2143 value = UseTempRegister(instr->value()); 2139 value = UseTempRegister(instr->value());
2144 } else { 2140 } else {
2145 context = UseRegister(instr->context()); 2141 context = UseRegister(instr->context());
2146 value = UseRegister(instr->value()); 2142 value = UseRegister(instr->value());
2147 } 2143 }
2148 LInstruction* result = new(zone()) LStoreContextSlot(context, value); 2144 LInstruction* result = new (zone()) LStoreContextSlot(context, value);
2149 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) { 2145 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2150 result = AssignEnvironment(result); 2146 result = AssignEnvironment(result);
2151 } 2147 }
2152 return result; 2148 return result;
2153 } 2149 }
2154 2150
2155 2151
2156 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 2152 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2157 LOperand* obj = UseRegisterAtStart(instr->object()); 2153 LOperand* obj = UseRegisterAtStart(instr->object());
2158 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); 2154 return DefineAsRegister(new (zone()) LLoadNamedField(obj));
2159 } 2155 }
2160 2156
2161 2157
2162 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { 2158 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
2163 LOperand* context = UseFixed(instr->context(), cp); 2159 LOperand* context = UseFixed(instr->context(), cp);
2164 LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); 2160 LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
2165 LOperand* vector = NULL; 2161 LOperand* vector = NULL;
2166 if (FLAG_vector_ics) { 2162 if (FLAG_vector_ics) {
2167 vector = FixedTemp(LoadIC::VectorRegister()); 2163 vector = FixedTemp(LoadIC::VectorRegister());
2168 } 2164 }
2169 2165
2170 LInstruction* result = 2166 LInstruction* result =
2171 DefineFixed(new(zone()) LLoadNamedGeneric(context, object, vector), r0); 2167 DefineFixed(new (zone()) LLoadNamedGeneric(context, object, vector), r3);
2172 return MarkAsCall(result, instr); 2168 return MarkAsCall(result, instr);
2173 } 2169 }
2174 2170
2175 2171
2176 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( 2172 LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
2177 HLoadFunctionPrototype* instr) { 2173 HLoadFunctionPrototype* instr) {
2178 return AssignEnvironment(DefineAsRegister( 2174 return AssignEnvironment(DefineAsRegister(
2179 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); 2175 new (zone()) LLoadFunctionPrototype(UseRegister(instr->function()))));
2180 } 2176 }
2181 2177
2182 2178
2183 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { 2179 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2184 return DefineAsRegister(new(zone()) LLoadRoot); 2180 return DefineAsRegister(new (zone()) LLoadRoot);
2185 } 2181 }
2186 2182
2187 2183
2188 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { 2184 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2189 DCHECK(instr->key()->representation().IsSmiOrInteger32()); 2185 DCHECK(instr->key()->representation().IsSmiOrInteger32());
2190 ElementsKind elements_kind = instr->elements_kind(); 2186 ElementsKind elements_kind = instr->elements_kind();
2191 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2187 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2192 LInstruction* result = NULL; 2188 LInstruction* result = NULL;
2193 2189
2194 if (!instr->is_typed_elements()) { 2190 if (!instr->is_typed_elements()) {
2195 LOperand* obj = NULL; 2191 LOperand* obj = NULL;
2196 if (instr->representation().IsDouble()) { 2192 if (instr->representation().IsDouble()) {
2197 obj = UseRegister(instr->elements()); 2193 obj = UseRegister(instr->elements());
2198 } else { 2194 } else {
2199 DCHECK(instr->representation().IsSmiOrTagged());
2200 obj = UseRegisterAtStart(instr->elements()); 2195 obj = UseRegisterAtStart(instr->elements());
2201 } 2196 }
2202 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key)); 2197 result = DefineAsRegister(new (zone()) LLoadKeyed(obj, key));
2203 } else { 2198 } else {
2204 DCHECK( 2199 DCHECK((instr->representation().IsInteger32() &&
2205 (instr->representation().IsInteger32() && 2200 !IsDoubleOrFloatElementsKind(elements_kind)) ||
2206 !IsDoubleOrFloatElementsKind(elements_kind)) || 2201 (instr->representation().IsDouble() &&
2207 (instr->representation().IsDouble() && 2202 IsDoubleOrFloatElementsKind(elements_kind)));
2208 IsDoubleOrFloatElementsKind(elements_kind)));
2209 LOperand* backing_store = UseRegister(instr->elements()); 2203 LOperand* backing_store = UseRegister(instr->elements());
2210 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key)); 2204 result = DefineAsRegister(new (zone()) LLoadKeyed(backing_store, key));
2211 } 2205 }
2212 2206
2213 if ((instr->is_external() || instr->is_fixed_typed_array()) ? 2207 if ((instr->is_external() || instr->is_fixed_typed_array())
2214 // see LCodeGen::DoLoadKeyedExternalArray 2208 ?
2215 ((elements_kind == EXTERNAL_UINT32_ELEMENTS || 2209 // see LCodeGen::DoLoadKeyedExternalArray
2216 elements_kind == UINT32_ELEMENTS) && 2210 ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
2217 !instr->CheckFlag(HInstruction::kUint32)) : 2211 elements_kind == UINT32_ELEMENTS) &&
2218 // see LCodeGen::DoLoadKeyedFixedDoubleArray and 2212 !instr->CheckFlag(HInstruction::kUint32))
2219 // LCodeGen::DoLoadKeyedFixedArray 2213 :
2220 instr->RequiresHoleCheck()) { 2214 // see LCodeGen::DoLoadKeyedFixedDoubleArray and
2215 // LCodeGen::DoLoadKeyedFixedArray
2216 instr->RequiresHoleCheck()) {
2221 result = AssignEnvironment(result); 2217 result = AssignEnvironment(result);
2222 } 2218 }
2223 return result; 2219 return result;
2224 } 2220 }
2225 2221
2226 2222
2227 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 2223 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2228 LOperand* context = UseFixed(instr->context(), cp); 2224 LOperand* context = UseFixed(instr->context(), cp);
2229 LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); 2225 LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
2230 LOperand* key = UseFixed(instr->key(), LoadIC::NameRegister()); 2226 LOperand* key = UseFixed(instr->key(), LoadIC::NameRegister());
2231 LOperand* vector = NULL; 2227 LOperand* vector = NULL;
2232 if (FLAG_vector_ics) { 2228 if (FLAG_vector_ics) {
2233 vector = FixedTemp(LoadIC::VectorRegister()); 2229 vector = FixedTemp(LoadIC::VectorRegister());
2234 } 2230 }
2235 2231
2236 LInstruction* result = 2232 LInstruction* result = DefineFixed(
2237 DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key, vector), 2233 new (zone()) LLoadKeyedGeneric(context, object, key, vector), r3);
2238 r0);
2239 return MarkAsCall(result, instr); 2234 return MarkAsCall(result, instr);
2240 } 2235 }
2241 2236
2242 2237
2243 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { 2238 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2244 if (!instr->is_typed_elements()) { 2239 if (!instr->is_typed_elements()) {
2245 DCHECK(instr->elements()->representation().IsTagged()); 2240 DCHECK(instr->elements()->representation().IsTagged());
2246 bool needs_write_barrier = instr->NeedsWriteBarrier(); 2241 bool needs_write_barrier = instr->NeedsWriteBarrier();
2247 LOperand* object = NULL; 2242 LOperand* object = NULL;
2248 LOperand* key = NULL; 2243 LOperand* key = NULL;
2249 LOperand* val = NULL; 2244 LOperand* val = NULL;
2250 2245
2251 if (instr->value()->representation().IsDouble()) { 2246 if (instr->value()->representation().IsDouble()) {
2252 object = UseRegisterAtStart(instr->elements()); 2247 object = UseRegisterAtStart(instr->elements());
2253 val = UseRegister(instr->value()); 2248 val = UseRegister(instr->value());
2254 key = UseRegisterOrConstantAtStart(instr->key()); 2249 key = UseRegisterOrConstantAtStart(instr->key());
2255 } else { 2250 } else {
2256 DCHECK(instr->value()->representation().IsSmiOrTagged());
2257 if (needs_write_barrier) { 2251 if (needs_write_barrier) {
2258 object = UseTempRegister(instr->elements()); 2252 object = UseTempRegister(instr->elements());
2259 val = UseTempRegister(instr->value()); 2253 val = UseTempRegister(instr->value());
2260 key = UseTempRegister(instr->key()); 2254 key = UseTempRegister(instr->key());
2261 } else { 2255 } else {
2262 object = UseRegisterAtStart(instr->elements()); 2256 object = UseRegisterAtStart(instr->elements());
2263 val = UseRegisterAtStart(instr->value()); 2257 val = UseRegisterAtStart(instr->value());
2264 key = UseRegisterOrConstantAtStart(instr->key()); 2258 key = UseRegisterOrConstantAtStart(instr->key());
2265 } 2259 }
2266 } 2260 }
2267 2261
2268 return new(zone()) LStoreKeyed(object, key, val); 2262 return new (zone()) LStoreKeyed(object, key, val);
2269 } 2263 }
2270 2264
2271 DCHECK( 2265 DCHECK((instr->value()->representation().IsInteger32() &&
2272 (instr->value()->representation().IsInteger32() && 2266 !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
2273 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || 2267 (instr->value()->representation().IsDouble() &&
2274 (instr->value()->representation().IsDouble() && 2268 IsDoubleOrFloatElementsKind(instr->elements_kind())));
2275 IsDoubleOrFloatElementsKind(instr->elements_kind())));
2276 DCHECK((instr->is_fixed_typed_array() && 2269 DCHECK((instr->is_fixed_typed_array() &&
2277 instr->elements()->representation().IsTagged()) || 2270 instr->elements()->representation().IsTagged()) ||
2278 (instr->is_external() && 2271 (instr->is_external() &&
2279 instr->elements()->representation().IsExternal())); 2272 instr->elements()->representation().IsExternal()));
2280 LOperand* val = UseRegister(instr->value()); 2273 LOperand* val = UseRegister(instr->value());
2281 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2274 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2282 LOperand* backing_store = UseRegister(instr->elements()); 2275 LOperand* backing_store = UseRegister(instr->elements());
2283 return new(zone()) LStoreKeyed(backing_store, key, val); 2276 return new (zone()) LStoreKeyed(backing_store, key, val);
2284 } 2277 }
2285 2278
2286 2279
2287 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { 2280 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2288 LOperand* context = UseFixed(instr->context(), cp); 2281 LOperand* context = UseFixed(instr->context(), cp);
2289 LOperand* obj = UseFixed(instr->object(), KeyedStoreIC::ReceiverRegister()); 2282 LOperand* obj = UseFixed(instr->object(), KeyedStoreIC::ReceiverRegister());
2290 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); 2283 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister());
2291 LOperand* val = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); 2284 LOperand* val = UseFixed(instr->value(), KeyedStoreIC::ValueRegister());
2292 2285
2293 DCHECK(instr->object()->representation().IsTagged()); 2286 DCHECK(instr->object()->representation().IsTagged());
2294 DCHECK(instr->key()->representation().IsTagged()); 2287 DCHECK(instr->key()->representation().IsTagged());
2295 DCHECK(instr->value()->representation().IsTagged()); 2288 DCHECK(instr->value()->representation().IsTagged());
2296 2289
2297 return MarkAsCall( 2290 return MarkAsCall(new (zone()) LStoreKeyedGeneric(context, obj, key, val),
2298 new(zone()) LStoreKeyedGeneric(context, obj, key, val), instr); 2291 instr);
2299 } 2292 }
2300 2293
2301 2294
2302 LInstruction* LChunkBuilder::DoTransitionElementsKind( 2295 LInstruction* LChunkBuilder::DoTransitionElementsKind(
2303 HTransitionElementsKind* instr) { 2296 HTransitionElementsKind* instr) {
2304 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { 2297 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
2305 LOperand* object = UseRegister(instr->object()); 2298 LOperand* object = UseRegister(instr->object());
2306 LOperand* new_map_reg = TempRegister(); 2299 LOperand* new_map_reg = TempRegister();
2307 LTransitionElementsKind* result = 2300 LTransitionElementsKind* result =
2308 new(zone()) LTransitionElementsKind(object, NULL, new_map_reg); 2301 new (zone()) LTransitionElementsKind(object, NULL, new_map_reg);
2309 return result; 2302 return result;
2310 } else { 2303 } else {
2311 LOperand* object = UseFixed(instr->object(), r0); 2304 LOperand* object = UseFixed(instr->object(), r3);
2312 LOperand* context = UseFixed(instr->context(), cp); 2305 LOperand* context = UseFixed(instr->context(), cp);
2313 LTransitionElementsKind* result = 2306 LTransitionElementsKind* result =
2314 new(zone()) LTransitionElementsKind(object, context, NULL); 2307 new (zone()) LTransitionElementsKind(object, context, NULL);
2315 return MarkAsCall(result, instr); 2308 return MarkAsCall(result, instr);
2316 } 2309 }
2317 } 2310 }
2318 2311
2319 2312
2320 LInstruction* LChunkBuilder::DoTrapAllocationMemento( 2313 LInstruction* LChunkBuilder::DoTrapAllocationMemento(
2321 HTrapAllocationMemento* instr) { 2314 HTrapAllocationMemento* instr) {
2322 LOperand* object = UseRegister(instr->object()); 2315 LOperand* object = UseRegister(instr->object());
2323 LOperand* temp = TempRegister(); 2316 LOperand* temp = TempRegister();
2324 LTrapAllocationMemento* result = 2317 LTrapAllocationMemento* result =
2325 new(zone()) LTrapAllocationMemento(object, temp); 2318 new (zone()) LTrapAllocationMemento(object, temp);
2326 return AssignEnvironment(result); 2319 return AssignEnvironment(result);
2327 } 2320 }
2328 2321
2329 2322
2330 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { 2323 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2331 bool is_in_object = instr->access().IsInobject(); 2324 bool is_in_object = instr->access().IsInobject();
2332 bool needs_write_barrier = instr->NeedsWriteBarrier(); 2325 bool needs_write_barrier = instr->NeedsWriteBarrier();
2333 bool needs_write_barrier_for_map = instr->has_transition() && 2326 bool needs_write_barrier_for_map =
2334 instr->NeedsWriteBarrierForMap(); 2327 instr->has_transition() && instr->NeedsWriteBarrierForMap();
2335 2328
2336 LOperand* obj; 2329 LOperand* obj;
2337 if (needs_write_barrier) { 2330 if (needs_write_barrier) {
2338 obj = is_in_object 2331 obj = is_in_object ? UseRegister(instr->object())
2339 ? UseRegister(instr->object()) 2332 : UseTempRegister(instr->object());
2340 : UseTempRegister(instr->object());
2341 } else { 2333 } else {
2342 obj = needs_write_barrier_for_map 2334 obj = needs_write_barrier_for_map ? UseRegister(instr->object())
2343 ? UseRegister(instr->object()) 2335 : UseRegisterAtStart(instr->object());
2344 : UseRegisterAtStart(instr->object());
2345 } 2336 }
2346 2337
2347 LOperand* val; 2338 LOperand* val;
2348 if (needs_write_barrier || instr->field_representation().IsSmi()) { 2339 if (needs_write_barrier || instr->field_representation().IsSmi()) {
2349 val = UseTempRegister(instr->value()); 2340 val = UseTempRegister(instr->value());
2350 } else if (instr->field_representation().IsDouble()) { 2341 } else if (instr->field_representation().IsDouble()) {
2351 val = UseRegisterAtStart(instr->value()); 2342 val = UseRegisterAtStart(instr->value());
2352 } else { 2343 } else {
2353 val = UseRegister(instr->value()); 2344 val = UseRegister(instr->value());
2354 } 2345 }
2355 2346
2356 // We need a temporary register for write barrier of the map field. 2347 // We need a temporary register for write barrier of the map field.
2357 LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL; 2348 LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
2358 2349
2359 return new(zone()) LStoreNamedField(obj, val, temp); 2350 return new (zone()) LStoreNamedField(obj, val, temp);
2360 } 2351 }
2361 2352
2362 2353
2363 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 2354 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2364 LOperand* context = UseFixed(instr->context(), cp); 2355 LOperand* context = UseFixed(instr->context(), cp);
2365 LOperand* obj = UseFixed(instr->object(), StoreIC::ReceiverRegister()); 2356 LOperand* obj = UseFixed(instr->object(), StoreIC::ReceiverRegister());
2366 LOperand* val = UseFixed(instr->value(), StoreIC::ValueRegister()); 2357 LOperand* val = UseFixed(instr->value(), StoreIC::ValueRegister());
2367 2358
2368 LInstruction* result = new(zone()) LStoreNamedGeneric(context, obj, val); 2359 LInstruction* result = new (zone()) LStoreNamedGeneric(context, obj, val);
2369 return MarkAsCall(result, instr); 2360 return MarkAsCall(result, instr);
2370 } 2361 }
2371 2362
2372 2363
2373 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { 2364 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2374 LOperand* context = UseFixed(instr->context(), cp); 2365 LOperand* context = UseFixed(instr->context(), cp);
2375 LOperand* left = UseFixed(instr->left(), r1); 2366 LOperand* left = UseFixed(instr->left(), r4);
2376 LOperand* right = UseFixed(instr->right(), r0); 2367 LOperand* right = UseFixed(instr->right(), r3);
2377 return MarkAsCall( 2368 return MarkAsCall(
2378 DefineFixed(new(zone()) LStringAdd(context, left, right), r0), 2369 DefineFixed(new (zone()) LStringAdd(context, left, right), r3), instr);
2379 instr);
2380 } 2370 }
2381 2371
2382 2372
2383 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { 2373 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2384 LOperand* string = UseTempRegister(instr->string()); 2374 LOperand* string = UseTempRegister(instr->string());
2385 LOperand* index = UseTempRegister(instr->index()); 2375 LOperand* index = UseTempRegister(instr->index());
2386 LOperand* context = UseAny(instr->context()); 2376 LOperand* context = UseAny(instr->context());
2387 LStringCharCodeAt* result = 2377 LStringCharCodeAt* result =
2388 new(zone()) LStringCharCodeAt(context, string, index); 2378 new (zone()) LStringCharCodeAt(context, string, index);
2389 return AssignPointerMap(DefineAsRegister(result)); 2379 return AssignPointerMap(DefineAsRegister(result));
2390 } 2380 }
2391 2381
2392 2382
2393 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { 2383 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2394 LOperand* char_code = UseRegister(instr->value()); 2384 LOperand* char_code = UseRegister(instr->value());
2395 LOperand* context = UseAny(instr->context()); 2385 LOperand* context = UseAny(instr->context());
2396 LStringCharFromCode* result = 2386 LStringCharFromCode* result =
2397 new(zone()) LStringCharFromCode(context, char_code); 2387 new (zone()) LStringCharFromCode(context, char_code);
2398 return AssignPointerMap(DefineAsRegister(result)); 2388 return AssignPointerMap(DefineAsRegister(result));
2399 } 2389 }
2400 2390
2401 2391
2402 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { 2392 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
2403 info()->MarkAsDeferredCalling(); 2393 info()->MarkAsDeferredCalling();
2404 LOperand* context = UseAny(instr->context()); 2394 LOperand* context = UseAny(instr->context());
2405 LOperand* size = UseRegisterOrConstant(instr->size()); 2395 LOperand* size = UseRegisterOrConstant(instr->size());
2406 LOperand* temp1 = TempRegister(); 2396 LOperand* temp1 = TempRegister();
2407 LOperand* temp2 = TempRegister(); 2397 LOperand* temp2 = TempRegister();
2408 LAllocate* result = new(zone()) LAllocate(context, size, temp1, temp2); 2398 LAllocate* result = new (zone()) LAllocate(context, size, temp1, temp2);
2409 return AssignPointerMap(DefineAsRegister(result)); 2399 return AssignPointerMap(DefineAsRegister(result));
2410 } 2400 }
2411 2401
2412 2402
2413 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { 2403 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2414 LOperand* context = UseFixed(instr->context(), cp); 2404 LOperand* context = UseFixed(instr->context(), cp);
2415 return MarkAsCall( 2405 return MarkAsCall(DefineFixed(new (zone()) LRegExpLiteral(context), r3),
2416 DefineFixed(new(zone()) LRegExpLiteral(context), r0), instr); 2406 instr);
2417 } 2407 }
2418 2408
2419 2409
2420 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { 2410 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
2421 LOperand* context = UseFixed(instr->context(), cp); 2411 LOperand* context = UseFixed(instr->context(), cp);
2422 return MarkAsCall( 2412 return MarkAsCall(DefineFixed(new (zone()) LFunctionLiteral(context), r3),
2423 DefineFixed(new(zone()) LFunctionLiteral(context), r0), instr); 2413 instr);
2424 } 2414 }
2425 2415
2426 2416
2427 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { 2417 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2428 DCHECK(argument_count_ == 0); 2418 DCHECK(argument_count_ == 0);
2429 allocator_->MarkAsOsrEntry(); 2419 allocator_->MarkAsOsrEntry();
2430 current_block_->last_environment()->set_ast_id(instr->ast_id()); 2420 current_block_->last_environment()->set_ast_id(instr->ast_id());
2431 return AssignEnvironment(new(zone()) LOsrEntry); 2421 return AssignEnvironment(new (zone()) LOsrEntry);
2432 } 2422 }
2433 2423
2434 2424
2435 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { 2425 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2436 LParameter* result = new(zone()) LParameter; 2426 LParameter* result = new (zone()) LParameter;
2437 if (instr->kind() == HParameter::STACK_PARAMETER) { 2427 if (instr->kind() == HParameter::STACK_PARAMETER) {
2438 int spill_index = chunk()->GetParameterStackSlot(instr->index()); 2428 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2439 return DefineAsSpilled(result, spill_index); 2429 return DefineAsSpilled(result, spill_index);
2440 } else { 2430 } else {
2441 DCHECK(info()->IsStub()); 2431 DCHECK(info()->IsStub());
2442 CodeStubInterfaceDescriptor* descriptor = 2432 CodeStubInterfaceDescriptor* descriptor =
2443 info()->code_stub()->GetInterfaceDescriptor(); 2433 info()->code_stub()->GetInterfaceDescriptor();
2444 int index = static_cast<int>(instr->index()); 2434 int index = static_cast<int>(instr->index());
2445 Register reg = descriptor->GetEnvironmentParameterRegister(index); 2435 Register reg = descriptor->GetEnvironmentParameterRegister(index);
2446 return DefineFixed(result, reg); 2436 return DefineFixed(result, reg);
2447 } 2437 }
2448 } 2438 }
2449 2439
2450 2440
2451 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { 2441 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2452 // Use an index that corresponds to the location in the unoptimized frame, 2442 // Use an index that corresponds to the location in the unoptimized frame,
2453 // which the optimized frame will subsume. 2443 // which the optimized frame will subsume.
2454 int env_index = instr->index(); 2444 int env_index = instr->index();
2455 int spill_index = 0; 2445 int spill_index = 0;
2456 if (instr->environment()->is_parameter_index(env_index)) { 2446 if (instr->environment()->is_parameter_index(env_index)) {
2457 spill_index = chunk()->GetParameterStackSlot(env_index); 2447 spill_index = chunk()->GetParameterStackSlot(env_index);
2458 } else { 2448 } else {
2459 spill_index = env_index - instr->environment()->first_local_index(); 2449 spill_index = env_index - instr->environment()->first_local_index();
2460 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { 2450 if (spill_index > LUnallocated::kMaxFixedSlotIndex) {
2461 Abort(kTooManySpillSlotsNeededForOSR); 2451 Abort(kTooManySpillSlotsNeededForOSR);
2462 spill_index = 0; 2452 spill_index = 0;
2463 } 2453 }
2464 } 2454 }
2465 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); 2455 return DefineAsSpilled(new (zone()) LUnknownOSRValue, spill_index);
2466 } 2456 }
2467 2457
2468 2458
2469 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { 2459 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2470 LOperand* context = UseFixed(instr->context(), cp); 2460 LOperand* context = UseFixed(instr->context(), cp);
2471 return MarkAsCall(DefineFixed(new(zone()) LCallStub(context), r0), instr); 2461 return MarkAsCall(DefineFixed(new (zone()) LCallStub(context), r3), instr);
2472 } 2462 }
2473 2463
2474 2464
2475 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { 2465 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2476 // There are no real uses of the arguments object. 2466 // There are no real uses of the arguments object.
2477 // arguments.length and element access are supported directly on 2467 // arguments.length and element access are supported directly on
2478 // stack arguments, and any real arguments object use causes a bailout. 2468 // stack arguments, and any real arguments object use causes a bailout.
2479 // So this value is never used. 2469 // So this value is never used.
2480 return NULL; 2470 return NULL;
2481 } 2471 }
2482 2472
2483 2473
2484 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) { 2474 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
2485 instr->ReplayEnvironment(current_block_->last_environment()); 2475 instr->ReplayEnvironment(current_block_->last_environment());
2486 2476
2487 // There are no real uses of a captured object. 2477 // There are no real uses of a captured object.
2488 return NULL; 2478 return NULL;
2489 } 2479 }
2490 2480
2491 2481
2492 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 2482 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2493 info()->MarkAsRequiresFrame(); 2483 info()->MarkAsRequiresFrame();
2494 LOperand* args = UseRegister(instr->arguments()); 2484 LOperand* args = UseRegister(instr->arguments());
2495 LOperand* length = UseRegisterOrConstantAtStart(instr->length()); 2485 LOperand* length = UseRegisterOrConstantAtStart(instr->length());
2496 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); 2486 LOperand* index = UseRegisterOrConstantAtStart(instr->index());
2497 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index)); 2487 return DefineAsRegister(new (zone()) LAccessArgumentsAt(args, length, index));
2498 } 2488 }
2499 2489
2500 2490
2501 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { 2491 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2502 LOperand* object = UseFixed(instr->value(), r0); 2492 LOperand* object = UseFixed(instr->value(), r3);
2503 LToFastProperties* result = new(zone()) LToFastProperties(object); 2493 LToFastProperties* result = new (zone()) LToFastProperties(object);
2504 return MarkAsCall(DefineFixed(result, r0), instr); 2494 return MarkAsCall(DefineFixed(result, r3), instr);
2505 } 2495 }
2506 2496
2507 2497
2508 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 2498 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2509 LOperand* context = UseFixed(instr->context(), cp); 2499 LOperand* context = UseFixed(instr->context(), cp);
2510 LTypeof* result = new(zone()) LTypeof(context, UseFixed(instr->value(), r0)); 2500 LTypeof* result = new (zone()) LTypeof(context, UseFixed(instr->value(), r3));
2511 return MarkAsCall(DefineFixed(result, r0), instr); 2501 return MarkAsCall(DefineFixed(result, r3), instr);
2512 } 2502 }
2513 2503
2514 2504
2515 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { 2505 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2516 return new(zone()) LTypeofIsAndBranch(UseRegister(instr->value())); 2506 return new (zone()) LTypeofIsAndBranch(UseRegister(instr->value()));
2517 } 2507 }
2518 2508
2519 2509
2520 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( 2510 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
2521 HIsConstructCallAndBranch* instr) { 2511 HIsConstructCallAndBranch* instr) {
2522 return new(zone()) LIsConstructCallAndBranch(TempRegister()); 2512 return new (zone()) LIsConstructCallAndBranch(TempRegister());
2523 } 2513 }
2524 2514
2525 2515
2526 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 2516 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2527 instr->ReplayEnvironment(current_block_->last_environment()); 2517 instr->ReplayEnvironment(current_block_->last_environment());
2528 return NULL; 2518 return NULL;
2529 } 2519 }
2530 2520
2531 2521
2532 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 2522 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2533 if (instr->is_function_entry()) { 2523 if (instr->is_function_entry()) {
2534 LOperand* context = UseFixed(instr->context(), cp); 2524 LOperand* context = UseFixed(instr->context(), cp);
2535 return MarkAsCall(new(zone()) LStackCheck(context), instr); 2525 return MarkAsCall(new (zone()) LStackCheck(context), instr);
2536 } else { 2526 } else {
2537 DCHECK(instr->is_backwards_branch()); 2527 DCHECK(instr->is_backwards_branch());
2538 LOperand* context = UseAny(instr->context()); 2528 LOperand* context = UseAny(instr->context());
2539 return AssignEnvironment( 2529 return AssignEnvironment(
2540 AssignPointerMap(new(zone()) LStackCheck(context))); 2530 AssignPointerMap(new (zone()) LStackCheck(context)));
2541 } 2531 }
2542 } 2532 }
2543 2533
2544 2534
2545 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { 2535 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2546 HEnvironment* outer = current_block_->last_environment(); 2536 HEnvironment* outer = current_block_->last_environment();
2547 outer->set_ast_id(instr->ReturnId()); 2537 outer->set_ast_id(instr->ReturnId());
2548 HConstant* undefined = graph()->GetConstantUndefined(); 2538 HConstant* undefined = graph()->GetConstantUndefined();
2549 HEnvironment* inner = outer->CopyForInlining(instr->closure(), 2539 HEnvironment* inner = outer->CopyForInlining(
2550 instr->arguments_count(), 2540 instr->closure(), instr->arguments_count(), instr->function(), undefined,
2551 instr->function(), 2541 instr->inlining_kind());
2552 undefined,
2553 instr->inlining_kind());
2554 // Only replay binding of arguments object if it wasn't removed from graph. 2542 // Only replay binding of arguments object if it wasn't removed from graph.
2555 if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) { 2543 if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
2556 inner->Bind(instr->arguments_var(), instr->arguments_object()); 2544 inner->Bind(instr->arguments_var(), instr->arguments_object());
2557 } 2545 }
2558 inner->set_entry(instr); 2546 inner->set_entry(instr);
2559 current_block_->UpdateEnvironment(inner); 2547 current_block_->UpdateEnvironment(inner);
2560 chunk_->AddInlinedClosure(instr->closure()); 2548 chunk_->AddInlinedClosure(instr->closure());
2561 return NULL; 2549 return NULL;
2562 } 2550 }
2563 2551
2564 2552
2565 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 2553 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2566 LInstruction* pop = NULL; 2554 LInstruction* pop = NULL;
2567 2555
2568 HEnvironment* env = current_block_->last_environment(); 2556 HEnvironment* env = current_block_->last_environment();
2569 2557
2570 if (env->entry()->arguments_pushed()) { 2558 if (env->entry()->arguments_pushed()) {
2571 int argument_count = env->arguments_environment()->parameter_count(); 2559 int argument_count = env->arguments_environment()->parameter_count();
2572 pop = new(zone()) LDrop(argument_count); 2560 pop = new (zone()) LDrop(argument_count);
2573 DCHECK(instr->argument_delta() == -argument_count); 2561 DCHECK(instr->argument_delta() == -argument_count);
2574 } 2562 }
2575 2563
2576 HEnvironment* outer = current_block_->last_environment()-> 2564 HEnvironment* outer =
2577 DiscardInlined(false); 2565 current_block_->last_environment()->DiscardInlined(false);
2578 current_block_->UpdateEnvironment(outer); 2566 current_block_->UpdateEnvironment(outer);
2579 2567
2580 return pop; 2568 return pop;
2581 } 2569 }
2582 2570
2583 2571
2584 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { 2572 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
2585 LOperand* context = UseFixed(instr->context(), cp); 2573 LOperand* context = UseFixed(instr->context(), cp);
2586 LOperand* object = UseFixed(instr->enumerable(), r0); 2574 LOperand* object = UseFixed(instr->enumerable(), r3);
2587 LForInPrepareMap* result = new(zone()) LForInPrepareMap(context, object); 2575 LForInPrepareMap* result = new (zone()) LForInPrepareMap(context, object);
2588 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 2576 return MarkAsCall(DefineFixed(result, r3), instr, CAN_DEOPTIMIZE_EAGERLY);
2589 } 2577 }
2590 2578
2591 2579
2592 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) { 2580 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
2593 LOperand* map = UseRegister(instr->map()); 2581 LOperand* map = UseRegister(instr->map());
2594 return AssignEnvironment(DefineAsRegister(new(zone()) LForInCacheArray(map))); 2582 return AssignEnvironment(
2583 DefineAsRegister(new (zone()) LForInCacheArray(map)));
2595 } 2584 }
2596 2585
2597 2586
2598 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) { 2587 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
2599 LOperand* value = UseRegisterAtStart(instr->value()); 2588 LOperand* value = UseRegisterAtStart(instr->value());
2600 LOperand* map = UseRegisterAtStart(instr->map()); 2589 LOperand* map = UseRegisterAtStart(instr->map());
2601 return AssignEnvironment(new(zone()) LCheckMapValue(value, map)); 2590 return AssignEnvironment(new (zone()) LCheckMapValue(value, map));
2602 } 2591 }
2603 2592
2604 2593
2605 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2594 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2606 LOperand* object = UseRegister(instr->object()); 2595 LOperand* object = UseRegister(instr->object());
2607 LOperand* index = UseTempRegister(instr->index()); 2596 LOperand* index = UseTempRegister(instr->index());
2608 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); 2597 LLoadFieldByIndex* load = new (zone()) LLoadFieldByIndex(object, index);
2609 LInstruction* result = DefineSameAsFirst(load); 2598 LInstruction* result = DefineSameAsFirst(load);
2610 return AssignPointerMap(result); 2599 return AssignPointerMap(result);
2611 } 2600 }
2612 2601
2613 2602
2614 LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) { 2603 LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) {
2615 LOperand* context = UseRegisterAtStart(instr->context()); 2604 LOperand* context = UseRegisterAtStart(instr->context());
2616 return new(zone()) LStoreFrameContext(context); 2605 return new (zone()) LStoreFrameContext(context);
2617 } 2606 }
2618 2607
2619 2608
2620 LInstruction* LChunkBuilder::DoAllocateBlockContext( 2609 LInstruction* LChunkBuilder::DoAllocateBlockContext(
2621 HAllocateBlockContext* instr) { 2610 HAllocateBlockContext* instr) {
2622 LOperand* context = UseFixed(instr->context(), cp); 2611 LOperand* context = UseFixed(instr->context(), cp);
2623 LOperand* function = UseRegisterAtStart(instr->function()); 2612 LOperand* function = UseRegisterAtStart(instr->function());
2624 LAllocateBlockContext* result = 2613 LAllocateBlockContext* result =
2625 new(zone()) LAllocateBlockContext(context, function); 2614 new (zone()) LAllocateBlockContext(context, function);
2626 return MarkAsCall(DefineFixed(result, cp), instr); 2615 return MarkAsCall(DefineFixed(result, cp), instr);
2627 } 2616 }
2628 2617 }
2629 } } // namespace v8::internal 2618 } // namespace v8::internal
OLDNEW
« src/hydrogen-bch.cc ('K') | « src/ppc/lithium-ppc.h ('k') | src/ppc/macro-assembler-ppc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698