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