| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 158 |
| 159 | 159 |
| 160 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 160 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 161 ASSERT(locs()->out(0).reg() == RDX); | 161 ASSERT(locs()->out(0).reg() == RDX); |
| 162 | 162 |
| 163 // Clear upper part of the out register. We are going to use setcc on it | 163 // Clear upper part of the out register. We are going to use setcc on it |
| 164 // which is a byte move. | 164 // which is a byte move. |
| 165 __ xorq(RDX, RDX); | 165 __ xorq(RDX, RDX); |
| 166 | 166 |
| 167 // Emit comparison code. This must not overwrite the result register. | 167 // Emit comparison code. This must not overwrite the result register. |
| 168 // IfThenElseInstr::Supports() should prevent EmitComparisonCode from using |
| 169 // the labels or returning an invalid condition. |
| 168 BranchLabels labels = {NULL, NULL, NULL}; | 170 BranchLabels labels = {NULL, NULL, NULL}; |
| 169 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); | 171 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); |
| 172 ASSERT(true_condition != INVALID_CONDITION); |
| 170 | 173 |
| 171 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); | 174 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); |
| 172 | 175 |
| 173 intptr_t true_value = if_true_; | 176 intptr_t true_value = if_true_; |
| 174 intptr_t false_value = if_false_; | 177 intptr_t false_value = if_false_; |
| 175 | 178 |
| 176 if (is_power_of_two_kind) { | 179 if (is_power_of_two_kind) { |
| 177 if (true_value == 0) { | 180 if (true_value == 0) { |
| 178 // We need to have zero in RDX on true_condition. | 181 // We need to have zero in RDX on true_condition. |
| 179 true_condition = NegateCondition(true_condition); | 182 true_condition = NegateCondition(true_condition); |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 BranchLabels labels) { | 569 BranchLabels labels) { |
| 567 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) { | 570 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) { |
| 568 return EmitInt64ComparisonOp(compiler, *locs(), kind()); | 571 return EmitInt64ComparisonOp(compiler, *locs(), kind()); |
| 569 } else { | 572 } else { |
| 570 ASSERT(operation_cid() == kDoubleCid); | 573 ASSERT(operation_cid() == kDoubleCid); |
| 571 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); | 574 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); |
| 572 } | 575 } |
| 573 } | 576 } |
| 574 | 577 |
| 575 | 578 |
| 576 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 579 template <intptr_t N, |
| 577 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); | 580 typename ThrowsTrait, |
| 578 | 581 template <typename Impure, typename Pure> class CSETrait> |
| 582 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitNativeCode( |
| 583 FlowGraphCompiler* compiler) { |
| 579 Label is_true, is_false; | 584 Label is_true, is_false; |
| 580 BranchLabels labels = {&is_true, &is_false, &is_false}; | 585 BranchLabels labels = {&is_true, &is_false, &is_false}; |
| 581 Condition true_condition = EmitComparisonCode(compiler, labels); | 586 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 582 EmitBranchOnCondition(compiler, true_condition, labels); | 587 if (true_condition != INVALID_CONDITION) { |
| 588 EmitBranchOnCondition(compiler, true_condition, labels); |
| 589 } |
| 583 | 590 |
| 584 Register result = locs()->out(0).reg(); | 591 Register result = this->locs()->out(0).reg(); |
| 585 Label done; | 592 Label done; |
| 586 __ Bind(&is_false); | 593 __ Bind(&is_false); |
| 587 __ LoadObject(result, Bool::False()); | 594 __ LoadObject(result, Bool::False()); |
| 588 __ jmp(&done); | 595 __ jmp(&done); |
| 589 __ Bind(&is_true); | 596 __ Bind(&is_true); |
| 590 __ LoadObject(result, Bool::True()); | 597 __ LoadObject(result, Bool::True()); |
| 591 __ Bind(&done); | 598 __ Bind(&done); |
| 592 } | 599 } |
| 593 | 600 |
| 594 | 601 |
| 595 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 602 template <intptr_t N, |
| 596 BranchInstr* branch) { | 603 typename ThrowsTrait, |
| 597 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 604 template <typename Impure, typename Pure> class CSETrait> |
| 598 | 605 void TemplateComparison<N, ThrowsTrait, CSETrait>::EmitBranchCode( |
| 606 FlowGraphCompiler* compiler, |
| 607 BranchInstr* branch) { |
| 599 BranchLabels labels = compiler->CreateBranchLabels(branch); | 608 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 600 Condition true_condition = EmitComparisonCode(compiler, labels); | 609 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 601 EmitBranchOnCondition(compiler, true_condition, labels); | 610 if (true_condition != INVALID_CONDITION) { |
| 611 EmitBranchOnCondition(compiler, true_condition, labels); |
| 612 } |
| 602 } | 613 } |
| 603 | 614 |
| 604 | 615 |
| 616 // Explicit template instantiations. |
| 617 template void TemplateComparison<1, NoThrow, Pure>::EmitNativeCode( |
| 618 FlowGraphCompiler*); |
| 619 template void TemplateComparison<2, NoThrow, Pure>::EmitNativeCode( |
| 620 FlowGraphCompiler*); |
| 621 template void TemplateComparison<1, NoThrow, Pure>::EmitBranchCode( |
| 622 FlowGraphCompiler* compiler, |
| 623 BranchInstr* branch); |
| 624 template void TemplateComparison<2, NoThrow, Pure>::EmitBranchCode( |
| 625 FlowGraphCompiler* compiler, |
| 626 BranchInstr* branch); |
| 627 |
| 628 |
| 605 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { | 629 LocationSummary* TestSmiInstr::MakeLocationSummary(Zone* zone, bool opt) const { |
| 606 const intptr_t kNumInputs = 2; | 630 const intptr_t kNumInputs = 2; |
| 607 const intptr_t kNumTemps = 0; | 631 const intptr_t kNumTemps = 0; |
| 608 LocationSummary* locs = new (zone) | 632 LocationSummary* locs = new (zone) |
| 609 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 633 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 610 locs->set_in(0, Location::RequiresRegister()); | 634 locs->set_in(0, Location::RequiresRegister()); |
| 611 // Only one input can be a constant operand. The case of two constant | 635 // Only one input can be a constant operand. The case of two constant |
| 612 // operands should be handled by constant propagation. | 636 // operands should be handled by constant propagation. |
| 613 locs->set_in(1, Location::RegisterOrConstant(right())); | 637 locs->set_in(1, Location::RegisterOrConstant(right())); |
| 614 return locs; | 638 return locs; |
| 615 } | 639 } |
| 616 | 640 |
| 617 | 641 |
| 618 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 642 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 619 BranchLabels labels) { | 643 BranchLabels labels) { |
| 620 Register left_reg = locs()->in(0).reg(); | 644 Register left_reg = locs()->in(0).reg(); |
| 621 Location right = locs()->in(1); | 645 Location right = locs()->in(1); |
| 622 if (right.IsConstant()) { | 646 if (right.IsConstant()) { |
| 623 ASSERT(right.constant().IsSmi()); | 647 ASSERT(right.constant().IsSmi()); |
| 624 const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw()); | 648 const int64_t imm = reinterpret_cast<int64_t>(right.constant().raw()); |
| 625 __ TestImmediate(left_reg, Immediate(imm)); | 649 __ TestImmediate(left_reg, Immediate(imm)); |
| 626 } else { | 650 } else { |
| 627 __ testq(left_reg, right.reg()); | 651 __ testq(left_reg, right.reg()); |
| 628 } | 652 } |
| 629 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO; | 653 Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO; |
| 630 return true_condition; | 654 return true_condition; |
| 631 } | 655 } |
| 632 | 656 |
| 633 | 657 |
| 634 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 635 // Never emitted outside of the BranchInstr. | |
| 636 UNREACHABLE(); | |
| 637 } | |
| 638 | |
| 639 | |
| 640 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 641 BranchInstr* branch) { | |
| 642 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 643 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 644 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 645 } | |
| 646 | |
| 647 | |
| 648 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, | 658 LocationSummary* TestCidsInstr::MakeLocationSummary(Zone* zone, |
| 649 bool opt) const { | 659 bool opt) const { |
| 650 const intptr_t kNumInputs = 1; | 660 const intptr_t kNumInputs = 1; |
| 651 const intptr_t kNumTemps = 1; | 661 const intptr_t kNumTemps = 1; |
| 652 LocationSummary* locs = new (zone) | 662 LocationSummary* locs = new (zone) |
| 653 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 663 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 654 locs->set_in(0, Location::RequiresRegister()); | 664 locs->set_in(0, Location::RequiresRegister()); |
| 655 locs->set_temp(0, Location::RequiresRegister()); | 665 locs->set_temp(0, Location::RequiresRegister()); |
| 656 locs->set_out(0, Location::RequiresRegister()); | 666 locs->set_out(0, Location::RequiresRegister()); |
| 657 return locs; | 667 return locs; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 // If the cid is not in the list, jump to the opposite label from the cids | 699 // If the cid is not in the list, jump to the opposite label from the cids |
| 690 // that are in the list. These must be all the same (see asserts in the | 700 // that are in the list. These must be all the same (see asserts in the |
| 691 // constructor). | 701 // constructor). |
| 692 Label* target = result ? labels.false_label : labels.true_label; | 702 Label* target = result ? labels.false_label : labels.true_label; |
| 693 if (target != labels.fall_through) { | 703 if (target != labels.fall_through) { |
| 694 __ jmp(target); | 704 __ jmp(target); |
| 695 } | 705 } |
| 696 } else { | 706 } else { |
| 697 __ jmp(deopt); | 707 __ jmp(deopt); |
| 698 } | 708 } |
| 699 // Dummy result as the last instruction is a jump, any conditional | 709 // Dummy result as this method already did the jump, there's no need |
| 700 // branch using the result will therefore be skipped. | 710 // for the caller to branch on a condition. |
| 701 return ZERO; | 711 return INVALID_CONDITION; |
| 702 } | 712 } |
| 703 | 713 |
| 704 | 714 |
| 705 void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 706 BranchInstr* branch) { | |
| 707 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 708 EmitComparisonCode(compiler, labels); | |
| 709 } | |
| 710 | |
| 711 | |
| 712 void TestCidsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 713 Register result_reg = locs()->out(0).reg(); | |
| 714 Label is_true, is_false, done; | |
| 715 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
| 716 EmitComparisonCode(compiler, labels); | |
| 717 __ Bind(&is_false); | |
| 718 __ LoadObject(result_reg, Bool::False()); | |
| 719 __ jmp(&done, Assembler::kNearJump); | |
| 720 __ Bind(&is_true); | |
| 721 __ LoadObject(result_reg, Bool::True()); | |
| 722 __ Bind(&done); | |
| 723 } | |
| 724 | |
| 725 | |
| 726 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, | 715 LocationSummary* RelationalOpInstr::MakeLocationSummary(Zone* zone, |
| 727 bool opt) const { | 716 bool opt) const { |
| 728 const intptr_t kNumInputs = 2; | 717 const intptr_t kNumInputs = 2; |
| 729 const intptr_t kNumTemps = 0; | 718 const intptr_t kNumTemps = 0; |
| 730 if (operation_cid() == kDoubleCid) { | 719 if (operation_cid() == kDoubleCid) { |
| 731 LocationSummary* summary = new (zone) | 720 LocationSummary* summary = new (zone) |
| 732 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 721 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 733 summary->set_in(0, Location::RequiresFpuRegister()); | 722 summary->set_in(0, Location::RequiresFpuRegister()); |
| 734 summary->set_in(1, Location::RequiresFpuRegister()); | 723 summary->set_in(1, Location::RequiresFpuRegister()); |
| 735 summary->set_out(0, Location::RequiresRegister()); | 724 summary->set_out(0, Location::RequiresRegister()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 760 BranchLabels labels) { | 749 BranchLabels labels) { |
| 761 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) { | 750 if ((operation_cid() == kSmiCid) || (operation_cid() == kMintCid)) { |
| 762 return EmitInt64ComparisonOp(compiler, *locs(), kind()); | 751 return EmitInt64ComparisonOp(compiler, *locs(), kind()); |
| 763 } else { | 752 } else { |
| 764 ASSERT(operation_cid() == kDoubleCid); | 753 ASSERT(operation_cid() == kDoubleCid); |
| 765 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); | 754 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); |
| 766 } | 755 } |
| 767 } | 756 } |
| 768 | 757 |
| 769 | 758 |
| 770 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 771 Label is_true, is_false; | |
| 772 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
| 773 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 774 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 775 | |
| 776 Register result = locs()->out(0).reg(); | |
| 777 Label done; | |
| 778 __ Bind(&is_false); | |
| 779 __ LoadObject(result, Bool::False()); | |
| 780 __ jmp(&done); | |
| 781 __ Bind(&is_true); | |
| 782 __ LoadObject(result, Bool::True()); | |
| 783 __ Bind(&done); | |
| 784 } | |
| 785 | |
| 786 | |
| 787 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 788 BranchInstr* branch) { | |
| 789 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 790 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 791 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 792 } | |
| 793 | |
| 794 | |
| 795 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, | 759 LocationSummary* NativeCallInstr::MakeLocationSummary(Zone* zone, |
| 796 bool opt) const { | 760 bool opt) const { |
| 797 return MakeCallSummary(zone); | 761 return MakeCallSummary(zone); |
| 798 } | 762 } |
| 799 | 763 |
| 800 | 764 |
| 801 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 765 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 802 SetupNative(); | 766 SetupNative(); |
| 803 Register result = locs()->out(0).reg(); | 767 Register result = locs()->out(0).reg(); |
| 804 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); | 768 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function()); |
| (...skipping 2297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3102 | 3066 |
| 3103 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 3067 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 3104 BranchInstr* branch) { | 3068 BranchInstr* branch) { |
| 3105 BranchLabels labels = compiler->CreateBranchLabels(branch); | 3069 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 3106 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( | 3070 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( |
| 3107 this, compiler->CurrentTryIndex(), labels, | 3071 this, compiler->CurrentTryIndex(), labels, |
| 3108 /* merged = */ true); | 3072 /* merged = */ true); |
| 3109 compiler->AddSlowPathCode(slow_path); | 3073 compiler->AddSlowPathCode(slow_path); |
| 3110 EMIT_SMI_CHECK; | 3074 EMIT_SMI_CHECK; |
| 3111 Condition true_condition = EmitComparisonCode(compiler, labels); | 3075 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3076 ASSERT(true_condition != INVALID_CONDITION); |
| 3112 EmitBranchOnCondition(compiler, true_condition, labels); | 3077 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3113 __ Bind(slow_path->exit_label()); | 3078 __ Bind(slow_path->exit_label()); |
| 3114 } | 3079 } |
| 3115 | 3080 |
| 3116 | 3081 |
| 3117 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3082 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3118 Label true_label, false_label, done; | 3083 Label true_label, false_label, done; |
| 3119 BranchLabels labels = {&true_label, &false_label, &false_label}; | 3084 BranchLabels labels = {&true_label, &false_label, &false_label}; |
| 3120 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( | 3085 CheckedSmiComparisonSlowPath* slow_path = new CheckedSmiComparisonSlowPath( |
| 3121 this, compiler->CurrentTryIndex(), labels, | 3086 this, compiler->CurrentTryIndex(), labels, |
| 3122 /* merged = */ false); | 3087 /* merged = */ false); |
| 3123 compiler->AddSlowPathCode(slow_path); | 3088 compiler->AddSlowPathCode(slow_path); |
| 3124 EMIT_SMI_CHECK; | 3089 EMIT_SMI_CHECK; |
| 3125 Condition true_condition = EmitComparisonCode(compiler, labels); | 3090 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3091 ASSERT(true_condition != INVALID_CONDITION); |
| 3126 EmitBranchOnCondition(compiler, true_condition, labels); | 3092 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3127 Register result = locs()->out(0).reg(); | 3093 Register result = locs()->out(0).reg(); |
| 3128 __ Bind(&false_label); | 3094 __ Bind(&false_label); |
| 3129 __ LoadObject(result, Bool::False()); | 3095 __ LoadObject(result, Bool::False()); |
| 3130 __ jmp(&done); | 3096 __ jmp(&done); |
| 3131 __ Bind(&true_label); | 3097 __ Bind(&true_label); |
| 3132 __ LoadObject(result, Bool::True()); | 3098 __ LoadObject(result, Bool::True()); |
| 3133 __ Bind(&done); | 3099 __ Bind(&done); |
| 3134 __ Bind(slow_path->exit_label()); | 3100 __ Bind(slow_path->exit_label()); |
| 3135 } | 3101 } |
| (...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3944 __ AddImmediate(RSP, Immediate(kDoubleSize)); | 3910 __ AddImmediate(RSP, Immediate(kDoubleSize)); |
| 3945 // Mask off the sign. | 3911 // Mask off the sign. |
| 3946 __ AndImmediate(temp, Immediate(0x7FFFFFFFFFFFFFFFLL)); | 3912 __ AndImmediate(temp, Immediate(0x7FFFFFFFFFFFFFFFLL)); |
| 3947 // Compare with +infinity. | 3913 // Compare with +infinity. |
| 3948 __ CompareImmediate(temp, Immediate(0x7FF0000000000000LL)); | 3914 __ CompareImmediate(temp, Immediate(0x7FF0000000000000LL)); |
| 3949 return is_negated ? NOT_EQUAL : EQUAL; | 3915 return is_negated ? NOT_EQUAL : EQUAL; |
| 3950 } | 3916 } |
| 3951 } | 3917 } |
| 3952 | 3918 |
| 3953 | 3919 |
| 3954 void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 3955 BranchInstr* branch) { | |
| 3956 ASSERT(compiler->is_optimizing()); | |
| 3957 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 3958 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 3959 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 3960 } | |
| 3961 | |
| 3962 | |
| 3963 void DoubleTestOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 3964 Label is_true, is_false; | |
| 3965 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
| 3966 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 3967 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 3968 | |
| 3969 Register result = locs()->out(0).reg(); | |
| 3970 Label done; | |
| 3971 __ Bind(&is_false); | |
| 3972 __ LoadObject(result, Bool::False()); | |
| 3973 __ jmp(&done); | |
| 3974 __ Bind(&is_true); | |
| 3975 __ LoadObject(result, Bool::True()); | |
| 3976 __ Bind(&done); | |
| 3977 } | |
| 3978 | |
| 3979 | |
| 3980 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, | 3920 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(Zone* zone, |
| 3981 bool opt) const { | 3921 bool opt) const { |
| 3982 const intptr_t kNumInputs = 2; | 3922 const intptr_t kNumInputs = 2; |
| 3983 const intptr_t kNumTemps = 0; | 3923 const intptr_t kNumTemps = 0; |
| 3984 LocationSummary* summary = new (zone) | 3924 LocationSummary* summary = new (zone) |
| 3985 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3925 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3986 summary->set_in(0, Location::RequiresFpuRegister()); | 3926 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3987 summary->set_in(1, Location::RequiresFpuRegister()); | 3927 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3988 summary->set_out(0, Location::SameAsFirstInput()); | 3928 summary->set_out(0, Location::SameAsFirstInput()); |
| 3989 return summary; | 3929 return summary; |
| (...skipping 2641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6631 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); | 6571 left.reg(), right.reg(), needs_number_check(), token_pos(), deopt_id_); |
| 6632 } | 6572 } |
| 6633 if (kind() != Token::kEQ_STRICT) { | 6573 if (kind() != Token::kEQ_STRICT) { |
| 6634 ASSERT(kind() == Token::kNE_STRICT); | 6574 ASSERT(kind() == Token::kNE_STRICT); |
| 6635 true_condition = NegateCondition(true_condition); | 6575 true_condition = NegateCondition(true_condition); |
| 6636 } | 6576 } |
| 6637 return true_condition; | 6577 return true_condition; |
| 6638 } | 6578 } |
| 6639 | 6579 |
| 6640 | 6580 |
| 6641 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6642 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | |
| 6643 | |
| 6644 Label is_true, is_false; | |
| 6645 BranchLabels labels = {&is_true, &is_false, &is_false}; | |
| 6646 | |
| 6647 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 6648 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 6649 | |
| 6650 Register result = locs()->out(0).reg(); | |
| 6651 Label done; | |
| 6652 __ Bind(&is_false); | |
| 6653 __ LoadObject(result, Bool::False()); | |
| 6654 __ jmp(&done); | |
| 6655 __ Bind(&is_true); | |
| 6656 __ LoadObject(result, Bool::True()); | |
| 6657 __ Bind(&done); | |
| 6658 } | |
| 6659 | |
| 6660 | |
| 6661 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | |
| 6662 BranchInstr* branch) { | |
| 6663 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | |
| 6664 | |
| 6665 BranchLabels labels = compiler->CreateBranchLabels(branch); | |
| 6666 Condition true_condition = EmitComparisonCode(compiler, labels); | |
| 6667 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 6668 } | |
| 6669 | |
| 6670 | |
| 6671 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone, | 6581 LocationSummary* ClosureCallInstr::MakeLocationSummary(Zone* zone, |
| 6672 bool opt) const { | 6582 bool opt) const { |
| 6673 const intptr_t kNumInputs = 1; | 6583 const intptr_t kNumInputs = 1; |
| 6674 const intptr_t kNumTemps = 0; | 6584 const intptr_t kNumTemps = 0; |
| 6675 LocationSummary* summary = new (zone) | 6585 LocationSummary* summary = new (zone) |
| 6676 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 6586 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
| 6677 summary->set_in(0, Location::RegisterLocation(RAX)); // Function. | 6587 summary->set_in(0, Location::RegisterLocation(RAX)); // Function. |
| 6678 summary->set_out(0, Location::RegisterLocation(RAX)); | 6588 summary->set_out(0, Location::RegisterLocation(RAX)); |
| 6679 return summary; | 6589 return summary; |
| 6680 } | 6590 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6781 __ Drop(1); | 6691 __ Drop(1); |
| 6782 __ popq(result); | 6692 __ popq(result); |
| 6783 } | 6693 } |
| 6784 | 6694 |
| 6785 | 6695 |
| 6786 } // namespace dart | 6696 } // namespace dart |
| 6787 | 6697 |
| 6788 #undef __ | 6698 #undef __ |
| 6789 | 6699 |
| 6790 #endif // defined TARGET_ARCH_X64 | 6700 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |