| 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1827 const bool is_truncating = shift_left->is_truncating(); | 1827 const bool is_truncating = shift_left->is_truncating(); |
| 1828 const LocationSummary& locs = *shift_left->locs(); | 1828 const LocationSummary& locs = *shift_left->locs(); |
| 1829 Register left = locs.in(0).reg(); | 1829 Register left = locs.in(0).reg(); |
| 1830 Register result = locs.out().reg(); | 1830 Register result = locs.out().reg(); |
| 1831 ASSERT(left == result); | 1831 ASSERT(left == result); |
| 1832 Label* deopt = shift_left->CanDeoptimize() ? | 1832 Label* deopt = shift_left->CanDeoptimize() ? |
| 1833 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; | 1833 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; |
| 1834 if (locs.in(1).IsConstant()) { | 1834 if (locs.in(1).IsConstant()) { |
| 1835 const Object& constant = locs.in(1).constant(); | 1835 const Object& constant = locs.in(1).constant(); |
| 1836 ASSERT(constant.IsSmi()); | 1836 ASSERT(constant.IsSmi()); |
| 1837 // shll operation masks the count to 6 bits. | 1837 // shlq operation masks the count to 6 bits. |
| 1838 const intptr_t kCountLimit = 0x3F; | 1838 const intptr_t kCountLimit = 0x3F; |
| 1839 const intptr_t value = Smi::Cast(constant).Value(); | 1839 const intptr_t value = Smi::Cast(constant).Value(); |
| 1840 if (value == 0) { | 1840 if (value == 0) { |
| 1841 // No code needed. | 1841 // No code needed. |
| 1842 } else if ((value < 0) || (value >= kCountLimit)) { | 1842 } else if ((value < 0) || (value >= kCountLimit)) { |
| 1843 // This condition may not be known earlier in some cases because | 1843 // This condition may not be known earlier in some cases because |
| 1844 // of constant propagation, inlining, etc. | 1844 // of constant propagation, inlining, etc. |
| 1845 if ((value >=kCountLimit) && is_truncating) { | 1845 if ((value >=kCountLimit) && is_truncating) { |
| 1846 __ xorq(result, result); | 1846 __ xorq(result, result); |
| 1847 } else { | 1847 } else { |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2048 break; | 2048 break; |
| 2049 } | 2049 } |
| 2050 case Token::kSUB: { | 2050 case Token::kSUB: { |
| 2051 __ subq(left, Immediate(imm)); | 2051 __ subq(left, Immediate(imm)); |
| 2052 if (deopt != NULL) __ j(OVERFLOW, deopt); | 2052 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 2053 break; | 2053 break; |
| 2054 } | 2054 } |
| 2055 case Token::kMUL: { | 2055 case Token::kMUL: { |
| 2056 // Keep left value tagged and untag right value. | 2056 // Keep left value tagged and untag right value. |
| 2057 const intptr_t value = Smi::Cast(constant).Value(); | 2057 const intptr_t value = Smi::Cast(constant).Value(); |
| 2058 __ imulq(left, Immediate(value)); | 2058 if (value == 2) { |
| 2059 __ shlq(left, Immediate(1)); |
| 2060 } else { |
| 2061 __ imulq(left, Immediate(value)); |
| 2062 } |
| 2059 if (deopt != NULL) __ j(OVERFLOW, deopt); | 2063 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 2060 break; | 2064 break; |
| 2061 } | 2065 } |
| 2062 case Token::kTRUNCDIV: { | 2066 case Token::kTRUNCDIV: { |
| 2063 const intptr_t value = Smi::Cast(constant).Value(); | 2067 const intptr_t value = Smi::Cast(constant).Value(); |
| 2064 if (value == 1) { | 2068 if (value == 1) { |
| 2065 // Do nothing. | 2069 // Do nothing. |
| 2066 break; | 2070 break; |
| 2067 } else if (value == -1) { | 2071 } else if (value == -1) { |
| 2068 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 2072 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| (...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3168 PcDescriptors::kOther, | 3172 PcDescriptors::kOther, |
| 3169 locs()); | 3173 locs()); |
| 3170 __ Drop(2); // Discard type arguments and receiver. | 3174 __ Drop(2); // Discard type arguments and receiver. |
| 3171 } | 3175 } |
| 3172 | 3176 |
| 3173 } // namespace dart | 3177 } // namespace dart |
| 3174 | 3178 |
| 3175 #undef __ | 3179 #undef __ |
| 3176 | 3180 |
| 3177 #endif // defined TARGET_ARCH_X64 | 3181 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |