| 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 } | 148 } |
| 149 | 149 |
| 150 | 150 |
| 151 // Detect pattern when one value is zero and another is a power of 2. | 151 // Detect pattern when one value is zero and another is a power of 2. |
| 152 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 152 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
| 153 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 153 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
| 154 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); | 154 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); |
| 155 } | 155 } |
| 156 | 156 |
| 157 | 157 |
| 158 // Detect pattern when one value is increment of another. | |
| 159 static bool IsIncrementKind(intptr_t v1, intptr_t v2) { | |
| 160 return ((v1 == v2 + 1) || (v1 + 1 == v2)); | |
| 161 } | |
| 162 | |
| 163 | |
| 164 bool IfThenElseInstr::IsSupported() { | 158 bool IfThenElseInstr::IsSupported() { |
| 165 return true; | 159 return true; |
| 166 } | 160 } |
| 167 | 161 |
| 168 | 162 |
| 169 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, | 163 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, |
| 170 Value* v1, | 164 Value* v1, |
| 171 Value* v2) { | 165 Value* v2) { |
| 172 if (!(comparison->IsStrictCompare() && | 166 if (!(comparison->IsStrictCompare() && |
| 173 !comparison->AsStrictCompare()->needs_number_check()) && | 167 !comparison->AsStrictCompare()->needs_number_check()) && |
| 174 !(comparison->IsEqualityCompare() && | 168 !(comparison->IsEqualityCompare() && |
| 175 (comparison->AsEqualityCompare()->receiver_class_id() == kSmiCid))) { | 169 (comparison->AsEqualityCompare()->receiver_class_id() == kSmiCid))) { |
| 176 return false; | 170 return false; |
| 177 } | 171 } |
| 178 | 172 |
| 179 intptr_t v1_value, v2_value; | 173 intptr_t v1_value, v2_value; |
| 180 | 174 |
| 181 if (!BindsToSmiConstant(v1, &v1_value) || | 175 if (!BindsToSmiConstant(v1, &v1_value) || |
| 182 !BindsToSmiConstant(v2, &v2_value)) { | 176 !BindsToSmiConstant(v2, &v2_value)) { |
| 183 return false; | 177 return false; |
| 184 } | 178 } |
| 185 | 179 |
| 186 if (IsPowerOfTwoKind(v1_value, v2_value) || | |
| 187 IsIncrementKind(v1_value, v2_value)) { | |
| 188 return true; | |
| 189 } | |
| 190 | |
| 191 return false; | 180 return false; |
| 192 } | 181 } |
| 193 | 182 |
| 194 | 183 |
| 195 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { | 184 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { |
| 196 const intptr_t kNumInputs = 2; | 185 const intptr_t kNumInputs = 2; |
| 197 const intptr_t kNumTemps = 0; | 186 const intptr_t kNumTemps = 0; |
| 198 LocationSummary* locs = | 187 LocationSummary* locs = |
| 199 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 188 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 200 locs->set_in(0, Location::RegisterOrConstant(left())); | 189 locs->set_in(0, Location::RegisterOrConstant(left())); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 227 } else { | 216 } else { |
| 228 __ cmpq(left.reg(), right.reg()); | 217 __ cmpq(left.reg(), right.reg()); |
| 229 } | 218 } |
| 230 | 219 |
| 231 Condition true_condition = | 220 Condition true_condition = |
| 232 ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQUAL | 221 ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQUAL |
| 233 : NOT_EQUAL; | 222 : NOT_EQUAL; |
| 234 | 223 |
| 235 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); | 224 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); |
| 236 | 225 |
| 237 const intptr_t base = Utils::Minimum(if_true_, if_false_); | 226 intptr_t true_value = if_true_; |
| 227 intptr_t false_value = if_false_; |
| 238 | 228 |
| 239 if (if_true_ == base) { | 229 if (is_power_of_two_kind) { |
| 240 // We need to have zero in RDX on true_condition. | 230 if (true_value == 0) { |
| 241 true_condition = NegateCondition(true_condition); | 231 // We need to have zero in RDX on true_condition. |
| 232 true_condition = NegateCondition(true_condition); |
| 233 } |
| 234 } else { |
| 235 if (true_value == 0) { |
| 236 // Swap values so that false_value is zero. |
| 237 intptr_t temp = true_value; |
| 238 true_value = false_value; |
| 239 false_value = temp; |
| 240 } else { |
| 241 true_condition = NegateCondition(true_condition); |
| 242 } |
| 242 } | 243 } |
| 243 | 244 |
| 244 __ setcc(true_condition, DL); | 245 __ setcc(true_condition, DL); |
| 245 | 246 |
| 246 if (is_power_of_two_kind) { | 247 if (is_power_of_two_kind) { |
| 247 const intptr_t shift = | 248 const intptr_t shift = |
| 248 Utils::ShiftForPowerOfTwo(Utils::Maximum(if_true_, if_false_)); | 249 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); |
| 249 __ shlq(RDX, Immediate(shift + kSmiTagSize)); | 250 __ shlq(RDX, Immediate(shift + kSmiTagSize)); |
| 250 } else { | 251 } else { |
| 251 ASSERT(kSmiTagSize == 1); | 252 __ subq(RDX, Immediate(1)); |
| 252 __ leaq(RDX, Address(RDX, TIMES_2, base << kSmiTagSize)); | 253 __ andq(RDX, Immediate( |
| 254 Smi::RawValue(true_value) - Smi::RawValue(false_value))); |
| 255 if (false_value != 0) { |
| 256 __ addq(RDX, Immediate(Smi::RawValue(false_value))); |
| 257 } |
| 253 } | 258 } |
| 254 } | 259 } |
| 255 | 260 |
| 256 | 261 |
| 257 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { | 262 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { |
| 258 const intptr_t kNumInputs = 0; | 263 const intptr_t kNumInputs = 0; |
| 259 const intptr_t kNumTemps = 1; | 264 const intptr_t kNumTemps = 1; |
| 260 LocationSummary* result = | 265 LocationSummary* result = |
| 261 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 266 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 262 result->set_out(Location::RegisterLocation(RAX)); | 267 result->set_out(Location::RegisterLocation(RAX)); |
| (...skipping 3312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3575 PcDescriptors::kOther, | 3580 PcDescriptors::kOther, |
| 3576 locs()); | 3581 locs()); |
| 3577 __ Drop(2); // Discard type arguments and receiver. | 3582 __ Drop(2); // Discard type arguments and receiver. |
| 3578 } | 3583 } |
| 3579 | 3584 |
| 3580 } // namespace dart | 3585 } // namespace dart |
| 3581 | 3586 |
| 3582 #undef __ | 3587 #undef __ |
| 3583 | 3588 |
| 3584 #endif // defined TARGET_ARCH_X64 | 3589 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |