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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 4818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4829 return summary; | 4829 return summary; |
4830 } | 4830 } |
4831 | 4831 |
4832 | 4832 |
4833 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4833 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4834 __ Comment("CheckSmiInstr"); | 4834 __ Comment("CheckSmiInstr"); |
4835 Register value = locs()->in(0).reg(); | 4835 Register value = locs()->in(0).reg(); |
4836 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4836 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
4837 ICData::kDeoptCheckSmi, | 4837 ICData::kDeoptCheckSmi, |
4838 licm_hoisted_ ? ICData::kHoisted : 0); | 4838 licm_hoisted_ ? ICData::kHoisted : 0); |
4839 __ BranchIfNotSmi(value, deopt); | 4839 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); |
| 4840 __ bne(CMPRES1, ZR, deopt); |
4840 } | 4841 } |
4841 | 4842 |
4842 | 4843 |
4843 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone, | 4844 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone, |
4844 bool opt) const { | 4845 bool opt) const { |
4845 const intptr_t kNumInputs = 1; | 4846 const intptr_t kNumInputs = 1; |
4846 const intptr_t kNumTemps = 0; | 4847 const intptr_t kNumTemps = 0; |
4847 LocationSummary* summary = new(zone) LocationSummary( | 4848 LocationSummary* summary = new(zone) LocationSummary( |
4848 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4849 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4849 summary->set_in(0, Location::RequiresRegister()); | 4850 summary->set_in(0, Location::RequiresRegister()); |
4850 return summary; | 4851 return summary; |
4851 } | 4852 } |
4852 | 4853 |
4853 | 4854 |
4854 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4855 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4855 Register value = locs()->in(0).reg(); | 4856 Register value = locs()->in(0).reg(); |
4856 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | 4857 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); |
4857 __ BranchNotEqual(value, Immediate(Smi::RawValue(cid_)), deopt); | 4858 __ BranchNotEqual(value, Immediate(Smi::RawValue(cid_)), deopt); |
4858 } | 4859 } |
4859 | 4860 |
4860 | 4861 |
4861 LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone, | |
4862 bool opt) const { | |
4863 const intptr_t kNumInputs = 2; | |
4864 const intptr_t kNumTemps = 0; | |
4865 LocationSummary* locs = new(zone) LocationSummary( | |
4866 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | |
4867 locs->set_in(kLengthPos, Location::RequiresRegister()); | |
4868 locs->set_in(kIndexPos, Location::RequiresRegister()); | |
4869 return locs; | |
4870 } | |
4871 | |
4872 | |
4873 class RangeErrorSlowPath : public SlowPathCode { | |
4874 public: | |
4875 RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index) | |
4876 : instruction_(instruction), try_index_(try_index) { } | |
4877 | |
4878 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
4879 if (Assembler::EmittingComments()) { | |
4880 __ Comment("slow path check bound operation"); | |
4881 } | |
4882 __ Bind(entry_label()); | |
4883 LocationSummary* locs = instruction_->locs(); | |
4884 __ Push(locs->in(0).reg()); | |
4885 __ Push(locs->in(1).reg()); | |
4886 compiler->GenerateRuntimeCall(instruction_->token_pos(), | |
4887 instruction_->deopt_id(), | |
4888 kRangeErrorRuntimeEntry, | |
4889 2, | |
4890 instruction_->locs()); | |
4891 compiler->RecordSafepoint(locs, /* slow_path_argument_count = */ 2); | |
4892 compiler->pc_descriptors_list()->AddDescriptor( | |
4893 RawPcDescriptors::kOther, | |
4894 compiler->assembler()->CodeSize(), | |
4895 instruction_->deopt_id(), | |
4896 instruction_->token_pos(), | |
4897 try_index_); | |
4898 __ break_(0); | |
4899 } | |
4900 | |
4901 private: | |
4902 GenericCheckBoundInstr* instruction_; | |
4903 intptr_t try_index_; | |
4904 }; | |
4905 | |
4906 | |
4907 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
4908 RangeErrorSlowPath* slow_path = | |
4909 new RangeErrorSlowPath(this, compiler->CurrentTryIndex()); | |
4910 compiler->AddSlowPathCode(slow_path); | |
4911 | |
4912 Location length_loc = locs()->in(kLengthPos); | |
4913 Location index_loc = locs()->in(kIndexPos); | |
4914 Register length = length_loc.reg(); | |
4915 Register index = index_loc.reg(); | |
4916 const intptr_t index_cid = this->index()->Type()->ToCid(); | |
4917 if (index_cid != kSmiCid) { | |
4918 __ BranchIfNotSmi(index, slow_path->entry_label()); | |
4919 } | |
4920 __ BranchUnsignedGreaterEqual(index, length, slow_path->entry_label()); | |
4921 } | |
4922 | |
4923 | |
4924 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone, | 4862 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone, |
4925 bool opt) const { | 4863 bool opt) const { |
4926 const intptr_t kNumInputs = 2; | 4864 const intptr_t kNumInputs = 2; |
4927 const intptr_t kNumTemps = 0; | 4865 const intptr_t kNumTemps = 0; |
4928 LocationSummary* locs = new(zone) LocationSummary( | 4866 LocationSummary* locs = new(zone) LocationSummary( |
4929 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4867 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4930 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 4868 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
4931 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 4869 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
4932 return locs; | 4870 return locs; |
4933 } | 4871 } |
(...skipping 13 matching lines...) Expand all Loading... |
4947 if (length_loc.IsConstant() && index_loc.IsConstant()) { | 4885 if (length_loc.IsConstant() && index_loc.IsConstant()) { |
4948 ASSERT((Smi::Cast(length_loc.constant()).Value() <= | 4886 ASSERT((Smi::Cast(length_loc.constant()).Value() <= |
4949 Smi::Cast(index_loc.constant()).Value()) || | 4887 Smi::Cast(index_loc.constant()).Value()) || |
4950 (Smi::Cast(index_loc.constant()).Value() < 0)); | 4888 (Smi::Cast(index_loc.constant()).Value() < 0)); |
4951 // Unconditionally deoptimize for constant bounds checks because they | 4889 // Unconditionally deoptimize for constant bounds checks because they |
4952 // only occur only when index is out-of-bounds. | 4890 // only occur only when index is out-of-bounds. |
4953 __ b(deopt); | 4891 __ b(deopt); |
4954 return; | 4892 return; |
4955 } | 4893 } |
4956 | 4894 |
4957 const intptr_t index_cid = index()->Type()->ToCid(); | |
4958 if (index_loc.IsConstant()) { | 4895 if (index_loc.IsConstant()) { |
4959 Register length = length_loc.reg(); | 4896 Register length = length_loc.reg(); |
4960 const Smi& index = Smi::Cast(index_loc.constant()); | 4897 const Smi& index = Smi::Cast(index_loc.constant()); |
4961 __ BranchUnsignedLessEqual( | 4898 __ BranchUnsignedLessEqual( |
4962 length, Immediate(reinterpret_cast<int32_t>(index.raw())), deopt); | 4899 length, Immediate(reinterpret_cast<int32_t>(index.raw())), deopt); |
4963 } else if (length_loc.IsConstant()) { | 4900 } else if (length_loc.IsConstant()) { |
4964 const Smi& length = Smi::Cast(length_loc.constant()); | 4901 const Smi& length = Smi::Cast(length_loc.constant()); |
4965 Register index = index_loc.reg(); | 4902 Register index = index_loc.reg(); |
4966 if (index_cid != kSmiCid) { | |
4967 __ BranchIfNotSmi(index, deopt); | |
4968 } | |
4969 if (length.Value() == Smi::kMaxValue) { | 4903 if (length.Value() == Smi::kMaxValue) { |
4970 __ BranchSignedLess(index, Immediate(0), deopt); | 4904 __ BranchSignedLess(index, Immediate(0), deopt); |
4971 } else { | 4905 } else { |
4972 __ BranchUnsignedGreaterEqual( | 4906 __ BranchUnsignedGreaterEqual( |
4973 index, Immediate(reinterpret_cast<int32_t>(length.raw())), deopt); | 4907 index, Immediate(reinterpret_cast<int32_t>(length.raw())), deopt); |
4974 } | 4908 } |
4975 } else { | 4909 } else { |
4976 Register length = length_loc.reg(); | 4910 Register length = length_loc.reg(); |
4977 Register index = index_loc.reg(); | 4911 Register index = index_loc.reg(); |
4978 if (index_cid != kSmiCid) { | |
4979 __ BranchIfNotSmi(index, deopt); | |
4980 } | |
4981 __ BranchUnsignedGreaterEqual(index, length, deopt); | 4912 __ BranchUnsignedGreaterEqual(index, length, deopt); |
4982 } | 4913 } |
4983 } | 4914 } |
4984 | 4915 |
4985 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, | 4916 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, |
4986 bool opt) const { | 4917 bool opt) const { |
4987 const intptr_t kNumInputs = 2; | 4918 const intptr_t kNumInputs = 2; |
4988 const intptr_t kNumTemps = 0; | 4919 const intptr_t kNumTemps = 0; |
4989 LocationSummary* summary = new(zone) LocationSummary( | 4920 LocationSummary* summary = new(zone) LocationSummary( |
4990 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4921 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5796 1, | 5727 1, |
5797 locs()); | 5728 locs()); |
5798 __ lw(result, Address(SP, 1 * kWordSize)); | 5729 __ lw(result, Address(SP, 1 * kWordSize)); |
5799 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 5730 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
5800 } | 5731 } |
5801 | 5732 |
5802 | 5733 |
5803 } // namespace dart | 5734 } // namespace dart |
5804 | 5735 |
5805 #endif // defined TARGET_ARCH_MIPS | 5736 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |