| 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 intptr_t kNumTemps = !IsNullCheck() ? 1 : 0; | 5689 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); |
| 5690 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; |
| 5690 LocationSummary* summary = new(isolate) LocationSummary( | 5691 LocationSummary* summary = new(isolate) LocationSummary( |
| 5691 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5692 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5692 summary->set_in(0, Location::RequiresRegister()); | 5693 summary->set_in(0, Location::RequiresRegister()); |
| 5693 if (!IsNullCheck()) { | 5694 if (!IsNullCheck()) { |
| 5694 summary->set_temp(0, Location::RequiresRegister()); | 5695 summary->set_temp(0, Location::RequiresRegister()); |
| 5696 if (need_mask_temp) { |
| 5697 summary->set_temp(1, Location::RequiresRegister()); |
| 5698 } |
| 5695 } | 5699 } |
| 5696 return summary; | 5700 return summary; |
| 5697 } | 5701 } |
| 5698 | 5702 |
| 5699 | 5703 |
| 5700 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5704 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5701 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? | 5705 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 5702 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; | 5706 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 5703 if (IsNullCheck()) { | 5707 if (IsNullCheck()) { |
| 5704 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 5708 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5717 intptr_t cix = 0; | 5721 intptr_t cix = 0; |
| 5718 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 5722 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { |
| 5719 __ tst(value, Operand(kSmiTagMask)); | 5723 __ tst(value, Operand(kSmiTagMask)); |
| 5720 __ b(&is_ok, EQ); | 5724 __ b(&is_ok, EQ); |
| 5721 cix++; // Skip first check. | 5725 cix++; // Skip first check. |
| 5722 } else { | 5726 } else { |
| 5723 __ tst(value, Operand(kSmiTagMask)); | 5727 __ tst(value, Operand(kSmiTagMask)); |
| 5724 __ b(deopt, EQ); | 5728 __ b(deopt, EQ); |
| 5725 } | 5729 } |
| 5726 __ LoadClassId(temp, value); | 5730 __ LoadClassId(temp, value); |
| 5727 const intptr_t num_checks = unary_checks().NumberOfChecks(); | 5731 |
| 5728 for (intptr_t i = cix; i < num_checks; i++) { | 5732 if (IsDenseSwitch()) { |
| 5729 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); | 5733 ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
| 5730 __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i)); | 5734 __ AddImmediate(temp, -cids_[0]); |
| 5731 if (i == (num_checks - 1)) { | 5735 __ CompareImmediate(temp, cids_[cids_.length() - 1] - cids_[0]); |
| 5732 __ b(deopt, NE); | 5736 __ b(deopt, HI); |
| 5733 } else { | 5737 |
| 5734 __ b(&is_ok, EQ); | 5738 intptr_t mask = ComputeCidMask(); |
| 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 } |
| 5735 } | 5758 } |
| 5736 } | 5759 } |
| 5737 __ Bind(&is_ok); | 5760 __ Bind(&is_ok); |
| 5738 } | 5761 } |
| 5739 | 5762 |
| 5740 | 5763 |
| 5741 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, | 5764 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, |
| 5742 bool opt) const { | 5765 bool opt) const { |
| 5743 const intptr_t kNumInputs = 1; | 5766 const intptr_t kNumInputs = 1; |
| 5744 const intptr_t kNumTemps = 0; | 5767 const intptr_t kNumTemps = 0; |
| 5745 LocationSummary* summary = new(isolate) LocationSummary( | 5768 LocationSummary* summary = new(isolate) LocationSummary( |
| 5746 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5769 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5747 summary->set_in(0, Location::RequiresRegister()); | 5770 summary->set_in(0, Location::RequiresRegister()); |
| 5748 return summary; | 5771 return summary; |
| 5749 } | 5772 } |
| 5750 | 5773 |
| 5751 | 5774 |
| 5752 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5775 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5753 const Register value = locs()->in(0).reg(); | 5776 const Register value = locs()->in(0).reg(); |
| 5754 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); | 5777 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); |
| 5755 __ tst(value, Operand(kSmiTagMask)); | 5778 __ tst(value, Operand(kSmiTagMask)); |
| 5756 __ b(deopt, NE); | 5779 __ b(deopt, NE); |
| 5757 } | 5780 } |
| 5758 | 5781 |
| 5759 | 5782 |
| 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 |
| 5760 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, | 5810 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, |
| 5761 bool opt) const { | 5811 bool opt) const { |
| 5762 const intptr_t kNumInputs = 2; | 5812 const intptr_t kNumInputs = 2; |
| 5763 const intptr_t kNumTemps = 0; | 5813 const intptr_t kNumTemps = 0; |
| 5764 LocationSummary* locs = new(isolate) LocationSummary( | 5814 LocationSummary* locs = new(isolate) LocationSummary( |
| 5765 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5815 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5766 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 5816 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 5767 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 5817 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
| 5768 return locs; | 5818 return locs; |
| 5769 } | 5819 } |
| (...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6459 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 6509 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 6460 #if defined(DEBUG) | 6510 #if defined(DEBUG) |
| 6461 __ LoadImmediate(R4, kInvalidObjectPointer); | 6511 __ LoadImmediate(R4, kInvalidObjectPointer); |
| 6462 __ LoadImmediate(R5, kInvalidObjectPointer); | 6512 __ LoadImmediate(R5, kInvalidObjectPointer); |
| 6463 #endif | 6513 #endif |
| 6464 } | 6514 } |
| 6465 | 6515 |
| 6466 } // namespace dart | 6516 } // namespace dart |
| 6467 | 6517 |
| 6468 #endif // defined TARGET_ARCH_ARM | 6518 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |