| 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 2635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2646 } | 2646 } |
| 2647 return; | 2647 return; |
| 2648 } | 2648 } |
| 2649 | 2649 |
| 2650 const bool right_needs_check = | 2650 const bool right_needs_check = |
| 2651 (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1)); | 2651 (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1)); |
| 2652 ASSERT(right == RCX); // Count must be in RCX | 2652 ASSERT(right == RCX); // Count must be in RCX |
| 2653 if (is_truncating) { | 2653 if (is_truncating) { |
| 2654 if (right_needs_check) { | 2654 if (right_needs_check) { |
| 2655 const bool right_may_be_negative = | 2655 const bool right_may_be_negative = |
| 2656 (right_range == NULL) || | 2656 (right_range == NULL) || right_range->IsNegative(); |
| 2657 !right_range->IsWithin(0, RangeBoundary::kPlusInfinity); | |
| 2658 if (right_may_be_negative) { | 2657 if (right_may_be_negative) { |
| 2659 ASSERT(shift_left->CanDeoptimize()); | 2658 ASSERT(shift_left->CanDeoptimize()); |
| 2660 __ CompareImmediate(right, Immediate(0), PP); | 2659 __ CompareImmediate(right, Immediate(0), PP); |
| 2661 __ j(NEGATIVE, deopt); | 2660 __ j(NEGATIVE, deopt); |
| 2662 } | 2661 } |
| 2663 Label done, is_not_zero; | 2662 Label done, is_not_zero; |
| 2664 __ CompareImmediate(right, | 2663 __ CompareImmediate(right, |
| 2665 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))), PP); | 2664 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))), PP); |
| 2666 __ j(BELOW, &is_not_zero, Assembler::kNearJump); | 2665 __ j(BELOW, &is_not_zero, Assembler::kNearJump); |
| 2667 __ xorq(left, left); | 2666 __ xorq(left, left); |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3099 __ j(GREATER_EQUAL, &all_done, Assembler::kNearJump); | 3098 __ j(GREATER_EQUAL, &all_done, Assembler::kNearJump); |
| 3100 // Result is negative, adjust it. | 3099 // Result is negative, adjust it. |
| 3101 if ((right_range == NULL) || right_range->Overlaps(-1, 1)) { | 3100 if ((right_range == NULL) || right_range->Overlaps(-1, 1)) { |
| 3102 Label subtract; | 3101 Label subtract; |
| 3103 __ cmpq(right, Immediate(0)); | 3102 __ cmpq(right, Immediate(0)); |
| 3104 __ j(LESS, &subtract, Assembler::kNearJump); | 3103 __ j(LESS, &subtract, Assembler::kNearJump); |
| 3105 __ addq(result, right); | 3104 __ addq(result, right); |
| 3106 __ jmp(&all_done, Assembler::kNearJump); | 3105 __ jmp(&all_done, Assembler::kNearJump); |
| 3107 __ Bind(&subtract); | 3106 __ Bind(&subtract); |
| 3108 __ subq(result, right); | 3107 __ subq(result, right); |
| 3109 } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) { | 3108 } else if (right_range->IsPositive()) { |
| 3110 // Right is positive. | 3109 // Right is positive. |
| 3111 __ addq(result, right); | 3110 __ addq(result, right); |
| 3112 } else { | 3111 } else { |
| 3113 // Right is negative. | 3112 // Right is negative. |
| 3114 __ subq(result, right); | 3113 __ subq(result, right); |
| 3115 } | 3114 } |
| 3116 __ Bind(&all_done); | 3115 __ Bind(&all_done); |
| 3117 __ SmiTag(result); | 3116 __ SmiTag(result); |
| 3118 break; | 3117 break; |
| 3119 } | 3118 } |
| 3120 case Token::kSHR: { | 3119 case Token::kSHR: { |
| 3121 if (CanDeoptimize()) { | 3120 if (CanDeoptimize()) { |
| 3122 __ CompareImmediate(right, Immediate(0), PP); | 3121 __ CompareImmediate(right, Immediate(0), PP); |
| 3123 __ j(LESS, deopt); | 3122 __ j(LESS, deopt); |
| 3124 } | 3123 } |
| 3125 __ SmiUntag(right); | 3124 __ SmiUntag(right); |
| 3126 // sarq operation masks the count to 6 bits. | 3125 // sarq operation masks the count to 6 bits. |
| 3127 const intptr_t kCountLimit = 0x3F; | 3126 const intptr_t kCountLimit = 0x3F; |
| 3128 if ((right_range == NULL) || | 3127 if ((right_range == NULL) || |
| 3129 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { | 3128 !right_range->OnlyLessThanOrEqualTo(kCountLimit)) { |
| 3130 __ CompareImmediate(right, Immediate(kCountLimit), PP); | 3129 __ CompareImmediate(right, Immediate(kCountLimit), PP); |
| 3131 Label count_ok; | 3130 Label count_ok; |
| 3132 __ j(LESS, &count_ok, Assembler::kNearJump); | 3131 __ j(LESS, &count_ok, Assembler::kNearJump); |
| 3133 __ LoadImmediate(right, Immediate(kCountLimit), PP); | 3132 __ LoadImmediate(right, Immediate(kCountLimit), PP); |
| 3134 __ Bind(&count_ok); | 3133 __ Bind(&count_ok); |
| 3135 } | 3134 } |
| 3136 ASSERT(right == RCX); // Count must be in RCX | 3135 ASSERT(right == RCX); // Count must be in RCX |
| 3137 __ SmiUntag(left); | 3136 __ SmiUntag(left); |
| 3138 __ sarq(left, right); | 3137 __ sarq(left, right); |
| 3139 __ SmiTag(left); | 3138 __ SmiTag(left); |
| (...skipping 2100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5240 __ j(GREATER_EQUAL, &all_done, Assembler::kNearJump); | 5239 __ j(GREATER_EQUAL, &all_done, Assembler::kNearJump); |
| 5241 // Result is negative, adjust it. | 5240 // Result is negative, adjust it. |
| 5242 if ((right_range == NULL) || right_range->Overlaps(-1, 1)) { | 5241 if ((right_range == NULL) || right_range->Overlaps(-1, 1)) { |
| 5243 Label subtract; | 5242 Label subtract; |
| 5244 __ cmpq(right, Immediate(0)); | 5243 __ cmpq(right, Immediate(0)); |
| 5245 __ j(LESS, &subtract, Assembler::kNearJump); | 5244 __ j(LESS, &subtract, Assembler::kNearJump); |
| 5246 __ addq(RDX, right); | 5245 __ addq(RDX, right); |
| 5247 __ jmp(&all_done, Assembler::kNearJump); | 5246 __ jmp(&all_done, Assembler::kNearJump); |
| 5248 __ Bind(&subtract); | 5247 __ Bind(&subtract); |
| 5249 __ subq(RDX, right); | 5248 __ subq(RDX, right); |
| 5250 } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) { | 5249 } else if (right_range->IsPositive()) { |
| 5251 // Right is positive. | 5250 // Right is positive. |
| 5252 __ addq(RDX, right); | 5251 __ addq(RDX, right); |
| 5253 } else { | 5252 } else { |
| 5254 // Right is negative. | 5253 // Right is negative. |
| 5255 __ subq(RDX, right); | 5254 __ subq(RDX, right); |
| 5256 } | 5255 } |
| 5257 __ Bind(&all_done); | 5256 __ Bind(&all_done); |
| 5258 | 5257 |
| 5259 __ SmiTag(RAX); | 5258 __ SmiTag(RAX); |
| 5260 __ SmiTag(RDX); | 5259 __ SmiTag(RDX); |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5820 PcDescriptors::kOther, | 5819 PcDescriptors::kOther, |
| 5821 locs()); | 5820 locs()); |
| 5822 __ Drop(ArgumentCount()); // Discard arguments. | 5821 __ Drop(ArgumentCount()); // Discard arguments. |
| 5823 } | 5822 } |
| 5824 | 5823 |
| 5825 } // namespace dart | 5824 } // namespace dart |
| 5826 | 5825 |
| 5827 #undef __ | 5826 #undef __ |
| 5828 | 5827 |
| 5829 #endif // defined TARGET_ARCH_X64 | 5828 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |