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/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 } | 161 } |
162 } | 162 } |
163 | 163 |
164 __ setcc(true_condition, DL); | 164 __ setcc(true_condition, DL); |
165 | 165 |
166 if (is_power_of_two_kind) { | 166 if (is_power_of_two_kind) { |
167 const intptr_t shift = | 167 const intptr_t shift = |
168 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); | 168 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); |
169 __ shlq(RDX, Immediate(shift + kSmiTagSize)); | 169 __ shlq(RDX, Immediate(shift + kSmiTagSize)); |
170 } else { | 170 } else { |
171 __ AddImmediate(RDX, Immediate(-1), PP); | 171 __ decq(RDX); |
172 __ AndImmediate(RDX, | 172 __ AndImmediate(RDX, |
173 Immediate(Smi::RawValue(true_value) - Smi::RawValue(false_value)), PP); | 173 Immediate(Smi::RawValue(true_value) - Smi::RawValue(false_value)), PP); |
174 if (false_value != 0) { | 174 if (false_value != 0) { |
175 __ AddImmediate(RDX, Immediate(Smi::RawValue(false_value)), PP); | 175 __ AddImmediate(RDX, Immediate(Smi::RawValue(false_value)), PP); |
176 } | 176 } |
177 } | 177 } |
178 } | 178 } |
179 | 179 |
180 | 180 |
181 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { | 181 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { |
(...skipping 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2732 Register result = locs()->out(0).reg(); | 2732 Register result = locs()->out(0).reg(); |
2733 ASSERT(left == result); | 2733 ASSERT(left == result); |
2734 Label* deopt = NULL; | 2734 Label* deopt = NULL; |
2735 if (CanDeoptimize()) { | 2735 if (CanDeoptimize()) { |
2736 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); | 2736 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
2737 } | 2737 } |
2738 | 2738 |
2739 if (locs()->in(1).IsConstant()) { | 2739 if (locs()->in(1).IsConstant()) { |
2740 const Object& constant = locs()->in(1).constant(); | 2740 const Object& constant = locs()->in(1).constant(); |
2741 ASSERT(constant.IsSmi()); | 2741 ASSERT(constant.IsSmi()); |
2742 const int64_t imm = | 2742 const int64_t imm = reinterpret_cast<int64_t>(constant.raw()); |
2743 reinterpret_cast<int64_t>(constant.raw()); | |
2744 switch (op_kind()) { | 2743 switch (op_kind()) { |
2745 case Token::kADD: { | 2744 case Token::kADD: { |
2746 __ AddImmediate(left, Immediate(imm), PP); | 2745 if (imm != 0) { |
2747 if (deopt != NULL) __ j(OVERFLOW, deopt); | 2746 // Checking overflow without emitting an instruction would be wrong. |
| 2747 __ AddImmediate(left, Immediate(imm), PP); |
| 2748 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 2749 } |
2748 break; | 2750 break; |
2749 } | 2751 } |
2750 case Token::kSUB: { | 2752 case Token::kSUB: { |
2751 __ AddImmediate(left, Immediate(-imm), PP); | 2753 if (imm != 0) { |
2752 if (deopt != NULL) __ j(OVERFLOW, deopt); | 2754 // Checking overflow without emitting an instruction would be wrong. |
| 2755 __ SubImmediate(left, Immediate(imm), PP); |
| 2756 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 2757 } |
2753 break; | 2758 break; |
2754 } | 2759 } |
2755 case Token::kMUL: { | 2760 case Token::kMUL: { |
2756 // Keep left value tagged and untag right value. | 2761 // Keep left value tagged and untag right value. |
2757 const intptr_t value = Smi::Cast(constant).Value(); | 2762 const intptr_t value = Smi::Cast(constant).Value(); |
2758 if (value == 2) { | 2763 if (value == 2) { |
2759 __ shlq(left, Immediate(1)); | 2764 __ shlq(left, Immediate(1)); |
2760 } else { | 2765 } else { |
2761 __ MulImmediate(left, Immediate(value), PP); | 2766 __ MulImmediate(left, Immediate(value), PP); |
2762 } | 2767 } |
(...skipping 2909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5672 PcDescriptors::kOther, | 5677 PcDescriptors::kOther, |
5673 locs()); | 5678 locs()); |
5674 __ Drop(ArgumentCount()); // Discard arguments. | 5679 __ Drop(ArgumentCount()); // Discard arguments. |
5675 } | 5680 } |
5676 | 5681 |
5677 } // namespace dart | 5682 } // namespace dart |
5678 | 5683 |
5679 #undef __ | 5684 #undef __ |
5680 | 5685 |
5681 #endif // defined TARGET_ARCH_X64 | 5686 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |