| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 3706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3717 } | 3717 } |
| 3718 | 3718 |
| 3719 | 3719 |
| 3720 // Detect pattern when one value is zero and another is a power of 2. | 3720 // Detect pattern when one value is zero and another is a power of 2. |
| 3721 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 3721 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
| 3722 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 3722 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
| 3723 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); | 3723 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); |
| 3724 } | 3724 } |
| 3725 | 3725 |
| 3726 | 3726 |
| 3727 // Detect pattern when one value is increment of another. | |
| 3728 static bool IsIncrementKind(intptr_t v1, intptr_t v2) { | |
| 3729 return ((v1 == v2 + 1) || (v1 + 1 == v2)); | |
| 3730 } | |
| 3731 | |
| 3732 | |
| 3733 bool IfThenElseInstr::IsSupported() { | 3727 bool IfThenElseInstr::IsSupported() { |
| 3734 return true; | 3728 return true; |
| 3735 } | 3729 } |
| 3736 | 3730 |
| 3737 | 3731 |
| 3738 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, | 3732 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, |
| 3739 Value* v1, | 3733 Value* v1, |
| 3740 Value* v2) { | 3734 Value* v2) { |
| 3741 if (!(comparison->IsStrictCompare() && | 3735 if (!(comparison->IsStrictCompare() && |
| 3742 !comparison->AsStrictCompare()->needs_number_check()) && | 3736 !comparison->AsStrictCompare()->needs_number_check()) && |
| 3743 !(comparison->IsEqualityCompare() && | 3737 !(comparison->IsEqualityCompare() && |
| 3744 (comparison->AsEqualityCompare()->receiver_class_id() == kSmiCid))) { | 3738 (comparison->AsEqualityCompare()->receiver_class_id() == kSmiCid))) { |
| 3745 return false; | 3739 return false; |
| 3746 } | 3740 } |
| 3747 | 3741 |
| 3748 intptr_t v1_value, v2_value; | 3742 intptr_t v1_value, v2_value; |
| 3749 | 3743 |
| 3750 if (!BindsToSmiConstant(v1, &v1_value) || | 3744 if (!BindsToSmiConstant(v1, &v1_value) || |
| 3751 !BindsToSmiConstant(v2, &v2_value)) { | 3745 !BindsToSmiConstant(v2, &v2_value)) { |
| 3752 return false; | 3746 return false; |
| 3753 } | 3747 } |
| 3754 | 3748 |
| 3755 if (IsPowerOfTwoKind(v1_value, v2_value) || | 3749 return true; |
| 3756 IsIncrementKind(v1_value, v2_value)) { | |
| 3757 return true; | |
| 3758 } | |
| 3759 | |
| 3760 return false; | |
| 3761 } | 3750 } |
| 3762 | 3751 |
| 3763 | 3752 |
| 3764 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { | 3753 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { |
| 3765 const intptr_t kNumInputs = 2; | 3754 const intptr_t kNumInputs = 2; |
| 3766 const intptr_t kNumTemps = 0; | 3755 const intptr_t kNumTemps = 0; |
| 3767 LocationSummary* locs = | 3756 LocationSummary* locs = |
| 3768 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3757 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3769 locs->set_in(0, Location::RegisterOrConstant(left())); | 3758 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 3770 locs->set_in(1, Location::RegisterOrConstant(right())); | 3759 locs->set_in(1, Location::RegisterOrConstant(right())); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3796 } else { | 3785 } else { |
| 3797 __ cmpl(left.reg(), right.reg()); | 3786 __ cmpl(left.reg(), right.reg()); |
| 3798 } | 3787 } |
| 3799 | 3788 |
| 3800 Condition true_condition = | 3789 Condition true_condition = |
| 3801 ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQUAL | 3790 ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQUAL |
| 3802 : NOT_EQUAL; | 3791 : NOT_EQUAL; |
| 3803 | 3792 |
| 3804 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); | 3793 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); |
| 3805 | 3794 |
| 3806 const intptr_t base = Utils::Minimum(if_true_, if_false_); | 3795 intptr_t true_value = if_true_; |
| 3796 intptr_t false_value = if_false_; |
| 3807 | 3797 |
| 3808 if (if_true_ == base) { | 3798 if (is_power_of_two_kind) { |
| 3809 // We need to have zero in EDX on true_condition. | 3799 if (true_value == 0) { |
| 3810 true_condition = NegateCondition(true_condition); | 3800 // We need to have zero in EDX on true_condition. |
| 3801 true_condition = NegateCondition(true_condition); |
| 3802 } |
| 3803 } else { |
| 3804 if (true_value == 0) { |
| 3805 // Swap values so that false_value is zero. |
| 3806 intptr_t temp = true_value; |
| 3807 true_value = false_value; |
| 3808 false_value = temp; |
| 3809 } else { |
| 3810 true_condition = NegateCondition(true_condition); |
| 3811 } |
| 3811 } | 3812 } |
| 3812 | 3813 |
| 3813 __ setcc(true_condition, DL); | 3814 __ setcc(true_condition, DL); |
| 3814 | 3815 |
| 3815 if (is_power_of_two_kind) { | 3816 if (is_power_of_two_kind) { |
| 3816 const intptr_t shift = | 3817 const intptr_t shift = |
| 3817 Utils::ShiftForPowerOfTwo(Utils::Maximum(if_true_, if_false_)); | 3818 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); |
| 3818 __ shll(EDX, Immediate(shift + kSmiTagSize)); | 3819 __ shll(EDX, Immediate(shift + kSmiTagSize)); |
| 3819 } else { | 3820 } else { |
| 3820 ASSERT(kSmiTagSize == 1); | 3821 __ subl(EDX, Immediate(1)); |
| 3821 __ leal(EDX, Address(EDX, TIMES_2, base << kSmiTagSize)); | 3822 __ andl(EDX, Immediate( |
| 3823 Smi::RawValue(true_value) - Smi::RawValue(false_value))); |
| 3824 if (false_value != 0) { |
| 3825 __ addl(EDX, Immediate(Smi::RawValue(false_value))); |
| 3826 } |
| 3822 } | 3827 } |
| 3823 } | 3828 } |
| 3824 | 3829 |
| 3825 | 3830 |
| 3826 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3831 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3827 // The arguments to the stub include the closure, as does the arguments | 3832 // The arguments to the stub include the closure, as does the arguments |
| 3828 // descriptor. | 3833 // descriptor. |
| 3829 Register temp_reg = locs()->temp(0).reg(); | 3834 Register temp_reg = locs()->temp(0).reg(); |
| 3830 int argument_count = ArgumentCount(); | 3835 int argument_count = ArgumentCount(); |
| 3831 const Array& arguments_descriptor = | 3836 const Array& arguments_descriptor = |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3939 PcDescriptors::kOther, | 3944 PcDescriptors::kOther, |
| 3940 locs()); | 3945 locs()); |
| 3941 __ Drop(2); // Discard type arguments and receiver. | 3946 __ Drop(2); // Discard type arguments and receiver. |
| 3942 } | 3947 } |
| 3943 | 3948 |
| 3944 } // namespace dart | 3949 } // namespace dart |
| 3945 | 3950 |
| 3946 #undef __ | 3951 #undef __ |
| 3947 | 3952 |
| 3948 #endif // defined TARGET_ARCH_IA32 | 3953 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |