Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 631 Register left = locs()->in(0).reg(); | 631 Register left = locs()->in(0).reg(); |
| 632 Register right = locs()->in(1).reg(); | 632 Register right = locs()->in(1).reg(); |
| 633 __ pushq(left); | 633 __ pushq(left); |
| 634 __ pushq(right); | 634 __ pushq(right); |
| 635 EmitEqualityAsInstanceCall(compiler, this); | 635 EmitEqualityAsInstanceCall(compiler, this); |
| 636 } | 636 } |
| 637 } | 637 } |
| 638 | 638 |
| 639 | 639 |
| 640 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 640 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 641 const intptr_t kNumInputs = 2; | |
| 641 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) { | 642 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) { |
| 642 const intptr_t kNumInputs = 2; | |
| 643 const intptr_t kNumTemps = 1; | 643 const intptr_t kNumTemps = 1; |
| 644 LocationSummary* summary = | 644 LocationSummary* summary = |
| 645 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 645 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 646 summary->set_in(0, Location::RequiresRegister()); | 646 summary->set_in(0, Location::RequiresRegister()); |
| 647 summary->set_in(1, Location::RequiresRegister()); | 647 summary->set_in(1, Location::RequiresRegister()); |
| 648 summary->set_out(Location::RequiresRegister()); | 648 summary->set_out(Location::RequiresRegister()); |
| 649 summary->set_temp(0, Location::RequiresRegister()); | 649 summary->set_temp(0, Location::RequiresRegister()); |
| 650 return summary; | 650 return summary; |
| 651 } | 651 } |
| 652 return MakeCallSummary(); | 652 const intptr_t kNumTemps = 0; |
| 653 LocationSummary* locs = | |
| 654 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | |
| 655 locs->set_in(0, Location::RegisterLocation(RAX)); | |
| 656 locs->set_in(1, Location::RegisterLocation(RCX)); | |
| 657 locs->set_out(Location::RegisterLocation(RAX)); | |
| 658 return locs; | |
| 653 } | 659 } |
| 654 | 660 |
| 655 | 661 |
| 656 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 662 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 657 if (operands_class_id() == kSmiCid) { | 663 if (operands_class_id() == kSmiCid) { |
| 658 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, | 664 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, |
| 659 deopt_id(), token_pos(), try_index()); | 665 deopt_id(), token_pos(), try_index()); |
| 660 return; | 666 return; |
| 661 } | 667 } |
| 662 if (operands_class_id() == kDoubleCid) { | 668 if (operands_class_id() == kDoubleCid) { |
| 663 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, | 669 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, |
| 664 deopt_id(), token_pos(), try_index()); | 670 deopt_id(), token_pos(), try_index()); |
| 665 return; | 671 return; |
| 666 } | 672 } |
| 667 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 673 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 668 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 674 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 669 try_index(), | 675 try_index(), |
| 670 kDeoptRelationalOp); | 676 kDeoptRelationalOp); |
| 671 // Load receiver into RAX, class into RDI. | 677 // Push arguments for the call. |
| 678 // TODO(fschneider): Split this instruction into different types to avoid | |
| 679 // explicitly pushing arguments to the call here. | |
| 680 Register left = locs()->in(0).reg(); | |
| 681 Register right = locs()->in(1).reg(); | |
| 682 __ pushq(left); | |
| 683 __ pushq(right); | |
| 684 | |
|
srdjan
2012/08/15 21:48:38
ditto
Florian Schneider
2012/08/16 08:30:37
Done.
| |
| 685 // Load class into RDI. | |
| 686 ASSERT((left != RDI) && (right != RDI)); | |
| 672 Label done; | 687 Label done; |
| 688 __ movq(RDI, Immediate(kSmiCid)); | |
| 689 __ testq(left, Immediate(kSmiTagMask)); | |
| 690 __ j(ZERO, &done); | |
| 691 __ LoadClassId(RDI, left); | |
| 692 __ Bind(&done); | |
| 673 const intptr_t kNumArguments = 2; | 693 const intptr_t kNumArguments = 2; |
| 674 __ movq(RDI, Immediate(kSmiCid)); | |
| 675 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); | |
| 676 __ testq(RAX, Immediate(kSmiTagMask)); | |
| 677 __ j(ZERO, &done); | |
| 678 __ LoadClassId(RDI, RAX); | |
| 679 __ Bind(&done); | |
| 680 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), | 694 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), |
| 681 RDI, // Class id register. | 695 RDI, // Class id register. |
| 682 kNumArguments, | 696 kNumArguments, |
| 683 Array::Handle(), // No named arguments. | 697 Array::Handle(), // No named arguments. |
| 684 deopt, // Deoptimize target. | 698 deopt, // Deoptimize target. |
| 685 NULL, // Fallthrough when done. | 699 NULL, // Fallthrough when done. |
| 686 deopt_id(), | 700 deopt_id(), |
| 687 token_pos(), | 701 token_pos(), |
| 688 try_index(), | 702 try_index(), |
| 689 locs()->stack_bitmap()); | 703 locs()->stack_bitmap()); |
| 704 ASSERT(locs()->out().reg() == RAX); | |
| 690 return; | 705 return; |
| 691 } | 706 } |
| 707 // Push arguments to the call. | |
| 708 // TODO(fschneider): Split this instruction into different types to avoid | |
| 709 // explicitly pushing arguments to the call here. | |
| 710 Register left = locs()->in(0).reg(); | |
| 711 Register right = locs()->in(1).reg(); | |
| 712 __ pushq(left); | |
| 713 __ pushq(right); | |
| 714 | |
| 692 const String& function_name = | 715 const String& function_name = |
| 693 String::ZoneHandle(Symbols::New(Token::Str(kind()))); | 716 String::ZoneHandle(Symbols::New(Token::Str(kind()))); |
| 694 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 717 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 695 deopt_id(), | 718 deopt_id(), |
| 696 token_pos(), | 719 token_pos(), |
| 697 try_index()); | 720 try_index()); |
| 698 const intptr_t kNumArguments = 2; | 721 const intptr_t kNumArguments = 2; |
| 699 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 722 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 700 compiler->GenerateInstanceCall(deopt_id(), | 723 compiler->GenerateInstanceCall(deopt_id(), |
| 701 token_pos(), | 724 token_pos(), |
| (...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2130 locs()->stack_bitmap()); | 2153 locs()->stack_bitmap()); |
| 2131 __ CompareObject(RAX, compiler->bool_true()); | 2154 __ CompareObject(RAX, compiler->bool_true()); |
| 2132 EmitBranchOnCondition(compiler, branch_condition); | 2155 EmitBranchOnCondition(compiler, branch_condition); |
| 2133 } | 2156 } |
| 2134 | 2157 |
| 2135 } // namespace dart | 2158 } // namespace dart |
| 2136 | 2159 |
| 2137 #undef __ | 2160 #undef __ |
| 2138 | 2161 |
| 2139 #endif // defined TARGET_ARCH_X64 | 2162 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |