| 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_ARM. | 5 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM. | 
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) | 
| 7 | 7 | 
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" | 
| 9 | 9 | 
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 84 // that will be overwritten by the patch instructions: a branch macro sequence. | 84 // that will be overwritten by the patch instructions: a branch macro sequence. | 
| 85 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 85 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 86   const Register result = locs()->in(0).reg(); | 86   const Register result = locs()->in(0).reg(); | 
| 87   ASSERT(result == R0); | 87   ASSERT(result == R0); | 
| 88 #if defined(DEBUG) | 88 #if defined(DEBUG) | 
| 89   Label stack_ok; | 89   Label stack_ok; | 
| 90   __ Comment("Stack Check"); | 90   __ Comment("Stack Check"); | 
| 91   const intptr_t fp_sp_dist = | 91   const intptr_t fp_sp_dist = | 
| 92       (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; | 92       (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; | 
| 93   ASSERT(fp_sp_dist <= 0); | 93   ASSERT(fp_sp_dist <= 0); | 
| 94   __ sub(R2, SP, ShifterOperand(FP)); | 94   __ sub(R2, SP, Operand(FP)); | 
| 95   __ CompareImmediate(R2, fp_sp_dist); | 95   __ CompareImmediate(R2, fp_sp_dist); | 
| 96   __ b(&stack_ok, EQ); | 96   __ b(&stack_ok, EQ); | 
| 97   __ bkpt(0); | 97   __ bkpt(0); | 
| 98   __ Bind(&stack_ok); | 98   __ Bind(&stack_ok); | 
| 99 #endif | 99 #endif | 
| 100   __ LeaveDartFrame(); | 100   __ LeaveDartFrame(); | 
| 101   __ Ret(); | 101   __ Ret(); | 
| 102 } | 102 } | 
| 103 | 103 | 
| 104 | 104 | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 136 | 136 | 
| 137 | 137 | 
| 138 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 138 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 139   const Register result = locs()->out(0).reg(); | 139   const Register result = locs()->out(0).reg(); | 
| 140 | 140 | 
| 141   Location left = locs()->in(0); | 141   Location left = locs()->in(0); | 
| 142   Location right = locs()->in(1); | 142   Location right = locs()->in(1); | 
| 143   ASSERT(!left.IsConstant() || !right.IsConstant()); | 143   ASSERT(!left.IsConstant() || !right.IsConstant()); | 
| 144 | 144 | 
| 145   // Clear out register. | 145   // Clear out register. | 
| 146   __ eor(result, result, ShifterOperand(result)); | 146   __ eor(result, result, Operand(result)); | 
| 147 | 147 | 
| 148   // Emit comparison code. This must not overwrite the result register. | 148   // Emit comparison code. This must not overwrite the result register. | 
| 149   BranchLabels labels = { NULL, NULL, NULL }; | 149   BranchLabels labels = { NULL, NULL, NULL }; | 
| 150   Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); | 150   Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); | 
| 151 | 151 | 
| 152   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); | 152   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); | 
| 153 | 153 | 
| 154   intptr_t true_value = if_true_; | 154   intptr_t true_value = if_true_; | 
| 155   intptr_t false_value = if_false_; | 155   intptr_t false_value = if_false_; | 
| 156 | 156 | 
| 157   if (is_power_of_two_kind) { | 157   if (is_power_of_two_kind) { | 
| 158     if (true_value == 0) { | 158     if (true_value == 0) { | 
| 159       // We need to have zero in result on true_condition. | 159       // We need to have zero in result on true_condition. | 
| 160       true_condition = NegateCondition(true_condition); | 160       true_condition = NegateCondition(true_condition); | 
| 161     } | 161     } | 
| 162   } else { | 162   } else { | 
| 163     if (true_value == 0) { | 163     if (true_value == 0) { | 
| 164       // Swap values so that false_value is zero. | 164       // Swap values so that false_value is zero. | 
| 165       intptr_t temp = true_value; | 165       intptr_t temp = true_value; | 
| 166       true_value = false_value; | 166       true_value = false_value; | 
| 167       false_value = temp; | 167       false_value = temp; | 
| 168     } else { | 168     } else { | 
| 169       true_condition = NegateCondition(true_condition); | 169       true_condition = NegateCondition(true_condition); | 
| 170     } | 170     } | 
| 171   } | 171   } | 
| 172 | 172 | 
| 173   __ mov(result, ShifterOperand(1), true_condition); | 173   __ mov(result, Operand(1), true_condition); | 
| 174 | 174 | 
| 175   if (is_power_of_two_kind) { | 175   if (is_power_of_two_kind) { | 
| 176     const intptr_t shift = | 176     const intptr_t shift = | 
| 177         Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); | 177         Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); | 
| 178     __ Lsl(result, result, shift + kSmiTagSize); | 178     __ Lsl(result, result, shift + kSmiTagSize); | 
| 179   } else { | 179   } else { | 
| 180     __ sub(result, result, ShifterOperand(1)); | 180     __ sub(result, result, Operand(1)); | 
| 181     const int32_t val = | 181     const int32_t val = | 
| 182         Smi::RawValue(true_value) - Smi::RawValue(false_value); | 182         Smi::RawValue(true_value) - Smi::RawValue(false_value); | 
| 183     __ AndImmediate(result, result, val); | 183     __ AndImmediate(result, result, val); | 
| 184     if (false_value != 0) { | 184     if (false_value != 0) { | 
| 185       __ AddImmediate(result, Smi::RawValue(false_value)); | 185       __ AddImmediate(result, Smi::RawValue(false_value)); | 
| 186     } | 186     } | 
| 187   } | 187   } | 
| 188 } | 188 } | 
| 189 | 189 | 
| 190 | 190 | 
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 433   return NULL; | 433   return NULL; | 
| 434 } | 434 } | 
| 435 | 435 | 
| 436 | 436 | 
| 437 static void LoadValueCid(FlowGraphCompiler* compiler, | 437 static void LoadValueCid(FlowGraphCompiler* compiler, | 
| 438                          Register value_cid_reg, | 438                          Register value_cid_reg, | 
| 439                          Register value_reg, | 439                          Register value_reg, | 
| 440                          Label* value_is_smi = NULL) { | 440                          Label* value_is_smi = NULL) { | 
| 441   Label done; | 441   Label done; | 
| 442   if (value_is_smi == NULL) { | 442   if (value_is_smi == NULL) { | 
| 443     __ mov(value_cid_reg, ShifterOperand(kSmiCid)); | 443     __ mov(value_cid_reg, Operand(kSmiCid)); | 
| 444   } | 444   } | 
| 445   __ tst(value_reg, ShifterOperand(kSmiTagMask)); | 445   __ tst(value_reg, Operand(kSmiTagMask)); | 
| 446   if (value_is_smi == NULL) { | 446   if (value_is_smi == NULL) { | 
| 447     __ b(&done, EQ); | 447     __ b(&done, EQ); | 
| 448   } else { | 448   } else { | 
| 449     __ b(value_is_smi, EQ); | 449     __ b(value_is_smi, EQ); | 
| 450   } | 450   } | 
| 451   __ LoadClassId(value_cid_reg, value_reg); | 451   __ LoadClassId(value_cid_reg, value_reg); | 
| 452   __ Bind(&done); | 452   __ Bind(&done); | 
| 453 } | 453 } | 
| 454 | 454 | 
| 455 | 455 | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 499   ASSERT(!left.IsConstant() || !right.IsConstant()); | 499   ASSERT(!left.IsConstant() || !right.IsConstant()); | 
| 500 | 500 | 
| 501   Condition true_condition = TokenKindToSmiCondition(kind); | 501   Condition true_condition = TokenKindToSmiCondition(kind); | 
| 502 | 502 | 
| 503   if (left.IsConstant()) { | 503   if (left.IsConstant()) { | 
| 504     __ CompareObject(right.reg(), left.constant()); | 504     __ CompareObject(right.reg(), left.constant()); | 
| 505     true_condition = FlipCondition(true_condition); | 505     true_condition = FlipCondition(true_condition); | 
| 506   } else if (right.IsConstant()) { | 506   } else if (right.IsConstant()) { | 
| 507     __ CompareObject(left.reg(), right.constant()); | 507     __ CompareObject(left.reg(), right.constant()); | 
| 508   } else { | 508   } else { | 
| 509     __ cmp(left.reg(), ShifterOperand(right.reg())); | 509     __ cmp(left.reg(), Operand(right.reg())); | 
| 510   } | 510   } | 
| 511   return true_condition; | 511   return true_condition; | 
| 512 } | 512 } | 
| 513 | 513 | 
| 514 | 514 | 
| 515 static Condition TokenKindToMintCondition(Token::Kind kind) { | 515 static Condition TokenKindToMintCondition(Token::Kind kind) { | 
| 516   switch (kind) { | 516   switch (kind) { | 
| 517     case Token::kEQ: return EQ; | 517     case Token::kEQ: return EQ; | 
| 518     case Token::kNE: return NE; | 518     case Token::kNE: return NE; | 
| 519     case Token::kLT: return LT; | 519     case Token::kLT: return LT; | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 532                                            Token::Kind kind) { | 532                                            Token::Kind kind) { | 
| 533   ASSERT(Token::IsEqualityOperator(kind)); | 533   ASSERT(Token::IsEqualityOperator(kind)); | 
| 534   PairLocation* left_pair = locs->in(0).AsPairLocation(); | 534   PairLocation* left_pair = locs->in(0).AsPairLocation(); | 
| 535   Register left1 = left_pair->At(0).reg(); | 535   Register left1 = left_pair->At(0).reg(); | 
| 536   Register left2 = left_pair->At(1).reg(); | 536   Register left2 = left_pair->At(1).reg(); | 
| 537   PairLocation* right_pair = locs->in(1).AsPairLocation(); | 537   PairLocation* right_pair = locs->in(1).AsPairLocation(); | 
| 538   Register right1 = right_pair->At(0).reg(); | 538   Register right1 = right_pair->At(0).reg(); | 
| 539   Register right2 = right_pair->At(1).reg(); | 539   Register right2 = right_pair->At(1).reg(); | 
| 540 | 540 | 
| 541   // Compare lower. | 541   // Compare lower. | 
| 542   __ cmp(left1, ShifterOperand(right1)); | 542   __ cmp(left1, Operand(right1)); | 
| 543   // Compare upper if lower is equal. | 543   // Compare upper if lower is equal. | 
| 544   __ cmp(left2, ShifterOperand(right2), EQ); | 544   __ cmp(left2, Operand(right2), EQ); | 
| 545   return TokenKindToMintCondition(kind); | 545   return TokenKindToMintCondition(kind); | 
| 546 } | 546 } | 
| 547 | 547 | 
| 548 | 548 | 
| 549 static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, | 549 static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, | 
| 550                                              LocationSummary* locs, | 550                                              LocationSummary* locs, | 
| 551                                              Token::Kind kind) { | 551                                              Token::Kind kind) { | 
| 552   PairLocation* left_pair = locs->in(0).AsPairLocation(); | 552   PairLocation* left_pair = locs->in(0).AsPairLocation(); | 
| 553   Register left1 = left_pair->At(0).reg(); | 553   Register left1 = left_pair->At(0).reg(); | 
| 554   Register left2 = left_pair->At(1).reg(); | 554   Register left2 = left_pair->At(1).reg(); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 573       hi_false_cond = LT; | 573       hi_false_cond = LT; | 
| 574       lo_false_cond = (kind == Token::kGT) ? LS : CC; | 574       lo_false_cond = (kind == Token::kGT) ? LS : CC; | 
| 575       break; | 575       break; | 
| 576     default: | 576     default: | 
| 577       UNREACHABLE(); | 577       UNREACHABLE(); | 
| 578       hi_true_cond = hi_false_cond = lo_false_cond = VS; | 578       hi_true_cond = hi_false_cond = lo_false_cond = VS; | 
| 579   } | 579   } | 
| 580 | 580 | 
| 581   Label is_true, is_false, done; | 581   Label is_true, is_false, done; | 
| 582   // Compare upper halves first. | 582   // Compare upper halves first. | 
| 583   __ cmp(left2, ShifterOperand(right2)); | 583   __ cmp(left2, Operand(right2)); | 
| 584   __ LoadImmediate(out, 0, hi_false_cond); | 584   __ LoadImmediate(out, 0, hi_false_cond); | 
| 585   __ LoadImmediate(out, 1, hi_true_cond); | 585   __ LoadImmediate(out, 1, hi_true_cond); | 
| 586   // If higher words aren't equal, skip comparing lower words. | 586   // If higher words aren't equal, skip comparing lower words. | 
| 587   __ b(&done, NE); | 587   __ b(&done, NE); | 
| 588 | 588 | 
| 589   __ cmp(left1, ShifterOperand(right1)); | 589   __ cmp(left1, Operand(right1)); | 
| 590   __ LoadImmediate(out, 1); | 590   __ LoadImmediate(out, 1); | 
| 591   __ LoadImmediate(out, 0, lo_false_cond); | 591   __ LoadImmediate(out, 0, lo_false_cond); | 
| 592   __ Bind(&done); | 592   __ Bind(&done); | 
| 593 | 593 | 
| 594   return NegateCondition(lo_false_cond); | 594   return NegateCondition(lo_false_cond); | 
| 595 } | 595 } | 
| 596 | 596 | 
| 597 | 597 | 
| 598 static Condition TokenKindToDoubleCondition(Token::Kind kind) { | 598 static Condition TokenKindToDoubleCondition(Token::Kind kind) { | 
| 599   switch (kind) { | 599   switch (kind) { | 
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 694 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 694 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 
| 695                                            BranchLabels labels) { | 695                                            BranchLabels labels) { | 
| 696   const Register left = locs()->in(0).reg(); | 696   const Register left = locs()->in(0).reg(); | 
| 697   Location right = locs()->in(1); | 697   Location right = locs()->in(1); | 
| 698   if (right.IsConstant()) { | 698   if (right.IsConstant()) { | 
| 699     ASSERT(right.constant().IsSmi()); | 699     ASSERT(right.constant().IsSmi()); | 
| 700     const int32_t imm = | 700     const int32_t imm = | 
| 701         reinterpret_cast<int32_t>(right.constant().raw()); | 701         reinterpret_cast<int32_t>(right.constant().raw()); | 
| 702     __ TestImmediate(left, imm); | 702     __ TestImmediate(left, imm); | 
| 703   } else { | 703   } else { | 
| 704     __ tst(left, ShifterOperand(right.reg())); | 704     __ tst(left, Operand(right.reg())); | 
| 705   } | 705   } | 
| 706   Condition true_condition = (kind() == Token::kNE) ? NE : EQ; | 706   Condition true_condition = (kind() == Token::kNE) ? NE : EQ; | 
| 707   return true_condition; | 707   return true_condition; | 
| 708 } | 708 } | 
| 709 | 709 | 
| 710 | 710 | 
| 711 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 711 void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 712   // Never emitted outside of the BranchInstr. | 712   // Never emitted outside of the BranchInstr. | 
| 713   UNREACHABLE(); | 713   UNREACHABLE(); | 
| 714 } | 714 } | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 741   const Register val_reg = locs()->in(0).reg(); | 741   const Register val_reg = locs()->in(0).reg(); | 
| 742   const Register cid_reg = locs()->temp(0).reg(); | 742   const Register cid_reg = locs()->temp(0).reg(); | 
| 743 | 743 | 
| 744   Label* deopt = CanDeoptimize() ? | 744   Label* deopt = CanDeoptimize() ? | 
| 745       compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL; | 745       compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL; | 
| 746 | 746 | 
| 747   const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; | 747   const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; | 
| 748   const ZoneGrowableArray<intptr_t>& data = cid_results(); | 748   const ZoneGrowableArray<intptr_t>& data = cid_results(); | 
| 749   ASSERT(data[0] == kSmiCid); | 749   ASSERT(data[0] == kSmiCid); | 
| 750   bool result = data[1] == true_result; | 750   bool result = data[1] == true_result; | 
| 751   __ tst(val_reg, ShifterOperand(kSmiTagMask)); | 751   __ tst(val_reg, Operand(kSmiTagMask)); | 
| 752   __ b(result ? labels.true_label : labels.false_label, EQ); | 752   __ b(result ? labels.true_label : labels.false_label, EQ); | 
| 753   __ LoadClassId(cid_reg, val_reg); | 753   __ LoadClassId(cid_reg, val_reg); | 
| 754 | 754 | 
| 755   for (intptr_t i = 2; i < data.length(); i += 2) { | 755   for (intptr_t i = 2; i < data.length(); i += 2) { | 
| 756     const intptr_t test_cid = data[i]; | 756     const intptr_t test_cid = data[i]; | 
| 757     ASSERT(test_cid != kSmiCid); | 757     ASSERT(test_cid != kSmiCid); | 
| 758     result = data[i + 1] == true_result; | 758     result = data[i + 1] == true_result; | 
| 759     __ CompareImmediate(cid_reg, test_cid); | 759     __ CompareImmediate(cid_reg, test_cid); | 
| 760     __ b(result ? labels.true_label : labels.false_label, EQ); | 760     __ b(result ? labels.true_label : labels.false_label, EQ); | 
| 761   } | 761   } | 
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 985                                Location::RequiresRegister(), | 985                                Location::RequiresRegister(), | 
| 986                                LocationSummary::kNoCall); | 986                                LocationSummary::kNoCall); | 
| 987 } | 987 } | 
| 988 | 988 | 
| 989 | 989 | 
| 990 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 990 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 991   ASSERT(cid_ == kOneByteStringCid); | 991   ASSERT(cid_ == kOneByteStringCid); | 
| 992   const Register str = locs()->in(0).reg(); | 992   const Register str = locs()->in(0).reg(); | 
| 993   const Register result = locs()->out(0).reg(); | 993   const Register result = locs()->out(0).reg(); | 
| 994   __ ldr(result, FieldAddress(str, String::length_offset())); | 994   __ ldr(result, FieldAddress(str, String::length_offset())); | 
| 995   __ cmp(result, ShifterOperand(Smi::RawValue(1))); | 995   __ cmp(result, Operand(Smi::RawValue(1))); | 
| 996   __ LoadImmediate(result, -1, NE); | 996   __ LoadImmediate(result, -1, NE); | 
| 997   __ ldrb(result, FieldAddress(str, OneByteString::data_offset()), EQ); | 997   __ ldrb(result, FieldAddress(str, OneByteString::data_offset()), EQ); | 
| 998   __ SmiTag(result); | 998   __ SmiTag(result); | 
| 999 } | 999 } | 
| 1000 | 1000 | 
| 1001 | 1001 | 
| 1002 LocationSummary* StringInterpolateInstr::MakeLocationSummary(Isolate* isolate, | 1002 LocationSummary* StringInterpolateInstr::MakeLocationSummary(Isolate* isolate, | 
| 1003                                                              bool opt) const { | 1003                                                              bool opt) const { | 
| 1004   const intptr_t kNumInputs = 1; | 1004   const intptr_t kNumInputs = 1; | 
| 1005   const intptr_t kNumTemps = 0; | 1005   const intptr_t kNumTemps = 0; | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1050                                kNumInputs, | 1050                                kNumInputs, | 
| 1051                                Location::RequiresRegister(), | 1051                                Location::RequiresRegister(), | 
| 1052                                LocationSummary::kNoCall); | 1052                                LocationSummary::kNoCall); | 
| 1053 } | 1053 } | 
| 1054 | 1054 | 
| 1055 | 1055 | 
| 1056 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1056 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 1057   const Register object = locs()->in(0).reg(); | 1057   const Register object = locs()->in(0).reg(); | 
| 1058   const Register result = locs()->out(0).reg(); | 1058   const Register result = locs()->out(0).reg(); | 
| 1059   Label load, done; | 1059   Label load, done; | 
| 1060   __ tst(object, ShifterOperand(kSmiTagMask)); | 1060   __ tst(object, Operand(kSmiTagMask)); | 
| 1061   __ b(&load, NE); | 1061   __ b(&load, NE); | 
| 1062   __ LoadImmediate(result, Smi::RawValue(kSmiCid)); | 1062   __ LoadImmediate(result, Smi::RawValue(kSmiCid)); | 
| 1063   __ b(&done); | 1063   __ b(&done); | 
| 1064   __ Bind(&load); | 1064   __ Bind(&load); | 
| 1065   __ LoadClassId(result, object); | 1065   __ LoadClassId(result, object); | 
| 1066   __ SmiTag(result); | 1066   __ SmiTag(result); | 
| 1067   __ Bind(&done); | 1067   __ Bind(&done); | 
| 1068 } | 1068 } | 
| 1069 | 1069 | 
| 1070 | 1070 | 
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1233   int32_t offset = | 1233   int32_t offset = | 
| 1234       is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); | 1234       is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); | 
| 1235   const OperandSize size = Address::OperandSizeFor(cid); | 1235   const OperandSize size = Address::OperandSizeFor(cid); | 
| 1236   ASSERT(array != IP); | 1236   ASSERT(array != IP); | 
| 1237   ASSERT(index != IP); | 1237   ASSERT(index != IP); | 
| 1238   const Register base = is_load ? IP : index; | 1238   const Register base = is_load ? IP : index; | 
| 1239   if ((offset != 0) || | 1239   if ((offset != 0) || | 
| 1240       (size == kSWord) || (size == kDWord) || (size == kRegList)) { | 1240       (size == kSWord) || (size == kDWord) || (size == kRegList)) { | 
| 1241     if (shift < 0) { | 1241     if (shift < 0) { | 
| 1242       ASSERT(shift == -1); | 1242       ASSERT(shift == -1); | 
| 1243       assembler->add(base, array, ShifterOperand(index, ASR, 1)); | 1243       assembler->add(base, array, Operand(index, ASR, 1)); | 
| 1244     } else { | 1244     } else { | 
| 1245       assembler->add(base, array, ShifterOperand(index, LSL, shift)); | 1245       assembler->add(base, array, Operand(index, LSL, shift)); | 
| 1246     } | 1246     } | 
| 1247   } else { | 1247   } else { | 
| 1248     if (shift < 0) { | 1248     if (shift < 0) { | 
| 1249       ASSERT(shift == -1); | 1249       ASSERT(shift == -1); | 
| 1250       return Address(array, index, ASR, 1); | 1250       return Address(array, index, ASR, 1); | 
| 1251     } else { | 1251     } else { | 
| 1252       return Address(array, index, LSL, shift); | 1252       return Address(array, index, LSL, shift); | 
| 1253     } | 1253     } | 
| 1254   } | 1254   } | 
| 1255   int32_t offset_mask = 0; | 1255   int32_t offset_mask = 0; | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1317       case kTypedDataInt32ArrayCid: | 1317       case kTypedDataInt32ArrayCid: | 
| 1318         // Load low word. | 1318         // Load low word. | 
| 1319         __ ldr(result1, element_address); | 1319         __ ldr(result1, element_address); | 
| 1320         // Sign extend into high word. | 1320         // Sign extend into high word. | 
| 1321         __ SignFill(result2, result1); | 1321         __ SignFill(result2, result1); | 
| 1322         break; | 1322         break; | 
| 1323       case kTypedDataUint32ArrayCid: | 1323       case kTypedDataUint32ArrayCid: | 
| 1324         // Load low word. | 1324         // Load low word. | 
| 1325         __ ldr(result1, element_address); | 1325         __ ldr(result1, element_address); | 
| 1326         // Zero high word. | 1326         // Zero high word. | 
| 1327         __ eor(result2, result2, ShifterOperand(result2)); | 1327         __ eor(result2, result2, Operand(result2)); | 
| 1328         break; | 1328         break; | 
| 1329       default: | 1329       default: | 
| 1330         UNREACHABLE(); | 1330         UNREACHABLE(); | 
| 1331         break; | 1331         break; | 
| 1332     } | 1332     } | 
| 1333     return; | 1333     return; | 
| 1334   } | 1334   } | 
| 1335 | 1335 | 
| 1336   ASSERT(representation() == kTagged); | 1336   ASSERT(representation() == kTagged); | 
| 1337 | 1337 | 
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1535           value = 0xFF; | 1535           value = 0xFF; | 
| 1536         } else if (value < 0) { | 1536         } else if (value < 0) { | 
| 1537           value = 0; | 1537           value = 0; | 
| 1538         } | 1538         } | 
| 1539         __ LoadImmediate(IP, static_cast<int8_t>(value)); | 1539         __ LoadImmediate(IP, static_cast<int8_t>(value)); | 
| 1540         __ strb(IP, element_address); | 1540         __ strb(IP, element_address); | 
| 1541       } else { | 1541       } else { | 
| 1542         const Register value = locs()->in(2).reg(); | 1542         const Register value = locs()->in(2).reg(); | 
| 1543         Label store_value; | 1543         Label store_value; | 
| 1544         __ SmiUntag(value); | 1544         __ SmiUntag(value); | 
| 1545         __ cmp(value, ShifterOperand(0xFF)); | 1545         __ cmp(value, Operand(0xFF)); | 
| 1546         // Clamp to 0x00 or 0xFF respectively. | 1546         // Clamp to 0x00 or 0xFF respectively. | 
| 1547         __ b(&store_value, LS); | 1547         __ b(&store_value, LS); | 
| 1548         __ mov(value, ShifterOperand(0x00), LE); | 1548         __ mov(value, Operand(0x00), LE); | 
| 1549         __ mov(value, ShifterOperand(0xFF), GT); | 1549         __ mov(value, Operand(0xFF), GT); | 
| 1550         __ Bind(&store_value); | 1550         __ Bind(&store_value); | 
| 1551         __ strb(value, element_address); | 1551         __ strb(value, element_address); | 
| 1552       } | 1552       } | 
| 1553       break; | 1553       break; | 
| 1554     } | 1554     } | 
| 1555     case kTypedDataInt16ArrayCid: | 1555     case kTypedDataInt16ArrayCid: | 
| 1556     case kTypedDataUint16ArrayCid: { | 1556     case kTypedDataUint16ArrayCid: { | 
| 1557       const Register value = locs()->in(2).reg(); | 1557       const Register value = locs()->in(2).reg(); | 
| 1558       __ SmiUntag(value); | 1558       __ SmiUntag(value); | 
| 1559       __ strh(value, element_address); | 1559       __ strh(value, element_address); | 
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1670     FieldAddress field_length_operand( | 1670     FieldAddress field_length_operand( | 
| 1671         field_reg, Field::guarded_list_length_offset()); | 1671         field_reg, Field::guarded_list_length_offset()); | 
| 1672 | 1672 | 
| 1673     ASSERT(value_cid_reg != kNoRegister); | 1673     ASSERT(value_cid_reg != kNoRegister); | 
| 1674     ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); | 1674     ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); | 
| 1675 | 1675 | 
| 1676     if (value_cid == kDynamicCid) { | 1676     if (value_cid == kDynamicCid) { | 
| 1677       LoadValueCid(compiler, value_cid_reg, value_reg); | 1677       LoadValueCid(compiler, value_cid_reg, value_reg); | 
| 1678       Label skip_length_check; | 1678       Label skip_length_check; | 
| 1679       __ ldr(IP, field_cid_operand); | 1679       __ ldr(IP, field_cid_operand); | 
| 1680       __ cmp(value_cid_reg, ShifterOperand(IP)); | 1680       __ cmp(value_cid_reg, Operand(IP)); | 
| 1681       __ b(&skip_length_check, NE); | 1681       __ b(&skip_length_check, NE); | 
| 1682       if (field_has_length) { | 1682       if (field_has_length) { | 
| 1683         ASSERT(temp_reg != kNoRegister); | 1683         ASSERT(temp_reg != kNoRegister); | 
| 1684         // Field guard may have remembered list length, check it. | 1684         // Field guard may have remembered list length, check it. | 
| 1685         if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1685         if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 
| 1686           __ ldr(temp_reg, | 1686           __ ldr(temp_reg, | 
| 1687                  FieldAddress(value_reg, Array::length_offset())); | 1687                  FieldAddress(value_reg, Array::length_offset())); | 
| 1688           __ CompareImmediate(temp_reg, Smi::RawValue(field_length)); | 1688           __ CompareImmediate(temp_reg, Smi::RawValue(field_length)); | 
| 1689         } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1689         } else if (RawObject::IsTypedDataClassId(field_cid)) { | 
| 1690           __ ldr(temp_reg, | 1690           __ ldr(temp_reg, | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 1709           __ b(&no_fixed_length, EQ); | 1709           __ b(&no_fixed_length, EQ); | 
| 1710           // Check for typed data array. | 1710           // Check for typed data array. | 
| 1711           __ CompareImmediate(value_cid_reg, kTypedDataInt32x4ArrayCid); | 1711           __ CompareImmediate(value_cid_reg, kTypedDataInt32x4ArrayCid); | 
| 1712           __ b(&no_fixed_length, GT); | 1712           __ b(&no_fixed_length, GT); | 
| 1713           __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); | 1713           __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); | 
| 1714           // Could still be a regular array. | 1714           // Could still be a regular array. | 
| 1715           __ b(&check_array, LT); | 1715           __ b(&check_array, LT); | 
| 1716           __ ldr(temp_reg, | 1716           __ ldr(temp_reg, | 
| 1717                  FieldAddress(value_reg, TypedData::length_offset())); | 1717                  FieldAddress(value_reg, TypedData::length_offset())); | 
| 1718           __ ldr(IP, field_length_operand); | 1718           __ ldr(IP, field_length_operand); | 
| 1719           __ cmp(temp_reg, ShifterOperand(IP)); | 1719           __ cmp(temp_reg, Operand(IP)); | 
| 1720           __ b(&length_compared); | 1720           __ b(&length_compared); | 
| 1721           // Check for regular array. | 1721           // Check for regular array. | 
| 1722           __ Bind(&check_array); | 1722           __ Bind(&check_array); | 
| 1723           __ CompareImmediate(value_cid_reg, kImmutableArrayCid); | 1723           __ CompareImmediate(value_cid_reg, kImmutableArrayCid); | 
| 1724           __ b(&no_fixed_length, GT); | 1724           __ b(&no_fixed_length, GT); | 
| 1725           __ CompareImmediate(value_cid_reg, kArrayCid); | 1725           __ CompareImmediate(value_cid_reg, kArrayCid); | 
| 1726           __ b(&no_fixed_length, LT); | 1726           __ b(&no_fixed_length, LT); | 
| 1727           __ ldr(temp_reg, | 1727           __ ldr(temp_reg, | 
| 1728                  FieldAddress(value_reg, Array::length_offset())); | 1728                  FieldAddress(value_reg, Array::length_offset())); | 
| 1729           __ ldr(IP, field_length_operand); | 1729           __ ldr(IP, field_length_operand); | 
| 1730           __ cmp(temp_reg, ShifterOperand(IP)); | 1730           __ cmp(temp_reg, Operand(IP)); | 
| 1731           __ b(&length_compared); | 1731           __ b(&length_compared); | 
| 1732           __ Bind(&no_fixed_length); | 1732           __ Bind(&no_fixed_length); | 
| 1733           __ b(fail); | 1733           __ b(fail); | 
| 1734           __ Bind(&length_compared); | 1734           __ Bind(&length_compared); | 
| 1735           // Following branch cannot not occur, fall through. | 1735           // Following branch cannot not occur, fall through. | 
| 1736         } | 1736         } | 
| 1737         __ b(fail, NE); | 1737         __ b(fail, NE); | 
| 1738       } | 1738       } | 
| 1739       __ Bind(&skip_length_check); | 1739       __ Bind(&skip_length_check); | 
| 1740       __ ldr(IP, field_nullability_operand); | 1740       __ ldr(IP, field_nullability_operand); | 
| 1741       __ cmp(value_cid_reg, ShifterOperand(IP)); | 1741       __ cmp(value_cid_reg, Operand(IP)); | 
| 1742     } else if (value_cid == kNullCid) { | 1742     } else if (value_cid == kNullCid) { | 
| 1743       __ ldr(value_cid_reg, field_nullability_operand); | 1743       __ ldr(value_cid_reg, field_nullability_operand); | 
| 1744       __ CompareImmediate(value_cid_reg, value_cid); | 1744       __ CompareImmediate(value_cid_reg, value_cid); | 
| 1745     } else { | 1745     } else { | 
| 1746       Label skip_length_check; | 1746       Label skip_length_check; | 
| 1747       __ ldr(value_cid_reg, field_cid_operand); | 1747       __ ldr(value_cid_reg, field_cid_operand); | 
| 1748       __ CompareImmediate(value_cid_reg, value_cid); | 1748       __ CompareImmediate(value_cid_reg, value_cid); | 
| 1749       __ b(&skip_length_check, NE); | 1749       __ b(&skip_length_check, NE); | 
| 1750       if (field_has_length) { | 1750       if (field_has_length) { | 
| 1751         ASSERT(value_cid_reg != kNoRegister); | 1751         ASSERT(value_cid_reg != kNoRegister); | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1853     } | 1853     } | 
| 1854   } else { | 1854   } else { | 
| 1855     ASSERT(compiler->is_optimizing()); | 1855     ASSERT(compiler->is_optimizing()); | 
| 1856     ASSERT(deopt != NULL); | 1856     ASSERT(deopt != NULL); | 
| 1857     // Field guard class has been initialized and is known. | 1857     // Field guard class has been initialized and is known. | 
| 1858     if (field_reg != kNoRegister) { | 1858     if (field_reg != kNoRegister) { | 
| 1859       __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); | 1859       __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); | 
| 1860     } | 1860     } | 
| 1861     if (value_cid == kDynamicCid) { | 1861     if (value_cid == kDynamicCid) { | 
| 1862       // Field's guarded class id is fixed by value's class id is not known. | 1862       // Field's guarded class id is fixed by value's class id is not known. | 
| 1863       __ tst(value_reg, ShifterOperand(kSmiTagMask)); | 1863       __ tst(value_reg, Operand(kSmiTagMask)); | 
| 1864 | 1864 | 
| 1865       if (field_cid != kSmiCid) { | 1865       if (field_cid != kSmiCid) { | 
| 1866         __ b(fail, EQ); | 1866         __ b(fail, EQ); | 
| 1867         __ LoadClassId(value_cid_reg, value_reg); | 1867         __ LoadClassId(value_cid_reg, value_reg); | 
| 1868         __ CompareImmediate(value_cid_reg, field_cid); | 1868         __ CompareImmediate(value_cid_reg, field_cid); | 
| 1869       } | 1869       } | 
| 1870 | 1870 | 
| 1871       if (field_has_length) { | 1871       if (field_has_length) { | 
| 1872         __ b(fail, NE); | 1872         __ b(fail, NE); | 
| 1873         // Classes are same, perform guarded list length check. | 1873         // Classes are same, perform guarded list length check. | 
| 1874         ASSERT(field_reg != kNoRegister); | 1874         ASSERT(field_reg != kNoRegister); | 
| 1875         ASSERT(value_cid_reg != kNoRegister); | 1875         ASSERT(value_cid_reg != kNoRegister); | 
| 1876         FieldAddress field_length_operand( | 1876         FieldAddress field_length_operand( | 
| 1877             field_reg, Field::guarded_list_length_offset()); | 1877             field_reg, Field::guarded_list_length_offset()); | 
| 1878         if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1878         if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 
| 1879           // Destroy value_cid_reg (safe because we are finished with it). | 1879           // Destroy value_cid_reg (safe because we are finished with it). | 
| 1880           __ ldr(value_cid_reg, | 1880           __ ldr(value_cid_reg, | 
| 1881                  FieldAddress(value_reg, Array::length_offset())); | 1881                  FieldAddress(value_reg, Array::length_offset())); | 
| 1882         } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1882         } else if (RawObject::IsTypedDataClassId(field_cid)) { | 
| 1883           // Destroy value_cid_reg (safe because we are finished with it). | 1883           // Destroy value_cid_reg (safe because we are finished with it). | 
| 1884           __ ldr(value_cid_reg, | 1884           __ ldr(value_cid_reg, | 
| 1885                  FieldAddress(value_reg, TypedData::length_offset())); | 1885                  FieldAddress(value_reg, TypedData::length_offset())); | 
| 1886         } | 1886         } | 
| 1887         __ ldr(IP, field_length_operand); | 1887         __ ldr(IP, field_length_operand); | 
| 1888         __ cmp(value_cid_reg, ShifterOperand(IP)); | 1888         __ cmp(value_cid_reg, Operand(IP)); | 
| 1889       } | 1889       } | 
| 1890 | 1890 | 
| 1891       if (field().is_nullable() && (field_cid != kNullCid)) { | 1891       if (field().is_nullable() && (field_cid != kNullCid)) { | 
| 1892         __ b(&ok, EQ); | 1892         __ b(&ok, EQ); | 
| 1893         __ CompareImmediate(value_reg, | 1893         __ CompareImmediate(value_reg, | 
| 1894                             reinterpret_cast<intptr_t>(Object::null())); | 1894                             reinterpret_cast<intptr_t>(Object::null())); | 
| 1895       } | 1895       } | 
| 1896       __ b(fail, NE); | 1896       __ b(fail, NE); | 
| 1897     } else { | 1897     } else { | 
| 1898       // Both value's and field's class id is known. | 1898       // Both value's and field's class id is known. | 
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2063     Label store_float32x4; | 2063     Label store_float32x4; | 
| 2064     Label store_float64x2; | 2064     Label store_float64x2; | 
| 2065 | 2065 | 
| 2066     __ LoadObject(temp, Field::ZoneHandle(field().raw())); | 2066     __ LoadObject(temp, Field::ZoneHandle(field().raw())); | 
| 2067 | 2067 | 
| 2068     __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); | 2068     __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); | 
| 2069     __ CompareImmediate(temp2, kNullCid); | 2069     __ CompareImmediate(temp2, kNullCid); | 
| 2070     __ b(&store_pointer, EQ); | 2070     __ b(&store_pointer, EQ); | 
| 2071 | 2071 | 
| 2072     __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset())); | 2072     __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset())); | 
| 2073     __ tst(temp2, ShifterOperand(1 << Field::kUnboxingCandidateBit)); | 2073     __ tst(temp2, Operand(1 << Field::kUnboxingCandidateBit)); | 
| 2074     __ b(&store_pointer, EQ); | 2074     __ b(&store_pointer, EQ); | 
| 2075 | 2075 | 
| 2076     __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); | 2076     __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); | 
| 2077     __ CompareImmediate(temp2, kDoubleCid); | 2077     __ CompareImmediate(temp2, kDoubleCid); | 
| 2078     __ b(&store_double, EQ); | 2078     __ b(&store_double, EQ); | 
| 2079 | 2079 | 
| 2080     __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); | 2080     __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); | 
| 2081     __ CompareImmediate(temp2, kFloat32x4Cid); | 2081     __ CompareImmediate(temp2, kFloat32x4Cid); | 
| 2082     __ b(&store_float32x4, EQ); | 2082     __ b(&store_float32x4, EQ); | 
| 2083 | 2083 | 
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2303   __ LoadImmediate(R6, heap->TopAddress()); | 2303   __ LoadImmediate(R6, heap->TopAddress()); | 
| 2304   __ ldr(R0, Address(R6, 0));  // Potential new object start. | 2304   __ ldr(R0, Address(R6, 0));  // Potential new object start. | 
| 2305   __ AddImmediate(R7, R0, kArraySize);  // Potential next object start. | 2305   __ AddImmediate(R7, R0, kArraySize);  // Potential next object start. | 
| 2306   __ b(slow_path, VS); | 2306   __ b(slow_path, VS); | 
| 2307 | 2307 | 
| 2308   // Check if the allocation fits into the remaining space. | 2308   // Check if the allocation fits into the remaining space. | 
| 2309   // R0: potential new object start. | 2309   // R0: potential new object start. | 
| 2310   // R7: potential next object start. | 2310   // R7: potential next object start. | 
| 2311   __ LoadImmediate(R3, heap->EndAddress()); | 2311   __ LoadImmediate(R3, heap->EndAddress()); | 
| 2312   __ ldr(R3, Address(R3, 0)); | 2312   __ ldr(R3, Address(R3, 0)); | 
| 2313   __ cmp(R7, ShifterOperand(R3)); | 2313   __ cmp(R7, Operand(R3)); | 
| 2314   __ b(slow_path, CS); | 2314   __ b(slow_path, CS); | 
| 2315 | 2315 | 
| 2316   // Successfully allocated the object(s), now update top to point to | 2316   // Successfully allocated the object(s), now update top to point to | 
| 2317   // next object start and initialize the object. | 2317   // next object start and initialize the object. | 
| 2318   __ str(R7, Address(R6, 0)); | 2318   __ str(R7, Address(R6, 0)); | 
| 2319   __ add(R0, R0, ShifterOperand(kHeapObjectTag)); | 2319   __ add(R0, R0, Operand(kHeapObjectTag)); | 
| 2320   __ LoadImmediate(R8, heap->TopAddress()); | 2320   __ LoadImmediate(R8, heap->TopAddress()); | 
| 2321   __ UpdateAllocationStatsWithSize(kArrayCid, R8, R4); | 2321   __ UpdateAllocationStatsWithSize(kArrayCid, R8, R4); | 
| 2322 | 2322 | 
| 2323 | 2323 | 
| 2324   // Initialize the tags. | 2324   // Initialize the tags. | 
| 2325   // R0: new object start as a tagged pointer. | 2325   // R0: new object start as a tagged pointer. | 
| 2326   { | 2326   { | 
| 2327     uword tags = 0; | 2327     uword tags = 0; | 
| 2328     tags = RawObject::ClassIdTag::update(kArrayCid, tags); | 2328     tags = RawObject::ClassIdTag::update(kArrayCid, tags); | 
| 2329     tags = RawObject::SizeTag::update(kArraySize, tags); | 2329     tags = RawObject::SizeTag::update(kArraySize, tags); | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 2347   // R0: new object start as a tagged pointer. | 2347   // R0: new object start as a tagged pointer. | 
| 2348   // R7: new object end address. | 2348   // R7: new object end address. | 
| 2349   // R8: iterator which initially points to the start of the variable | 2349   // R8: iterator which initially points to the start of the variable | 
| 2350   // data area to be initialized. | 2350   // data area to be initialized. | 
| 2351   // R3: null | 2351   // R3: null | 
| 2352   __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | 2352   __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); | 
| 2353   __ AddImmediate(R8, R0, sizeof(RawArray) - kHeapObjectTag); | 2353   __ AddImmediate(R8, R0, sizeof(RawArray) - kHeapObjectTag); | 
| 2354 | 2354 | 
| 2355   Label init_loop; | 2355   Label init_loop; | 
| 2356   __ Bind(&init_loop); | 2356   __ Bind(&init_loop); | 
| 2357   __ cmp(R8, ShifterOperand(R7)); | 2357   __ cmp(R8, Operand(R7)); | 
| 2358   __ str(R3, Address(R8, 0), CC); | 2358   __ str(R3, Address(R8, 0), CC); | 
| 2359   __ AddImmediate(R8, kWordSize, CC); | 2359   __ AddImmediate(R8, kWordSize, CC); | 
| 2360   __ b(&init_loop, CC); | 2360   __ b(&init_loop, CC); | 
| 2361   __ b(done); | 2361   __ b(done); | 
| 2362 } | 2362 } | 
| 2363 | 2363 | 
| 2364 | 2364 | 
| 2365 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2365 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 2366   const Register kLengthReg = R2; | 2366   const Register kLengthReg = R2; | 
| 2367   const Register kElemTypeReg = R1; | 2367   const Register kElemTypeReg = R1; | 
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2446     const ExternalLabel label(stub.EntryPoint()); | 2446     const ExternalLabel label(stub.EntryPoint()); | 
| 2447 | 2447 | 
| 2448     LocationSummary* locs = instruction_->locs(); | 2448     LocationSummary* locs = instruction_->locs(); | 
| 2449     locs->live_registers()->Remove(locs->out(0)); | 2449     locs->live_registers()->Remove(locs->out(0)); | 
| 2450 | 2450 | 
| 2451     compiler->SaveLiveRegisters(locs); | 2451     compiler->SaveLiveRegisters(locs); | 
| 2452     compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position. | 2452     compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position. | 
| 2453                            &label, | 2453                            &label, | 
| 2454                            PcDescriptors::kOther, | 2454                            PcDescriptors::kOther, | 
| 2455                            locs); | 2455                            locs); | 
| 2456     __ mov(locs->out(0).reg(), ShifterOperand(R0)); | 2456     __ mov(locs->out(0).reg(), Operand(R0)); | 
| 2457     compiler->RestoreLiveRegisters(locs); | 2457     compiler->RestoreLiveRegisters(locs); | 
| 2458 | 2458 | 
| 2459     __ b(exit_label()); | 2459     __ b(exit_label()); | 
| 2460   } | 2460   } | 
| 2461 | 2461 | 
| 2462  private: | 2462  private: | 
| 2463   Instruction* instruction_; | 2463   Instruction* instruction_; | 
| 2464 }; | 2464 }; | 
| 2465 | 2465 | 
| 2466 | 2466 | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 2478     const ExternalLabel label(stub.EntryPoint()); | 2478     const ExternalLabel label(stub.EntryPoint()); | 
| 2479 | 2479 | 
| 2480     LocationSummary* locs = instruction_->locs(); | 2480     LocationSummary* locs = instruction_->locs(); | 
| 2481     locs->live_registers()->Remove(locs->out(0)); | 2481     locs->live_registers()->Remove(locs->out(0)); | 
| 2482 | 2482 | 
| 2483     compiler->SaveLiveRegisters(locs); | 2483     compiler->SaveLiveRegisters(locs); | 
| 2484     compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position. | 2484     compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position. | 
| 2485                            &label, | 2485                            &label, | 
| 2486                            PcDescriptors::kOther, | 2486                            PcDescriptors::kOther, | 
| 2487                            locs); | 2487                            locs); | 
| 2488     __ mov(locs->out(0).reg(), ShifterOperand(R0)); | 2488     __ mov(locs->out(0).reg(), Operand(R0)); | 
| 2489     compiler->RestoreLiveRegisters(locs); | 2489     compiler->RestoreLiveRegisters(locs); | 
| 2490 | 2490 | 
| 2491     __ b(exit_label()); | 2491     __ b(exit_label()); | 
| 2492   } | 2492   } | 
| 2493 | 2493 | 
| 2494  private: | 2494  private: | 
| 2495   Instruction* instruction_; | 2495   Instruction* instruction_; | 
| 2496 }; | 2496 }; | 
| 2497 | 2497 | 
| 2498 | 2498 | 
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2699   ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 2699   ASSERT(!type_arguments().IsUninstantiatedIdentity() && | 
| 2700          !type_arguments().CanShareInstantiatorTypeArguments( | 2700          !type_arguments().CanShareInstantiatorTypeArguments( | 
| 2701              instantiator_class())); | 2701              instantiator_class())); | 
| 2702   // If the instantiator is null and if the type argument vector | 2702   // If the instantiator is null and if the type argument vector | 
| 2703   // instantiated from null becomes a vector of dynamic, then use null as | 2703   // instantiated from null becomes a vector of dynamic, then use null as | 
| 2704   // the type arguments. | 2704   // the type arguments. | 
| 2705   Label type_arguments_instantiated; | 2705   Label type_arguments_instantiated; | 
| 2706   const intptr_t len = type_arguments().Length(); | 2706   const intptr_t len = type_arguments().Length(); | 
| 2707   if (type_arguments().IsRawInstantiatedRaw(len)) { | 2707   if (type_arguments().IsRawInstantiatedRaw(len)) { | 
| 2708     __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 2708     __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 
| 2709     __ cmp(instantiator_reg, ShifterOperand(IP)); | 2709     __ cmp(instantiator_reg, Operand(IP)); | 
| 2710     __ b(&type_arguments_instantiated, EQ); | 2710     __ b(&type_arguments_instantiated, EQ); | 
| 2711   } | 2711   } | 
| 2712 | 2712 | 
| 2713   __ LoadObject(R2, type_arguments()); | 2713   __ LoadObject(R2, type_arguments()); | 
| 2714   __ ldr(R2, FieldAddress(R2, TypeArguments::instantiations_offset())); | 2714   __ ldr(R2, FieldAddress(R2, TypeArguments::instantiations_offset())); | 
| 2715   __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag); | 2715   __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag); | 
| 2716   // The instantiations cache is initialized with Object::zero_array() and is | 2716   // The instantiations cache is initialized with Object::zero_array() and is | 
| 2717   // therefore guaranteed to contain kNoInstantiator. No length check needed. | 2717   // therefore guaranteed to contain kNoInstantiator. No length check needed. | 
| 2718   Label loop, found, slow_case; | 2718   Label loop, found, slow_case; | 
| 2719   __ Bind(&loop); | 2719   __ Bind(&loop); | 
| 2720   __ ldr(R1, Address(R2, 0 * kWordSize));  // Cached instantiator. | 2720   __ ldr(R1, Address(R2, 0 * kWordSize));  // Cached instantiator. | 
| 2721   __ cmp(R1, ShifterOperand(R0)); | 2721   __ cmp(R1, Operand(R0)); | 
| 2722   __ b(&found, EQ); | 2722   __ b(&found, EQ); | 
| 2723   __ AddImmediate(R2, 2 * kWordSize); | 2723   __ AddImmediate(R2, 2 * kWordSize); | 
| 2724   __ CompareImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator)); | 2724   __ CompareImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator)); | 
| 2725   __ b(&loop, NE); | 2725   __ b(&loop, NE); | 
| 2726   __ b(&slow_case); | 2726   __ b(&slow_case); | 
| 2727   __ Bind(&found); | 2727   __ Bind(&found); | 
| 2728   __ ldr(R0, Address(R2, 1 * kWordSize));  // Cached instantiated args. | 2728   __ ldr(R0, Address(R2, 1 * kWordSize));  // Cached instantiated args. | 
| 2729   __ b(&type_arguments_instantiated); | 2729   __ b(&type_arguments_instantiated); | 
| 2730 | 2730 | 
| 2731   __ Bind(&slow_case); | 2731   __ Bind(&slow_case); | 
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2899   Label osr_entry_label_; | 2899   Label osr_entry_label_; | 
| 2900 }; | 2900 }; | 
| 2901 | 2901 | 
| 2902 | 2902 | 
| 2903 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2903 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 2904   CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); | 2904   CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); | 
| 2905   compiler->AddSlowPathCode(slow_path); | 2905   compiler->AddSlowPathCode(slow_path); | 
| 2906 | 2906 | 
| 2907   __ LoadImmediate(IP, Isolate::Current()->stack_limit_address()); | 2907   __ LoadImmediate(IP, Isolate::Current()->stack_limit_address()); | 
| 2908   __ ldr(IP, Address(IP)); | 2908   __ ldr(IP, Address(IP)); | 
| 2909   __ cmp(SP, ShifterOperand(IP)); | 2909   __ cmp(SP, Operand(IP)); | 
| 2910   __ b(slow_path->entry_label(), LS); | 2910   __ b(slow_path->entry_label(), LS); | 
| 2911   if (compiler->CanOSRFunction() && in_loop()) { | 2911   if (compiler->CanOSRFunction() && in_loop()) { | 
| 2912     const Register temp = locs()->temp(0).reg(); | 2912     const Register temp = locs()->temp(0).reg(); | 
| 2913     // In unoptimized code check the usage counter to trigger OSR at loop | 2913     // In unoptimized code check the usage counter to trigger OSR at loop | 
| 2914     // stack checks.  Use progressively higher thresholds for more deeply | 2914     // stack checks.  Use progressively higher thresholds for more deeply | 
| 2915     // nested loops to attempt to hit outer loops with OSR when possible. | 2915     // nested loops to attempt to hit outer loops with OSR when possible. | 
| 2916     __ LoadObject(temp, compiler->parsed_function().function()); | 2916     __ LoadObject(temp, compiler->parsed_function().function()); | 
| 2917     intptr_t threshold = | 2917     intptr_t threshold = | 
| 2918         FLAG_optimization_counter_threshold * (loop_depth() + 1); | 2918         FLAG_optimization_counter_threshold * (loop_depth() + 1); | 
| 2919     __ ldr(temp, FieldAddress(temp, Function::usage_counter_offset())); | 2919     __ ldr(temp, FieldAddress(temp, Function::usage_counter_offset())); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 2941     ASSERT(constant.IsSmi()); | 2941     ASSERT(constant.IsSmi()); | 
| 2942     // Immediate shift operation takes 5 bits for the count. | 2942     // Immediate shift operation takes 5 bits for the count. | 
| 2943     const intptr_t kCountLimit = 0x1F; | 2943     const intptr_t kCountLimit = 0x1F; | 
| 2944     const intptr_t value = Smi::Cast(constant).Value(); | 2944     const intptr_t value = Smi::Cast(constant).Value(); | 
| 2945     if (value == 0) { | 2945     if (value == 0) { | 
| 2946       __ MoveRegister(result, left); | 2946       __ MoveRegister(result, left); | 
| 2947     } else if ((value < 0) || (value >= kCountLimit)) { | 2947     } else if ((value < 0) || (value >= kCountLimit)) { | 
| 2948       // This condition may not be known earlier in some cases because | 2948       // This condition may not be known earlier in some cases because | 
| 2949       // of constant propagation, inlining, etc. | 2949       // of constant propagation, inlining, etc. | 
| 2950       if ((value >= kCountLimit) && is_truncating) { | 2950       if ((value >= kCountLimit) && is_truncating) { | 
| 2951         __ mov(result, ShifterOperand(0)); | 2951         __ mov(result, Operand(0)); | 
| 2952       } else { | 2952       } else { | 
| 2953         // Result is Mint or exception. | 2953         // Result is Mint or exception. | 
| 2954         __ b(deopt); | 2954         __ b(deopt); | 
| 2955       } | 2955       } | 
| 2956     } else { | 2956     } else { | 
| 2957       if (!is_truncating) { | 2957       if (!is_truncating) { | 
| 2958         // Check for overflow (preserve left). | 2958         // Check for overflow (preserve left). | 
| 2959         __ Lsl(IP, left, value); | 2959         __ Lsl(IP, left, value); | 
| 2960         __ cmp(left, ShifterOperand(IP, ASR, value)); | 2960         __ cmp(left, Operand(IP, ASR, value)); | 
| 2961         __ b(deopt, NE);  // Overflow. | 2961         __ b(deopt, NE);  // Overflow. | 
| 2962       } | 2962       } | 
| 2963       // Shift for result now we know there is no overflow. | 2963       // Shift for result now we know there is no overflow. | 
| 2964       __ Lsl(result, left, value); | 2964       __ Lsl(result, left, value); | 
| 2965     } | 2965     } | 
| 2966     return; | 2966     return; | 
| 2967   } | 2967   } | 
| 2968 | 2968 | 
| 2969   // Right (locs.in(1)) is not constant. | 2969   // Right (locs.in(1)) is not constant. | 
| 2970   const Register right = locs.in(1).reg(); | 2970   const Register right = locs.in(1).reg(); | 
| 2971   Range* right_range = shift_left->right()->definition()->range(); | 2971   Range* right_range = shift_left->right()->definition()->range(); | 
| 2972   if (shift_left->left()->BindsToConstant() && !is_truncating) { | 2972   if (shift_left->left()->BindsToConstant() && !is_truncating) { | 
| 2973     // TODO(srdjan): Implement code below for is_truncating(). | 2973     // TODO(srdjan): Implement code below for is_truncating(). | 
| 2974     // If left is constant, we know the maximal allowed size for right. | 2974     // If left is constant, we know the maximal allowed size for right. | 
| 2975     const Object& obj = shift_left->left()->BoundConstant(); | 2975     const Object& obj = shift_left->left()->BoundConstant(); | 
| 2976     if (obj.IsSmi()) { | 2976     if (obj.IsSmi()) { | 
| 2977       const intptr_t left_int = Smi::Cast(obj).Value(); | 2977       const intptr_t left_int = Smi::Cast(obj).Value(); | 
| 2978       if (left_int == 0) { | 2978       if (left_int == 0) { | 
| 2979         __ cmp(right, ShifterOperand(0)); | 2979         __ cmp(right, Operand(0)); | 
| 2980         __ b(deopt, MI); | 2980         __ b(deopt, MI); | 
| 2981         __ mov(result, ShifterOperand(0)); | 2981         __ mov(result, Operand(0)); | 
| 2982         return; | 2982         return; | 
| 2983       } | 2983       } | 
| 2984       const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); | 2984       const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int); | 
| 2985       const bool right_needs_check = | 2985       const bool right_needs_check = | 
| 2986           (right_range == NULL) || | 2986           (right_range == NULL) || | 
| 2987           !right_range->IsWithin(0, max_right - 1); | 2987           !right_range->IsWithin(0, max_right - 1); | 
| 2988       if (right_needs_check) { | 2988       if (right_needs_check) { | 
| 2989         __ cmp(right, | 2989         __ cmp(right, Operand(reinterpret_cast<int32_t>(Smi::New(max_right)))); | 
| 2990                ShifterOperand(reinterpret_cast<int32_t>(Smi::New(max_right)))); |  | 
| 2991         __ b(deopt, CS); | 2990         __ b(deopt, CS); | 
| 2992       } | 2991       } | 
| 2993       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 2992       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 
| 2994       __ Lsl(result, left, IP); | 2993       __ Lsl(result, left, IP); | 
| 2995     } | 2994     } | 
| 2996     return; | 2995     return; | 
| 2997   } | 2996   } | 
| 2998 | 2997 | 
| 2999   const bool right_needs_check = | 2998   const bool right_needs_check = | 
| 3000       (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1)); | 2999       (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1)); | 
| 3001   if (is_truncating) { | 3000   if (is_truncating) { | 
| 3002     if (right_needs_check) { | 3001     if (right_needs_check) { | 
| 3003       const bool right_may_be_negative = | 3002       const bool right_may_be_negative = | 
| 3004           (right_range == NULL) || | 3003           (right_range == NULL) || | 
| 3005           !right_range->IsWithin(0, RangeBoundary::kPlusInfinity); | 3004           !right_range->IsWithin(0, RangeBoundary::kPlusInfinity); | 
| 3006       if (right_may_be_negative) { | 3005       if (right_may_be_negative) { | 
| 3007         ASSERT(shift_left->CanDeoptimize()); | 3006         ASSERT(shift_left->CanDeoptimize()); | 
| 3008         __ cmp(right, ShifterOperand(0)); | 3007         __ cmp(right, Operand(0)); | 
| 3009         __ b(deopt, MI); | 3008         __ b(deopt, MI); | 
| 3010       } | 3009       } | 
| 3011 | 3010 | 
| 3012       __ cmp(right, | 3011       __ cmp(right, Operand(reinterpret_cast<int32_t>(Smi::New(Smi::kBits)))); | 
| 3013              ShifterOperand(reinterpret_cast<int32_t>(Smi::New(Smi::kBits)))); | 3012       __ mov(result, Operand(0), CS); | 
| 3014       __ mov(result, ShifterOperand(0), CS); |  | 
| 3015       __ Asr(IP, right, kSmiTagSize, CC);  // SmiUntag right into IP if CC. | 3013       __ Asr(IP, right, kSmiTagSize, CC);  // SmiUntag right into IP if CC. | 
| 3016       __ Lsl(result, left, IP, CC); | 3014       __ Lsl(result, left, IP, CC); | 
| 3017     } else { | 3015     } else { | 
| 3018       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 3016       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 
| 3019       __ Lsl(result, left, IP); | 3017       __ Lsl(result, left, IP); | 
| 3020     } | 3018     } | 
| 3021   } else { | 3019   } else { | 
| 3022     if (right_needs_check) { | 3020     if (right_needs_check) { | 
| 3023       ASSERT(shift_left->CanDeoptimize()); | 3021       ASSERT(shift_left->CanDeoptimize()); | 
| 3024       __ cmp(right, | 3022       __ cmp(right, Operand(reinterpret_cast<int32_t>(Smi::New(Smi::kBits)))); | 
| 3025              ShifterOperand(reinterpret_cast<int32_t>(Smi::New(Smi::kBits)))); |  | 
| 3026       __ b(deopt, CS); | 3023       __ b(deopt, CS); | 
| 3027     } | 3024     } | 
| 3028     // Left is not a constant. | 3025     // Left is not a constant. | 
| 3029     // Check if count too large for handling it inlined. | 3026     // Check if count too large for handling it inlined. | 
| 3030     __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 3027     __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 
| 3031     // Overflow test (preserve left, right, and IP); | 3028     // Overflow test (preserve left, right, and IP); | 
| 3032     const Register temp = locs.temp(0).reg(); | 3029     const Register temp = locs.temp(0).reg(); | 
| 3033     __ Lsl(temp, left, IP); | 3030     __ Lsl(temp, left, IP); | 
| 3034     __ cmp(left, ShifterOperand(temp, ASR, IP)); | 3031     __ cmp(left, Operand(temp, ASR, IP)); | 
| 3035     __ b(deopt, NE);  // Overflow. | 3032     __ b(deopt, NE);  // Overflow. | 
| 3036     // Shift for result now we know there is no overflow. | 3033     // Shift for result now we know there is no overflow. | 
| 3037     __ Lsl(result, left, IP); | 3034     __ Lsl(result, left, IP); | 
| 3038   } | 3035   } | 
| 3039 } | 3036 } | 
| 3040 | 3037 | 
| 3041 | 3038 | 
| 3042 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 3039 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 
| 3043                                                        bool opt) const { | 3040                                                        bool opt) const { | 
| 3044   const intptr_t kNumInputs = 2; | 3041   const intptr_t kNumInputs = 2; | 
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3122           __ SubImmediateSetFlags(result, left, imm); | 3119           __ SubImmediateSetFlags(result, left, imm); | 
| 3123           __ b(deopt, VS); | 3120           __ b(deopt, VS); | 
| 3124         } | 3121         } | 
| 3125         break; | 3122         break; | 
| 3126       } | 3123       } | 
| 3127       case Token::kMUL: { | 3124       case Token::kMUL: { | 
| 3128         // Keep left value tagged and untag right value. | 3125         // Keep left value tagged and untag right value. | 
| 3129         const intptr_t value = Smi::Cast(constant).Value(); | 3126         const intptr_t value = Smi::Cast(constant).Value(); | 
| 3130         if (deopt == NULL) { | 3127         if (deopt == NULL) { | 
| 3131           if (value == 2) { | 3128           if (value == 2) { | 
| 3132             __ mov(result, ShifterOperand(left, LSL, 1)); | 3129             __ mov(result, Operand(left, LSL, 1)); | 
| 3133           } else { | 3130           } else { | 
| 3134             __ LoadImmediate(IP, value); | 3131             __ LoadImmediate(IP, value); | 
| 3135             __ mul(result, left, IP); | 3132             __ mul(result, left, IP); | 
| 3136           } | 3133           } | 
| 3137         } else { | 3134         } else { | 
| 3138           if (value == 2) { | 3135           if (value == 2) { | 
| 3139             __ mov(IP, ShifterOperand(left, ASR, 31));  // IP = sign of left. | 3136             __ mov(IP, Operand(left, ASR, 31));  // IP = sign of left. | 
| 3140             __ mov(result, ShifterOperand(left, LSL, 1)); | 3137             __ mov(result, Operand(left, LSL, 1)); | 
| 3141             // IP: result bits 32..63. | 3138             // IP: result bits 32..63. | 
| 3142             __ cmp(IP, ShifterOperand(result, ASR, 31)); | 3139             __ cmp(IP, Operand(result, ASR, 31)); | 
| 3143             __ b(deopt, NE); | 3140             __ b(deopt, NE); | 
| 3144           } else { | 3141           } else { | 
| 3145             if (TargetCPUFeatures::arm_version() == ARMv7) { | 3142             if (TargetCPUFeatures::arm_version() == ARMv7) { | 
| 3146               __ LoadImmediate(IP, value); | 3143               __ LoadImmediate(IP, value); | 
| 3147               __ smull(result, IP, left, IP); | 3144               __ smull(result, IP, left, IP); | 
| 3148               // IP: result bits 32..63. | 3145               // IP: result bits 32..63. | 
| 3149               __ cmp(IP, ShifterOperand(result, ASR, 31)); | 3146               __ cmp(IP, Operand(result, ASR, 31)); | 
| 3150               __ b(deopt, NE); | 3147               __ b(deopt, NE); | 
| 3151             } else { | 3148             } else { | 
| 3152               const QRegister qtmp = locs()->temp(0).fpu_reg(); | 3149               const QRegister qtmp = locs()->temp(0).fpu_reg(); | 
| 3153               const DRegister dtmp0 = EvenDRegisterOf(qtmp); | 3150               const DRegister dtmp0 = EvenDRegisterOf(qtmp); | 
| 3154               const DRegister dtmp1 = OddDRegisterOf(qtmp); | 3151               const DRegister dtmp1 = OddDRegisterOf(qtmp); | 
| 3155               __ LoadImmediate(IP, value); | 3152               __ LoadImmediate(IP, value); | 
| 3156               __ CheckMultSignedOverflow(left, IP, result, dtmp0, dtmp1, deopt); | 3153               __ CheckMultSignedOverflow(left, IP, result, dtmp0, dtmp1, deopt); | 
| 3157               __ mul(result, left, IP); | 3154               __ mul(result, left, IP); | 
| 3158             } | 3155             } | 
| 3159           } | 3156           } | 
| 3160         } | 3157         } | 
| 3161         break; | 3158         break; | 
| 3162       } | 3159       } | 
| 3163       case Token::kTRUNCDIV: { | 3160       case Token::kTRUNCDIV: { | 
| 3164         const intptr_t value = Smi::Cast(constant).Value(); | 3161         const intptr_t value = Smi::Cast(constant).Value(); | 
| 3165         if (value == 1) { | 3162         if (value == 1) { | 
| 3166           __ MoveRegister(result, left); | 3163           __ MoveRegister(result, left); | 
| 3167           break; | 3164           break; | 
| 3168         } else if (value == -1) { | 3165         } else if (value == -1) { | 
| 3169           // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 3166           // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 
| 3170           // case we cannot negate the result. | 3167           // case we cannot negate the result. | 
| 3171           __ CompareImmediate(left, 0x80000000); | 3168           __ CompareImmediate(left, 0x80000000); | 
| 3172           __ b(deopt, EQ); | 3169           __ b(deopt, EQ); | 
| 3173           __ rsb(result, left, ShifterOperand(0)); | 3170           __ rsb(result, left, Operand(0)); | 
| 3174           break; | 3171           break; | 
| 3175         } | 3172         } | 
| 3176         ASSERT(Utils::IsPowerOfTwo(Utils::Abs(value))); | 3173         ASSERT(Utils::IsPowerOfTwo(Utils::Abs(value))); | 
| 3177         const intptr_t shift_count = | 3174         const intptr_t shift_count = | 
| 3178             Utils::ShiftForPowerOfTwo(Utils::Abs(value)) + kSmiTagSize; | 3175             Utils::ShiftForPowerOfTwo(Utils::Abs(value)) + kSmiTagSize; | 
| 3179         ASSERT(kSmiTagSize == 1); | 3176         ASSERT(kSmiTagSize == 1); | 
| 3180         __ mov(IP, ShifterOperand(left, ASR, 31)); | 3177         __ mov(IP, Operand(left, ASR, 31)); | 
| 3181         ASSERT(shift_count > 1);  // 1, -1 case handled above. | 3178         ASSERT(shift_count > 1);  // 1, -1 case handled above. | 
| 3182         const Register temp = locs()->temp(0).reg(); | 3179         const Register temp = locs()->temp(0).reg(); | 
| 3183         __ add(temp, left, ShifterOperand(IP, LSR, 32 - shift_count)); | 3180         __ add(temp, left, Operand(IP, LSR, 32 - shift_count)); | 
| 3184         ASSERT(shift_count > 0); | 3181         ASSERT(shift_count > 0); | 
| 3185         __ mov(result, ShifterOperand(temp, ASR, shift_count)); | 3182         __ mov(result, Operand(temp, ASR, shift_count)); | 
| 3186         if (value < 0) { | 3183         if (value < 0) { | 
| 3187           __ rsb(result, result, ShifterOperand(0)); | 3184           __ rsb(result, result, Operand(0)); | 
| 3188         } | 3185         } | 
| 3189         __ SmiTag(result); | 3186         __ SmiTag(result); | 
| 3190         break; | 3187         break; | 
| 3191       } | 3188       } | 
| 3192       case Token::kBIT_AND: { | 3189       case Token::kBIT_AND: { | 
| 3193         // No overflow check. | 3190         // No overflow check. | 
| 3194         ShifterOperand shifter_op; | 3191         Operand o; | 
| 3195         if (ShifterOperand::CanHold(imm, &shifter_op)) { | 3192         if (Operand::CanHold(imm, &o)) { | 
| 3196           __ and_(result, left, shifter_op); | 3193           __ and_(result, left, o); | 
| 3197         } else if (ShifterOperand::CanHold(~imm, &shifter_op)) { | 3194         } else if (Operand::CanHold(~imm, &o)) { | 
| 3198           __ bic(result, left, shifter_op); | 3195           __ bic(result, left, o); | 
| 3199         } else { | 3196         } else { | 
| 3200           __ LoadImmediate(IP, imm); | 3197           __ LoadImmediate(IP, imm); | 
| 3201           __ and_(result, left, ShifterOperand(IP)); | 3198           __ and_(result, left, Operand(IP)); | 
| 3202         } | 3199         } | 
| 3203         break; | 3200         break; | 
| 3204       } | 3201       } | 
| 3205       case Token::kBIT_OR: { | 3202       case Token::kBIT_OR: { | 
| 3206         // No overflow check. | 3203         // No overflow check. | 
| 3207         ShifterOperand shifter_op; | 3204         Operand o; | 
| 3208         if (ShifterOperand::CanHold(imm, &shifter_op)) { | 3205         if (Operand::CanHold(imm, &o)) { | 
| 3209           __ orr(result, left, shifter_op); | 3206           __ orr(result, left, o); | 
| 3210         } else { | 3207         } else { | 
| 3211           __ LoadImmediate(IP, imm); | 3208           __ LoadImmediate(IP, imm); | 
| 3212           __ orr(result, left, ShifterOperand(IP)); | 3209           __ orr(result, left, Operand(IP)); | 
| 3213         } | 3210         } | 
| 3214         break; | 3211         break; | 
| 3215       } | 3212       } | 
| 3216       case Token::kBIT_XOR: { | 3213       case Token::kBIT_XOR: { | 
| 3217         // No overflow check. | 3214         // No overflow check. | 
| 3218         ShifterOperand shifter_op; | 3215         Operand o; | 
| 3219         if (ShifterOperand::CanHold(imm, &shifter_op)) { | 3216         if (Operand::CanHold(imm, &o)) { | 
| 3220           __ eor(result, left, shifter_op); | 3217           __ eor(result, left, o); | 
| 3221         } else { | 3218         } else { | 
| 3222           __ LoadImmediate(IP, imm); | 3219           __ LoadImmediate(IP, imm); | 
| 3223           __ eor(result, left, ShifterOperand(IP)); | 3220           __ eor(result, left, Operand(IP)); | 
| 3224         } | 3221         } | 
| 3225         break; | 3222         break; | 
| 3226       } | 3223       } | 
| 3227       case Token::kSHR: { | 3224       case Token::kSHR: { | 
| 3228         // sarl operation masks the count to 5 bits. | 3225         // sarl operation masks the count to 5 bits. | 
| 3229         const intptr_t kCountLimit = 0x1F; | 3226         const intptr_t kCountLimit = 0x1F; | 
| 3230         intptr_t value = Smi::Cast(constant).Value(); | 3227         intptr_t value = Smi::Cast(constant).Value(); | 
| 3231 | 3228 | 
| 3232         if (value == 0) { | 3229         if (value == 0) { | 
| 3233           // TODO(vegorov): should be handled outside. | 3230           // TODO(vegorov): should be handled outside. | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 3254         break; | 3251         break; | 
| 3255     } | 3252     } | 
| 3256     return; | 3253     return; | 
| 3257   } | 3254   } | 
| 3258 | 3255 | 
| 3259   const Register right = locs()->in(1).reg(); | 3256   const Register right = locs()->in(1).reg(); | 
| 3260   Range* right_range = this->right()->definition()->range(); | 3257   Range* right_range = this->right()->definition()->range(); | 
| 3261   switch (op_kind()) { | 3258   switch (op_kind()) { | 
| 3262     case Token::kADD: { | 3259     case Token::kADD: { | 
| 3263       if (deopt == NULL) { | 3260       if (deopt == NULL) { | 
| 3264         __ add(result, left, ShifterOperand(right)); | 3261         __ add(result, left, Operand(right)); | 
| 3265       } else { | 3262       } else { | 
| 3266         __ adds(result, left, ShifterOperand(right)); | 3263         __ adds(result, left, Operand(right)); | 
| 3267         __ b(deopt, VS); | 3264         __ b(deopt, VS); | 
| 3268       } | 3265       } | 
| 3269       break; | 3266       break; | 
| 3270     } | 3267     } | 
| 3271     case Token::kSUB: { | 3268     case Token::kSUB: { | 
| 3272       if (deopt == NULL) { | 3269       if (deopt == NULL) { | 
| 3273         __ sub(result, left, ShifterOperand(right)); | 3270         __ sub(result, left, Operand(right)); | 
| 3274       } else { | 3271       } else { | 
| 3275         __ subs(result, left, ShifterOperand(right)); | 3272         __ subs(result, left, Operand(right)); | 
| 3276         __ b(deopt, VS); | 3273         __ b(deopt, VS); | 
| 3277       } | 3274       } | 
| 3278       break; | 3275       break; | 
| 3279     } | 3276     } | 
| 3280     case Token::kMUL: { | 3277     case Token::kMUL: { | 
| 3281       __ Asr(IP, left, kSmiTagSize);  // SmiUntag left into IP. | 3278       __ Asr(IP, left, kSmiTagSize);  // SmiUntag left into IP. | 
| 3282       if (deopt == NULL) { | 3279       if (deopt == NULL) { | 
| 3283         __ mul(result, IP, right); | 3280         __ mul(result, IP, right); | 
| 3284       } else { | 3281       } else { | 
| 3285         if (TargetCPUFeatures::arm_version() == ARMv7) { | 3282         if (TargetCPUFeatures::arm_version() == ARMv7) { | 
| 3286           __ smull(result, IP, IP, right); | 3283           __ smull(result, IP, IP, right); | 
| 3287           // IP: result bits 32..63. | 3284           // IP: result bits 32..63. | 
| 3288           __ cmp(IP, ShifterOperand(result, ASR, 31)); | 3285           __ cmp(IP, Operand(result, ASR, 31)); | 
| 3289           __ b(deopt, NE); | 3286           __ b(deopt, NE); | 
| 3290         } else { | 3287         } else { | 
| 3291           const QRegister qtmp = locs()->temp(0).fpu_reg(); | 3288           const QRegister qtmp = locs()->temp(0).fpu_reg(); | 
| 3292           const DRegister dtmp0 = EvenDRegisterOf(qtmp); | 3289           const DRegister dtmp0 = EvenDRegisterOf(qtmp); | 
| 3293           const DRegister dtmp1 = OddDRegisterOf(qtmp); | 3290           const DRegister dtmp1 = OddDRegisterOf(qtmp); | 
| 3294           __ CheckMultSignedOverflow(IP, right, result, dtmp0, dtmp1, deopt); | 3291           __ CheckMultSignedOverflow(IP, right, result, dtmp0, dtmp1, deopt); | 
| 3295           __ mul(result, IP, right); | 3292           __ mul(result, IP, right); | 
| 3296         } | 3293         } | 
| 3297       } | 3294       } | 
| 3298       break; | 3295       break; | 
| 3299     } | 3296     } | 
| 3300     case Token::kBIT_AND: { | 3297     case Token::kBIT_AND: { | 
| 3301       // No overflow check. | 3298       // No overflow check. | 
| 3302       __ and_(result, left, ShifterOperand(right)); | 3299       __ and_(result, left, Operand(right)); | 
| 3303       break; | 3300       break; | 
| 3304     } | 3301     } | 
| 3305     case Token::kBIT_OR: { | 3302     case Token::kBIT_OR: { | 
| 3306       // No overflow check. | 3303       // No overflow check. | 
| 3307       __ orr(result, left, ShifterOperand(right)); | 3304       __ orr(result, left, Operand(right)); | 
| 3308       break; | 3305       break; | 
| 3309     } | 3306     } | 
| 3310     case Token::kBIT_XOR: { | 3307     case Token::kBIT_XOR: { | 
| 3311       // No overflow check. | 3308       // No overflow check. | 
| 3312       __ eor(result, left, ShifterOperand(right)); | 3309       __ eor(result, left, Operand(right)); | 
| 3313       break; | 3310       break; | 
| 3314     } | 3311     } | 
| 3315     case Token::kTRUNCDIV: { | 3312     case Token::kTRUNCDIV: { | 
| 3316       if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 3313       if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 
| 3317         // Handle divide by zero in runtime. | 3314         // Handle divide by zero in runtime. | 
| 3318         __ cmp(right, ShifterOperand(0)); | 3315         __ cmp(right, Operand(0)); | 
| 3319         __ b(deopt, EQ); | 3316         __ b(deopt, EQ); | 
| 3320       } | 3317       } | 
| 3321       const Register temp = locs()->temp(0).reg(); | 3318       const Register temp = locs()->temp(0).reg(); | 
| 3322       const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 3319       const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 
| 3323       __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp. | 3320       __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp. | 
| 3324       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 3321       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 
| 3325 | 3322 | 
| 3326       __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 3323       __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 
| 3327 | 3324 | 
| 3328       // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 3325       // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 
| 3329       // case we cannot tag the result. | 3326       // case we cannot tag the result. | 
| 3330       __ CompareImmediate(result, 0x40000000); | 3327       __ CompareImmediate(result, 0x40000000); | 
| 3331       __ b(deopt, EQ); | 3328       __ b(deopt, EQ); | 
| 3332       __ SmiTag(result); | 3329       __ SmiTag(result); | 
| 3333       break; | 3330       break; | 
| 3334     } | 3331     } | 
| 3335     case Token::kMOD: { | 3332     case Token::kMOD: { | 
| 3336       if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 3333       if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 
| 3337         // Handle divide by zero in runtime. | 3334         // Handle divide by zero in runtime. | 
| 3338         __ cmp(right, ShifterOperand(0)); | 3335         __ cmp(right, Operand(0)); | 
| 3339         __ b(deopt, EQ); | 3336         __ b(deopt, EQ); | 
| 3340       } | 3337       } | 
| 3341       const Register temp = locs()->temp(0).reg(); | 3338       const Register temp = locs()->temp(0).reg(); | 
| 3342       const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 3339       const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 
| 3343       __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp. | 3340       __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp. | 
| 3344       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 3341       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 
| 3345 | 3342 | 
| 3346       __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 3343       __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 
| 3347 | 3344 | 
| 3348       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 3345       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 
| 3349       __ mls(result, IP, result, temp);  // result <- left - right * result | 3346       __ mls(result, IP, result, temp);  // result <- left - right * result | 
| 3350       __ SmiTag(result); | 3347       __ SmiTag(result); | 
| 3351       //  res = left % right; | 3348       //  res = left % right; | 
| 3352       //  if (res < 0) { | 3349       //  if (res < 0) { | 
| 3353       //    if (right < 0) { | 3350       //    if (right < 0) { | 
| 3354       //      res = res - right; | 3351       //      res = res - right; | 
| 3355       //    } else { | 3352       //    } else { | 
| 3356       //      res = res + right; | 3353       //      res = res + right; | 
| 3357       //    } | 3354       //    } | 
| 3358       //  } | 3355       //  } | 
| 3359       Label done; | 3356       Label done; | 
| 3360       __ cmp(result, ShifterOperand(0)); | 3357       __ cmp(result, Operand(0)); | 
| 3361       __ b(&done, GE); | 3358       __ b(&done, GE); | 
| 3362       // Result is negative, adjust it. | 3359       // Result is negative, adjust it. | 
| 3363       __ cmp(right, ShifterOperand(0)); | 3360       __ cmp(right, Operand(0)); | 
| 3364       __ sub(result, result, ShifterOperand(right), LT); | 3361       __ sub(result, result, Operand(right), LT); | 
| 3365       __ add(result, result, ShifterOperand(right), GE); | 3362       __ add(result, result, Operand(right), GE); | 
| 3366       __ Bind(&done); | 3363       __ Bind(&done); | 
| 3367       break; | 3364       break; | 
| 3368     } | 3365     } | 
| 3369     case Token::kSHR: { | 3366     case Token::kSHR: { | 
| 3370       if (CanDeoptimize()) { | 3367       if (CanDeoptimize()) { | 
| 3371         __ CompareImmediate(right, 0); | 3368         __ CompareImmediate(right, 0); | 
| 3372         __ b(deopt, LT); | 3369         __ b(deopt, LT); | 
| 3373       } | 3370       } | 
| 3374       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 3371       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 
| 3375       // sarl operation masks the count to 5 bits. | 3372       // sarl operation masks the count to 5 bits. | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3421 | 3418 | 
| 3422 | 3419 | 
| 3423 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3420 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 3424   Label* deopt = compiler->AddDeoptStub(deopt_id(), | 3421   Label* deopt = compiler->AddDeoptStub(deopt_id(), | 
| 3425                                         ICData::kDeoptBinaryDoubleOp); | 3422                                         ICData::kDeoptBinaryDoubleOp); | 
| 3426   intptr_t left_cid = left()->Type()->ToCid(); | 3423   intptr_t left_cid = left()->Type()->ToCid(); | 
| 3427   intptr_t right_cid = right()->Type()->ToCid(); | 3424   intptr_t right_cid = right()->Type()->ToCid(); | 
| 3428   const Register left = locs()->in(0).reg(); | 3425   const Register left = locs()->in(0).reg(); | 
| 3429   const Register right = locs()->in(1).reg(); | 3426   const Register right = locs()->in(1).reg(); | 
| 3430   if (this->left()->definition() == this->right()->definition()) { | 3427   if (this->left()->definition() == this->right()->definition()) { | 
| 3431     __ tst(left, ShifterOperand(kSmiTagMask)); | 3428     __ tst(left, Operand(kSmiTagMask)); | 
| 3432   } else if (left_cid == kSmiCid) { | 3429   } else if (left_cid == kSmiCid) { | 
| 3433     __ tst(right, ShifterOperand(kSmiTagMask)); | 3430     __ tst(right, Operand(kSmiTagMask)); | 
| 3434   } else if (right_cid == kSmiCid) { | 3431   } else if (right_cid == kSmiCid) { | 
| 3435     __ tst(left, ShifterOperand(kSmiTagMask)); | 3432     __ tst(left, Operand(kSmiTagMask)); | 
| 3436   } else { | 3433   } else { | 
| 3437     __ orr(IP, left, ShifterOperand(right)); | 3434     __ orr(IP, left, Operand(right)); | 
| 3438     __ tst(IP, ShifterOperand(kSmiTagMask)); | 3435     __ tst(IP, Operand(kSmiTagMask)); | 
| 3439   } | 3436   } | 
| 3440   __ b(deopt, EQ); | 3437   __ b(deopt, EQ); | 
| 3441 } | 3438 } | 
| 3442 | 3439 | 
| 3443 | 3440 | 
| 3444 LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 3441 LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 
| 3445                                                      bool opt) const { | 3442                                                      bool opt) const { | 
| 3446   const intptr_t kNumInputs = 1; | 3443   const intptr_t kNumInputs = 1; | 
| 3447   const intptr_t kNumTemps = 1; | 3444   const intptr_t kNumTemps = 1; | 
| 3448   LocationSummary* summary = new(isolate) LocationSummary( | 3445   LocationSummary* summary = new(isolate) LocationSummary( | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3508     const Register temp = locs()->temp(0).reg(); | 3505     const Register temp = locs()->temp(0).reg(); | 
| 3509     if (value_type->is_nullable() && | 3506     if (value_type->is_nullable() && | 
| 3510         (value_type->ToNullableCid() == kDoubleCid)) { | 3507         (value_type->ToNullableCid() == kDoubleCid)) { | 
| 3511       __ CompareImmediate(value, reinterpret_cast<intptr_t>(Object::null())); | 3508       __ CompareImmediate(value, reinterpret_cast<intptr_t>(Object::null())); | 
| 3512       __ b(deopt, EQ); | 3509       __ b(deopt, EQ); | 
| 3513       // It must be double now. | 3510       // It must be double now. | 
| 3514       __ LoadDFromOffset(result, value, | 3511       __ LoadDFromOffset(result, value, | 
| 3515           Double::value_offset() - kHeapObjectTag); | 3512           Double::value_offset() - kHeapObjectTag); | 
| 3516     } else { | 3513     } else { | 
| 3517       Label is_smi, done; | 3514       Label is_smi, done; | 
| 3518       __ tst(value, ShifterOperand(kSmiTagMask)); | 3515       __ tst(value, Operand(kSmiTagMask)); | 
| 3519       __ b(&is_smi, EQ); | 3516       __ b(&is_smi, EQ); | 
| 3520       __ CompareClassId(value, kDoubleCid, temp); | 3517       __ CompareClassId(value, kDoubleCid, temp); | 
| 3521       __ b(deopt, NE); | 3518       __ b(deopt, NE); | 
| 3522       __ LoadDFromOffset(result, value, | 3519       __ LoadDFromOffset(result, value, | 
| 3523           Double::value_offset() - kHeapObjectTag); | 3520           Double::value_offset() - kHeapObjectTag); | 
| 3524       __ b(&done); | 3521       __ b(&done); | 
| 3525       __ Bind(&is_smi); | 3522       __ Bind(&is_smi); | 
| 3526       // TODO(regis): Why do we preserve value here but not above? | 3523       // TODO(regis): Why do we preserve value here but not above? | 
| 3527       __ mov(IP, ShifterOperand(value, ASR, 1));  // Copy and untag. | 3524       __ mov(IP, Operand(value, ASR, 1));  // Copy and untag. | 
| 3528       __ vmovsr(STMP, IP); | 3525       __ vmovsr(STMP, IP); | 
| 3529       __ vcvtdi(result, STMP); | 3526       __ vcvtdi(result, STMP); | 
| 3530       __ Bind(&done); | 3527       __ Bind(&done); | 
| 3531     } | 3528     } | 
| 3532   } | 3529   } | 
| 3533 } | 3530 } | 
| 3534 | 3531 | 
| 3535 | 3532 | 
| 3536 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 3533 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 
| 3537                                                         bool opt) const { | 3534                                                         bool opt) const { | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3585 | 3582 | 
| 3586 | 3583 | 
| 3587 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3584 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 3588   const intptr_t value_cid = value()->Type()->ToCid(); | 3585   const intptr_t value_cid = value()->Type()->ToCid(); | 
| 3589   const Register value = locs()->in(0).reg(); | 3586   const Register value = locs()->in(0).reg(); | 
| 3590   const QRegister result = locs()->out(0).fpu_reg(); | 3587   const QRegister result = locs()->out(0).fpu_reg(); | 
| 3591 | 3588 | 
| 3592   if (value_cid != kFloat32x4Cid) { | 3589   if (value_cid != kFloat32x4Cid) { | 
| 3593     const Register temp = locs()->temp(0).reg(); | 3590     const Register temp = locs()->temp(0).reg(); | 
| 3594     Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); | 3591     Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); | 
| 3595     __ tst(value, ShifterOperand(kSmiTagMask)); | 3592     __ tst(value, Operand(kSmiTagMask)); | 
| 3596     __ b(deopt, EQ); | 3593     __ b(deopt, EQ); | 
| 3597     __ CompareClassId(value, kFloat32x4Cid, temp); | 3594     __ CompareClassId(value, kFloat32x4Cid, temp); | 
| 3598     __ b(deopt, NE); | 3595     __ b(deopt, NE); | 
| 3599   } | 3596   } | 
| 3600 | 3597 | 
| 3601   const DRegister dresult0 = EvenDRegisterOf(result); | 3598   const DRegister dresult0 = EvenDRegisterOf(result); | 
| 3602   __ LoadMultipleDFromOffset(dresult0, 2, value, | 3599   __ LoadMultipleDFromOffset(dresult0, 2, value, | 
| 3603       Float32x4::value_offset() - kHeapObjectTag); | 3600       Float32x4::value_offset() - kHeapObjectTag); | 
| 3604 } | 3601 } | 
| 3605 | 3602 | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3656 | 3653 | 
| 3657 | 3654 | 
| 3658 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3655 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 3659   const intptr_t value_cid = value()->Type()->ToCid(); | 3656   const intptr_t value_cid = value()->Type()->ToCid(); | 
| 3660   const Register value = locs()->in(0).reg(); | 3657   const Register value = locs()->in(0).reg(); | 
| 3661   const QRegister result = locs()->out(0).fpu_reg(); | 3658   const QRegister result = locs()->out(0).fpu_reg(); | 
| 3662 | 3659 | 
| 3663   if (value_cid != kFloat64x2Cid) { | 3660   if (value_cid != kFloat64x2Cid) { | 
| 3664     const Register temp = locs()->temp(0).reg(); | 3661     const Register temp = locs()->temp(0).reg(); | 
| 3665     Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); | 3662     Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); | 
| 3666     __ tst(value, ShifterOperand(kSmiTagMask)); | 3663     __ tst(value, Operand(kSmiTagMask)); | 
| 3667     __ b(deopt, EQ); | 3664     __ b(deopt, EQ); | 
| 3668     __ CompareClassId(value, kFloat64x2Cid, temp); | 3665     __ CompareClassId(value, kFloat64x2Cid, temp); | 
| 3669     __ b(deopt, NE); | 3666     __ b(deopt, NE); | 
| 3670   } | 3667   } | 
| 3671 | 3668 | 
| 3672   const DRegister dresult0 = EvenDRegisterOf(result); | 3669   const DRegister dresult0 = EvenDRegisterOf(result); | 
| 3673   __ LoadMultipleDFromOffset(dresult0, 2, value, | 3670   __ LoadMultipleDFromOffset(dresult0, 2, value, | 
| 3674       Float64x2::value_offset() - kHeapObjectTag); | 3671       Float64x2::value_offset() - kHeapObjectTag); | 
| 3675 } | 3672 } | 
| 3676 | 3673 | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 3704     const ExternalLabel label(stub.EntryPoint()); | 3701     const ExternalLabel label(stub.EntryPoint()); | 
| 3705 | 3702 | 
| 3706     LocationSummary* locs = instruction_->locs(); | 3703     LocationSummary* locs = instruction_->locs(); | 
| 3707     locs->live_registers()->Remove(locs->out(0)); | 3704     locs->live_registers()->Remove(locs->out(0)); | 
| 3708 | 3705 | 
| 3709     compiler->SaveLiveRegisters(locs); | 3706     compiler->SaveLiveRegisters(locs); | 
| 3710     compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position. | 3707     compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position. | 
| 3711                            &label, | 3708                            &label, | 
| 3712                            PcDescriptors::kOther, | 3709                            PcDescriptors::kOther, | 
| 3713                            locs); | 3710                            locs); | 
| 3714     __ mov(locs->out(0).reg(), ShifterOperand(R0)); | 3711     __ mov(locs->out(0).reg(), Operand(R0)); | 
| 3715     compiler->RestoreLiveRegisters(locs); | 3712     compiler->RestoreLiveRegisters(locs); | 
| 3716 | 3713 | 
| 3717     __ b(exit_label()); | 3714     __ b(exit_label()); | 
| 3718   } | 3715   } | 
| 3719 | 3716 | 
| 3720  private: | 3717  private: | 
| 3721   BoxInt32x4Instr* instruction_; | 3718   BoxInt32x4Instr* instruction_; | 
| 3722 }; | 3719 }; | 
| 3723 | 3720 | 
| 3724 | 3721 | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3758 | 3755 | 
| 3759 | 3756 | 
| 3760 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3757 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 3761   const intptr_t value_cid = value()->Type()->ToCid(); | 3758   const intptr_t value_cid = value()->Type()->ToCid(); | 
| 3762   const Register value = locs()->in(0).reg(); | 3759   const Register value = locs()->in(0).reg(); | 
| 3763   const QRegister result = locs()->out(0).fpu_reg(); | 3760   const QRegister result = locs()->out(0).fpu_reg(); | 
| 3764 | 3761 | 
| 3765   if (value_cid != kInt32x4Cid) { | 3762   if (value_cid != kInt32x4Cid) { | 
| 3766     const Register temp = locs()->temp(0).reg(); | 3763     const Register temp = locs()->temp(0).reg(); | 
| 3767     Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); | 3764     Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); | 
| 3768     __ tst(value, ShifterOperand(kSmiTagMask)); | 3765     __ tst(value, Operand(kSmiTagMask)); | 
| 3769     __ b(deopt, EQ); | 3766     __ b(deopt, EQ); | 
| 3770     __ CompareClassId(value, kInt32x4Cid, temp); | 3767     __ CompareClassId(value, kInt32x4Cid, temp); | 
| 3771     __ b(deopt, NE); | 3768     __ b(deopt, NE); | 
| 3772   } | 3769   } | 
| 3773 | 3770 | 
| 3774   const DRegister dresult0 = EvenDRegisterOf(result); | 3771   const DRegister dresult0 = EvenDRegisterOf(result); | 
| 3775   __ LoadMultipleDFromOffset(dresult0, 2, value, | 3772   __ LoadMultipleDFromOffset(dresult0, 2, value, | 
| 3776       Int32x4::value_offset() - kHeapObjectTag); | 3773       Int32x4::value_offset() - kHeapObjectTag); | 
| 3777 } | 3774 } | 
| 3778 | 3775 | 
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4039 | 4036 | 
| 4040   const Register out = locs()->out(0).reg(); | 4037   const Register out = locs()->out(0).reg(); | 
| 4041   const Register temp = locs()->temp(0).reg(); | 4038   const Register temp = locs()->temp(0).reg(); | 
| 4042 | 4039 | 
| 4043   // X lane. | 4040   // X lane. | 
| 4044   __ vmovrs(out, EvenSRegisterOf(dvalue0)); | 4041   __ vmovrs(out, EvenSRegisterOf(dvalue0)); | 
| 4045   __ Lsr(out, out, 31); | 4042   __ Lsr(out, out, 31); | 
| 4046   // Y lane. | 4043   // Y lane. | 
| 4047   __ vmovrs(temp, OddSRegisterOf(dvalue0)); | 4044   __ vmovrs(temp, OddSRegisterOf(dvalue0)); | 
| 4048   __ Lsr(temp, temp, 31); | 4045   __ Lsr(temp, temp, 31); | 
| 4049   __ orr(out, out, ShifterOperand(temp, LSL, 1)); | 4046   __ orr(out, out, Operand(temp, LSL, 1)); | 
| 4050   // Z lane. | 4047   // Z lane. | 
| 4051   __ vmovrs(temp, EvenSRegisterOf(dvalue1)); | 4048   __ vmovrs(temp, EvenSRegisterOf(dvalue1)); | 
| 4052   __ Lsr(temp, temp, 31); | 4049   __ Lsr(temp, temp, 31); | 
| 4053   __ orr(out, out, ShifterOperand(temp, LSL, 2)); | 4050   __ orr(out, out, Operand(temp, LSL, 2)); | 
| 4054   // W lane. | 4051   // W lane. | 
| 4055   __ vmovrs(temp, OddSRegisterOf(dvalue1)); | 4052   __ vmovrs(temp, OddSRegisterOf(dvalue1)); | 
| 4056   __ Lsr(temp, temp, 31); | 4053   __ Lsr(temp, temp, 31); | 
| 4057   __ orr(out, out, ShifterOperand(temp, LSL, 3)); | 4054   __ orr(out, out, Operand(temp, LSL, 3)); | 
| 4058   // Tag. | 4055   // Tag. | 
| 4059   __ SmiTag(out); | 4056   __ SmiTag(out); | 
| 4060 } | 4057 } | 
| 4061 | 4058 | 
| 4062 | 4059 | 
| 4063 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( | 4060 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( | 
| 4064     Isolate* isolate, bool opt) const { | 4061     Isolate* isolate, bool opt) const { | 
| 4065   const intptr_t kNumInputs = 4; | 4062   const intptr_t kNumInputs = 4; | 
| 4066   const intptr_t kNumTemps = 0; | 4063   const intptr_t kNumTemps = 0; | 
| 4067   LocationSummary* summary = new(isolate) LocationSummary( | 4064   LocationSummary* summary = new(isolate) LocationSummary( | 
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4592     const DRegister dvalue1 = OddDRegisterOf(q); | 4589     const DRegister dvalue1 = OddDRegisterOf(q); | 
| 4593 | 4590 | 
| 4594     const Register out = locs()->out(0).reg(); | 4591     const Register out = locs()->out(0).reg(); | 
| 4595 | 4592 | 
| 4596     // Upper 32-bits of X lane. | 4593     // Upper 32-bits of X lane. | 
| 4597     __ vmovrs(out, OddSRegisterOf(dvalue0)); | 4594     __ vmovrs(out, OddSRegisterOf(dvalue0)); | 
| 4598     __ Lsr(out, out, 31); | 4595     __ Lsr(out, out, 31); | 
| 4599     // Upper 32-bits of Y lane. | 4596     // Upper 32-bits of Y lane. | 
| 4600     __ vmovrs(TMP, OddSRegisterOf(dvalue1)); | 4597     __ vmovrs(TMP, OddSRegisterOf(dvalue1)); | 
| 4601     __ Lsr(TMP, TMP, 31); | 4598     __ Lsr(TMP, TMP, 31); | 
| 4602     __ orr(out, out, ShifterOperand(TMP, LSL, 1)); | 4599     __ orr(out, out, Operand(TMP, LSL, 1)); | 
| 4603     // Tag. | 4600     // Tag. | 
| 4604     __ SmiTag(out); | 4601     __ SmiTag(out); | 
| 4605     return; | 4602     return; | 
| 4606   } | 4603   } | 
| 4607   ASSERT(representation() == kUnboxedFloat64x2); | 4604   ASSERT(representation() == kUnboxedFloat64x2); | 
| 4608   const QRegister r = locs()->out(0).fpu_reg(); | 4605   const QRegister r = locs()->out(0).fpu_reg(); | 
| 4609 | 4606 | 
| 4610   const DRegister dvalue0 = EvenDRegisterOf(q); | 4607   const DRegister dvalue0 = EvenDRegisterOf(q); | 
| 4611   const DRegister dvalue1 = OddDRegisterOf(q); | 4608   const DRegister dvalue1 = OddDRegisterOf(q); | 
| 4612   const DRegister dresult0 = EvenDRegisterOf(r); | 4609   const DRegister dresult0 = EvenDRegisterOf(r); | 
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4784       break; | 4781       break; | 
| 4785     case MethodRecognizer::kInt32x4GetFlagZ: | 4782     case MethodRecognizer::kInt32x4GetFlagZ: | 
| 4786       __ vmovrs(result, svalue2); | 4783       __ vmovrs(result, svalue2); | 
| 4787       break; | 4784       break; | 
| 4788     case MethodRecognizer::kInt32x4GetFlagW: | 4785     case MethodRecognizer::kInt32x4GetFlagW: | 
| 4789       __ vmovrs(result, svalue3); | 4786       __ vmovrs(result, svalue3); | 
| 4790       break; | 4787       break; | 
| 4791     default: UNREACHABLE(); | 4788     default: UNREACHABLE(); | 
| 4792   } | 4789   } | 
| 4793 | 4790 | 
| 4794   __ tst(result, ShifterOperand(result)); | 4791   __ tst(result, Operand(result)); | 
| 4795   __ LoadObject(result, Bool::True(), NE); | 4792   __ LoadObject(result, Bool::True(), NE); | 
| 4796   __ LoadObject(result, Bool::False(), EQ); | 4793   __ LoadObject(result, Bool::False(), EQ); | 
| 4797 } | 4794 } | 
| 4798 | 4795 | 
| 4799 | 4796 | 
| 4800 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(Isolate* isolate, | 4797 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(Isolate* isolate, | 
| 4801                                                          bool opt) const { | 4798                                                          bool opt) const { | 
| 4802   const intptr_t kNumInputs = 3; | 4799   const intptr_t kNumInputs = 3; | 
| 4803   const intptr_t kNumTemps = 1; | 4800   const intptr_t kNumTemps = 1; | 
| 4804   LocationSummary* summary = new(isolate) LocationSummary( | 4801   LocationSummary* summary = new(isolate) LocationSummary( | 
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5043     __ b(&done); | 5040     __ b(&done); | 
| 5044 | 5041 | 
| 5045     __ Bind(&are_equal); | 5042     __ Bind(&are_equal); | 
| 5046     // Check for negative zero: -0.0 is equal 0.0 but min or max must return | 5043     // Check for negative zero: -0.0 is equal 0.0 but min or max must return | 
| 5047     // -0.0 or 0.0 respectively. | 5044     // -0.0 or 0.0 respectively. | 
| 5048     // Check for negative left value (get the sign bit): | 5045     // Check for negative left value (get the sign bit): | 
| 5049     // - min -> left is negative ? left : right. | 5046     // - min -> left is negative ? left : right. | 
| 5050     // - max -> left is negative ? right : left | 5047     // - max -> left is negative ? right : left | 
| 5051     // Check the sign bit. | 5048     // Check the sign bit. | 
| 5052     __ vmovrrd(IP, temp, left);  // Sign bit is in bit 31 of temp. | 5049     __ vmovrrd(IP, temp, left);  // Sign bit is in bit 31 of temp. | 
| 5053     __ cmp(temp, ShifterOperand(0)); | 5050     __ cmp(temp, Operand(0)); | 
| 5054     if (is_min) { | 5051     if (is_min) { | 
| 5055       ASSERT(left == result); | 5052       ASSERT(left == result); | 
| 5056       __ vmovd(result, right, GE); | 5053       __ vmovd(result, right, GE); | 
| 5057     } else { | 5054     } else { | 
| 5058       __ vmovd(result, right, LT); | 5055       __ vmovd(result, right, LT); | 
| 5059       ASSERT(left == result); | 5056       ASSERT(left == result); | 
| 5060     } | 5057     } | 
| 5061     __ Bind(&done); | 5058     __ Bind(&done); | 
| 5062     return; | 5059     return; | 
| 5063   } | 5060   } | 
| 5064 | 5061 | 
| 5065   ASSERT(result_cid() == kSmiCid); | 5062   ASSERT(result_cid() == kSmiCid); | 
| 5066   const Register left = locs()->in(0).reg(); | 5063   const Register left = locs()->in(0).reg(); | 
| 5067   const Register right = locs()->in(1).reg(); | 5064   const Register right = locs()->in(1).reg(); | 
| 5068   const Register result = locs()->out(0).reg(); | 5065   const Register result = locs()->out(0).reg(); | 
| 5069   __ cmp(left, ShifterOperand(right)); | 5066   __ cmp(left, Operand(right)); | 
| 5070   ASSERT(result == left); | 5067   ASSERT(result == left); | 
| 5071   if (is_min) { | 5068   if (is_min) { | 
| 5072     __ mov(result, ShifterOperand(right), GT); | 5069     __ mov(result, Operand(right), GT); | 
| 5073   } else { | 5070   } else { | 
| 5074     __ mov(result, ShifterOperand(right), LT); | 5071     __ mov(result, Operand(right), LT); | 
| 5075   } | 5072   } | 
| 5076 } | 5073 } | 
| 5077 | 5074 | 
| 5078 | 5075 | 
| 5079 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 5076 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 
| 5080                                                       bool opt) const { | 5077                                                       bool opt) const { | 
| 5081   const intptr_t kNumInputs = 1; | 5078   const intptr_t kNumInputs = 1; | 
| 5082   const intptr_t kNumTemps = 0; | 5079   const intptr_t kNumTemps = 0; | 
| 5083   LocationSummary* summary = new(isolate) LocationSummary( | 5080   LocationSummary* summary = new(isolate) LocationSummary( | 
| 5084       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5081       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 
| 5085   summary->set_in(0, Location::RequiresRegister()); | 5082   summary->set_in(0, Location::RequiresRegister()); | 
| 5086   // We make use of 3-operand instructions by not requiring result register | 5083   // We make use of 3-operand instructions by not requiring result register | 
| 5087   // to be identical to first input register as on Intel. | 5084   // to be identical to first input register as on Intel. | 
| 5088   summary->set_out(0, Location::RequiresRegister()); | 5085   summary->set_out(0, Location::RequiresRegister()); | 
| 5089   return summary; | 5086   return summary; | 
| 5090 } | 5087 } | 
| 5091 | 5088 | 
| 5092 | 5089 | 
| 5093 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5090 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 5094   const Register value = locs()->in(0).reg(); | 5091   const Register value = locs()->in(0).reg(); | 
| 5095   const Register result = locs()->out(0).reg(); | 5092   const Register result = locs()->out(0).reg(); | 
| 5096   switch (op_kind()) { | 5093   switch (op_kind()) { | 
| 5097     case Token::kNEGATE: { | 5094     case Token::kNEGATE: { | 
| 5098       Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp); | 5095       Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp); | 
| 5099       __ rsbs(result, value, ShifterOperand(0)); | 5096       __ rsbs(result, value, Operand(0)); | 
| 5100       __ b(deopt, VS); | 5097       __ b(deopt, VS); | 
| 5101       break; | 5098       break; | 
| 5102     } | 5099     } | 
| 5103     case Token::kBIT_NOT: | 5100     case Token::kBIT_NOT: | 
| 5104       __ mvn(result, ShifterOperand(value)); | 5101       __ mvn(result, Operand(value)); | 
| 5105       // Remove inverted smi-tag. | 5102       // Remove inverted smi-tag. | 
| 5106       __ bic(result, result, ShifterOperand(kSmiTagMask)); | 5103       __ bic(result, result, Operand(kSmiTagMask)); | 
| 5107       break; | 5104       break; | 
| 5108     default: | 5105     default: | 
| 5109       UNREACHABLE(); | 5106       UNREACHABLE(); | 
| 5110   } | 5107   } | 
| 5111 } | 5108 } | 
| 5112 | 5109 | 
| 5113 | 5110 | 
| 5114 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, | 5111 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, | 
| 5115                                                          bool opt) const { | 5112                                                          bool opt) const { | 
| 5116   const intptr_t kNumInputs = 1; | 5113   const intptr_t kNumInputs = 1; | 
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5511   PairLocation* pair = locs()->in(0).AsPairLocation(); | 5508   PairLocation* pair = locs()->in(0).AsPairLocation(); | 
| 5512   Location in_loc = pair->At(index()); | 5509   Location in_loc = pair->At(index()); | 
| 5513   if (representation() == kUnboxedDouble) { | 5510   if (representation() == kUnboxedDouble) { | 
| 5514     const QRegister out = locs()->out(0).fpu_reg(); | 5511     const QRegister out = locs()->out(0).fpu_reg(); | 
| 5515     const QRegister in = in_loc.fpu_reg(); | 5512     const QRegister in = in_loc.fpu_reg(); | 
| 5516     __ vmovq(out, in); | 5513     __ vmovq(out, in); | 
| 5517   } else { | 5514   } else { | 
| 5518     ASSERT(representation() == kTagged); | 5515     ASSERT(representation() == kTagged); | 
| 5519     const Register out = locs()->out(0).reg(); | 5516     const Register out = locs()->out(0).reg(); | 
| 5520     const Register in = in_loc.reg(); | 5517     const Register in = in_loc.reg(); | 
| 5521     __ mov(out, ShifterOperand(in)); | 5518     __ mov(out, Operand(in)); | 
| 5522   } | 5519   } | 
| 5523 } | 5520 } | 
| 5524 | 5521 | 
| 5525 | 5522 | 
| 5526 LocationSummary* MergedMathInstr::MakeLocationSummary(Isolate* isolate, | 5523 LocationSummary* MergedMathInstr::MakeLocationSummary(Isolate* isolate, | 
| 5527                                                       bool opt) const { | 5524                                                       bool opt) const { | 
| 5528   if (kind() == MergedMathInstr::kTruncDivMod) { | 5525   if (kind() == MergedMathInstr::kTruncDivMod) { | 
| 5529     const intptr_t kNumInputs = 2; | 5526     const intptr_t kNumInputs = 2; | 
| 5530     const intptr_t kNumTemps = 2; | 5527     const intptr_t kNumTemps = 2; | 
| 5531     LocationSummary* summary = new(isolate) LocationSummary( | 5528     LocationSummary* summary = new(isolate) LocationSummary( | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 5552   if (kind() == MergedMathInstr::kTruncDivMod) { | 5549   if (kind() == MergedMathInstr::kTruncDivMod) { | 
| 5553     const Register left = locs()->in(0).reg(); | 5550     const Register left = locs()->in(0).reg(); | 
| 5554     const Register right = locs()->in(1).reg(); | 5551     const Register right = locs()->in(1).reg(); | 
| 5555     ASSERT(locs()->out(0).IsPairLocation()); | 5552     ASSERT(locs()->out(0).IsPairLocation()); | 
| 5556     PairLocation* pair = locs()->out(0).AsPairLocation(); | 5553     PairLocation* pair = locs()->out(0).AsPairLocation(); | 
| 5557     const Register result_div = pair->At(0).reg(); | 5554     const Register result_div = pair->At(0).reg(); | 
| 5558     const Register result_mod = pair->At(1).reg(); | 5555     const Register result_mod = pair->At(1).reg(); | 
| 5559     Range* right_range = InputAt(1)->definition()->range(); | 5556     Range* right_range = InputAt(1)->definition()->range(); | 
| 5560     if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 5557     if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 
| 5561       // Handle divide by zero in runtime. | 5558       // Handle divide by zero in runtime. | 
| 5562       __ cmp(right, ShifterOperand(0)); | 5559       __ cmp(right, Operand(0)); | 
| 5563       __ b(deopt, EQ); | 5560       __ b(deopt, EQ); | 
| 5564     } | 5561     } | 
| 5565     const Register temp = locs()->temp(0).reg(); | 5562     const Register temp = locs()->temp(0).reg(); | 
| 5566     const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 5563     const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 
| 5567 | 5564 | 
| 5568     __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp. | 5565     __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp. | 
| 5569     __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 5566     __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 
| 5570 | 5567 | 
| 5571     __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); | 5568     __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); | 
| 5572 | 5569 | 
| 5573     // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 5570     // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 
| 5574     // case we cannot tag the result. | 5571     // case we cannot tag the result. | 
| 5575     __ CompareImmediate(result_div, 0x40000000); | 5572     __ CompareImmediate(result_div, 0x40000000); | 
| 5576     __ b(deopt, EQ); | 5573     __ b(deopt, EQ); | 
| 5577     __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 5574     __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP. | 
| 5578     // result_mod <- left - right * result_div. | 5575     // result_mod <- left - right * result_div. | 
| 5579     __ mls(result_mod, IP, result_div, temp); | 5576     __ mls(result_mod, IP, result_div, temp); | 
| 5580     __ SmiTag(result_div); | 5577     __ SmiTag(result_div); | 
| 5581     __ SmiTag(result_mod); | 5578     __ SmiTag(result_mod); | 
| 5582     // Correct MOD result: | 5579     // Correct MOD result: | 
| 5583     //  res = left % right; | 5580     //  res = left % right; | 
| 5584     //  if (res < 0) { | 5581     //  if (res < 0) { | 
| 5585     //    if (right < 0) { | 5582     //    if (right < 0) { | 
| 5586     //      res = res - right; | 5583     //      res = res - right; | 
| 5587     //    } else { | 5584     //    } else { | 
| 5588     //      res = res + right; | 5585     //      res = res + right; | 
| 5589     //    } | 5586     //    } | 
| 5590     //  } | 5587     //  } | 
| 5591     Label done; | 5588     Label done; | 
| 5592     __ cmp(result_mod, ShifterOperand(0)); | 5589     __ cmp(result_mod, Operand(0)); | 
| 5593     __ b(&done, GE); | 5590     __ b(&done, GE); | 
| 5594     // Result is negative, adjust it. | 5591     // Result is negative, adjust it. | 
| 5595     __ cmp(right, ShifterOperand(0)); | 5592     __ cmp(right, Operand(0)); | 
| 5596     __ sub(result_mod, result_mod, ShifterOperand(right), LT); | 5593     __ sub(result_mod, result_mod, Operand(right), LT); | 
| 5597     __ add(result_mod, result_mod, ShifterOperand(right), GE); | 5594     __ add(result_mod, result_mod, Operand(right), GE); | 
| 5598     __ Bind(&done); | 5595     __ Bind(&done); | 
| 5599 | 5596 | 
| 5600     return; | 5597     return; | 
| 5601   } | 5598   } | 
| 5602   if (kind() == MergedMathInstr::kSinCos) { | 5599   if (kind() == MergedMathInstr::kSinCos) { | 
| 5603     UNIMPLEMENTED(); | 5600     UNIMPLEMENTED(); | 
| 5604   } | 5601   } | 
| 5605   UNIMPLEMENTED(); | 5602   UNIMPLEMENTED(); | 
| 5606 } | 5603 } | 
| 5607 | 5604 | 
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5690   } | 5687   } | 
| 5691 | 5688 | 
| 5692   ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | 5689   ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | 
| 5693          (unary_checks().NumberOfChecks() > 1)); | 5690          (unary_checks().NumberOfChecks() > 1)); | 
| 5694   const Register value = locs()->in(0).reg(); | 5691   const Register value = locs()->in(0).reg(); | 
| 5695   const Register temp = locs()->temp(0).reg(); | 5692   const Register temp = locs()->temp(0).reg(); | 
| 5696   Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 5693   Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 
| 5697   Label is_ok; | 5694   Label is_ok; | 
| 5698   intptr_t cix = 0; | 5695   intptr_t cix = 0; | 
| 5699   if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 5696   if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 
| 5700     __ tst(value, ShifterOperand(kSmiTagMask)); | 5697     __ tst(value, Operand(kSmiTagMask)); | 
| 5701     __ b(&is_ok, EQ); | 5698     __ b(&is_ok, EQ); | 
| 5702     cix++;  // Skip first check. | 5699     cix++;  // Skip first check. | 
| 5703   } else { | 5700   } else { | 
| 5704     __ tst(value, ShifterOperand(kSmiTagMask)); | 5701     __ tst(value, Operand(kSmiTagMask)); | 
| 5705     __ b(deopt, EQ); | 5702     __ b(deopt, EQ); | 
| 5706   } | 5703   } | 
| 5707   __ LoadClassId(temp, value); | 5704   __ LoadClassId(temp, value); | 
| 5708   const intptr_t num_checks = unary_checks().NumberOfChecks(); | 5705   const intptr_t num_checks = unary_checks().NumberOfChecks(); | 
| 5709   for (intptr_t i = cix; i < num_checks; i++) { | 5706   for (intptr_t i = cix; i < num_checks; i++) { | 
| 5710     ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); | 5707     ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); | 
| 5711     __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i)); | 5708     __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i)); | 
| 5712     if (i == (num_checks - 1)) { | 5709     if (i == (num_checks - 1)) { | 
| 5713       __ b(deopt, NE); | 5710       __ b(deopt, NE); | 
| 5714     } else { | 5711     } else { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 5726   LocationSummary* summary = new(isolate) LocationSummary( | 5723   LocationSummary* summary = new(isolate) LocationSummary( | 
| 5727       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5724       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 
| 5728   summary->set_in(0, Location::RequiresRegister()); | 5725   summary->set_in(0, Location::RequiresRegister()); | 
| 5729   return summary; | 5726   return summary; | 
| 5730 } | 5727 } | 
| 5731 | 5728 | 
| 5732 | 5729 | 
| 5733 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5730 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 5734   const Register value = locs()->in(0).reg(); | 5731   const Register value = locs()->in(0).reg(); | 
| 5735   Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); | 5732   Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); | 
| 5736   __ tst(value, ShifterOperand(kSmiTagMask)); | 5733   __ tst(value, Operand(kSmiTagMask)); | 
| 5737   __ b(deopt, NE); | 5734   __ b(deopt, NE); | 
| 5738 } | 5735 } | 
| 5739 | 5736 | 
| 5740 | 5737 | 
| 5741 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, | 5738 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, | 
| 5742                                                            bool opt) const { | 5739                                                            bool opt) const { | 
| 5743   const intptr_t kNumInputs = 2; | 5740   const intptr_t kNumInputs = 2; | 
| 5744   const intptr_t kNumTemps = 0; | 5741   const intptr_t kNumTemps = 0; | 
| 5745   LocationSummary* locs = new(isolate) LocationSummary( | 5742   LocationSummary* locs = new(isolate) LocationSummary( | 
| 5746       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5743       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 5773     __ CompareImmediate(length, reinterpret_cast<int32_t>(index.raw())); | 5770     __ CompareImmediate(length, reinterpret_cast<int32_t>(index.raw())); | 
| 5774     __ b(deopt, LS); | 5771     __ b(deopt, LS); | 
| 5775   } else if (length_loc.IsConstant()) { | 5772   } else if (length_loc.IsConstant()) { | 
| 5776     const Smi& length = Smi::Cast(length_loc.constant()); | 5773     const Smi& length = Smi::Cast(length_loc.constant()); | 
| 5777     const Register index = index_loc.reg(); | 5774     const Register index = index_loc.reg(); | 
| 5778     __ CompareImmediate(index, reinterpret_cast<int32_t>(length.raw())); | 5775     __ CompareImmediate(index, reinterpret_cast<int32_t>(length.raw())); | 
| 5779     __ b(deopt, CS); | 5776     __ b(deopt, CS); | 
| 5780   } else { | 5777   } else { | 
| 5781     const Register length = length_loc.reg(); | 5778     const Register length = length_loc.reg(); | 
| 5782     const Register index = index_loc.reg(); | 5779     const Register index = index_loc.reg(); | 
| 5783     __ cmp(index, ShifterOperand(length)); | 5780     __ cmp(index, Operand(length)); | 
| 5784     __ b(deopt, CS); | 5781     __ b(deopt, CS); | 
| 5785   } | 5782   } | 
| 5786 } | 5783 } | 
| 5787 | 5784 | 
| 5788 | 5785 | 
| 5789 static void EmitJavascriptIntOverflowCheck(FlowGraphCompiler* compiler, | 5786 static void EmitJavascriptIntOverflowCheck(FlowGraphCompiler* compiler, | 
| 5790                                            Label* overflow, | 5787                                            Label* overflow, | 
| 5791                                            Register result_lo, | 5788                                            Register result_lo, | 
| 5792                                            Register result_hi) { | 5789                                            Register result_hi) { | 
| 5793   // Compare upper half. | 5790   // Compare upper half. | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5837                       result_lo, | 5834                       result_lo, | 
| 5838                       value, | 5835                       value, | 
| 5839                       Mint::value_offset() - kHeapObjectTag); | 5836                       Mint::value_offset() - kHeapObjectTag); | 
| 5840     // Load high word. | 5837     // Load high word. | 
| 5841     __ LoadFromOffset(kWord, | 5838     __ LoadFromOffset(kWord, | 
| 5842                       result_hi, | 5839                       result_hi, | 
| 5843                       value, | 5840                       value, | 
| 5844                       Mint::value_offset() - kHeapObjectTag + kWordSize); | 5841                       Mint::value_offset() - kHeapObjectTag + kWordSize); | 
| 5845   } else if (value_cid == kSmiCid) { | 5842   } else if (value_cid == kSmiCid) { | 
| 5846     // Load Smi into result_lo. | 5843     // Load Smi into result_lo. | 
| 5847     __ mov(result_lo, ShifterOperand(value)); | 5844     __ mov(result_lo, Operand(value)); | 
| 5848     // Untag. | 5845     // Untag. | 
| 5849     __ SmiUntag(result_lo); | 5846     __ SmiUntag(result_lo); | 
| 5850     __ SignFill(result_hi, result_lo); | 5847     __ SignFill(result_hi, result_lo); | 
| 5851   } else { | 5848   } else { | 
| 5852     const Register temp = locs()->temp(0).reg(); | 5849     const Register temp = locs()->temp(0).reg(); | 
| 5853     Label* deopt = compiler->AddDeoptStub(deopt_id_, | 5850     Label* deopt = compiler->AddDeoptStub(deopt_id_, | 
| 5854                                           ICData::kDeoptUnboxInteger); | 5851                                           ICData::kDeoptUnboxInteger); | 
| 5855     Label is_smi, done; | 5852     Label is_smi, done; | 
| 5856     __ tst(value, ShifterOperand(kSmiTagMask)); | 5853     __ tst(value, Operand(kSmiTagMask)); | 
| 5857     __ b(&is_smi, EQ); | 5854     __ b(&is_smi, EQ); | 
| 5858     __ CompareClassId(value, kMintCid, temp); | 5855     __ CompareClassId(value, kMintCid, temp); | 
| 5859     __ b(deopt, NE); | 5856     __ b(deopt, NE); | 
| 5860 | 5857 | 
| 5861     // It's a Mint. | 5858     // It's a Mint. | 
| 5862     // Load low word. | 5859     // Load low word. | 
| 5863     __ LoadFromOffset(kWord, | 5860     __ LoadFromOffset(kWord, | 
| 5864                       result_lo, | 5861                       result_lo, | 
| 5865                       value, | 5862                       value, | 
| 5866                       Mint::value_offset() - kHeapObjectTag); | 5863                       Mint::value_offset() - kHeapObjectTag); | 
| 5867     // Load high word. | 5864     // Load high word. | 
| 5868     __ LoadFromOffset(kWord, | 5865     __ LoadFromOffset(kWord, | 
| 5869                       result_hi, | 5866                       result_hi, | 
| 5870                       value, | 5867                       value, | 
| 5871                       Mint::value_offset() - kHeapObjectTag + kWordSize); | 5868                       Mint::value_offset() - kHeapObjectTag + kWordSize); | 
| 5872     __ b(&done); | 5869     __ b(&done); | 
| 5873 | 5870 | 
| 5874     // It's a Smi. | 5871     // It's a Smi. | 
| 5875     __ Bind(&is_smi); | 5872     __ Bind(&is_smi); | 
| 5876     // Load Smi into result_lo. | 5873     // Load Smi into result_lo. | 
| 5877     __ mov(result_lo, ShifterOperand(value)); | 5874     __ mov(result_lo, Operand(value)); | 
| 5878     // Untag. | 5875     // Untag. | 
| 5879     __ SmiUntag(result_lo); | 5876     __ SmiUntag(result_lo); | 
| 5880     // Sign extend result_lo into result_hi. | 5877     // Sign extend result_lo into result_hi. | 
| 5881     __ SignFill(result_hi, result_lo); | 5878     __ SignFill(result_hi, result_lo); | 
| 5882     __ Bind(&done); | 5879     __ Bind(&done); | 
| 5883   } | 5880   } | 
| 5884 } | 5881 } | 
| 5885 | 5882 | 
| 5886 | 5883 | 
| 5887 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, | 5884 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 5915     const ExternalLabel label(stub.EntryPoint()); | 5912     const ExternalLabel label(stub.EntryPoint()); | 
| 5916 | 5913 | 
| 5917     LocationSummary* locs = instruction_->locs(); | 5914     LocationSummary* locs = instruction_->locs(); | 
| 5918     locs->live_registers()->Remove(locs->out(0)); | 5915     locs->live_registers()->Remove(locs->out(0)); | 
| 5919 | 5916 | 
| 5920     compiler->SaveLiveRegisters(locs); | 5917     compiler->SaveLiveRegisters(locs); | 
| 5921     compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position. | 5918     compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position. | 
| 5922                            &label, | 5919                            &label, | 
| 5923                            PcDescriptors::kOther, | 5920                            PcDescriptors::kOther, | 
| 5924                            locs); | 5921                            locs); | 
| 5925     __ mov(locs->out(0).reg(), ShifterOperand(R0)); | 5922     __ mov(locs->out(0).reg(), Operand(R0)); | 
| 5926     compiler->RestoreLiveRegisters(locs); | 5923     compiler->RestoreLiveRegisters(locs); | 
| 5927 | 5924 | 
| 5928     __ b(exit_label()); | 5925     __ b(exit_label()); | 
| 5929   } | 5926   } | 
| 5930 | 5927 | 
| 5931  private: | 5928  private: | 
| 5932   BoxIntegerInstr* instruction_; | 5929   BoxIntegerInstr* instruction_; | 
| 5933 }; | 5930 }; | 
| 5934 | 5931 | 
| 5935 | 5932 | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 5960   __ b(¬_smi); | 5957   __ b(¬_smi); | 
| 5961 | 5958 | 
| 5962   __ Bind(&maybe_neg_smi); | 5959   __ Bind(&maybe_neg_smi); | 
| 5963   __ CompareImmediate(value_lo, 0); | 5960   __ CompareImmediate(value_lo, 0); | 
| 5964   __ b(¬_smi, GE); | 5961   __ b(¬_smi, GE); | 
| 5965   __ CompareImmediate(value_lo, kSmiMin); | 5962   __ CompareImmediate(value_lo, kSmiMin); | 
| 5966   __ b(¬_smi, LT); | 5963   __ b(¬_smi, LT); | 
| 5967 | 5964 | 
| 5968   // lo is a Smi. Tag it and return. | 5965   // lo is a Smi. Tag it and return. | 
| 5969   __ Bind(&is_smi); | 5966   __ Bind(&is_smi); | 
| 5970   __ mov(out_reg, ShifterOperand(value_lo)); | 5967   __ mov(out_reg, Operand(value_lo)); | 
| 5971   __ SmiTag(out_reg); | 5968   __ SmiTag(out_reg); | 
| 5972   __ b(&done); | 5969   __ b(&done); | 
| 5973 | 5970 | 
| 5974   // Not a smi. Box it. | 5971   // Not a smi. Box it. | 
| 5975   __ Bind(¬_smi); | 5972   __ Bind(¬_smi); | 
| 5976   __ TryAllocate( | 5973   __ TryAllocate( | 
| 5977       Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), | 5974       Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), | 
| 5978       slow_path->entry_label(), | 5975       slow_path->entry_label(), | 
| 5979       out_reg, | 5976       out_reg, | 
| 5980       tmp); | 5977       tmp); | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6017   PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6014   PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 
| 6018   Register out_lo = out_pair->At(0).reg(); | 6015   Register out_lo = out_pair->At(0).reg(); | 
| 6019   Register out_hi = out_pair->At(1).reg(); | 6016   Register out_hi = out_pair->At(1).reg(); | 
| 6020 | 6017 | 
| 6021   Label* deopt = NULL; | 6018   Label* deopt = NULL; | 
| 6022   if (FLAG_throw_on_javascript_int_overflow) { | 6019   if (FLAG_throw_on_javascript_int_overflow) { | 
| 6023     deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 6020     deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 
| 6024   } | 6021   } | 
| 6025   switch (op_kind()) { | 6022   switch (op_kind()) { | 
| 6026     case Token::kBIT_AND: { | 6023     case Token::kBIT_AND: { | 
| 6027       __ and_(out_lo, left_lo, ShifterOperand(right_lo)); | 6024       __ and_(out_lo, left_lo, Operand(right_lo)); | 
| 6028       __ and_(out_hi, left_hi, ShifterOperand(right_hi)); | 6025       __ and_(out_hi, left_hi, Operand(right_hi)); | 
| 6029     } | 6026     } | 
| 6030     break; | 6027     break; | 
| 6031     case Token::kBIT_OR: { | 6028     case Token::kBIT_OR: { | 
| 6032       __ orr(out_lo, left_lo, ShifterOperand(right_lo)); | 6029       __ orr(out_lo, left_lo, Operand(right_lo)); | 
| 6033       __ orr(out_hi, left_hi, ShifterOperand(right_hi)); | 6030       __ orr(out_hi, left_hi, Operand(right_hi)); | 
| 6034     } | 6031     } | 
| 6035     break; | 6032     break; | 
| 6036     case Token::kBIT_XOR: { | 6033     case Token::kBIT_XOR: { | 
| 6037      __ eor(out_lo, left_lo, ShifterOperand(right_lo)); | 6034      __ eor(out_lo, left_lo, Operand(right_lo)); | 
| 6038      __ eor(out_hi, left_hi, ShifterOperand(right_hi)); | 6035      __ eor(out_hi, left_hi, Operand(right_hi)); | 
| 6039     } | 6036     } | 
| 6040     break; | 6037     break; | 
| 6041     case Token::kADD: | 6038     case Token::kADD: | 
| 6042     case Token::kSUB: { | 6039     case Token::kSUB: { | 
| 6043       if (!FLAG_throw_on_javascript_int_overflow) { | 6040       if (!FLAG_throw_on_javascript_int_overflow) { | 
| 6044         deopt  = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 6041         deopt  = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 
| 6045       } | 6042       } | 
| 6046       if (op_kind() == Token::kADD) { | 6043       if (op_kind() == Token::kADD) { | 
| 6047         __ adds(out_lo, left_lo, ShifterOperand(right_lo)); | 6044         __ adds(out_lo, left_lo, Operand(right_lo)); | 
| 6048         __ adcs(out_hi, left_hi, ShifterOperand(right_hi)); | 6045         __ adcs(out_hi, left_hi, Operand(right_hi)); | 
| 6049       } else { | 6046       } else { | 
| 6050         ASSERT(op_kind() == Token::kSUB); | 6047         ASSERT(op_kind() == Token::kSUB); | 
| 6051         __ subs(out_lo, left_lo, ShifterOperand(right_lo)); | 6048         __ subs(out_lo, left_lo, Operand(right_lo)); | 
| 6052         __ sbcs(out_hi, left_hi, ShifterOperand(right_hi)); | 6049         __ sbcs(out_hi, left_hi, Operand(right_hi)); | 
| 6053       } | 6050       } | 
| 6054       // Deopt on overflow. | 6051       // Deopt on overflow. | 
| 6055       __ b(deopt, VS); | 6052       __ b(deopt, VS); | 
| 6056       break; | 6053       break; | 
| 6057     } | 6054     } | 
| 6058     default: | 6055     default: | 
| 6059       UNREACHABLE(); | 6056       UNREACHABLE(); | 
| 6060     break; | 6057     break; | 
| 6061   } | 6058   } | 
| 6062   if (FLAG_throw_on_javascript_int_overflow) { | 6059   if (FLAG_throw_on_javascript_int_overflow) { | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 6089   PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6086   PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 
| 6090   Register out_lo = out_pair->At(0).reg(); | 6087   Register out_lo = out_pair->At(0).reg(); | 
| 6091   Register out_hi = out_pair->At(1).reg(); | 6088   Register out_hi = out_pair->At(1).reg(); | 
| 6092   Register temp = locs()->temp(0).reg(); | 6089   Register temp = locs()->temp(0).reg(); | 
| 6093 | 6090 | 
| 6094   Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); | 6091   Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); | 
| 6095   Label done; | 6092   Label done; | 
| 6096 | 6093 | 
| 6097   // Early out if shift is 0. | 6094   // Early out if shift is 0. | 
| 6098   __ CompareImmediate(shift, 0); | 6095   __ CompareImmediate(shift, 0); | 
| 6099   __ mov(out_lo, ShifterOperand(left_lo)); | 6096   __ mov(out_lo, Operand(left_lo)); | 
| 6100   __ mov(out_hi, ShifterOperand(left_hi)); | 6097   __ mov(out_hi, Operand(left_hi)); | 
| 6101   __ b(&done, EQ); | 6098   __ b(&done, EQ); | 
| 6102 | 6099 | 
| 6103   // Untag shift count. | 6100   // Untag shift count. | 
| 6104   __ SmiUntag(shift); | 6101   __ SmiUntag(shift); | 
| 6105 | 6102 | 
| 6106   // Deopt if shift is negative. | 6103   // Deopt if shift is negative. | 
| 6107   __ CompareImmediate(shift, 1); | 6104   __ CompareImmediate(shift, 1); | 
| 6108   __ b(deopt, LT); | 6105   __ b(deopt, LT); | 
| 6109 | 6106 | 
| 6110   // Deopt if shift is larger than 63. | 6107   // Deopt if shift is larger than 63. | 
| 6111   __ CompareImmediate(shift, 63); | 6108   __ CompareImmediate(shift, 63); | 
| 6112   __ b(deopt, GT); | 6109   __ b(deopt, GT); | 
| 6113 | 6110 | 
| 6114   switch (op_kind()) { | 6111   switch (op_kind()) { | 
| 6115     case Token::kSHR: { | 6112     case Token::kSHR: { | 
| 6116       __ cmp(shift, ShifterOperand(32)); | 6113       __ cmp(shift, Operand(32)); | 
| 6117 | 6114 | 
| 6118       __ mov(out_lo, ShifterOperand(out_hi), HI); | 6115       __ mov(out_lo, Operand(out_hi), HI); | 
| 6119       __ Asr(out_hi, out_hi, 31, HI); | 6116       __ Asr(out_hi, out_hi, 31, HI); | 
| 6120       __ sub(shift, shift, ShifterOperand(32), HI); | 6117       __ sub(shift, shift, Operand(32), HI); | 
| 6121 | 6118 | 
| 6122       __ rsb(temp, shift, ShifterOperand(32)); | 6119       __ rsb(temp, shift, Operand(32)); | 
| 6123       __ mov(temp, ShifterOperand(out_hi, LSL, temp)); | 6120       __ mov(temp, Operand(out_hi, LSL, temp)); | 
| 6124       __ orr(out_lo, temp, ShifterOperand(out_lo, LSR, shift)); | 6121       __ orr(out_lo, temp, Operand(out_lo, LSR, shift)); | 
| 6125       __ Asr(out_hi, out_hi, shift); | 6122       __ Asr(out_hi, out_hi, shift); | 
| 6126       break; | 6123       break; | 
| 6127     } | 6124     } | 
| 6128     case Token::kSHL: { | 6125     case Token::kSHL: { | 
| 6129       __ rsbs(temp, shift, ShifterOperand(32)); | 6126       __ rsbs(temp, shift, Operand(32)); | 
| 6130       __ sub(temp, shift, ShifterOperand(32), MI); | 6127       __ sub(temp, shift, Operand(32), MI); | 
| 6131       __ mov(out_hi, ShifterOperand(out_lo, LSL, temp), MI); | 6128       __ mov(out_hi, Operand(out_lo, LSL, temp), MI); | 
| 6132       __ mov(out_hi, ShifterOperand(out_hi, LSL, shift), PL); | 6129       __ mov(out_hi, Operand(out_hi, LSL, shift), PL); | 
| 6133       __ orr(out_hi, out_hi, ShifterOperand(out_lo, LSR, temp), PL); | 6130       __ orr(out_hi, out_hi, Operand(out_lo, LSR, temp), PL); | 
| 6134       __ mov(out_lo, ShifterOperand(out_lo, LSL, shift)); | 6131       __ mov(out_lo, Operand(out_lo, LSL, shift)); | 
| 6135 | 6132 | 
| 6136       // Check for overflow. | 6133       // Check for overflow. | 
| 6137 | 6134 | 
| 6138       // Copy high word from output. | 6135       // Copy high word from output. | 
| 6139       __ mov(temp, ShifterOperand(out_hi)); | 6136       __ mov(temp, Operand(out_hi)); | 
| 6140       // Shift copy right. | 6137       // Shift copy right. | 
| 6141       __ Asr(temp, temp, shift); | 6138       __ Asr(temp, temp, shift); | 
| 6142       // Compare with high word from input. | 6139       // Compare with high word from input. | 
| 6143       __ cmp(temp, ShifterOperand(left_hi)); | 6140       __ cmp(temp, Operand(left_hi)); | 
| 6144       // Overflow if they aren't equal. | 6141       // Overflow if they aren't equal. | 
| 6145       __ b(deopt, NE); | 6142       __ b(deopt, NE); | 
| 6146       break; | 6143       break; | 
| 6147     } | 6144     } | 
| 6148     default: | 6145     default: | 
| 6149       UNREACHABLE(); | 6146       UNREACHABLE(); | 
| 6150       break; | 6147       break; | 
| 6151   } | 6148   } | 
| 6152 | 6149 | 
| 6153   __ Bind(&done); | 6150   __ Bind(&done); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 6179 | 6176 | 
| 6180   PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6177   PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 
| 6181   Register out_lo = out_pair->At(0).reg(); | 6178   Register out_lo = out_pair->At(0).reg(); | 
| 6182   Register out_hi = out_pair->At(1).reg(); | 6179   Register out_hi = out_pair->At(1).reg(); | 
| 6183 | 6180 | 
| 6184   Label* deopt = NULL; | 6181   Label* deopt = NULL; | 
| 6185 | 6182 | 
| 6186   if (FLAG_throw_on_javascript_int_overflow) { | 6183   if (FLAG_throw_on_javascript_int_overflow) { | 
| 6187     deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); | 6184     deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); | 
| 6188   } | 6185   } | 
| 6189   __ mvn(out_lo, ShifterOperand(left_lo)); | 6186   __ mvn(out_lo, Operand(left_lo)); | 
| 6190   __ mvn(out_hi, ShifterOperand(left_hi)); | 6187   __ mvn(out_hi, Operand(left_hi)); | 
| 6191   if (FLAG_throw_on_javascript_int_overflow) { | 6188   if (FLAG_throw_on_javascript_int_overflow) { | 
| 6192     EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); | 6189     EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); | 
| 6193   } | 6190   } | 
| 6194 } | 6191 } | 
| 6195 | 6192 | 
| 6196 | 6193 | 
| 6197 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, | 6194 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, | 
| 6198                                                  bool opt) const { | 6195                                                  bool opt) const { | 
| 6199   return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); | 6196   return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); | 
| 6200 } | 6197 } | 
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6289 LocationSummary* CurrentContextInstr::MakeLocationSummary(Isolate* isolate, | 6286 LocationSummary* CurrentContextInstr::MakeLocationSummary(Isolate* isolate, | 
| 6290                                                           bool opt) const { | 6287                                                           bool opt) const { | 
| 6291   return LocationSummary::Make(isolate, | 6288   return LocationSummary::Make(isolate, | 
| 6292                                0, | 6289                                0, | 
| 6293                                Location::RequiresRegister(), | 6290                                Location::RequiresRegister(), | 
| 6294                                LocationSummary::kNoCall); | 6291                                LocationSummary::kNoCall); | 
| 6295 } | 6292 } | 
| 6296 | 6293 | 
| 6297 | 6294 | 
| 6298 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6295 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 6299   __ mov(locs()->out(0).reg(), ShifterOperand(CTX)); | 6296   __ mov(locs()->out(0).reg(), Operand(CTX)); | 
| 6300 } | 6297 } | 
| 6301 | 6298 | 
| 6302 | 6299 | 
| 6303 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, | 6300 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, | 
| 6304                                                          bool opt) const { | 6301                                                          bool opt) const { | 
| 6305   const intptr_t kNumInputs = 2; | 6302   const intptr_t kNumInputs = 2; | 
| 6306   const intptr_t kNumTemps = 0; | 6303   const intptr_t kNumTemps = 0; | 
| 6307   if (needs_number_check()) { | 6304   if (needs_number_check()) { | 
| 6308     LocationSummary* locs = new(isolate) LocationSummary( | 6305     LocationSummary* locs = new(isolate) LocationSummary( | 
| 6309         isolate, kNumInputs, kNumTemps, LocationSummary::kCall); | 6306         isolate, kNumInputs, kNumTemps, LocationSummary::kCall); | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6381                                Location::RequiresRegister(), | 6378                                Location::RequiresRegister(), | 
| 6382                                LocationSummary::kNoCall); | 6379                                LocationSummary::kNoCall); | 
| 6383 } | 6380 } | 
| 6384 | 6381 | 
| 6385 | 6382 | 
| 6386 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6383 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 6387   const Register value = locs()->in(0).reg(); | 6384   const Register value = locs()->in(0).reg(); | 
| 6388   const Register result = locs()->out(0).reg(); | 6385   const Register result = locs()->out(0).reg(); | 
| 6389 | 6386 | 
| 6390   __ LoadObject(result, Bool::True()); | 6387   __ LoadObject(result, Bool::True()); | 
| 6391   __ cmp(result, ShifterOperand(value)); | 6388   __ cmp(result, Operand(value)); | 
| 6392   __ LoadObject(result, Bool::False(), EQ); | 6389   __ LoadObject(result, Bool::False(), EQ); | 
| 6393 } | 6390 } | 
| 6394 | 6391 | 
| 6395 | 6392 | 
| 6396 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Isolate* isolate, | 6393 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Isolate* isolate, | 
| 6397                                                           bool opt) const { | 6394                                                           bool opt) const { | 
| 6398   return MakeCallSummary(); | 6395   return MakeCallSummary(); | 
| 6399 } | 6396 } | 
| 6400 | 6397 | 
| 6401 | 6398 | 
| 6402 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6399 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 
| 6403   const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); | 6400   const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); | 
| 6404   const ExternalLabel label(stub.EntryPoint()); | 6401   const ExternalLabel label(stub.EntryPoint()); | 
| 6405   compiler->GenerateCall(token_pos(), | 6402   compiler->GenerateCall(token_pos(), | 
| 6406                          &label, | 6403                          &label, | 
| 6407                          PcDescriptors::kOther, | 6404                          PcDescriptors::kOther, | 
| 6408                          locs()); | 6405                          locs()); | 
| 6409   __ Drop(ArgumentCount());  // Discard arguments. | 6406   __ Drop(ArgumentCount());  // Discard arguments. | 
| 6410 } | 6407 } | 
| 6411 | 6408 | 
| 6412 }  // namespace dart | 6409 }  // namespace dart | 
| 6413 | 6410 | 
| 6414 #endif  // defined TARGET_ARCH_ARM | 6411 #endif  // defined TARGET_ARCH_ARM | 
| OLD | NEW | 
|---|