| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/arm64/lithium-codegen-arm64.h" | 7 #include "src/arm64/lithium-codegen-arm64.h" |
| 8 #include "src/hydrogen-osr.h" | 8 #include "src/hydrogen-osr.h" |
| 9 #include "src/lithium-inl.h" | 9 #include "src/lithium-inl.h" |
| 10 | 10 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 | 13 |
| 14 #define DEFINE_COMPILE(type) \ | 14 #define DEFINE_COMPILE(type) \ |
| 15 void L##type::CompileToNative(LCodeGen* generator) { \ | 15 void L##type::CompileToNative(LCodeGen* generator) { \ |
| 16 generator->Do##type(this); \ | 16 generator->Do##type(this); \ |
| 17 } | 17 } |
| 18 LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) | 18 LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) |
| 19 #undef DEFINE_COMPILE | 19 #undef DEFINE_COMPILE |
| 20 | 20 |
| 21 #ifdef DEBUG | 21 #ifdef DEBUG |
| 22 void LInstruction::VerifyCall() { | 22 void LInstruction::VerifyCall() { |
| 23 // Call instructions can use only fixed registers as temporaries and | 23 // Call instructions can use only fixed registers as temporaries and |
| 24 // outputs because all registers are blocked by the calling convention. | 24 // outputs because all registers are blocked by the calling convention. |
| 25 // Inputs operands must use a fixed register or use-at-start policy or | 25 // Inputs operands must use a fixed register or use-at-start policy or |
| 26 // a non-register policy. | 26 // a non-register policy. |
| 27 ASSERT(Output() == NULL || | 27 DCHECK(Output() == NULL || |
| 28 LUnallocated::cast(Output())->HasFixedPolicy() || | 28 LUnallocated::cast(Output())->HasFixedPolicy() || |
| 29 !LUnallocated::cast(Output())->HasRegisterPolicy()); | 29 !LUnallocated::cast(Output())->HasRegisterPolicy()); |
| 30 for (UseIterator it(this); !it.Done(); it.Advance()) { | 30 for (UseIterator it(this); !it.Done(); it.Advance()) { |
| 31 LUnallocated* operand = LUnallocated::cast(it.Current()); | 31 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 32 ASSERT(operand->HasFixedPolicy() || | 32 DCHECK(operand->HasFixedPolicy() || |
| 33 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 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); | 37 DCHECK(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); |
| 38 } | 38 } |
| 39 } | 39 } |
| 40 #endif | 40 #endif |
| 41 | 41 |
| 42 | 42 |
| 43 void LLabel::PrintDataTo(StringStream* stream) { | 43 void LLabel::PrintDataTo(StringStream* stream) { |
| 44 LGap::PrintDataTo(stream); | 44 LGap::PrintDataTo(stream); |
| 45 LLabel* rep = replacement(); | 45 LLabel* rep = replacement(); |
| 46 if (rep != NULL) { | 46 if (rep != NULL) { |
| 47 stream->Add(" Dead block replaced with B%d", rep->block_id()); | 47 stream->Add(" Dead block replaced with B%d", rep->block_id()); |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 instr = AssignEnvironment(instr); | 494 instr = AssignEnvironment(instr); |
| 495 // We can't really figure out if the environment is needed or not. | 495 // We can't really figure out if the environment is needed or not. |
| 496 instr->environment()->set_has_been_used(); | 496 instr->environment()->set_has_been_used(); |
| 497 } | 497 } |
| 498 | 498 |
| 499 return instr; | 499 return instr; |
| 500 } | 500 } |
| 501 | 501 |
| 502 | 502 |
| 503 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 503 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
| 504 ASSERT(!instr->HasPointerMap()); | 504 DCHECK(!instr->HasPointerMap()); |
| 505 instr->set_pointer_map(new(zone()) LPointerMap(zone())); | 505 instr->set_pointer_map(new(zone()) LPointerMap(zone())); |
| 506 return instr; | 506 return instr; |
| 507 } | 507 } |
| 508 | 508 |
| 509 | 509 |
| 510 LUnallocated* LChunkBuilder::TempRegister() { | 510 LUnallocated* LChunkBuilder::TempRegister() { |
| 511 LUnallocated* operand = | 511 LUnallocated* operand = |
| 512 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); | 512 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); |
| 513 int vreg = allocator_->GetVirtualRegister(); | 513 int vreg = allocator_->GetVirtualRegister(); |
| 514 if (!allocator_->AllocationOk()) { | 514 if (!allocator_->AllocationOk()) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 536 int LPlatformChunk::GetNextSpillIndex() { | 536 int LPlatformChunk::GetNextSpillIndex() { |
| 537 return spill_slot_count_++; | 537 return spill_slot_count_++; |
| 538 } | 538 } |
| 539 | 539 |
| 540 | 540 |
| 541 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { | 541 LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { |
| 542 int index = GetNextSpillIndex(); | 542 int index = GetNextSpillIndex(); |
| 543 if (kind == DOUBLE_REGISTERS) { | 543 if (kind == DOUBLE_REGISTERS) { |
| 544 return LDoubleStackSlot::Create(index, zone()); | 544 return LDoubleStackSlot::Create(index, zone()); |
| 545 } else { | 545 } else { |
| 546 ASSERT(kind == GENERAL_REGISTERS); | 546 DCHECK(kind == GENERAL_REGISTERS); |
| 547 return LStackSlot::Create(index, zone()); | 547 return LStackSlot::Create(index, zone()); |
| 548 } | 548 } |
| 549 } | 549 } |
| 550 | 550 |
| 551 | 551 |
| 552 LOperand* LChunkBuilder::FixedTemp(Register reg) { | 552 LOperand* LChunkBuilder::FixedTemp(Register reg) { |
| 553 LUnallocated* operand = ToUnallocated(reg); | 553 LUnallocated* operand = ToUnallocated(reg); |
| 554 ASSERT(operand->HasFixedPolicy()); | 554 DCHECK(operand->HasFixedPolicy()); |
| 555 return operand; | 555 return operand; |
| 556 } | 556 } |
| 557 | 557 |
| 558 | 558 |
| 559 LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) { | 559 LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) { |
| 560 LUnallocated* operand = ToUnallocated(reg); | 560 LUnallocated* operand = ToUnallocated(reg); |
| 561 ASSERT(operand->HasFixedPolicy()); | 561 DCHECK(operand->HasFixedPolicy()); |
| 562 return operand; | 562 return operand; |
| 563 } | 563 } |
| 564 | 564 |
| 565 | 565 |
| 566 LPlatformChunk* LChunkBuilder::Build() { | 566 LPlatformChunk* LChunkBuilder::Build() { |
| 567 ASSERT(is_unused()); | 567 DCHECK(is_unused()); |
| 568 chunk_ = new(zone()) LPlatformChunk(info_, graph_); | 568 chunk_ = new(zone()) LPlatformChunk(info_, graph_); |
| 569 LPhase phase("L_Building chunk", chunk_); | 569 LPhase phase("L_Building chunk", chunk_); |
| 570 status_ = BUILDING; | 570 status_ = BUILDING; |
| 571 | 571 |
| 572 // If compiling for OSR, reserve space for the unoptimized frame, | 572 // If compiling for OSR, reserve space for the unoptimized frame, |
| 573 // which will be subsumed into this frame. | 573 // which will be subsumed into this frame. |
| 574 if (graph()->has_osr()) { | 574 if (graph()->has_osr()) { |
| 575 // TODO(all): GetNextSpillIndex just increments a field. It has no other | 575 // TODO(all): GetNextSpillIndex just increments a field. It has no other |
| 576 // side effects, so we should get rid of this loop. | 576 // side effects, so we should get rid of this loop. |
| 577 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { | 577 for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { |
| 578 chunk_->GetNextSpillIndex(); | 578 chunk_->GetNextSpillIndex(); |
| 579 } | 579 } |
| 580 } | 580 } |
| 581 | 581 |
| 582 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); | 582 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); |
| 583 for (int i = 0; i < blocks->length(); i++) { | 583 for (int i = 0; i < blocks->length(); i++) { |
| 584 DoBasicBlock(blocks->at(i)); | 584 DoBasicBlock(blocks->at(i)); |
| 585 if (is_aborted()) return NULL; | 585 if (is_aborted()) return NULL; |
| 586 } | 586 } |
| 587 status_ = DONE; | 587 status_ = DONE; |
| 588 return chunk_; | 588 return chunk_; |
| 589 } | 589 } |
| 590 | 590 |
| 591 | 591 |
| 592 void LChunkBuilder::DoBasicBlock(HBasicBlock* block) { | 592 void LChunkBuilder::DoBasicBlock(HBasicBlock* block) { |
| 593 ASSERT(is_building()); | 593 DCHECK(is_building()); |
| 594 current_block_ = block; | 594 current_block_ = block; |
| 595 | 595 |
| 596 if (block->IsStartBlock()) { | 596 if (block->IsStartBlock()) { |
| 597 block->UpdateEnvironment(graph_->start_environment()); | 597 block->UpdateEnvironment(graph_->start_environment()); |
| 598 argument_count_ = 0; | 598 argument_count_ = 0; |
| 599 } else if (block->predecessors()->length() == 1) { | 599 } else if (block->predecessors()->length() == 1) { |
| 600 // We have a single predecessor => copy environment and outgoing | 600 // We have a single predecessor => copy environment and outgoing |
| 601 // argument count from the predecessor. | 601 // argument count from the predecessor. |
| 602 ASSERT(block->phis()->length() == 0); | 602 DCHECK(block->phis()->length() == 0); |
| 603 HBasicBlock* pred = block->predecessors()->at(0); | 603 HBasicBlock* pred = block->predecessors()->at(0); |
| 604 HEnvironment* last_environment = pred->last_environment(); | 604 HEnvironment* last_environment = pred->last_environment(); |
| 605 ASSERT(last_environment != NULL); | 605 DCHECK(last_environment != NULL); |
| 606 | 606 |
| 607 // Only copy the environment, if it is later used again. | 607 // Only copy the environment, if it is later used again. |
| 608 if (pred->end()->SecondSuccessor() == NULL) { | 608 if (pred->end()->SecondSuccessor() == NULL) { |
| 609 ASSERT(pred->end()->FirstSuccessor() == block); | 609 DCHECK(pred->end()->FirstSuccessor() == block); |
| 610 } else { | 610 } else { |
| 611 if ((pred->end()->FirstSuccessor()->block_id() > block->block_id()) || | 611 if ((pred->end()->FirstSuccessor()->block_id() > block->block_id()) || |
| 612 (pred->end()->SecondSuccessor()->block_id() > block->block_id())) { | 612 (pred->end()->SecondSuccessor()->block_id() > block->block_id())) { |
| 613 last_environment = last_environment->Copy(); | 613 last_environment = last_environment->Copy(); |
| 614 } | 614 } |
| 615 } | 615 } |
| 616 block->UpdateEnvironment(last_environment); | 616 block->UpdateEnvironment(last_environment); |
| 617 ASSERT(pred->argument_count() >= 0); | 617 DCHECK(pred->argument_count() >= 0); |
| 618 argument_count_ = pred->argument_count(); | 618 argument_count_ = pred->argument_count(); |
| 619 } else { | 619 } else { |
| 620 // We are at a state join => process phis. | 620 // We are at a state join => process phis. |
| 621 HBasicBlock* pred = block->predecessors()->at(0); | 621 HBasicBlock* pred = block->predecessors()->at(0); |
| 622 // No need to copy the environment, it cannot be used later. | 622 // No need to copy the environment, it cannot be used later. |
| 623 HEnvironment* last_environment = pred->last_environment(); | 623 HEnvironment* last_environment = pred->last_environment(); |
| 624 for (int i = 0; i < block->phis()->length(); ++i) { | 624 for (int i = 0; i < block->phis()->length(); ++i) { |
| 625 HPhi* phi = block->phis()->at(i); | 625 HPhi* phi = block->phis()->at(i); |
| 626 if (phi->HasMergedIndex()) { | 626 if (phi->HasMergedIndex()) { |
| 627 last_environment->SetValueAt(phi->merged_index(), phi); | 627 last_environment->SetValueAt(phi->merged_index(), phi); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 | 660 |
| 661 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 661 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 662 HInstruction* old_current = current_instruction_; | 662 HInstruction* old_current = current_instruction_; |
| 663 current_instruction_ = current; | 663 current_instruction_ = current; |
| 664 | 664 |
| 665 LInstruction* instr = NULL; | 665 LInstruction* instr = NULL; |
| 666 if (current->CanReplaceWithDummyUses()) { | 666 if (current->CanReplaceWithDummyUses()) { |
| 667 if (current->OperandCount() == 0) { | 667 if (current->OperandCount() == 0) { |
| 668 instr = DefineAsRegister(new(zone()) LDummy()); | 668 instr = DefineAsRegister(new(zone()) LDummy()); |
| 669 } else { | 669 } else { |
| 670 ASSERT(!current->OperandAt(0)->IsControlInstruction()); | 670 DCHECK(!current->OperandAt(0)->IsControlInstruction()); |
| 671 instr = DefineAsRegister(new(zone()) | 671 instr = DefineAsRegister(new(zone()) |
| 672 LDummyUse(UseAny(current->OperandAt(0)))); | 672 LDummyUse(UseAny(current->OperandAt(0)))); |
| 673 } | 673 } |
| 674 for (int i = 1; i < current->OperandCount(); ++i) { | 674 for (int i = 1; i < current->OperandCount(); ++i) { |
| 675 if (current->OperandAt(i)->IsControlInstruction()) continue; | 675 if (current->OperandAt(i)->IsControlInstruction()) continue; |
| 676 LInstruction* dummy = | 676 LInstruction* dummy = |
| 677 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 677 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 678 dummy->set_hydrogen_value(current); | 678 dummy->set_hydrogen_value(current); |
| 679 chunk_->AddInstruction(dummy, current_block_); | 679 chunk_->AddInstruction(dummy, current_block_); |
| 680 } | 680 } |
| 681 } else { | 681 } else { |
| 682 HBasicBlock* successor; | 682 HBasicBlock* successor; |
| 683 if (current->IsControlInstruction() && | 683 if (current->IsControlInstruction() && |
| 684 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && | 684 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && |
| 685 successor != NULL) { | 685 successor != NULL) { |
| 686 instr = new(zone()) LGoto(successor); | 686 instr = new(zone()) LGoto(successor); |
| 687 } else { | 687 } else { |
| 688 instr = current->CompileToLithium(this); | 688 instr = current->CompileToLithium(this); |
| 689 } | 689 } |
| 690 } | 690 } |
| 691 | 691 |
| 692 argument_count_ += current->argument_delta(); | 692 argument_count_ += current->argument_delta(); |
| 693 ASSERT(argument_count_ >= 0); | 693 DCHECK(argument_count_ >= 0); |
| 694 | 694 |
| 695 if (instr != NULL) { | 695 if (instr != NULL) { |
| 696 AddInstruction(instr, current); | 696 AddInstruction(instr, current); |
| 697 } | 697 } |
| 698 | 698 |
| 699 current_instruction_ = old_current; | 699 current_instruction_ = old_current; |
| 700 } | 700 } |
| 701 | 701 |
| 702 | 702 |
| 703 void LChunkBuilder::AddInstruction(LInstruction* instr, | 703 void LChunkBuilder::AddInstruction(LInstruction* instr, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 725 LUnallocated* operand = LUnallocated::cast(it.Current()); | 725 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 726 if (operand->IsUsedAtStart()) ++used_at_start; | 726 if (operand->IsUsedAtStart()) ++used_at_start; |
| 727 } | 727 } |
| 728 if (instr->Output() != NULL) { | 728 if (instr->Output() != NULL) { |
| 729 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; | 729 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; |
| 730 } | 730 } |
| 731 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 731 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
| 732 LUnallocated* operand = LUnallocated::cast(it.Current()); | 732 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 733 if (operand->HasFixedPolicy()) ++fixed; | 733 if (operand->HasFixedPolicy()) ++fixed; |
| 734 } | 734 } |
| 735 ASSERT(fixed == 0 || used_at_start == 0); | 735 DCHECK(fixed == 0 || used_at_start == 0); |
| 736 } | 736 } |
| 737 #endif | 737 #endif |
| 738 | 738 |
| 739 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 739 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 740 instr = AssignPointerMap(instr); | 740 instr = AssignPointerMap(instr); |
| 741 } | 741 } |
| 742 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 742 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 743 instr = AssignEnvironment(instr); | 743 instr = AssignEnvironment(instr); |
| 744 } | 744 } |
| 745 chunk_->AddInstruction(instr, current_block_); | 745 chunk_->AddInstruction(instr, current_block_); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 | 779 |
| 780 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { | 780 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
| 781 // The control instruction marking the end of a block that completed | 781 // The control instruction marking the end of a block that completed |
| 782 // abruptly (e.g., threw an exception). There is nothing specific to do. | 782 // abruptly (e.g., threw an exception). There is nothing specific to do. |
| 783 return NULL; | 783 return NULL; |
| 784 } | 784 } |
| 785 | 785 |
| 786 | 786 |
| 787 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 787 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 788 HArithmeticBinaryOperation* instr) { | 788 HArithmeticBinaryOperation* instr) { |
| 789 ASSERT(instr->representation().IsDouble()); | 789 DCHECK(instr->representation().IsDouble()); |
| 790 ASSERT(instr->left()->representation().IsDouble()); | 790 DCHECK(instr->left()->representation().IsDouble()); |
| 791 ASSERT(instr->right()->representation().IsDouble()); | 791 DCHECK(instr->right()->representation().IsDouble()); |
| 792 | 792 |
| 793 if (op == Token::MOD) { | 793 if (op == Token::MOD) { |
| 794 LOperand* left = UseFixedDouble(instr->left(), d0); | 794 LOperand* left = UseFixedDouble(instr->left(), d0); |
| 795 LOperand* right = UseFixedDouble(instr->right(), d1); | 795 LOperand* right = UseFixedDouble(instr->right(), d1); |
| 796 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); | 796 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); |
| 797 return MarkAsCall(DefineFixedDouble(result, d0), instr); | 797 return MarkAsCall(DefineFixedDouble(result, d0), instr); |
| 798 } else { | 798 } else { |
| 799 LOperand* left = UseRegisterAtStart(instr->left()); | 799 LOperand* left = UseRegisterAtStart(instr->left()); |
| 800 LOperand* right = UseRegisterAtStart(instr->right()); | 800 LOperand* right = UseRegisterAtStart(instr->right()); |
| 801 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); | 801 LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); |
| 802 return DefineAsRegister(result); | 802 return DefineAsRegister(result); |
| 803 } | 803 } |
| 804 } | 804 } |
| 805 | 805 |
| 806 | 806 |
| 807 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 807 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 808 HBinaryOperation* instr) { | 808 HBinaryOperation* instr) { |
| 809 ASSERT((op == Token::ADD) || (op == Token::SUB) || (op == Token::MUL) || | 809 DCHECK((op == Token::ADD) || (op == Token::SUB) || (op == Token::MUL) || |
| 810 (op == Token::DIV) || (op == Token::MOD) || (op == Token::SHR) || | 810 (op == Token::DIV) || (op == Token::MOD) || (op == Token::SHR) || |
| 811 (op == Token::SHL) || (op == Token::SAR) || (op == Token::ROR) || | 811 (op == Token::SHL) || (op == Token::SAR) || (op == Token::ROR) || |
| 812 (op == Token::BIT_OR) || (op == Token::BIT_AND) || | 812 (op == Token::BIT_OR) || (op == Token::BIT_AND) || |
| 813 (op == Token::BIT_XOR)); | 813 (op == Token::BIT_XOR)); |
| 814 HValue* left = instr->left(); | 814 HValue* left = instr->left(); |
| 815 HValue* right = instr->right(); | 815 HValue* right = instr->right(); |
| 816 | 816 |
| 817 // TODO(jbramley): Once we've implemented smi support for all arithmetic | 817 // TODO(jbramley): Once we've implemented smi support for all arithmetic |
| 818 // operations, these assertions should check IsTagged(). | 818 // operations, these assertions should check IsTagged(). |
| 819 ASSERT(instr->representation().IsSmiOrTagged()); | 819 DCHECK(instr->representation().IsSmiOrTagged()); |
| 820 ASSERT(left->representation().IsSmiOrTagged()); | 820 DCHECK(left->representation().IsSmiOrTagged()); |
| 821 ASSERT(right->representation().IsSmiOrTagged()); | 821 DCHECK(right->representation().IsSmiOrTagged()); |
| 822 | 822 |
| 823 LOperand* context = UseFixed(instr->context(), cp); | 823 LOperand* context = UseFixed(instr->context(), cp); |
| 824 LOperand* left_operand = UseFixed(left, x1); | 824 LOperand* left_operand = UseFixed(left, x1); |
| 825 LOperand* right_operand = UseFixed(right, x0); | 825 LOperand* right_operand = UseFixed(right, x0); |
| 826 LArithmeticT* result = | 826 LArithmeticT* result = |
| 827 new(zone()) LArithmeticT(op, context, left_operand, right_operand); | 827 new(zone()) LArithmeticT(op, context, left_operand, right_operand); |
| 828 return MarkAsCall(DefineFixed(result, x0), instr); | 828 return MarkAsCall(DefineFixed(result, x0), instr); |
| 829 } | 829 } |
| 830 | 830 |
| 831 | 831 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 851 length = UseRegisterAtStart(instr->length()); | 851 length = UseRegisterAtStart(instr->length()); |
| 852 index = UseRegisterOrConstantAtStart(instr->index()); | 852 index = UseRegisterOrConstantAtStart(instr->index()); |
| 853 } | 853 } |
| 854 | 854 |
| 855 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index)); | 855 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index)); |
| 856 } | 856 } |
| 857 | 857 |
| 858 | 858 |
| 859 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 859 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
| 860 if (instr->representation().IsSmiOrInteger32()) { | 860 if (instr->representation().IsSmiOrInteger32()) { |
| 861 ASSERT(instr->left()->representation().Equals(instr->representation())); | 861 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 862 ASSERT(instr->right()->representation().Equals(instr->representation())); | 862 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 863 | 863 |
| 864 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr); | 864 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr); |
| 865 if (shifted_operation != NULL) { | 865 if (shifted_operation != NULL) { |
| 866 return shifted_operation; | 866 return shifted_operation; |
| 867 } | 867 } |
| 868 | 868 |
| 869 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 869 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 870 LOperand* right = | 870 LOperand* right = |
| 871 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); | 871 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); |
| 872 LInstruction* result = instr->representation().IsSmi() ? | 872 LInstruction* result = instr->representation().IsSmi() ? |
| 873 DefineAsRegister(new(zone()) LAddS(left, right)) : | 873 DefineAsRegister(new(zone()) LAddS(left, right)) : |
| 874 DefineAsRegister(new(zone()) LAddI(left, right)); | 874 DefineAsRegister(new(zone()) LAddI(left, right)); |
| 875 if (instr->CheckFlag(HValue::kCanOverflow)) { | 875 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 876 result = AssignEnvironment(result); | 876 result = AssignEnvironment(result); |
| 877 } | 877 } |
| 878 return result; | 878 return result; |
| 879 } else if (instr->representation().IsExternal()) { | 879 } else if (instr->representation().IsExternal()) { |
| 880 ASSERT(instr->left()->representation().IsExternal()); | 880 DCHECK(instr->left()->representation().IsExternal()); |
| 881 ASSERT(instr->right()->representation().IsInteger32()); | 881 DCHECK(instr->right()->representation().IsInteger32()); |
| 882 ASSERT(!instr->CheckFlag(HValue::kCanOverflow)); | 882 DCHECK(!instr->CheckFlag(HValue::kCanOverflow)); |
| 883 LOperand* left = UseRegisterAtStart(instr->left()); | 883 LOperand* left = UseRegisterAtStart(instr->left()); |
| 884 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); | 884 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); |
| 885 return DefineAsRegister(new(zone()) LAddE(left, right)); | 885 return DefineAsRegister(new(zone()) LAddE(left, right)); |
| 886 } else if (instr->representation().IsDouble()) { | 886 } else if (instr->representation().IsDouble()) { |
| 887 return DoArithmeticD(Token::ADD, instr); | 887 return DoArithmeticD(Token::ADD, instr); |
| 888 } else { | 888 } else { |
| 889 ASSERT(instr->representation().IsTagged()); | 889 DCHECK(instr->representation().IsTagged()); |
| 890 return DoArithmeticT(Token::ADD, instr); | 890 return DoArithmeticT(Token::ADD, instr); |
| 891 } | 891 } |
| 892 } | 892 } |
| 893 | 893 |
| 894 | 894 |
| 895 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { | 895 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { |
| 896 info()->MarkAsDeferredCalling(); | 896 info()->MarkAsDeferredCalling(); |
| 897 LOperand* context = UseAny(instr->context()); | 897 LOperand* context = UseAny(instr->context()); |
| 898 LOperand* size = UseRegisterOrConstant(instr->size()); | 898 LOperand* size = UseRegisterOrConstant(instr->size()); |
| 899 LOperand* temp1 = TempRegister(); | 899 LOperand* temp1 = TempRegister(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 // There are no real uses of the arguments object. | 935 // There are no real uses of the arguments object. |
| 936 // arguments.length and element access are supported directly on | 936 // arguments.length and element access are supported directly on |
| 937 // stack arguments, and any real arguments object use causes a bailout. | 937 // stack arguments, and any real arguments object use causes a bailout. |
| 938 // So this value is never used. | 938 // So this value is never used. |
| 939 return NULL; | 939 return NULL; |
| 940 } | 940 } |
| 941 | 941 |
| 942 | 942 |
| 943 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 943 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
| 944 if (instr->representation().IsSmiOrInteger32()) { | 944 if (instr->representation().IsSmiOrInteger32()) { |
| 945 ASSERT(instr->left()->representation().Equals(instr->representation())); | 945 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 946 ASSERT(instr->right()->representation().Equals(instr->representation())); | 946 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 947 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32)); | 947 DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32)); |
| 948 | 948 |
| 949 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr); | 949 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr); |
| 950 if (shifted_operation != NULL) { | 950 if (shifted_operation != NULL) { |
| 951 return shifted_operation; | 951 return shifted_operation; |
| 952 } | 952 } |
| 953 | 953 |
| 954 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 954 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 955 LOperand* right = | 955 LOperand* right = |
| 956 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); | 956 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); |
| 957 return instr->representation().IsSmi() ? | 957 return instr->representation().IsSmi() ? |
| (...skipping 29 matching lines...) Expand all Loading... |
| 987 | 987 |
| 988 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 988 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
| 989 HValue* value = instr->value(); | 989 HValue* value = instr->value(); |
| 990 Representation r = value->representation(); | 990 Representation r = value->representation(); |
| 991 HType type = value->type(); | 991 HType type = value->type(); |
| 992 | 992 |
| 993 if (r.IsInteger32() || r.IsSmi() || r.IsDouble()) { | 993 if (r.IsInteger32() || r.IsSmi() || r.IsDouble()) { |
| 994 // These representations have simple checks that cannot deoptimize. | 994 // These representations have simple checks that cannot deoptimize. |
| 995 return new(zone()) LBranch(UseRegister(value), NULL, NULL); | 995 return new(zone()) LBranch(UseRegister(value), NULL, NULL); |
| 996 } else { | 996 } else { |
| 997 ASSERT(r.IsTagged()); | 997 DCHECK(r.IsTagged()); |
| 998 if (type.IsBoolean() || type.IsSmi() || type.IsJSArray() || | 998 if (type.IsBoolean() || type.IsSmi() || type.IsJSArray() || |
| 999 type.IsHeapNumber()) { | 999 type.IsHeapNumber()) { |
| 1000 // These types have simple checks that cannot deoptimize. | 1000 // These types have simple checks that cannot deoptimize. |
| 1001 return new(zone()) LBranch(UseRegister(value), NULL, NULL); | 1001 return new(zone()) LBranch(UseRegister(value), NULL, NULL); |
| 1002 } | 1002 } |
| 1003 | 1003 |
| 1004 if (type.IsString()) { | 1004 if (type.IsString()) { |
| 1005 // This type cannot deoptimize, but needs a scratch register. | 1005 // This type cannot deoptimize, but needs a scratch register. |
| 1006 return new(zone()) LBranch(UseRegister(value), TempRegister(), NULL); | 1006 return new(zone()) LBranch(UseRegister(value), TempRegister(), NULL); |
| 1007 } | 1007 } |
| 1008 | 1008 |
| 1009 ToBooleanStub::Types expected = instr->expected_input_types(); | 1009 ToBooleanStub::Types expected = instr->expected_input_types(); |
| 1010 bool needs_temps = expected.NeedsMap() || expected.IsEmpty(); | 1010 bool needs_temps = expected.NeedsMap() || expected.IsEmpty(); |
| 1011 LOperand* temp1 = needs_temps ? TempRegister() : NULL; | 1011 LOperand* temp1 = needs_temps ? TempRegister() : NULL; |
| 1012 LOperand* temp2 = needs_temps ? TempRegister() : NULL; | 1012 LOperand* temp2 = needs_temps ? TempRegister() : NULL; |
| 1013 | 1013 |
| 1014 if (expected.IsGeneric() || expected.IsEmpty()) { | 1014 if (expected.IsGeneric() || expected.IsEmpty()) { |
| 1015 // The generic case cannot deoptimize because it already supports every | 1015 // The generic case cannot deoptimize because it already supports every |
| 1016 // possible input type. | 1016 // possible input type. |
| 1017 ASSERT(needs_temps); | 1017 DCHECK(needs_temps); |
| 1018 return new(zone()) LBranch(UseRegister(value), temp1, temp2); | 1018 return new(zone()) LBranch(UseRegister(value), temp1, temp2); |
| 1019 } else { | 1019 } else { |
| 1020 return AssignEnvironment( | 1020 return AssignEnvironment( |
| 1021 new(zone()) LBranch(UseRegister(value), temp1, temp2)); | 1021 new(zone()) LBranch(UseRegister(value), temp1, temp2)); |
| 1022 } | 1022 } |
| 1023 } | 1023 } |
| 1024 } | 1024 } |
| 1025 | 1025 |
| 1026 | 1026 |
| 1027 LInstruction* LChunkBuilder::DoCallJSFunction( | 1027 LInstruction* LChunkBuilder::DoCallJSFunction( |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 DefineAsRegister(new(zone()) LNumberUntagD(value, temp)); | 1119 DefineAsRegister(new(zone()) LNumberUntagD(value, temp)); |
| 1120 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1120 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1121 return result; | 1121 return result; |
| 1122 } else if (to.IsSmi()) { | 1122 } else if (to.IsSmi()) { |
| 1123 LOperand* value = UseRegister(val); | 1123 LOperand* value = UseRegister(val); |
| 1124 if (val->type().IsSmi()) { | 1124 if (val->type().IsSmi()) { |
| 1125 return DefineSameAsFirst(new(zone()) LDummyUse(value)); | 1125 return DefineSameAsFirst(new(zone()) LDummyUse(value)); |
| 1126 } | 1126 } |
| 1127 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); | 1127 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
| 1128 } else { | 1128 } else { |
| 1129 ASSERT(to.IsInteger32()); | 1129 DCHECK(to.IsInteger32()); |
| 1130 if (val->type().IsSmi() || val->representation().IsSmi()) { | 1130 if (val->type().IsSmi() || val->representation().IsSmi()) { |
| 1131 LOperand* value = UseRegisterAtStart(val); | 1131 LOperand* value = UseRegisterAtStart(val); |
| 1132 return DefineAsRegister(new(zone()) LSmiUntag(value, false)); | 1132 return DefineAsRegister(new(zone()) LSmiUntag(value, false)); |
| 1133 } else { | 1133 } else { |
| 1134 LOperand* value = UseRegister(val); | 1134 LOperand* value = UseRegister(val); |
| 1135 LOperand* temp1 = TempRegister(); | 1135 LOperand* temp1 = TempRegister(); |
| 1136 LOperand* temp2 = instr->CanTruncateToInt32() | 1136 LOperand* temp2 = instr->CanTruncateToInt32() |
| 1137 ? NULL : TempDoubleRegister(); | 1137 ? NULL : TempDoubleRegister(); |
| 1138 LInstruction* result = | 1138 LInstruction* result = |
| 1139 DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2)); | 1139 DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2)); |
| 1140 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1140 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1141 return result; | 1141 return result; |
| 1142 } | 1142 } |
| 1143 } | 1143 } |
| 1144 } else if (from.IsDouble()) { | 1144 } else if (from.IsDouble()) { |
| 1145 if (to.IsTagged()) { | 1145 if (to.IsTagged()) { |
| 1146 info()->MarkAsDeferredCalling(); | 1146 info()->MarkAsDeferredCalling(); |
| 1147 LOperand* value = UseRegister(val); | 1147 LOperand* value = UseRegister(val); |
| 1148 LOperand* temp1 = TempRegister(); | 1148 LOperand* temp1 = TempRegister(); |
| 1149 LOperand* temp2 = TempRegister(); | 1149 LOperand* temp2 = TempRegister(); |
| 1150 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); | 1150 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); |
| 1151 return AssignPointerMap(DefineAsRegister(result)); | 1151 return AssignPointerMap(DefineAsRegister(result)); |
| 1152 } else { | 1152 } else { |
| 1153 ASSERT(to.IsSmi() || to.IsInteger32()); | 1153 DCHECK(to.IsSmi() || to.IsInteger32()); |
| 1154 if (instr->CanTruncateToInt32()) { | 1154 if (instr->CanTruncateToInt32()) { |
| 1155 LOperand* value = UseRegister(val); | 1155 LOperand* value = UseRegister(val); |
| 1156 return DefineAsRegister(new(zone()) LTruncateDoubleToIntOrSmi(value)); | 1156 return DefineAsRegister(new(zone()) LTruncateDoubleToIntOrSmi(value)); |
| 1157 } else { | 1157 } else { |
| 1158 LOperand* value = UseRegister(val); | 1158 LOperand* value = UseRegister(val); |
| 1159 LDoubleToIntOrSmi* result = new(zone()) LDoubleToIntOrSmi(value); | 1159 LDoubleToIntOrSmi* result = new(zone()) LDoubleToIntOrSmi(value); |
| 1160 return AssignEnvironment(DefineAsRegister(result)); | 1160 return AssignEnvironment(DefineAsRegister(result)); |
| 1161 } | 1161 } |
| 1162 } | 1162 } |
| 1163 } else if (from.IsInteger32()) { | 1163 } else if (from.IsInteger32()) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1175 return DefineAsRegister(new(zone()) LSmiTag(value)); | 1175 return DefineAsRegister(new(zone()) LSmiTag(value)); |
| 1176 } | 1176 } |
| 1177 } else if (to.IsSmi()) { | 1177 } else if (to.IsSmi()) { |
| 1178 LOperand* value = UseRegisterAtStart(val); | 1178 LOperand* value = UseRegisterAtStart(val); |
| 1179 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); | 1179 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); |
| 1180 if (val->CheckFlag(HInstruction::kUint32)) { | 1180 if (val->CheckFlag(HInstruction::kUint32)) { |
| 1181 result = AssignEnvironment(result); | 1181 result = AssignEnvironment(result); |
| 1182 } | 1182 } |
| 1183 return result; | 1183 return result; |
| 1184 } else { | 1184 } else { |
| 1185 ASSERT(to.IsDouble()); | 1185 DCHECK(to.IsDouble()); |
| 1186 if (val->CheckFlag(HInstruction::kUint32)) { | 1186 if (val->CheckFlag(HInstruction::kUint32)) { |
| 1187 return DefineAsRegister( | 1187 return DefineAsRegister( |
| 1188 new(zone()) LUint32ToDouble(UseRegisterAtStart(val))); | 1188 new(zone()) LUint32ToDouble(UseRegisterAtStart(val))); |
| 1189 } else { | 1189 } else { |
| 1190 return DefineAsRegister( | 1190 return DefineAsRegister( |
| 1191 new(zone()) LInteger32ToDouble(UseRegisterAtStart(val))); | 1191 new(zone()) LInteger32ToDouble(UseRegisterAtStart(val))); |
| 1192 } | 1192 } |
| 1193 } | 1193 } |
| 1194 } | 1194 } |
| 1195 UNREACHABLE(); | 1195 UNREACHABLE(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1242 | 1242 |
| 1243 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { | 1243 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
| 1244 HValue* value = instr->value(); | 1244 HValue* value = instr->value(); |
| 1245 Representation input_rep = value->representation(); | 1245 Representation input_rep = value->representation(); |
| 1246 LOperand* reg = UseRegister(value); | 1246 LOperand* reg = UseRegister(value); |
| 1247 if (input_rep.IsDouble()) { | 1247 if (input_rep.IsDouble()) { |
| 1248 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); | 1248 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); |
| 1249 } else if (input_rep.IsInteger32()) { | 1249 } else if (input_rep.IsInteger32()) { |
| 1250 return DefineAsRegister(new(zone()) LClampIToUint8(reg)); | 1250 return DefineAsRegister(new(zone()) LClampIToUint8(reg)); |
| 1251 } else { | 1251 } else { |
| 1252 ASSERT(input_rep.IsSmiOrTagged()); | 1252 DCHECK(input_rep.IsSmiOrTagged()); |
| 1253 return AssignEnvironment( | 1253 return AssignEnvironment( |
| 1254 DefineAsRegister(new(zone()) LClampTToUint8(reg, | 1254 DefineAsRegister(new(zone()) LClampTToUint8(reg, |
| 1255 TempRegister(), | 1255 TempRegister(), |
| 1256 TempDoubleRegister()))); | 1256 TempDoubleRegister()))); |
| 1257 } | 1257 } |
| 1258 } | 1258 } |
| 1259 | 1259 |
| 1260 | 1260 |
| 1261 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( | 1261 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( |
| 1262 HClassOfTestAndBranch* instr) { | 1262 HClassOfTestAndBranch* instr) { |
| 1263 ASSERT(instr->value()->representation().IsTagged()); | 1263 DCHECK(instr->value()->representation().IsTagged()); |
| 1264 LOperand* value = UseRegisterAtStart(instr->value()); | 1264 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1265 return new(zone()) LClassOfTestAndBranch(value, | 1265 return new(zone()) LClassOfTestAndBranch(value, |
| 1266 TempRegister(), | 1266 TempRegister(), |
| 1267 TempRegister()); | 1267 TempRegister()); |
| 1268 } | 1268 } |
| 1269 | 1269 |
| 1270 | 1270 |
| 1271 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1271 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
| 1272 HCompareNumericAndBranch* instr) { | 1272 HCompareNumericAndBranch* instr) { |
| 1273 Representation r = instr->representation(); | 1273 Representation r = instr->representation(); |
| 1274 if (r.IsSmiOrInteger32()) { | 1274 if (r.IsSmiOrInteger32()) { |
| 1275 ASSERT(instr->left()->representation().Equals(r)); | 1275 DCHECK(instr->left()->representation().Equals(r)); |
| 1276 ASSERT(instr->right()->representation().Equals(r)); | 1276 DCHECK(instr->right()->representation().Equals(r)); |
| 1277 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1277 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
| 1278 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); | 1278 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); |
| 1279 return new(zone()) LCompareNumericAndBranch(left, right); | 1279 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1280 } else { | 1280 } else { |
| 1281 ASSERT(r.IsDouble()); | 1281 DCHECK(r.IsDouble()); |
| 1282 ASSERT(instr->left()->representation().IsDouble()); | 1282 DCHECK(instr->left()->representation().IsDouble()); |
| 1283 ASSERT(instr->right()->representation().IsDouble()); | 1283 DCHECK(instr->right()->representation().IsDouble()); |
| 1284 if (instr->left()->IsConstant() && instr->right()->IsConstant()) { | 1284 if (instr->left()->IsConstant() && instr->right()->IsConstant()) { |
| 1285 LOperand* left = UseConstant(instr->left()); | 1285 LOperand* left = UseConstant(instr->left()); |
| 1286 LOperand* right = UseConstant(instr->right()); | 1286 LOperand* right = UseConstant(instr->right()); |
| 1287 return new(zone()) LCompareNumericAndBranch(left, right); | 1287 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1288 } | 1288 } |
| 1289 LOperand* left = UseRegisterAtStart(instr->left()); | 1289 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1290 LOperand* right = UseRegisterAtStart(instr->right()); | 1290 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1291 return new(zone()) LCompareNumericAndBranch(left, right); | 1291 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1292 } | 1292 } |
| 1293 } | 1293 } |
| 1294 | 1294 |
| 1295 | 1295 |
| 1296 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { | 1296 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
| 1297 ASSERT(instr->left()->representation().IsTagged()); | 1297 DCHECK(instr->left()->representation().IsTagged()); |
| 1298 ASSERT(instr->right()->representation().IsTagged()); | 1298 DCHECK(instr->right()->representation().IsTagged()); |
| 1299 LOperand* context = UseFixed(instr->context(), cp); | 1299 LOperand* context = UseFixed(instr->context(), cp); |
| 1300 LOperand* left = UseFixed(instr->left(), x1); | 1300 LOperand* left = UseFixed(instr->left(), x1); |
| 1301 LOperand* right = UseFixed(instr->right(), x0); | 1301 LOperand* right = UseFixed(instr->right(), x0); |
| 1302 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1302 LCmpT* result = new(zone()) LCmpT(context, left, right); |
| 1303 return MarkAsCall(DefineFixed(result, x0), instr); | 1303 return MarkAsCall(DefineFixed(result, x0), instr); |
| 1304 } | 1304 } |
| 1305 | 1305 |
| 1306 | 1306 |
| 1307 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( | 1307 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( |
| 1308 HCompareHoleAndBranch* instr) { | 1308 HCompareHoleAndBranch* instr) { |
| 1309 LOperand* value = UseRegister(instr->value()); | 1309 LOperand* value = UseRegister(instr->value()); |
| 1310 if (instr->representation().IsTagged()) { | 1310 if (instr->representation().IsTagged()) { |
| 1311 return new(zone()) LCmpHoleAndBranchT(value); | 1311 return new(zone()) LCmpHoleAndBranchT(value); |
| 1312 } else { | 1312 } else { |
| 1313 LOperand* temp = TempRegister(); | 1313 LOperand* temp = TempRegister(); |
| 1314 return new(zone()) LCmpHoleAndBranchD(value, temp); | 1314 return new(zone()) LCmpHoleAndBranchD(value, temp); |
| 1315 } | 1315 } |
| 1316 } | 1316 } |
| 1317 | 1317 |
| 1318 | 1318 |
| 1319 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1319 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
| 1320 HCompareObjectEqAndBranch* instr) { | 1320 HCompareObjectEqAndBranch* instr) { |
| 1321 LOperand* left = UseRegisterAtStart(instr->left()); | 1321 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1322 LOperand* right = UseRegisterAtStart(instr->right()); | 1322 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1323 return new(zone()) LCmpObjectEqAndBranch(left, right); | 1323 return new(zone()) LCmpObjectEqAndBranch(left, right); |
| 1324 } | 1324 } |
| 1325 | 1325 |
| 1326 | 1326 |
| 1327 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 1327 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 1328 ASSERT(instr->value()->representation().IsTagged()); | 1328 DCHECK(instr->value()->representation().IsTagged()); |
| 1329 LOperand* value = UseRegisterAtStart(instr->value()); | 1329 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1330 LOperand* temp = TempRegister(); | 1330 LOperand* temp = TempRegister(); |
| 1331 return new(zone()) LCmpMapAndBranch(value, temp); | 1331 return new(zone()) LCmpMapAndBranch(value, temp); |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 | 1334 |
| 1335 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1335 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| 1336 Representation r = instr->representation(); | 1336 Representation r = instr->representation(); |
| 1337 if (r.IsSmi()) { | 1337 if (r.IsSmi()) { |
| 1338 return DefineAsRegister(new(zone()) LConstantS); | 1338 return DefineAsRegister(new(zone()) LConstantS); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); | 1379 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); |
| 1380 } | 1380 } |
| 1381 | 1381 |
| 1382 | 1382 |
| 1383 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 1383 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 1384 return AssignEnvironment(new(zone()) LDeoptimize); | 1384 return AssignEnvironment(new(zone()) LDeoptimize); |
| 1385 } | 1385 } |
| 1386 | 1386 |
| 1387 | 1387 |
| 1388 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { | 1388 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { |
| 1389 ASSERT(instr->representation().IsInteger32()); | 1389 DCHECK(instr->representation().IsInteger32()); |
| 1390 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1390 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1391 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1391 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1392 LOperand* dividend = UseRegister(instr->left()); | 1392 LOperand* dividend = UseRegister(instr->left()); |
| 1393 int32_t divisor = instr->right()->GetInteger32Constant(); | 1393 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1394 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( | 1394 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( |
| 1395 dividend, divisor)); | 1395 dividend, divisor)); |
| 1396 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1396 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1397 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || | 1397 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || |
| 1398 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && | 1398 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
| 1399 divisor != 1 && divisor != -1)) { | 1399 divisor != 1 && divisor != -1)) { |
| 1400 result = AssignEnvironment(result); | 1400 result = AssignEnvironment(result); |
| 1401 } | 1401 } |
| 1402 return result; | 1402 return result; |
| 1403 } | 1403 } |
| 1404 | 1404 |
| 1405 | 1405 |
| 1406 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { | 1406 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { |
| 1407 ASSERT(instr->representation().IsInteger32()); | 1407 DCHECK(instr->representation().IsInteger32()); |
| 1408 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1408 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1409 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1409 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1410 LOperand* dividend = UseRegister(instr->left()); | 1410 LOperand* dividend = UseRegister(instr->left()); |
| 1411 int32_t divisor = instr->right()->GetInteger32Constant(); | 1411 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1412 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) | 1412 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) |
| 1413 ? NULL : TempRegister(); | 1413 ? NULL : TempRegister(); |
| 1414 LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI( | 1414 LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI( |
| 1415 dividend, divisor, temp)); | 1415 dividend, divisor, temp)); |
| 1416 if (divisor == 0 || | 1416 if (divisor == 0 || |
| 1417 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1417 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1418 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1418 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { |
| 1419 result = AssignEnvironment(result); | 1419 result = AssignEnvironment(result); |
| 1420 } | 1420 } |
| 1421 return result; | 1421 return result; |
| 1422 } | 1422 } |
| 1423 | 1423 |
| 1424 | 1424 |
| 1425 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { | 1425 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { |
| 1426 ASSERT(instr->representation().IsSmiOrInteger32()); | 1426 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1427 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1427 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1428 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1428 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1429 LOperand* dividend = UseRegister(instr->left()); | 1429 LOperand* dividend = UseRegister(instr->left()); |
| 1430 LOperand* divisor = UseRegister(instr->right()); | 1430 LOperand* divisor = UseRegister(instr->right()); |
| 1431 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) | 1431 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) |
| 1432 ? NULL : TempRegister(); | 1432 ? NULL : TempRegister(); |
| 1433 LInstruction* result = | 1433 LInstruction* result = |
| 1434 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); | 1434 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); |
| 1435 if (!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { | 1435 if (!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
| 1436 result = AssignEnvironment(result); | 1436 result = AssignEnvironment(result); |
| 1437 } | 1437 } |
| 1438 return result; | 1438 return result; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1499 | 1499 |
| 1500 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 1500 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 1501 LOperand* context = UseFixed(instr->context(), cp); | 1501 LOperand* context = UseFixed(instr->context(), cp); |
| 1502 return MarkAsCall( | 1502 return MarkAsCall( |
| 1503 DefineFixed(new(zone()) LFunctionLiteral(context), x0), instr); | 1503 DefineFixed(new(zone()) LFunctionLiteral(context), x0), instr); |
| 1504 } | 1504 } |
| 1505 | 1505 |
| 1506 | 1506 |
| 1507 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( | 1507 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( |
| 1508 HGetCachedArrayIndex* instr) { | 1508 HGetCachedArrayIndex* instr) { |
| 1509 ASSERT(instr->value()->representation().IsTagged()); | 1509 DCHECK(instr->value()->representation().IsTagged()); |
| 1510 LOperand* value = UseRegisterAtStart(instr->value()); | 1510 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1511 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); | 1511 return DefineAsRegister(new(zone()) LGetCachedArrayIndex(value)); |
| 1512 } | 1512 } |
| 1513 | 1513 |
| 1514 | 1514 |
| 1515 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 1515 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
| 1516 return new(zone()) LGoto(instr->FirstSuccessor()); | 1516 return new(zone()) LGoto(instr->FirstSuccessor()); |
| 1517 } | 1517 } |
| 1518 | 1518 |
| 1519 | 1519 |
| 1520 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( | 1520 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch( |
| 1521 HHasCachedArrayIndexAndBranch* instr) { | 1521 HHasCachedArrayIndexAndBranch* instr) { |
| 1522 ASSERT(instr->value()->representation().IsTagged()); | 1522 DCHECK(instr->value()->representation().IsTagged()); |
| 1523 return new(zone()) LHasCachedArrayIndexAndBranch( | 1523 return new(zone()) LHasCachedArrayIndexAndBranch( |
| 1524 UseRegisterAtStart(instr->value()), TempRegister()); | 1524 UseRegisterAtStart(instr->value()), TempRegister()); |
| 1525 } | 1525 } |
| 1526 | 1526 |
| 1527 | 1527 |
| 1528 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( | 1528 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch( |
| 1529 HHasInstanceTypeAndBranch* instr) { | 1529 HHasInstanceTypeAndBranch* instr) { |
| 1530 ASSERT(instr->value()->representation().IsTagged()); | 1530 DCHECK(instr->value()->representation().IsTagged()); |
| 1531 LOperand* value = UseRegisterAtStart(instr->value()); | 1531 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1532 return new(zone()) LHasInstanceTypeAndBranch(value, TempRegister()); | 1532 return new(zone()) LHasInstanceTypeAndBranch(value, TempRegister()); |
| 1533 } | 1533 } |
| 1534 | 1534 |
| 1535 | 1535 |
| 1536 LInstruction* LChunkBuilder::DoInnerAllocatedObject( | 1536 LInstruction* LChunkBuilder::DoInnerAllocatedObject( |
| 1537 HInnerAllocatedObject* instr) { | 1537 HInnerAllocatedObject* instr) { |
| 1538 LOperand* base_object = UseRegisterAtStart(instr->base_object()); | 1538 LOperand* base_object = UseRegisterAtStart(instr->base_object()); |
| 1539 LOperand* offset = UseRegisterOrConstantAtStart(instr->offset()); | 1539 LOperand* offset = UseRegisterOrConstantAtStart(instr->offset()); |
| 1540 return DefineAsRegister( | 1540 return DefineAsRegister( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1578 | 1578 |
| 1579 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( | 1579 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
| 1580 HCompareMinusZeroAndBranch* instr) { | 1580 HCompareMinusZeroAndBranch* instr) { |
| 1581 LOperand* value = UseRegister(instr->value()); | 1581 LOperand* value = UseRegister(instr->value()); |
| 1582 LOperand* scratch = TempRegister(); | 1582 LOperand* scratch = TempRegister(); |
| 1583 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); | 1583 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); |
| 1584 } | 1584 } |
| 1585 | 1585 |
| 1586 | 1586 |
| 1587 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1587 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
| 1588 ASSERT(instr->value()->representation().IsTagged()); | 1588 DCHECK(instr->value()->representation().IsTagged()); |
| 1589 LOperand* value = UseRegisterAtStart(instr->value()); | 1589 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1590 LOperand* temp1 = TempRegister(); | 1590 LOperand* temp1 = TempRegister(); |
| 1591 LOperand* temp2 = TempRegister(); | 1591 LOperand* temp2 = TempRegister(); |
| 1592 return new(zone()) LIsObjectAndBranch(value, temp1, temp2); | 1592 return new(zone()) LIsObjectAndBranch(value, temp1, temp2); |
| 1593 } | 1593 } |
| 1594 | 1594 |
| 1595 | 1595 |
| 1596 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { | 1596 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) { |
| 1597 ASSERT(instr->value()->representation().IsTagged()); | 1597 DCHECK(instr->value()->representation().IsTagged()); |
| 1598 LOperand* value = UseRegisterAtStart(instr->value()); | 1598 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1599 LOperand* temp = TempRegister(); | 1599 LOperand* temp = TempRegister(); |
| 1600 return new(zone()) LIsStringAndBranch(value, temp); | 1600 return new(zone()) LIsStringAndBranch(value, temp); |
| 1601 } | 1601 } |
| 1602 | 1602 |
| 1603 | 1603 |
| 1604 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { | 1604 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { |
| 1605 ASSERT(instr->value()->representation().IsTagged()); | 1605 DCHECK(instr->value()->representation().IsTagged()); |
| 1606 return new(zone()) LIsSmiAndBranch(UseRegisterAtStart(instr->value())); | 1606 return new(zone()) LIsSmiAndBranch(UseRegisterAtStart(instr->value())); |
| 1607 } | 1607 } |
| 1608 | 1608 |
| 1609 | 1609 |
| 1610 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( | 1610 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( |
| 1611 HIsUndetectableAndBranch* instr) { | 1611 HIsUndetectableAndBranch* instr) { |
| 1612 ASSERT(instr->value()->representation().IsTagged()); | 1612 DCHECK(instr->value()->representation().IsTagged()); |
| 1613 LOperand* value = UseRegisterAtStart(instr->value()); | 1613 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1614 return new(zone()) LIsUndetectableAndBranch(value, TempRegister()); | 1614 return new(zone()) LIsUndetectableAndBranch(value, TempRegister()); |
| 1615 } | 1615 } |
| 1616 | 1616 |
| 1617 | 1617 |
| 1618 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 1618 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 1619 LInstruction* pop = NULL; | 1619 LInstruction* pop = NULL; |
| 1620 HEnvironment* env = current_block_->last_environment(); | 1620 HEnvironment* env = current_block_->last_environment(); |
| 1621 | 1621 |
| 1622 if (env->entry()->arguments_pushed()) { | 1622 if (env->entry()->arguments_pushed()) { |
| 1623 int argument_count = env->arguments_environment()->parameter_count(); | 1623 int argument_count = env->arguments_environment()->parameter_count(); |
| 1624 pop = new(zone()) LDrop(argument_count); | 1624 pop = new(zone()) LDrop(argument_count); |
| 1625 ASSERT(instr->argument_delta() == -argument_count); | 1625 DCHECK(instr->argument_delta() == -argument_count); |
| 1626 } | 1626 } |
| 1627 | 1627 |
| 1628 HEnvironment* outer = | 1628 HEnvironment* outer = |
| 1629 current_block_->last_environment()->DiscardInlined(false); | 1629 current_block_->last_environment()->DiscardInlined(false); |
| 1630 current_block_->UpdateEnvironment(outer); | 1630 current_block_->UpdateEnvironment(outer); |
| 1631 | 1631 |
| 1632 return pop; | 1632 return pop; |
| 1633 } | 1633 } |
| 1634 | 1634 |
| 1635 | 1635 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1670 vector = FixedTemp(LoadIC::VectorRegister()); | 1670 vector = FixedTemp(LoadIC::VectorRegister()); |
| 1671 } | 1671 } |
| 1672 | 1672 |
| 1673 LLoadGlobalGeneric* result = | 1673 LLoadGlobalGeneric* result = |
| 1674 new(zone()) LLoadGlobalGeneric(context, global_object, vector); | 1674 new(zone()) LLoadGlobalGeneric(context, global_object, vector); |
| 1675 return MarkAsCall(DefineFixed(result, x0), instr); | 1675 return MarkAsCall(DefineFixed(result, x0), instr); |
| 1676 } | 1676 } |
| 1677 | 1677 |
| 1678 | 1678 |
| 1679 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 1679 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 1680 ASSERT(instr->key()->representation().IsSmiOrInteger32()); | 1680 DCHECK(instr->key()->representation().IsSmiOrInteger32()); |
| 1681 ElementsKind elements_kind = instr->elements_kind(); | 1681 ElementsKind elements_kind = instr->elements_kind(); |
| 1682 LOperand* elements = UseRegister(instr->elements()); | 1682 LOperand* elements = UseRegister(instr->elements()); |
| 1683 LOperand* key = UseRegisterOrConstant(instr->key()); | 1683 LOperand* key = UseRegisterOrConstant(instr->key()); |
| 1684 | 1684 |
| 1685 if (!instr->is_typed_elements()) { | 1685 if (!instr->is_typed_elements()) { |
| 1686 if (instr->representation().IsDouble()) { | 1686 if (instr->representation().IsDouble()) { |
| 1687 LOperand* temp = (!instr->key()->IsConstant() || | 1687 LOperand* temp = (!instr->key()->IsConstant() || |
| 1688 instr->RequiresHoleCheck()) | 1688 instr->RequiresHoleCheck()) |
| 1689 ? TempRegister() | 1689 ? TempRegister() |
| 1690 : NULL; | 1690 : NULL; |
| 1691 | 1691 |
| 1692 LLoadKeyedFixedDouble* result = | 1692 LLoadKeyedFixedDouble* result = |
| 1693 new(zone()) LLoadKeyedFixedDouble(elements, key, temp); | 1693 new(zone()) LLoadKeyedFixedDouble(elements, key, temp); |
| 1694 return instr->RequiresHoleCheck() | 1694 return instr->RequiresHoleCheck() |
| 1695 ? AssignEnvironment(DefineAsRegister(result)) | 1695 ? AssignEnvironment(DefineAsRegister(result)) |
| 1696 : DefineAsRegister(result); | 1696 : DefineAsRegister(result); |
| 1697 } else { | 1697 } else { |
| 1698 ASSERT(instr->representation().IsSmiOrTagged() || | 1698 DCHECK(instr->representation().IsSmiOrTagged() || |
| 1699 instr->representation().IsInteger32()); | 1699 instr->representation().IsInteger32()); |
| 1700 LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister(); | 1700 LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister(); |
| 1701 LLoadKeyedFixed* result = | 1701 LLoadKeyedFixed* result = |
| 1702 new(zone()) LLoadKeyedFixed(elements, key, temp); | 1702 new(zone()) LLoadKeyedFixed(elements, key, temp); |
| 1703 return instr->RequiresHoleCheck() | 1703 return instr->RequiresHoleCheck() |
| 1704 ? AssignEnvironment(DefineAsRegister(result)) | 1704 ? AssignEnvironment(DefineAsRegister(result)) |
| 1705 : DefineAsRegister(result); | 1705 : DefineAsRegister(result); |
| 1706 } | 1706 } |
| 1707 } else { | 1707 } else { |
| 1708 ASSERT((instr->representation().IsInteger32() && | 1708 DCHECK((instr->representation().IsInteger32() && |
| 1709 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || | 1709 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || |
| 1710 (instr->representation().IsDouble() && | 1710 (instr->representation().IsDouble() && |
| 1711 IsDoubleOrFloatElementsKind(instr->elements_kind()))); | 1711 IsDoubleOrFloatElementsKind(instr->elements_kind()))); |
| 1712 | 1712 |
| 1713 LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister(); | 1713 LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister(); |
| 1714 LInstruction* result = DefineAsRegister( | 1714 LInstruction* result = DefineAsRegister( |
| 1715 new(zone()) LLoadKeyedExternal(elements, key, temp)); | 1715 new(zone()) LLoadKeyedExternal(elements, key, temp)); |
| 1716 if ((elements_kind == EXTERNAL_UINT32_ELEMENTS || | 1716 if ((elements_kind == EXTERNAL_UINT32_ELEMENTS || |
| 1717 elements_kind == UINT32_ELEMENTS) && | 1717 elements_kind == UINT32_ELEMENTS) && |
| 1718 !instr->CheckFlag(HInstruction::kUint32)) { | 1718 !instr->CheckFlag(HInstruction::kUint32)) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 } | 1764 } |
| 1765 | 1765 |
| 1766 | 1766 |
| 1767 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1767 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
| 1768 LOperand* map = UseRegisterAtStart(instr->value()); | 1768 LOperand* map = UseRegisterAtStart(instr->value()); |
| 1769 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1769 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
| 1770 } | 1770 } |
| 1771 | 1771 |
| 1772 | 1772 |
| 1773 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) { | 1773 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) { |
| 1774 ASSERT(instr->representation().IsInteger32()); | 1774 DCHECK(instr->representation().IsInteger32()); |
| 1775 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1775 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1776 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1776 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1777 LOperand* dividend = UseRegisterAtStart(instr->left()); | 1777 LOperand* dividend = UseRegisterAtStart(instr->left()); |
| 1778 int32_t divisor = instr->right()->GetInteger32Constant(); | 1778 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1779 LInstruction* result = DefineAsRegister(new(zone()) LFlooringDivByPowerOf2I( | 1779 LInstruction* result = DefineAsRegister(new(zone()) LFlooringDivByPowerOf2I( |
| 1780 dividend, divisor)); | 1780 dividend, divisor)); |
| 1781 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1781 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1782 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { | 1782 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { |
| 1783 result = AssignEnvironment(result); | 1783 result = AssignEnvironment(result); |
| 1784 } | 1784 } |
| 1785 return result; | 1785 return result; |
| 1786 } | 1786 } |
| 1787 | 1787 |
| 1788 | 1788 |
| 1789 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { | 1789 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { |
| 1790 ASSERT(instr->representation().IsInteger32()); | 1790 DCHECK(instr->representation().IsInteger32()); |
| 1791 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1791 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1792 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1792 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1793 LOperand* dividend = UseRegister(instr->left()); | 1793 LOperand* dividend = UseRegister(instr->left()); |
| 1794 int32_t divisor = instr->right()->GetInteger32Constant(); | 1794 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1795 LOperand* temp = | 1795 LOperand* temp = |
| 1796 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || | 1796 ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) || |
| 1797 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? | 1797 (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ? |
| 1798 NULL : TempRegister(); | 1798 NULL : TempRegister(); |
| 1799 LInstruction* result = DefineAsRegister( | 1799 LInstruction* result = DefineAsRegister( |
| 1800 new(zone()) LFlooringDivByConstI(dividend, divisor, temp)); | 1800 new(zone()) LFlooringDivByConstI(dividend, divisor, temp)); |
| 1801 if (divisor == 0 || | 1801 if (divisor == 0 || |
| 1802 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { | 1802 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1824 } else { | 1824 } else { |
| 1825 return DoFlooringDivI(instr); | 1825 return DoFlooringDivI(instr); |
| 1826 } | 1826 } |
| 1827 } | 1827 } |
| 1828 | 1828 |
| 1829 | 1829 |
| 1830 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1830 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
| 1831 LOperand* left = NULL; | 1831 LOperand* left = NULL; |
| 1832 LOperand* right = NULL; | 1832 LOperand* right = NULL; |
| 1833 if (instr->representation().IsSmiOrInteger32()) { | 1833 if (instr->representation().IsSmiOrInteger32()) { |
| 1834 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1834 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1835 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1835 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1836 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1836 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1837 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); | 1837 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); |
| 1838 } else { | 1838 } else { |
| 1839 ASSERT(instr->representation().IsDouble()); | 1839 DCHECK(instr->representation().IsDouble()); |
| 1840 ASSERT(instr->left()->representation().IsDouble()); | 1840 DCHECK(instr->left()->representation().IsDouble()); |
| 1841 ASSERT(instr->right()->representation().IsDouble()); | 1841 DCHECK(instr->right()->representation().IsDouble()); |
| 1842 left = UseRegisterAtStart(instr->left()); | 1842 left = UseRegisterAtStart(instr->left()); |
| 1843 right = UseRegisterAtStart(instr->right()); | 1843 right = UseRegisterAtStart(instr->right()); |
| 1844 } | 1844 } |
| 1845 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); | 1845 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); |
| 1846 } | 1846 } |
| 1847 | 1847 |
| 1848 | 1848 |
| 1849 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { | 1849 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { |
| 1850 ASSERT(instr->representation().IsInteger32()); | 1850 DCHECK(instr->representation().IsInteger32()); |
| 1851 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1851 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1852 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1852 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1853 LOperand* dividend = UseRegisterAtStart(instr->left()); | 1853 LOperand* dividend = UseRegisterAtStart(instr->left()); |
| 1854 int32_t divisor = instr->right()->GetInteger32Constant(); | 1854 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1855 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( | 1855 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( |
| 1856 dividend, divisor)); | 1856 dividend, divisor)); |
| 1857 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && | 1857 if (instr->CheckFlag(HValue::kLeftCanBeNegative) && |
| 1858 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1858 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1859 result = AssignEnvironment(result); | 1859 result = AssignEnvironment(result); |
| 1860 } | 1860 } |
| 1861 return result; | 1861 return result; |
| 1862 } | 1862 } |
| 1863 | 1863 |
| 1864 | 1864 |
| 1865 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { | 1865 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { |
| 1866 ASSERT(instr->representation().IsInteger32()); | 1866 DCHECK(instr->representation().IsInteger32()); |
| 1867 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1867 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1868 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1868 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1869 LOperand* dividend = UseRegister(instr->left()); | 1869 LOperand* dividend = UseRegister(instr->left()); |
| 1870 int32_t divisor = instr->right()->GetInteger32Constant(); | 1870 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1871 LOperand* temp = TempRegister(); | 1871 LOperand* temp = TempRegister(); |
| 1872 LInstruction* result = DefineAsRegister(new(zone()) LModByConstI( | 1872 LInstruction* result = DefineAsRegister(new(zone()) LModByConstI( |
| 1873 dividend, divisor, temp)); | 1873 dividend, divisor, temp)); |
| 1874 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1874 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1875 result = AssignEnvironment(result); | 1875 result = AssignEnvironment(result); |
| 1876 } | 1876 } |
| 1877 return result; | 1877 return result; |
| 1878 } | 1878 } |
| 1879 | 1879 |
| 1880 | 1880 |
| 1881 LInstruction* LChunkBuilder::DoModI(HMod* instr) { | 1881 LInstruction* LChunkBuilder::DoModI(HMod* instr) { |
| 1882 ASSERT(instr->representation().IsSmiOrInteger32()); | 1882 DCHECK(instr->representation().IsSmiOrInteger32()); |
| 1883 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1883 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1884 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1884 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1885 LOperand* dividend = UseRegister(instr->left()); | 1885 LOperand* dividend = UseRegister(instr->left()); |
| 1886 LOperand* divisor = UseRegister(instr->right()); | 1886 LOperand* divisor = UseRegister(instr->right()); |
| 1887 LInstruction* result = DefineAsRegister(new(zone()) LModI(dividend, divisor)); | 1887 LInstruction* result = DefineAsRegister(new(zone()) LModI(dividend, divisor)); |
| 1888 if (instr->CheckFlag(HValue::kCanBeDivByZero) || | 1888 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1889 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1889 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1890 result = AssignEnvironment(result); | 1890 result = AssignEnvironment(result); |
| 1891 } | 1891 } |
| 1892 return result; | 1892 return result; |
| 1893 } | 1893 } |
| 1894 | 1894 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1905 } else if (instr->representation().IsDouble()) { | 1905 } else if (instr->representation().IsDouble()) { |
| 1906 return DoArithmeticD(Token::MOD, instr); | 1906 return DoArithmeticD(Token::MOD, instr); |
| 1907 } else { | 1907 } else { |
| 1908 return DoArithmeticT(Token::MOD, instr); | 1908 return DoArithmeticT(Token::MOD, instr); |
| 1909 } | 1909 } |
| 1910 } | 1910 } |
| 1911 | 1911 |
| 1912 | 1912 |
| 1913 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1913 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1914 if (instr->representation().IsSmiOrInteger32()) { | 1914 if (instr->representation().IsSmiOrInteger32()) { |
| 1915 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1915 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 1916 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1916 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 1917 | 1917 |
| 1918 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); | 1918 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
| 1919 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); | 1919 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); |
| 1920 | 1920 |
| 1921 HValue* least_const = instr->BetterLeftOperand(); | 1921 HValue* least_const = instr->BetterLeftOperand(); |
| 1922 HValue* most_const = instr->BetterRightOperand(); | 1922 HValue* most_const = instr->BetterRightOperand(); |
| 1923 | 1923 |
| 1924 // LMulConstI can handle a subset of constants: | 1924 // LMulConstI can handle a subset of constants: |
| 1925 // With support for overflow detection: | 1925 // With support for overflow detection: |
| 1926 // -1, 0, 1, 2 | 1926 // -1, 0, 1, 2 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1964 return result; | 1964 return result; |
| 1965 } else if (instr->representation().IsDouble()) { | 1965 } else if (instr->representation().IsDouble()) { |
| 1966 return DoArithmeticD(Token::MUL, instr); | 1966 return DoArithmeticD(Token::MUL, instr); |
| 1967 } else { | 1967 } else { |
| 1968 return DoArithmeticT(Token::MUL, instr); | 1968 return DoArithmeticT(Token::MUL, instr); |
| 1969 } | 1969 } |
| 1970 } | 1970 } |
| 1971 | 1971 |
| 1972 | 1972 |
| 1973 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1973 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 1974 ASSERT(argument_count_ == 0); | 1974 DCHECK(argument_count_ == 0); |
| 1975 allocator_->MarkAsOsrEntry(); | 1975 allocator_->MarkAsOsrEntry(); |
| 1976 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 1976 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 1977 return AssignEnvironment(new(zone()) LOsrEntry); | 1977 return AssignEnvironment(new(zone()) LOsrEntry); |
| 1978 } | 1978 } |
| 1979 | 1979 |
| 1980 | 1980 |
| 1981 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 1981 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 1982 LParameter* result = new(zone()) LParameter; | 1982 LParameter* result = new(zone()) LParameter; |
| 1983 if (instr->kind() == HParameter::STACK_PARAMETER) { | 1983 if (instr->kind() == HParameter::STACK_PARAMETER) { |
| 1984 int spill_index = chunk_->GetParameterStackSlot(instr->index()); | 1984 int spill_index = chunk_->GetParameterStackSlot(instr->index()); |
| 1985 return DefineAsSpilled(result, spill_index); | 1985 return DefineAsSpilled(result, spill_index); |
| 1986 } else { | 1986 } else { |
| 1987 ASSERT(info()->IsStub()); | 1987 DCHECK(info()->IsStub()); |
| 1988 CodeStubInterfaceDescriptor* descriptor = | 1988 CodeStubInterfaceDescriptor* descriptor = |
| 1989 info()->code_stub()->GetInterfaceDescriptor(); | 1989 info()->code_stub()->GetInterfaceDescriptor(); |
| 1990 int index = static_cast<int>(instr->index()); | 1990 int index = static_cast<int>(instr->index()); |
| 1991 Register reg = descriptor->GetEnvironmentParameterRegister(index); | 1991 Register reg = descriptor->GetEnvironmentParameterRegister(index); |
| 1992 return DefineFixed(result, reg); | 1992 return DefineFixed(result, reg); |
| 1993 } | 1993 } |
| 1994 } | 1994 } |
| 1995 | 1995 |
| 1996 | 1996 |
| 1997 LInstruction* LChunkBuilder::DoPower(HPower* instr) { | 1997 LInstruction* LChunkBuilder::DoPower(HPower* instr) { |
| 1998 ASSERT(instr->representation().IsDouble()); | 1998 DCHECK(instr->representation().IsDouble()); |
| 1999 // We call a C function for double power. It can't trigger a GC. | 1999 // We call a C function for double power. It can't trigger a GC. |
| 2000 // We need to use fixed result register for the call. | 2000 // We need to use fixed result register for the call. |
| 2001 Representation exponent_type = instr->right()->representation(); | 2001 Representation exponent_type = instr->right()->representation(); |
| 2002 ASSERT(instr->left()->representation().IsDouble()); | 2002 DCHECK(instr->left()->representation().IsDouble()); |
| 2003 LOperand* left = UseFixedDouble(instr->left(), d0); | 2003 LOperand* left = UseFixedDouble(instr->left(), d0); |
| 2004 LOperand* right = exponent_type.IsInteger32() | 2004 LOperand* right = exponent_type.IsInteger32() |
| 2005 ? UseFixed(instr->right(), x12) | 2005 ? UseFixed(instr->right(), x12) |
| 2006 : exponent_type.IsDouble() | 2006 : exponent_type.IsDouble() |
| 2007 ? UseFixedDouble(instr->right(), d1) | 2007 ? UseFixedDouble(instr->right(), d1) |
| 2008 : UseFixed(instr->right(), x11); | 2008 : UseFixed(instr->right(), x11); |
| 2009 LPower* result = new(zone()) LPower(left, right); | 2009 LPower* result = new(zone()) LPower(left, right); |
| 2010 return MarkAsCall(DefineFixedDouble(result, d0), | 2010 return MarkAsCall(DefineFixedDouble(result, d0), |
| 2011 instr, | 2011 instr, |
| 2012 CAN_DEOPTIMIZE_EAGERLY); | 2012 CAN_DEOPTIMIZE_EAGERLY); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2033 | 2033 |
| 2034 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 2034 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 2035 LOperand* context = UseFixed(instr->context(), cp); | 2035 LOperand* context = UseFixed(instr->context(), cp); |
| 2036 return MarkAsCall( | 2036 return MarkAsCall( |
| 2037 DefineFixed(new(zone()) LRegExpLiteral(context), x0), instr); | 2037 DefineFixed(new(zone()) LRegExpLiteral(context), x0), instr); |
| 2038 } | 2038 } |
| 2039 | 2039 |
| 2040 | 2040 |
| 2041 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { | 2041 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { |
| 2042 HValue* value = instr->value(); | 2042 HValue* value = instr->value(); |
| 2043 ASSERT(value->representation().IsDouble()); | 2043 DCHECK(value->representation().IsDouble()); |
| 2044 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); | 2044 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); |
| 2045 } | 2045 } |
| 2046 | 2046 |
| 2047 | 2047 |
| 2048 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { | 2048 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { |
| 2049 LOperand* lo = UseRegisterAndClobber(instr->lo()); | 2049 LOperand* lo = UseRegisterAndClobber(instr->lo()); |
| 2050 LOperand* hi = UseRegister(instr->hi()); | 2050 LOperand* hi = UseRegister(instr->hi()); |
| 2051 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); | 2051 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo)); |
| 2052 } | 2052 } |
| 2053 | 2053 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2087 | 2087 |
| 2088 | 2088 |
| 2089 HBitwiseBinaryOperation* LChunkBuilder::CanTransformToShiftedOp(HValue* val, | 2089 HBitwiseBinaryOperation* LChunkBuilder::CanTransformToShiftedOp(HValue* val, |
| 2090 HValue** left) { | 2090 HValue** left) { |
| 2091 if (!val->representation().IsInteger32()) return NULL; | 2091 if (!val->representation().IsInteger32()) return NULL; |
| 2092 if (!(val->IsBitwise() || val->IsAdd() || val->IsSub())) return NULL; | 2092 if (!(val->IsBitwise() || val->IsAdd() || val->IsSub())) return NULL; |
| 2093 | 2093 |
| 2094 HBinaryOperation* hinstr = HBinaryOperation::cast(val); | 2094 HBinaryOperation* hinstr = HBinaryOperation::cast(val); |
| 2095 HValue* hleft = hinstr->left(); | 2095 HValue* hleft = hinstr->left(); |
| 2096 HValue* hright = hinstr->right(); | 2096 HValue* hright = hinstr->right(); |
| 2097 ASSERT(hleft->representation().Equals(hinstr->representation())); | 2097 DCHECK(hleft->representation().Equals(hinstr->representation())); |
| 2098 ASSERT(hright->representation().Equals(hinstr->representation())); | 2098 DCHECK(hright->representation().Equals(hinstr->representation())); |
| 2099 | 2099 |
| 2100 if ((hright->IsConstant() && | 2100 if ((hright->IsConstant() && |
| 2101 LikelyFitsImmField(hinstr, HConstant::cast(hright)->Integer32Value())) || | 2101 LikelyFitsImmField(hinstr, HConstant::cast(hright)->Integer32Value())) || |
| 2102 (hinstr->IsCommutative() && hleft->IsConstant() && | 2102 (hinstr->IsCommutative() && hleft->IsConstant() && |
| 2103 LikelyFitsImmField(hinstr, HConstant::cast(hleft)->Integer32Value()))) { | 2103 LikelyFitsImmField(hinstr, HConstant::cast(hleft)->Integer32Value()))) { |
| 2104 // The constant operand will likely fit in the immediate field. We are | 2104 // The constant operand will likely fit in the immediate field. We are |
| 2105 // better off with | 2105 // better off with |
| 2106 // lsl x8, x9, #imm | 2106 // lsl x8, x9, #imm |
| 2107 // add x0, x8, #imm2 | 2107 // add x0, x8, #imm2 |
| 2108 // than with | 2108 // than with |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2160 | 2160 |
| 2161 if ((shift != NULL) && ShiftCanBeOptimizedAway(shift)) { | 2161 if ((shift != NULL) && ShiftCanBeOptimizedAway(shift)) { |
| 2162 return DoShiftedBinaryOp(instr, left, shift); | 2162 return DoShiftedBinaryOp(instr, left, shift); |
| 2163 } | 2163 } |
| 2164 return NULL; | 2164 return NULL; |
| 2165 } | 2165 } |
| 2166 | 2166 |
| 2167 | 2167 |
| 2168 LInstruction* LChunkBuilder::DoShiftedBinaryOp( | 2168 LInstruction* LChunkBuilder::DoShiftedBinaryOp( |
| 2169 HBinaryOperation* hinstr, HValue* hleft, HBitwiseBinaryOperation* hshift) { | 2169 HBinaryOperation* hinstr, HValue* hleft, HBitwiseBinaryOperation* hshift) { |
| 2170 ASSERT(hshift->IsBitwiseBinaryShift()); | 2170 DCHECK(hshift->IsBitwiseBinaryShift()); |
| 2171 ASSERT(!hshift->IsShr() || (JSShiftAmountFromHConstant(hshift->right()) > 0)); | 2171 DCHECK(!hshift->IsShr() || (JSShiftAmountFromHConstant(hshift->right()) > 0)); |
| 2172 | 2172 |
| 2173 LTemplateResultInstruction<1>* res; | 2173 LTemplateResultInstruction<1>* res; |
| 2174 LOperand* left = UseRegisterAtStart(hleft); | 2174 LOperand* left = UseRegisterAtStart(hleft); |
| 2175 LOperand* right = UseRegisterAtStart(hshift->left()); | 2175 LOperand* right = UseRegisterAtStart(hshift->left()); |
| 2176 LOperand* shift_amount = UseConstant(hshift->right()); | 2176 LOperand* shift_amount = UseConstant(hshift->right()); |
| 2177 Shift shift_op; | 2177 Shift shift_op; |
| 2178 switch (hshift->opcode()) { | 2178 switch (hshift->opcode()) { |
| 2179 case HValue::kShl: shift_op = LSL; break; | 2179 case HValue::kShl: shift_op = LSL; break; |
| 2180 case HValue::kShr: shift_op = LSR; break; | 2180 case HValue::kShr: shift_op = LSR; break; |
| 2181 case HValue::kSar: shift_op = ASR; break; | 2181 case HValue::kSar: shift_op = ASR; break; |
| 2182 default: UNREACHABLE(); shift_op = NO_SHIFT; | 2182 default: UNREACHABLE(); shift_op = NO_SHIFT; |
| 2183 } | 2183 } |
| 2184 | 2184 |
| 2185 if (hinstr->IsBitwise()) { | 2185 if (hinstr->IsBitwise()) { |
| 2186 res = new(zone()) LBitI(left, right, shift_op, shift_amount); | 2186 res = new(zone()) LBitI(left, right, shift_op, shift_amount); |
| 2187 } else if (hinstr->IsAdd()) { | 2187 } else if (hinstr->IsAdd()) { |
| 2188 res = new(zone()) LAddI(left, right, shift_op, shift_amount); | 2188 res = new(zone()) LAddI(left, right, shift_op, shift_amount); |
| 2189 } else { | 2189 } else { |
| 2190 ASSERT(hinstr->IsSub()); | 2190 DCHECK(hinstr->IsSub()); |
| 2191 res = new(zone()) LSubI(left, right, shift_op, shift_amount); | 2191 res = new(zone()) LSubI(left, right, shift_op, shift_amount); |
| 2192 } | 2192 } |
| 2193 if (hinstr->CheckFlag(HValue::kCanOverflow)) { | 2193 if (hinstr->CheckFlag(HValue::kCanOverflow)) { |
| 2194 AssignEnvironment(res); | 2194 AssignEnvironment(res); |
| 2195 } | 2195 } |
| 2196 return DefineAsRegister(res); | 2196 return DefineAsRegister(res); |
| 2197 } | 2197 } |
| 2198 | 2198 |
| 2199 | 2199 |
| 2200 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 2200 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 2201 HBitwiseBinaryOperation* instr) { | 2201 HBitwiseBinaryOperation* instr) { |
| 2202 if (instr->representation().IsTagged()) { | 2202 if (instr->representation().IsTagged()) { |
| 2203 return DoArithmeticT(op, instr); | 2203 return DoArithmeticT(op, instr); |
| 2204 } | 2204 } |
| 2205 | 2205 |
| 2206 ASSERT(instr->representation().IsInteger32() || | 2206 DCHECK(instr->representation().IsInteger32() || |
| 2207 instr->representation().IsSmi()); | 2207 instr->representation().IsSmi()); |
| 2208 ASSERT(instr->left()->representation().Equals(instr->representation())); | 2208 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 2209 ASSERT(instr->right()->representation().Equals(instr->representation())); | 2209 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 2210 | 2210 |
| 2211 if (ShiftCanBeOptimizedAway(instr)) { | 2211 if (ShiftCanBeOptimizedAway(instr)) { |
| 2212 return NULL; | 2212 return NULL; |
| 2213 } | 2213 } |
| 2214 | 2214 |
| 2215 LOperand* left = instr->representation().IsSmi() | 2215 LOperand* left = instr->representation().IsSmi() |
| 2216 ? UseRegister(instr->left()) | 2216 ? UseRegister(instr->left()) |
| 2217 : UseRegisterAtStart(instr->left()); | 2217 : UseRegisterAtStart(instr->left()); |
| 2218 | 2218 |
| 2219 HValue* right_value = instr->right(); | 2219 HValue* right_value = instr->right(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2238 does_deopt = !instr->CheckFlag(HInstruction::kUint32); | 2238 does_deopt = !instr->CheckFlag(HInstruction::kUint32); |
| 2239 } else { | 2239 } else { |
| 2240 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32); | 2240 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32); |
| 2241 } | 2241 } |
| 2242 } | 2242 } |
| 2243 | 2243 |
| 2244 LInstruction* result; | 2244 LInstruction* result; |
| 2245 if (instr->representation().IsInteger32()) { | 2245 if (instr->representation().IsInteger32()) { |
| 2246 result = DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); | 2246 result = DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); |
| 2247 } else { | 2247 } else { |
| 2248 ASSERT(instr->representation().IsSmi()); | 2248 DCHECK(instr->representation().IsSmi()); |
| 2249 result = DefineAsRegister( | 2249 result = DefineAsRegister( |
| 2250 new(zone()) LShiftS(op, left, right, temp, does_deopt)); | 2250 new(zone()) LShiftS(op, left, right, temp, does_deopt)); |
| 2251 } | 2251 } |
| 2252 | 2252 |
| 2253 return does_deopt ? AssignEnvironment(result) : result; | 2253 return does_deopt ? AssignEnvironment(result) : result; |
| 2254 } | 2254 } |
| 2255 | 2255 |
| 2256 | 2256 |
| 2257 LInstruction* LChunkBuilder::DoRor(HRor* instr) { | 2257 LInstruction* LChunkBuilder::DoRor(HRor* instr) { |
| 2258 return DoShift(Token::ROR, instr); | 2258 return DoShift(Token::ROR, instr); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2278 instr->ReplayEnvironment(current_block_->last_environment()); | 2278 instr->ReplayEnvironment(current_block_->last_environment()); |
| 2279 return NULL; | 2279 return NULL; |
| 2280 } | 2280 } |
| 2281 | 2281 |
| 2282 | 2282 |
| 2283 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2283 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2284 if (instr->is_function_entry()) { | 2284 if (instr->is_function_entry()) { |
| 2285 LOperand* context = UseFixed(instr->context(), cp); | 2285 LOperand* context = UseFixed(instr->context(), cp); |
| 2286 return MarkAsCall(new(zone()) LStackCheck(context), instr); | 2286 return MarkAsCall(new(zone()) LStackCheck(context), instr); |
| 2287 } else { | 2287 } else { |
| 2288 ASSERT(instr->is_backwards_branch()); | 2288 DCHECK(instr->is_backwards_branch()); |
| 2289 LOperand* context = UseAny(instr->context()); | 2289 LOperand* context = UseAny(instr->context()); |
| 2290 return AssignEnvironment( | 2290 return AssignEnvironment( |
| 2291 AssignPointerMap(new(zone()) LStackCheck(context))); | 2291 AssignPointerMap(new(zone()) LStackCheck(context))); |
| 2292 } | 2292 } |
| 2293 } | 2293 } |
| 2294 | 2294 |
| 2295 | 2295 |
| 2296 LInstruction* LChunkBuilder::DoStoreCodeEntry(HStoreCodeEntry* instr) { | 2296 LInstruction* LChunkBuilder::DoStoreCodeEntry(HStoreCodeEntry* instr) { |
| 2297 LOperand* function = UseRegister(instr->function()); | 2297 LOperand* function = UseRegister(instr->function()); |
| 2298 LOperand* code_object = UseRegisterAtStart(instr->code_object()); | 2298 LOperand* code_object = UseRegisterAtStart(instr->code_object()); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2347 elements = UseRegisterAndClobber(instr->elements()); | 2347 elements = UseRegisterAndClobber(instr->elements()); |
| 2348 val = UseRegisterAndClobber(instr->value()); | 2348 val = UseRegisterAndClobber(instr->value()); |
| 2349 temp = TempRegister(); | 2349 temp = TempRegister(); |
| 2350 } else { | 2350 } else { |
| 2351 elements = UseRegister(instr->elements()); | 2351 elements = UseRegister(instr->elements()); |
| 2352 val = UseRegister(instr->value()); | 2352 val = UseRegister(instr->value()); |
| 2353 temp = instr->key()->IsConstant() ? NULL : TempRegister(); | 2353 temp = instr->key()->IsConstant() ? NULL : TempRegister(); |
| 2354 } | 2354 } |
| 2355 | 2355 |
| 2356 if (instr->is_typed_elements()) { | 2356 if (instr->is_typed_elements()) { |
| 2357 ASSERT((instr->value()->representation().IsInteger32() && | 2357 DCHECK((instr->value()->representation().IsInteger32() && |
| 2358 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || | 2358 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || |
| 2359 (instr->value()->representation().IsDouble() && | 2359 (instr->value()->representation().IsDouble() && |
| 2360 IsDoubleOrFloatElementsKind(instr->elements_kind()))); | 2360 IsDoubleOrFloatElementsKind(instr->elements_kind()))); |
| 2361 ASSERT((instr->is_fixed_typed_array() && | 2361 DCHECK((instr->is_fixed_typed_array() && |
| 2362 instr->elements()->representation().IsTagged()) || | 2362 instr->elements()->representation().IsTagged()) || |
| 2363 (instr->is_external() && | 2363 (instr->is_external() && |
| 2364 instr->elements()->representation().IsExternal())); | 2364 instr->elements()->representation().IsExternal())); |
| 2365 return new(zone()) LStoreKeyedExternal(elements, key, val, temp); | 2365 return new(zone()) LStoreKeyedExternal(elements, key, val, temp); |
| 2366 | 2366 |
| 2367 } else if (instr->value()->representation().IsDouble()) { | 2367 } else if (instr->value()->representation().IsDouble()) { |
| 2368 ASSERT(instr->elements()->representation().IsTagged()); | 2368 DCHECK(instr->elements()->representation().IsTagged()); |
| 2369 return new(zone()) LStoreKeyedFixedDouble(elements, key, val, temp); | 2369 return new(zone()) LStoreKeyedFixedDouble(elements, key, val, temp); |
| 2370 | 2370 |
| 2371 } else { | 2371 } else { |
| 2372 ASSERT(instr->elements()->representation().IsTagged()); | 2372 DCHECK(instr->elements()->representation().IsTagged()); |
| 2373 ASSERT(instr->value()->representation().IsSmiOrTagged() || | 2373 DCHECK(instr->value()->representation().IsSmiOrTagged() || |
| 2374 instr->value()->representation().IsInteger32()); | 2374 instr->value()->representation().IsInteger32()); |
| 2375 return new(zone()) LStoreKeyedFixed(elements, key, val, temp); | 2375 return new(zone()) LStoreKeyedFixed(elements, key, val, temp); |
| 2376 } | 2376 } |
| 2377 } | 2377 } |
| 2378 | 2378 |
| 2379 | 2379 |
| 2380 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2380 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 2381 LOperand* context = UseFixed(instr->context(), cp); | 2381 LOperand* context = UseFixed(instr->context(), cp); |
| 2382 LOperand* object = UseFixed(instr->object(), | 2382 LOperand* object = UseFixed(instr->object(), |
| 2383 KeyedStoreIC::ReceiverRegister()); | 2383 KeyedStoreIC::ReceiverRegister()); |
| 2384 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); | 2384 LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister()); |
| 2385 LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); | 2385 LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister()); |
| 2386 | 2386 |
| 2387 ASSERT(instr->object()->representation().IsTagged()); | 2387 DCHECK(instr->object()->representation().IsTagged()); |
| 2388 ASSERT(instr->key()->representation().IsTagged()); | 2388 DCHECK(instr->key()->representation().IsTagged()); |
| 2389 ASSERT(instr->value()->representation().IsTagged()); | 2389 DCHECK(instr->value()->representation().IsTagged()); |
| 2390 | 2390 |
| 2391 return MarkAsCall( | 2391 return MarkAsCall( |
| 2392 new(zone()) LStoreKeyedGeneric(context, object, key, value), instr); | 2392 new(zone()) LStoreKeyedGeneric(context, object, key, value), instr); |
| 2393 } | 2393 } |
| 2394 | 2394 |
| 2395 | 2395 |
| 2396 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { | 2396 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
| 2397 // TODO(jbramley): It might be beneficial to allow value to be a constant in | 2397 // TODO(jbramley): It might be beneficial to allow value to be a constant in |
| 2398 // some cases. x64 makes use of this with FLAG_track_fields, for example. | 2398 // some cases. x64 makes use of this with FLAG_track_fields, for example. |
| 2399 | 2399 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2456 LOperand* char_code = UseRegister(instr->value()); | 2456 LOperand* char_code = UseRegister(instr->value()); |
| 2457 LOperand* context = UseAny(instr->context()); | 2457 LOperand* context = UseAny(instr->context()); |
| 2458 LStringCharFromCode* result = | 2458 LStringCharFromCode* result = |
| 2459 new(zone()) LStringCharFromCode(context, char_code); | 2459 new(zone()) LStringCharFromCode(context, char_code); |
| 2460 return AssignPointerMap(DefineAsRegister(result)); | 2460 return AssignPointerMap(DefineAsRegister(result)); |
| 2461 } | 2461 } |
| 2462 | 2462 |
| 2463 | 2463 |
| 2464 LInstruction* LChunkBuilder::DoStringCompareAndBranch( | 2464 LInstruction* LChunkBuilder::DoStringCompareAndBranch( |
| 2465 HStringCompareAndBranch* instr) { | 2465 HStringCompareAndBranch* instr) { |
| 2466 ASSERT(instr->left()->representation().IsTagged()); | 2466 DCHECK(instr->left()->representation().IsTagged()); |
| 2467 ASSERT(instr->right()->representation().IsTagged()); | 2467 DCHECK(instr->right()->representation().IsTagged()); |
| 2468 LOperand* context = UseFixed(instr->context(), cp); | 2468 LOperand* context = UseFixed(instr->context(), cp); |
| 2469 LOperand* left = UseFixed(instr->left(), x1); | 2469 LOperand* left = UseFixed(instr->left(), x1); |
| 2470 LOperand* right = UseFixed(instr->right(), x0); | 2470 LOperand* right = UseFixed(instr->right(), x0); |
| 2471 LStringCompareAndBranch* result = | 2471 LStringCompareAndBranch* result = |
| 2472 new(zone()) LStringCompareAndBranch(context, left, right); | 2472 new(zone()) LStringCompareAndBranch(context, left, right); |
| 2473 return MarkAsCall(result, instr); | 2473 return MarkAsCall(result, instr); |
| 2474 } | 2474 } |
| 2475 | 2475 |
| 2476 | 2476 |
| 2477 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 2477 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| 2478 if (instr->representation().IsSmiOrInteger32()) { | 2478 if (instr->representation().IsSmiOrInteger32()) { |
| 2479 ASSERT(instr->left()->representation().Equals(instr->representation())); | 2479 DCHECK(instr->left()->representation().Equals(instr->representation())); |
| 2480 ASSERT(instr->right()->representation().Equals(instr->representation())); | 2480 DCHECK(instr->right()->representation().Equals(instr->representation())); |
| 2481 | 2481 |
| 2482 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr); | 2482 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr); |
| 2483 if (shifted_operation != NULL) { | 2483 if (shifted_operation != NULL) { |
| 2484 return shifted_operation; | 2484 return shifted_operation; |
| 2485 } | 2485 } |
| 2486 | 2486 |
| 2487 LOperand *left; | 2487 LOperand *left; |
| 2488 if (instr->left()->IsConstant() && | 2488 if (instr->left()->IsConstant() && |
| 2489 (HConstant::cast(instr->left())->Integer32Value() == 0)) { | 2489 (HConstant::cast(instr->left())->Integer32Value() == 0)) { |
| 2490 left = UseConstant(instr->left()); | 2490 left = UseConstant(instr->left()); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2591 new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3)); | 2591 new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3)); |
| 2592 return AssignEnvironment(AssignPointerMap(result)); | 2592 return AssignEnvironment(AssignPointerMap(result)); |
| 2593 } else { | 2593 } else { |
| 2594 LOperand* input = UseRegisterAtStart(instr->value()); | 2594 LOperand* input = UseRegisterAtStart(instr->value()); |
| 2595 LInstruction* result = DefineAsRegister(new(zone()) LMathAbs(input)); | 2595 LInstruction* result = DefineAsRegister(new(zone()) LMathAbs(input)); |
| 2596 if (!r.IsDouble()) result = AssignEnvironment(result); | 2596 if (!r.IsDouble()) result = AssignEnvironment(result); |
| 2597 return result; | 2597 return result; |
| 2598 } | 2598 } |
| 2599 } | 2599 } |
| 2600 case kMathExp: { | 2600 case kMathExp: { |
| 2601 ASSERT(instr->representation().IsDouble()); | 2601 DCHECK(instr->representation().IsDouble()); |
| 2602 ASSERT(instr->value()->representation().IsDouble()); | 2602 DCHECK(instr->value()->representation().IsDouble()); |
| 2603 LOperand* input = UseRegister(instr->value()); | 2603 LOperand* input = UseRegister(instr->value()); |
| 2604 LOperand* double_temp1 = TempDoubleRegister(); | 2604 LOperand* double_temp1 = TempDoubleRegister(); |
| 2605 LOperand* temp1 = TempRegister(); | 2605 LOperand* temp1 = TempRegister(); |
| 2606 LOperand* temp2 = TempRegister(); | 2606 LOperand* temp2 = TempRegister(); |
| 2607 LOperand* temp3 = TempRegister(); | 2607 LOperand* temp3 = TempRegister(); |
| 2608 LMathExp* result = new(zone()) LMathExp(input, double_temp1, | 2608 LMathExp* result = new(zone()) LMathExp(input, double_temp1, |
| 2609 temp1, temp2, temp3); | 2609 temp1, temp2, temp3); |
| 2610 return DefineAsRegister(result); | 2610 return DefineAsRegister(result); |
| 2611 } | 2611 } |
| 2612 case kMathFloor: { | 2612 case kMathFloor: { |
| 2613 ASSERT(instr->value()->representation().IsDouble()); | 2613 DCHECK(instr->value()->representation().IsDouble()); |
| 2614 LOperand* input = UseRegisterAtStart(instr->value()); | 2614 LOperand* input = UseRegisterAtStart(instr->value()); |
| 2615 if (instr->representation().IsInteger32()) { | 2615 if (instr->representation().IsInteger32()) { |
| 2616 LMathFloorI* result = new(zone()) LMathFloorI(input); | 2616 LMathFloorI* result = new(zone()) LMathFloorI(input); |
| 2617 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 2617 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 2618 } else { | 2618 } else { |
| 2619 ASSERT(instr->representation().IsDouble()); | 2619 DCHECK(instr->representation().IsDouble()); |
| 2620 LMathFloorD* result = new(zone()) LMathFloorD(input); | 2620 LMathFloorD* result = new(zone()) LMathFloorD(input); |
| 2621 return DefineAsRegister(result); | 2621 return DefineAsRegister(result); |
| 2622 } | 2622 } |
| 2623 } | 2623 } |
| 2624 case kMathLog: { | 2624 case kMathLog: { |
| 2625 ASSERT(instr->representation().IsDouble()); | 2625 DCHECK(instr->representation().IsDouble()); |
| 2626 ASSERT(instr->value()->representation().IsDouble()); | 2626 DCHECK(instr->value()->representation().IsDouble()); |
| 2627 LOperand* input = UseFixedDouble(instr->value(), d0); | 2627 LOperand* input = UseFixedDouble(instr->value(), d0); |
| 2628 LMathLog* result = new(zone()) LMathLog(input); | 2628 LMathLog* result = new(zone()) LMathLog(input); |
| 2629 return MarkAsCall(DefineFixedDouble(result, d0), instr); | 2629 return MarkAsCall(DefineFixedDouble(result, d0), instr); |
| 2630 } | 2630 } |
| 2631 case kMathPowHalf: { | 2631 case kMathPowHalf: { |
| 2632 ASSERT(instr->representation().IsDouble()); | 2632 DCHECK(instr->representation().IsDouble()); |
| 2633 ASSERT(instr->value()->representation().IsDouble()); | 2633 DCHECK(instr->value()->representation().IsDouble()); |
| 2634 LOperand* input = UseRegister(instr->value()); | 2634 LOperand* input = UseRegister(instr->value()); |
| 2635 return DefineAsRegister(new(zone()) LMathPowHalf(input)); | 2635 return DefineAsRegister(new(zone()) LMathPowHalf(input)); |
| 2636 } | 2636 } |
| 2637 case kMathRound: { | 2637 case kMathRound: { |
| 2638 ASSERT(instr->value()->representation().IsDouble()); | 2638 DCHECK(instr->value()->representation().IsDouble()); |
| 2639 LOperand* input = UseRegister(instr->value()); | 2639 LOperand* input = UseRegister(instr->value()); |
| 2640 if (instr->representation().IsInteger32()) { | 2640 if (instr->representation().IsInteger32()) { |
| 2641 LOperand* temp = TempDoubleRegister(); | 2641 LOperand* temp = TempDoubleRegister(); |
| 2642 LMathRoundI* result = new(zone()) LMathRoundI(input, temp); | 2642 LMathRoundI* result = new(zone()) LMathRoundI(input, temp); |
| 2643 return AssignEnvironment(DefineAsRegister(result)); | 2643 return AssignEnvironment(DefineAsRegister(result)); |
| 2644 } else { | 2644 } else { |
| 2645 ASSERT(instr->representation().IsDouble()); | 2645 DCHECK(instr->representation().IsDouble()); |
| 2646 LMathRoundD* result = new(zone()) LMathRoundD(input); | 2646 LMathRoundD* result = new(zone()) LMathRoundD(input); |
| 2647 return DefineAsRegister(result); | 2647 return DefineAsRegister(result); |
| 2648 } | 2648 } |
| 2649 } | 2649 } |
| 2650 case kMathFround: { | 2650 case kMathFround: { |
| 2651 ASSERT(instr->value()->representation().IsDouble()); | 2651 DCHECK(instr->value()->representation().IsDouble()); |
| 2652 LOperand* input = UseRegister(instr->value()); | 2652 LOperand* input = UseRegister(instr->value()); |
| 2653 LMathFround* result = new (zone()) LMathFround(input); | 2653 LMathFround* result = new (zone()) LMathFround(input); |
| 2654 return DefineAsRegister(result); | 2654 return DefineAsRegister(result); |
| 2655 } | 2655 } |
| 2656 case kMathSqrt: { | 2656 case kMathSqrt: { |
| 2657 ASSERT(instr->representation().IsDouble()); | 2657 DCHECK(instr->representation().IsDouble()); |
| 2658 ASSERT(instr->value()->representation().IsDouble()); | 2658 DCHECK(instr->value()->representation().IsDouble()); |
| 2659 LOperand* input = UseRegisterAtStart(instr->value()); | 2659 LOperand* input = UseRegisterAtStart(instr->value()); |
| 2660 return DefineAsRegister(new(zone()) LMathSqrt(input)); | 2660 return DefineAsRegister(new(zone()) LMathSqrt(input)); |
| 2661 } | 2661 } |
| 2662 case kMathClz32: { | 2662 case kMathClz32: { |
| 2663 ASSERT(instr->representation().IsInteger32()); | 2663 DCHECK(instr->representation().IsInteger32()); |
| 2664 ASSERT(instr->value()->representation().IsInteger32()); | 2664 DCHECK(instr->value()->representation().IsInteger32()); |
| 2665 LOperand* input = UseRegisterAtStart(instr->value()); | 2665 LOperand* input = UseRegisterAtStart(instr->value()); |
| 2666 return DefineAsRegister(new(zone()) LMathClz32(input)); | 2666 return DefineAsRegister(new(zone()) LMathClz32(input)); |
| 2667 } | 2667 } |
| 2668 default: | 2668 default: |
| 2669 UNREACHABLE(); | 2669 UNREACHABLE(); |
| 2670 return NULL; | 2670 return NULL; |
| 2671 } | 2671 } |
| 2672 } | 2672 } |
| 2673 | 2673 |
| 2674 | 2674 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2746 HAllocateBlockContext* instr) { | 2746 HAllocateBlockContext* instr) { |
| 2747 LOperand* context = UseFixed(instr->context(), cp); | 2747 LOperand* context = UseFixed(instr->context(), cp); |
| 2748 LOperand* function = UseRegisterAtStart(instr->function()); | 2748 LOperand* function = UseRegisterAtStart(instr->function()); |
| 2749 LAllocateBlockContext* result = | 2749 LAllocateBlockContext* result = |
| 2750 new(zone()) LAllocateBlockContext(context, function); | 2750 new(zone()) LAllocateBlockContext(context, function); |
| 2751 return MarkAsCall(DefineFixed(result, cp), instr); | 2751 return MarkAsCall(DefineFixed(result, cp), instr); |
| 2752 } | 2752 } |
| 2753 | 2753 |
| 2754 | 2754 |
| 2755 } } // namespace v8::internal | 2755 } } // namespace v8::internal |
| OLD | NEW |