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

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

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