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

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

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

Powered by Google App Engine
This is Rietveld 408576698