| 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 5668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5679 | 5679 |
| 5680 | 5680 |
| 5681 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5681 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5682 comparison()->EmitBranchCode(compiler, this); | 5682 comparison()->EmitBranchCode(compiler, this); |
| 5683 } | 5683 } |
| 5684 | 5684 |
| 5685 | 5685 |
| 5686 LocationSummary* CheckClassInstr::MakeLocationSummary(Isolate* isolate, | 5686 LocationSummary* CheckClassInstr::MakeLocationSummary(Isolate* isolate, |
| 5687 bool opt) const { | 5687 bool opt) const { |
| 5688 const intptr_t kNumInputs = 1; | 5688 const intptr_t kNumInputs = 1; |
| 5689 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); | 5689 const intptr_t kNumTemps = !IsNullCheck() ? 1 : 0; |
| 5690 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; | |
| 5691 LocationSummary* summary = new(isolate) LocationSummary( | 5690 LocationSummary* summary = new(isolate) LocationSummary( |
| 5692 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5691 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5693 summary->set_in(0, Location::RequiresRegister()); | 5692 summary->set_in(0, Location::RequiresRegister()); |
| 5694 if (!IsNullCheck()) { | 5693 if (!IsNullCheck()) { |
| 5695 summary->set_temp(0, Location::RequiresRegister()); | 5694 summary->set_temp(0, Location::RequiresRegister()); |
| 5696 if (need_mask_temp) { | |
| 5697 summary->set_temp(1, Location::RequiresRegister()); | |
| 5698 } | |
| 5699 } | 5695 } |
| 5700 return summary; | 5696 return summary; |
| 5701 } | 5697 } |
| 5702 | 5698 |
| 5703 | 5699 |
| 5704 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5700 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5705 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? | 5701 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 5706 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; | 5702 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 5707 if (IsNullCheck()) { | 5703 if (IsNullCheck()) { |
| 5708 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 5704 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5721 intptr_t cix = 0; | 5717 intptr_t cix = 0; |
| 5722 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 5718 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { |
| 5723 __ tst(value, Operand(kSmiTagMask)); | 5719 __ tst(value, Operand(kSmiTagMask)); |
| 5724 __ b(&is_ok, EQ); | 5720 __ b(&is_ok, EQ); |
| 5725 cix++; // Skip first check. | 5721 cix++; // Skip first check. |
| 5726 } else { | 5722 } else { |
| 5727 __ tst(value, Operand(kSmiTagMask)); | 5723 __ tst(value, Operand(kSmiTagMask)); |
| 5728 __ b(deopt, EQ); | 5724 __ b(deopt, EQ); |
| 5729 } | 5725 } |
| 5730 __ LoadClassId(temp, value); | 5726 __ LoadClassId(temp, value); |
| 5731 | 5727 const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| 5732 if (IsDenseSwitch()) { | 5728 for (intptr_t i = cix; i < num_checks; i++) { |
| 5733 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | 5729 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); |
| 5734 __ AddImmediate(temp, -cids_[0]); | 5730 __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i)); |
| 5735 __ CompareImmediate(temp, cids_[cids_.length() - 1] - cids_[0]); | 5731 if (i == (num_checks - 1)) { |
| 5736 __ b(deopt, HI); | 5732 __ b(deopt, NE); |
| 5737 | 5733 } else { |
| 5738 intptr_t mask = ComputeCidMask(); | 5734 __ b(&is_ok, EQ); |
| 5739 if (!IsDenseMask(mask)) { | |
| 5740 // Only need mask if there are missing numbers in the range. | |
| 5741 ASSERT(cids_.length() > 2); | |
| 5742 Register mask_reg = locs()->temp(1).reg(); | |
| 5743 __ LoadImmediate(mask_reg, 1); | |
| 5744 __ Lsl(mask_reg, mask_reg, temp); | |
| 5745 __ TestImmediate(mask_reg, mask); | |
| 5746 __ b(deopt, EQ); | |
| 5747 } | |
| 5748 } else { | |
| 5749 const intptr_t num_checks = unary_checks().NumberOfChecks(); | |
| 5750 for (intptr_t i = cix; i < num_checks; i++) { | |
| 5751 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); | |
| 5752 __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i)); | |
| 5753 if (i == (num_checks - 1)) { | |
| 5754 __ b(deopt, NE); | |
| 5755 } else { | |
| 5756 __ b(&is_ok, EQ); | |
| 5757 } | |
| 5758 } | 5735 } |
| 5759 } | 5736 } |
| 5760 __ Bind(&is_ok); | 5737 __ Bind(&is_ok); |
| 5761 } | 5738 } |
| 5762 | 5739 |
| 5763 | 5740 |
| 5764 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, | 5741 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, |
| 5765 bool opt) const { | 5742 bool opt) const { |
| 5766 const intptr_t kNumInputs = 1; | 5743 const intptr_t kNumInputs = 1; |
| 5767 const intptr_t kNumTemps = 0; | 5744 const intptr_t kNumTemps = 0; |
| 5768 LocationSummary* summary = new(isolate) LocationSummary( | 5745 LocationSummary* summary = new(isolate) LocationSummary( |
| 5769 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5746 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5770 summary->set_in(0, Location::RequiresRegister()); | 5747 summary->set_in(0, Location::RequiresRegister()); |
| 5771 return summary; | 5748 return summary; |
| 5772 } | 5749 } |
| 5773 | 5750 |
| 5774 | 5751 |
| 5775 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5752 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5776 const Register value = locs()->in(0).reg(); | 5753 const Register value = locs()->in(0).reg(); |
| 5777 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); | 5754 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); |
| 5778 __ tst(value, Operand(kSmiTagMask)); | 5755 __ tst(value, Operand(kSmiTagMask)); |
| 5779 __ b(deopt, NE); | 5756 __ b(deopt, NE); |
| 5780 } | 5757 } |
| 5781 | 5758 |
| 5782 | 5759 |
| 5783 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Isolate* isolate, | |
| 5784 bool opt) const { | |
| 5785 const intptr_t kNumInputs = 2; | |
| 5786 const intptr_t kNumTemps = 0; | |
| 5787 LocationSummary* summary = new(isolate) LocationSummary( | |
| 5788 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 5789 summary->set_in(0, Location::RequiresRegister()); | |
| 5790 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | |
| 5791 return summary; | |
| 5792 } | |
| 5793 | |
| 5794 | |
| 5795 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 5796 Register left = locs()->in(0).reg(); | |
| 5797 Location right = locs()->in(1); | |
| 5798 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | |
| 5799 if (right.IsRegister()) { | |
| 5800 __ cmp(left, Operand(right.reg())); | |
| 5801 } else { | |
| 5802 ASSERT(right.IsConstant()); | |
| 5803 const Object& right_const = Smi::Cast(right.constant()); | |
| 5804 __ CompareImmediate(left, reinterpret_cast<int32_t>(right_const.raw())); | |
| 5805 } | |
| 5806 __ b(deopt, NE); | |
| 5807 } | |
| 5808 | |
| 5809 | |
| 5810 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, | 5760 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, |
| 5811 bool opt) const { | 5761 bool opt) const { |
| 5812 const intptr_t kNumInputs = 2; | 5762 const intptr_t kNumInputs = 2; |
| 5813 const intptr_t kNumTemps = 0; | 5763 const intptr_t kNumTemps = 0; |
| 5814 LocationSummary* locs = new(isolate) LocationSummary( | 5764 LocationSummary* locs = new(isolate) LocationSummary( |
| 5815 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5765 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5816 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 5766 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 5817 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 5767 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
| 5818 return locs; | 5768 return locs; |
| 5819 } | 5769 } |
| (...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6509 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 6459 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 6510 #if defined(DEBUG) | 6460 #if defined(DEBUG) |
| 6511 __ LoadImmediate(R4, kInvalidObjectPointer); | 6461 __ LoadImmediate(R4, kInvalidObjectPointer); |
| 6512 __ LoadImmediate(R5, kInvalidObjectPointer); | 6462 __ LoadImmediate(R5, kInvalidObjectPointer); |
| 6513 #endif | 6463 #endif |
| 6514 } | 6464 } |
| 6515 | 6465 |
| 6516 } // namespace dart | 6466 } // namespace dart |
| 6517 | 6467 |
| 6518 #endif // defined TARGET_ARCH_ARM | 6468 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |