| OLD | NEW |
| 1 | 1 |
| 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
| 4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 7 #if defined(TARGET_ARCH_ARM) | 7 #if defined(TARGET_ARCH_ARM) |
| 8 | 8 |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 | 10 |
| (...skipping 3241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3252 if (!combined_smi_check) { | 3252 if (!combined_smi_check) { |
| 3253 __ orr(result, left, Operand(right)); | 3253 __ orr(result, left, Operand(right)); |
| 3254 } | 3254 } |
| 3255 break; | 3255 break; |
| 3256 case Token::kBIT_AND: | 3256 case Token::kBIT_AND: |
| 3257 __ and_(result, left, Operand(right)); | 3257 __ and_(result, left, Operand(right)); |
| 3258 break; | 3258 break; |
| 3259 case Token::kBIT_XOR: | 3259 case Token::kBIT_XOR: |
| 3260 __ eor(result, left, Operand(right)); | 3260 __ eor(result, left, Operand(right)); |
| 3261 break; | 3261 break; |
| 3262 case Token::kEQ: | |
| 3263 case Token::kLT: | |
| 3264 case Token::kLTE: | |
| 3265 case Token::kGT: | |
| 3266 case Token::kGTE: { | |
| 3267 Condition true_condition = | |
| 3268 EmitSmiComparisonOp(compiler, locs(), op_kind()); | |
| 3269 __ LoadObject(result, Bool::True(), true_condition); | |
| 3270 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); | |
| 3271 break; | |
| 3272 } | |
| 3273 default: | 3262 default: |
| 3274 UNIMPLEMENTED(); | 3263 UNREACHABLE(); |
| 3275 } | 3264 } |
| 3276 __ Bind(slow_path->exit_label()); | 3265 __ Bind(slow_path->exit_label()); |
| 3277 } | 3266 } |
| 3278 | 3267 |
| 3279 | 3268 |
| 3269 class CheckedSmiComparisonSlowPath : public SlowPathCode { |
| 3270 public: |
| 3271 CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction, |
| 3272 intptr_t try_index, |
| 3273 BranchLabels labels, |
| 3274 bool merged) |
| 3275 : instruction_(instruction), |
| 3276 try_index_(try_index), |
| 3277 labels_(labels), |
| 3278 merged_(merged) { } |
| 3279 |
| 3280 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3281 if (Assembler::EmittingComments()) { |
| 3282 __ Comment("slow path smi operation"); |
| 3283 } |
| 3284 __ Bind(entry_label()); |
| 3285 LocationSummary* locs = instruction_->locs(); |
| 3286 Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg(); |
| 3287 locs->live_registers()->Remove(Location::RegisterLocation(result)); |
| 3288 |
| 3289 compiler->SaveLiveRegisters(locs); |
| 3290 __ Push(locs->in(0).reg()); |
| 3291 __ Push(locs->in(1).reg()); |
| 3292 compiler->EmitMegamorphicInstanceCall( |
| 3293 *instruction_->call()->ic_data(), |
| 3294 instruction_->call()->ArgumentCount(), |
| 3295 instruction_->call()->deopt_id(), |
| 3296 instruction_->call()->token_pos(), |
| 3297 locs, |
| 3298 try_index_, |
| 3299 /* slow_path_argument_count = */ 2); |
| 3300 __ mov(result, Operand(R0)); |
| 3301 compiler->RestoreLiveRegisters(locs); |
| 3302 if (merged_) { |
| 3303 __ CompareObject(result, Bool::True()); |
| 3304 __ b(instruction_->is_negated() |
| 3305 ? labels_.false_label : labels_.true_label, EQ); |
| 3306 __ b(instruction_->is_negated() |
| 3307 ? labels_.true_label : labels_.false_label); |
| 3308 } else { |
| 3309 __ b(exit_label()); |
| 3310 } |
| 3311 } |
| 3312 |
| 3313 private: |
| 3314 CheckedSmiComparisonInstr* instruction_; |
| 3315 intptr_t try_index_; |
| 3316 BranchLabels labels_; |
| 3317 bool merged_; |
| 3318 }; |
| 3319 |
| 3320 |
| 3321 LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary( |
| 3322 Zone* zone, bool opt) const { |
| 3323 const intptr_t kNumInputs = 2; |
| 3324 const intptr_t kNumTemps = 1; |
| 3325 LocationSummary* summary = new(zone) LocationSummary( |
| 3326 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
| 3327 summary->set_in(0, Location::RequiresRegister()); |
| 3328 summary->set_in(1, Location::RequiresRegister()); |
| 3329 summary->set_temp(0, Location::RequiresRegister()); |
| 3330 summary->set_out(0, Location::RequiresRegister()); |
| 3331 return summary; |
| 3332 } |
| 3333 |
| 3334 |
| 3335 Condition CheckedSmiComparisonInstr::EmitComparisonCode( |
| 3336 FlowGraphCompiler* compiler, BranchLabels labels) { |
| 3337 return EmitSmiComparisonOp(compiler, locs(), kind()); |
| 3338 } |
| 3339 |
| 3340 |
| 3341 #define EMIT_SMI_CHECK \ |
| 3342 Register left = locs()->in(0).reg(); \ |
| 3343 Register right = locs()->in(1).reg(); \ |
| 3344 Register temp = locs()->temp(0).reg(); \ |
| 3345 intptr_t left_cid = this->left()->Type()->ToCid(); \ |
| 3346 intptr_t right_cid = this->right()->Type()->ToCid(); \ |
| 3347 if (this->left()->definition() == this->right()->definition()) { \ |
| 3348 __ tst(left, Operand(kSmiTagMask)); \ |
| 3349 } else if (left_cid == kSmiCid) { \ |
| 3350 __ tst(right, Operand(kSmiTagMask)); \ |
| 3351 } else if (right_cid == kSmiCid) { \ |
| 3352 __ tst(left, Operand(kSmiTagMask)); \ |
| 3353 } else { \ |
| 3354 __ orr(temp, left, Operand(right)); \ |
| 3355 __ tst(temp, Operand(kSmiTagMask)); \ |
| 3356 } \ |
| 3357 __ b(slow_path->entry_label(), NE) |
| 3358 |
| 3359 |
| 3360 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 3361 BranchInstr* branch) { |
| 3362 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 3363 CheckedSmiComparisonSlowPath* slow_path = |
| 3364 new CheckedSmiComparisonSlowPath(this, |
| 3365 compiler->CurrentTryIndex(), |
| 3366 labels, |
| 3367 /* merged = */ true); |
| 3368 compiler->AddSlowPathCode(slow_path); |
| 3369 EMIT_SMI_CHECK; |
| 3370 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3371 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3372 __ Bind(slow_path->exit_label()); |
| 3373 } |
| 3374 |
| 3375 |
| 3376 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3377 BranchLabels labels = { NULL, NULL, NULL }; |
| 3378 CheckedSmiComparisonSlowPath* slow_path = |
| 3379 new CheckedSmiComparisonSlowPath(this, |
| 3380 compiler->CurrentTryIndex(), |
| 3381 labels, |
| 3382 /* merged = */ false); |
| 3383 compiler->AddSlowPathCode(slow_path); |
| 3384 EMIT_SMI_CHECK; |
| 3385 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3386 Register result = locs()->out(0).reg(); |
| 3387 __ LoadObject(result, Bool::True(), true_condition); |
| 3388 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); |
| 3389 __ Bind(slow_path->exit_label()); |
| 3390 } |
| 3391 #undef EMIT_SMI_CHECK |
| 3392 |
| 3393 |
| 3280 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, | 3394 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, |
| 3281 bool opt) const { | 3395 bool opt) const { |
| 3282 const intptr_t kNumInputs = 2; | 3396 const intptr_t kNumInputs = 2; |
| 3283 // Calculate number of temporaries. | 3397 // Calculate number of temporaries. |
| 3284 intptr_t num_temps = 0; | 3398 intptr_t num_temps = 0; |
| 3285 if (op_kind() == Token::kTRUNCDIV) { | 3399 if (op_kind() == Token::kTRUNCDIV) { |
| 3286 if (RightIsPowerOfTwoConstant()) { | 3400 if (RightIsPowerOfTwoConstant()) { |
| 3287 num_temps = 1; | 3401 num_temps = 1; |
| 3288 } else { | 3402 } else { |
| 3289 num_temps = 2; | 3403 num_temps = 2; |
| (...skipping 3877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7167 1, | 7281 1, |
| 7168 locs()); | 7282 locs()); |
| 7169 __ Drop(1); | 7283 __ Drop(1); |
| 7170 __ Pop(result); | 7284 __ Pop(result); |
| 7171 } | 7285 } |
| 7172 | 7286 |
| 7173 | 7287 |
| 7174 } // namespace dart | 7288 } // namespace dart |
| 7175 | 7289 |
| 7176 #endif // defined TARGET_ARCH_ARM | 7290 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |