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 4841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4852 } | 4852 } |
4853 | 4853 |
4854 | 4854 |
4855 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4855 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4856 Register value = locs()->in(0).reg(); | 4856 Register value = locs()->in(0).reg(); |
4857 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | 4857 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); |
4858 __ BranchNotEqual(value, Immediate(Smi::RawValue(cid_)), deopt); | 4858 __ BranchNotEqual(value, Immediate(Smi::RawValue(cid_)), deopt); |
4859 } | 4859 } |
4860 | 4860 |
4861 | 4861 |
4862 LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone, | |
4863 bool opt) const { | |
4864 const intptr_t kNumInputs = 2; | |
4865 const intptr_t kNumTemps = 0; | |
4866 LocationSummary* locs = new(zone) LocationSummary( | |
4867 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | |
4868 locs->set_in(kLengthPos, Location::RequiresRegister()); | |
4869 locs->set_in(kIndexPos, Location::RequiresRegister()); | |
4870 return locs; | |
4871 } | |
4872 | |
4873 | |
4874 class RangeErrorSlowPath : public SlowPathCode { | |
4875 public: | |
4876 RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index) | |
4877 : instruction_(instruction), try_index_(try_index) { } | |
4878 | |
4879 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
4880 if (Assembler::EmittingComments()) { | |
4881 __ Comment("slow path check bound operation"); | |
4882 } | |
4883 __ Bind(entry_label()); | |
4884 LocationSummary* locs = instruction_->locs(); | |
4885 __ Push(locs->in(0).reg()); | |
4886 __ Push(locs->in(1).reg()); | |
4887 compiler->GenerateRuntimeCall(instruction_->token_pos(), | |
4888 instruction_->deopt_id(), | |
4889 kRangeErrorRuntimeEntry, | |
4890 2, | |
4891 instruction_->locs()); | |
4892 compiler->RecordSafepoint(locs, /* slow_path_argument_count = */ 2); | |
4893 compiler->pc_descriptors_list()->AddDescriptor( | |
4894 RawPcDescriptors::kOther, | |
4895 compiler->assembler()->CodeSize(), | |
4896 instruction_->deopt_id(), | |
4897 instruction_->token_pos(), | |
4898 try_index_); | |
4899 __ break_(0); | |
4900 } | |
4901 | |
4902 private: | |
4903 GenericCheckBoundInstr* instruction_; | |
4904 intptr_t try_index_; | |
4905 }; | |
4906 | |
4907 | |
4908 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
4909 RangeErrorSlowPath* slow_path = | |
4910 new RangeErrorSlowPath(this, compiler->CurrentTryIndex()); | |
4911 compiler->AddSlowPathCode(slow_path); | |
4912 | |
4913 Location length_loc = locs()->in(kLengthPos); | |
4914 Location index_loc = locs()->in(kIndexPos); | |
4915 Register length = length_loc.reg(); | |
4916 Register index = index_loc.reg(); | |
4917 const intptr_t index_cid = this->index()->Type()->ToCid(); | |
4918 if (index_cid != kSmiCid) { | |
4919 __ andi(CMPRES1, index, Immediate(kSmiTagMask)); | |
Vyacheslav Egorov (Google)
2016/07/14 09:35:59
I wonder if assembler could benefit from BranchIfS
Florian Schneider
2016/07/14 17:05:21
Ya, I wished that too.
I'll add BranchIfNotSmi an
| |
4920 __ bne(CMPRES1, ZR, slow_path->entry_label()); | |
4921 } | |
4922 __ BranchUnsignedGreaterEqual(index, length, slow_path->entry_label()); | |
4923 } | |
4924 | |
4925 | |
4862 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone, | 4926 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone, |
4863 bool opt) const { | 4927 bool opt) const { |
4864 const intptr_t kNumInputs = 2; | 4928 const intptr_t kNumInputs = 2; |
4865 const intptr_t kNumTemps = 0; | 4929 const intptr_t kNumTemps = 0; |
4866 LocationSummary* locs = new(zone) LocationSummary( | 4930 LocationSummary* locs = new(zone) LocationSummary( |
4867 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4931 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4868 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 4932 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
4869 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 4933 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
4870 return locs; | 4934 return locs; |
4871 } | 4935 } |
(...skipping 13 matching lines...) Expand all Loading... | |
4885 if (length_loc.IsConstant() && index_loc.IsConstant()) { | 4949 if (length_loc.IsConstant() && index_loc.IsConstant()) { |
4886 ASSERT((Smi::Cast(length_loc.constant()).Value() <= | 4950 ASSERT((Smi::Cast(length_loc.constant()).Value() <= |
4887 Smi::Cast(index_loc.constant()).Value()) || | 4951 Smi::Cast(index_loc.constant()).Value()) || |
4888 (Smi::Cast(index_loc.constant()).Value() < 0)); | 4952 (Smi::Cast(index_loc.constant()).Value() < 0)); |
4889 // Unconditionally deoptimize for constant bounds checks because they | 4953 // Unconditionally deoptimize for constant bounds checks because they |
4890 // only occur only when index is out-of-bounds. | 4954 // only occur only when index is out-of-bounds. |
4891 __ b(deopt); | 4955 __ b(deopt); |
4892 return; | 4956 return; |
4893 } | 4957 } |
4894 | 4958 |
4959 const intptr_t index_cid = index()->Type()->ToCid(); | |
4895 if (index_loc.IsConstant()) { | 4960 if (index_loc.IsConstant()) { |
4896 Register length = length_loc.reg(); | 4961 Register length = length_loc.reg(); |
4897 const Smi& index = Smi::Cast(index_loc.constant()); | 4962 const Smi& index = Smi::Cast(index_loc.constant()); |
4898 __ BranchUnsignedLessEqual( | 4963 __ BranchUnsignedLessEqual( |
4899 length, Immediate(reinterpret_cast<int32_t>(index.raw())), deopt); | 4964 length, Immediate(reinterpret_cast<int32_t>(index.raw())), deopt); |
4900 } else if (length_loc.IsConstant()) { | 4965 } else if (length_loc.IsConstant()) { |
4901 const Smi& length = Smi::Cast(length_loc.constant()); | 4966 const Smi& length = Smi::Cast(length_loc.constant()); |
4902 Register index = index_loc.reg(); | 4967 Register index = index_loc.reg(); |
4968 if (index_cid != kSmiCid) { | |
4969 __ andi(CMPRES1, index, Immediate(kSmiTagMask)); | |
4970 __ bne(CMPRES1, ZR, deopt); | |
4971 } | |
4903 if (length.Value() == Smi::kMaxValue) { | 4972 if (length.Value() == Smi::kMaxValue) { |
4904 __ BranchSignedLess(index, Immediate(0), deopt); | 4973 __ BranchSignedLess(index, Immediate(0), deopt); |
4905 } else { | 4974 } else { |
4906 __ BranchUnsignedGreaterEqual( | 4975 __ BranchUnsignedGreaterEqual( |
4907 index, Immediate(reinterpret_cast<int32_t>(length.raw())), deopt); | 4976 index, Immediate(reinterpret_cast<int32_t>(length.raw())), deopt); |
4908 } | 4977 } |
4909 } else { | 4978 } else { |
4910 Register length = length_loc.reg(); | 4979 Register length = length_loc.reg(); |
4911 Register index = index_loc.reg(); | 4980 Register index = index_loc.reg(); |
4981 if (index_cid != kSmiCid) { | |
4982 __ andi(CMPRES1, index, Immediate(kSmiTagMask)); | |
4983 __ bne(CMPRES1, ZR, deopt); | |
4984 } | |
4912 __ BranchUnsignedGreaterEqual(index, length, deopt); | 4985 __ BranchUnsignedGreaterEqual(index, length, deopt); |
4913 } | 4986 } |
4914 } | 4987 } |
4915 | 4988 |
4916 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, | 4989 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, |
4917 bool opt) const { | 4990 bool opt) const { |
4918 const intptr_t kNumInputs = 2; | 4991 const intptr_t kNumInputs = 2; |
4919 const intptr_t kNumTemps = 0; | 4992 const intptr_t kNumTemps = 0; |
4920 LocationSummary* summary = new(zone) LocationSummary( | 4993 LocationSummary* summary = new(zone) LocationSummary( |
4921 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4994 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5727 1, | 5800 1, |
5728 locs()); | 5801 locs()); |
5729 __ lw(result, Address(SP, 1 * kWordSize)); | 5802 __ lw(result, Address(SP, 1 * kWordSize)); |
5730 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 5803 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
5731 } | 5804 } |
5732 | 5805 |
5733 | 5806 |
5734 } // namespace dart | 5807 } // namespace dart |
5735 | 5808 |
5736 #endif // defined TARGET_ARCH_MIPS | 5809 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |