| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1862 LocationSummary* summary = new (zone) LocationSummary( | 1862 LocationSummary* summary = new (zone) LocationSummary( |
| 1863 zone, kNumInputs, kNumTemps, | 1863 zone, kNumInputs, kNumTemps, |
| 1864 might_box ? LocationSummary::kCallOnSlowPath : LocationSummary::kNoCall); | 1864 might_box ? LocationSummary::kCallOnSlowPath : LocationSummary::kNoCall); |
| 1865 summary->set_in(0, Location::RequiresRegister()); | 1865 summary->set_in(0, Location::RequiresRegister()); |
| 1866 summary->set_in(1, Location::RequiresRegister()); | 1866 summary->set_in(1, Location::RequiresRegister()); |
| 1867 | 1867 |
| 1868 if (might_box) { | 1868 if (might_box) { |
| 1869 summary->set_temp(0, Location::RequiresRegister()); | 1869 summary->set_temp(0, Location::RequiresRegister()); |
| 1870 } | 1870 } |
| 1871 | 1871 |
| 1872 if (representation() == kUnboxedMint) { | 1872 if (representation() == kUnboxedInt64) { |
| 1873 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | 1873 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
| 1874 Location::RequiresRegister())); | 1874 Location::RequiresRegister())); |
| 1875 } else { | 1875 } else { |
| 1876 ASSERT(representation() == kTagged); | 1876 ASSERT(representation() == kTagged); |
| 1877 summary->set_out(0, Location::RequiresRegister()); | 1877 summary->set_out(0, Location::RequiresRegister()); |
| 1878 } | 1878 } |
| 1879 | 1879 |
| 1880 return summary; | 1880 return summary; |
| 1881 } | 1881 } |
| 1882 | 1882 |
| 1883 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1883 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1884 // The string register points to the backing store for external strings. | 1884 // The string register points to the backing store for external strings. |
| 1885 const Register str = locs()->in(0).reg(); | 1885 const Register str = locs()->in(0).reg(); |
| 1886 const Location index = locs()->in(1); | 1886 const Location index = locs()->in(1); |
| 1887 | 1887 |
| 1888 Address element_address = __ ElementAddressForRegIndex( | 1888 Address element_address = __ ElementAddressForRegIndex( |
| 1889 true, IsExternal(), class_id(), index_scale(), str, index.reg()); | 1889 true, IsExternal(), class_id(), index_scale(), str, index.reg()); |
| 1890 // Warning: element_address may use register IP as base. | 1890 // Warning: element_address may use register IP as base. |
| 1891 | 1891 |
| 1892 if (representation() == kUnboxedMint) { | 1892 if (representation() == kUnboxedInt64) { |
| 1893 ASSERT(compiler->is_optimizing()); | 1893 ASSERT(compiler->is_optimizing()); |
| 1894 ASSERT(locs()->out(0).IsPairLocation()); | 1894 ASSERT(locs()->out(0).IsPairLocation()); |
| 1895 PairLocation* result_pair = locs()->out(0).AsPairLocation(); | 1895 PairLocation* result_pair = locs()->out(0).AsPairLocation(); |
| 1896 Register result1 = result_pair->At(0).reg(); | 1896 Register result1 = result_pair->At(0).reg(); |
| 1897 Register result2 = result_pair->At(1).reg(); | 1897 Register result2 = result_pair->At(1).reg(); |
| 1898 switch (class_id()) { | 1898 switch (class_id()) { |
| 1899 case kOneByteStringCid: | 1899 case kOneByteStringCid: |
| 1900 case kExternalOneByteStringCid: | 1900 case kExternalOneByteStringCid: |
| 1901 ASSERT(element_count() == 4); | 1901 ASSERT(element_count() == 4); |
| 1902 __ ldr(result1, element_address); | 1902 __ ldr(result1, element_address); |
| (...skipping 1911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3814 LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, bool opt) const { | 3814 LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, bool opt) const { |
| 3815 const bool needs_temp = CanDeoptimize(); | 3815 const bool needs_temp = CanDeoptimize(); |
| 3816 const intptr_t kNumInputs = 1; | 3816 const intptr_t kNumInputs = 1; |
| 3817 const intptr_t kNumTemps = needs_temp ? 1 : 0; | 3817 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
| 3818 LocationSummary* summary = new (zone) | 3818 LocationSummary* summary = new (zone) |
| 3819 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3819 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3820 summary->set_in(0, Location::RequiresRegister()); | 3820 summary->set_in(0, Location::RequiresRegister()); |
| 3821 if (needs_temp) { | 3821 if (needs_temp) { |
| 3822 summary->set_temp(0, Location::RequiresRegister()); | 3822 summary->set_temp(0, Location::RequiresRegister()); |
| 3823 } | 3823 } |
| 3824 if (representation() == kUnboxedMint) { | 3824 if (representation() == kUnboxedInt64) { |
| 3825 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | 3825 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
| 3826 Location::RequiresRegister())); | 3826 Location::RequiresRegister())); |
| 3827 } else { | 3827 } else { |
| 3828 summary->set_out(0, Location::RequiresFpuRegister()); | 3828 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3829 } | 3829 } |
| 3830 return summary; | 3830 return summary; |
| 3831 } | 3831 } |
| 3832 | 3832 |
| 3833 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { | 3833 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { |
| 3834 const Register box = locs()->in(0).reg(); | 3834 const Register box = locs()->in(0).reg(); |
| 3835 | 3835 |
| 3836 switch (representation()) { | 3836 switch (representation()) { |
| 3837 case kUnboxedMint: { | 3837 case kUnboxedInt64: { |
| 3838 PairLocation* result = locs()->out(0).AsPairLocation(); | 3838 PairLocation* result = locs()->out(0).AsPairLocation(); |
| 3839 __ LoadFieldFromOffset(kWord, result->At(0).reg(), box, ValueOffset()); | 3839 __ LoadFieldFromOffset(kWord, result->At(0).reg(), box, ValueOffset()); |
| 3840 __ LoadFieldFromOffset(kWord, result->At(1).reg(), box, | 3840 __ LoadFieldFromOffset(kWord, result->At(1).reg(), box, |
| 3841 ValueOffset() + kWordSize); | 3841 ValueOffset() + kWordSize); |
| 3842 break; | 3842 break; |
| 3843 } | 3843 } |
| 3844 | 3844 |
| 3845 case kUnboxedDouble: { | 3845 case kUnboxedDouble: { |
| 3846 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | 3846 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 3847 __ LoadDFromOffset(result, box, ValueOffset() - kHeapObjectTag); | 3847 __ LoadDFromOffset(result, box, ValueOffset() - kHeapObjectTag); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3860 default: | 3860 default: |
| 3861 UNREACHABLE(); | 3861 UNREACHABLE(); |
| 3862 break; | 3862 break; |
| 3863 } | 3863 } |
| 3864 } | 3864 } |
| 3865 | 3865 |
| 3866 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { | 3866 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { |
| 3867 const Register box = locs()->in(0).reg(); | 3867 const Register box = locs()->in(0).reg(); |
| 3868 | 3868 |
| 3869 switch (representation()) { | 3869 switch (representation()) { |
| 3870 case kUnboxedMint: { | 3870 case kUnboxedInt64: { |
| 3871 PairLocation* result = locs()->out(0).AsPairLocation(); | 3871 PairLocation* result = locs()->out(0).AsPairLocation(); |
| 3872 __ SmiUntag(result->At(0).reg(), box); | 3872 __ SmiUntag(result->At(0).reg(), box); |
| 3873 __ SignFill(result->At(1).reg(), result->At(0).reg()); | 3873 __ SignFill(result->At(1).reg(), result->At(0).reg()); |
| 3874 break; | 3874 break; |
| 3875 } | 3875 } |
| 3876 | 3876 |
| 3877 case kUnboxedDouble: { | 3877 case kUnboxedDouble: { |
| 3878 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | 3878 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 3879 __ SmiUntag(IP, box); | 3879 __ SmiUntag(IP, box); |
| 3880 __ vmovdr(DTMP, 0, IP); | 3880 __ vmovdr(DTMP, 0, IP); |
| (...skipping 2300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6181 const Register length = length_loc.reg(); | 6181 const Register length = length_loc.reg(); |
| 6182 const Register index = index_loc.reg(); | 6182 const Register index = index_loc.reg(); |
| 6183 if (index_cid != kSmiCid) { | 6183 if (index_cid != kSmiCid) { |
| 6184 __ BranchIfNotSmi(index, deopt); | 6184 __ BranchIfNotSmi(index, deopt); |
| 6185 } | 6185 } |
| 6186 __ cmp(index, Operand(length)); | 6186 __ cmp(index, Operand(length)); |
| 6187 __ b(deopt, CS); | 6187 __ b(deopt, CS); |
| 6188 } | 6188 } |
| 6189 } | 6189 } |
| 6190 | 6190 |
| 6191 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, | 6191 LocationSummary* BinaryInt64OpInstr::MakeLocationSummary(Zone* zone, |
| 6192 bool opt) const { | 6192 bool opt) const { |
| 6193 const intptr_t kNumInputs = 2; | 6193 const intptr_t kNumInputs = 2; |
| 6194 const intptr_t kNumTemps = 0; | 6194 const intptr_t kNumTemps = 0; |
| 6195 LocationSummary* summary = new (zone) | 6195 LocationSummary* summary = new (zone) |
| 6196 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6196 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6197 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 6197 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 6198 Location::RequiresRegister())); | 6198 Location::RequiresRegister())); |
| 6199 summary->set_in(1, Location::Pair(Location::RequiresRegister(), | 6199 summary->set_in(1, Location::Pair(Location::RequiresRegister(), |
| 6200 Location::RequiresRegister())); | 6200 Location::RequiresRegister())); |
| 6201 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | 6201 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
| 6202 Location::RequiresRegister())); | 6202 Location::RequiresRegister())); |
| 6203 return summary; | 6203 return summary; |
| 6204 } | 6204 } |
| 6205 | 6205 |
| 6206 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6206 void BinaryInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6207 PairLocation* left_pair = locs()->in(0).AsPairLocation(); | 6207 PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
| 6208 Register left_lo = left_pair->At(0).reg(); | 6208 Register left_lo = left_pair->At(0).reg(); |
| 6209 Register left_hi = left_pair->At(1).reg(); | 6209 Register left_hi = left_pair->At(1).reg(); |
| 6210 PairLocation* right_pair = locs()->in(1).AsPairLocation(); | 6210 PairLocation* right_pair = locs()->in(1).AsPairLocation(); |
| 6211 Register right_lo = right_pair->At(0).reg(); | 6211 Register right_lo = right_pair->At(0).reg(); |
| 6212 Register right_hi = right_pair->At(1).reg(); | 6212 Register right_hi = right_pair->At(1).reg(); |
| 6213 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6213 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 6214 Register out_lo = out_pair->At(0).reg(); | 6214 Register out_lo = out_pair->At(0).reg(); |
| 6215 Register out_hi = out_pair->At(1).reg(); | 6215 Register out_hi = out_pair->At(1).reg(); |
| 6216 | 6216 |
| 6217 Label* deopt = NULL; | 6217 Label* deopt = NULL; |
| 6218 if (CanDeoptimize()) { | 6218 if (CanDeoptimize()) { |
| 6219 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 6219 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); |
| 6220 } | 6220 } |
| 6221 switch (op_kind()) { | 6221 switch (op_kind()) { |
| 6222 case Token::kBIT_AND: { | 6222 case Token::kBIT_AND: { |
| 6223 __ and_(out_lo, left_lo, Operand(right_lo)); | 6223 __ and_(out_lo, left_lo, Operand(right_lo)); |
| 6224 __ and_(out_hi, left_hi, Operand(right_hi)); | 6224 __ and_(out_hi, left_hi, Operand(right_hi)); |
| 6225 break; | 6225 break; |
| 6226 } | 6226 } |
| 6227 case Token::kBIT_OR: { | 6227 case Token::kBIT_OR: { |
| 6228 __ orr(out_lo, left_lo, Operand(right_lo)); | 6228 __ orr(out_lo, left_lo, Operand(right_lo)); |
| 6229 __ orr(out_hi, left_hi, Operand(right_hi)); | 6229 __ orr(out_hi, left_hi, Operand(right_hi)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 6259 __ cmp(right_hi, Operand(right_lo, ASR, 31), EQ); | 6259 __ cmp(right_hi, Operand(right_lo, ASR, 31), EQ); |
| 6260 __ b(deopt, NE); | 6260 __ b(deopt, NE); |
| 6261 __ smull(out_lo, out_hi, left_lo, right_lo); | 6261 __ smull(out_lo, out_hi, left_lo, right_lo); |
| 6262 break; | 6262 break; |
| 6263 } | 6263 } |
| 6264 default: | 6264 default: |
| 6265 UNREACHABLE(); | 6265 UNREACHABLE(); |
| 6266 } | 6266 } |
| 6267 } | 6267 } |
| 6268 | 6268 |
| 6269 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone, | 6269 LocationSummary* ShiftInt64OpInstr::MakeLocationSummary(Zone* zone, |
| 6270 bool opt) const { | 6270 bool opt) const { |
| 6271 const intptr_t kNumInputs = 2; | 6271 const intptr_t kNumInputs = 2; |
| 6272 const intptr_t kNumTemps = 0; | 6272 const intptr_t kNumTemps = 0; |
| 6273 LocationSummary* summary = new (zone) | 6273 LocationSummary* summary = new (zone) |
| 6274 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6274 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6275 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 6275 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 6276 Location::RequiresRegister())); | 6276 Location::RequiresRegister())); |
| 6277 summary->set_in(1, Location::WritableRegisterOrSmiConstant(right())); | 6277 summary->set_in(1, Location::WritableRegisterOrSmiConstant(right())); |
| 6278 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | 6278 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
| 6279 Location::RequiresRegister())); | 6279 Location::RequiresRegister())); |
| 6280 return summary; | 6280 return summary; |
| 6281 } | 6281 } |
| 6282 | 6282 |
| 6283 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6283 void ShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6284 PairLocation* left_pair = locs()->in(0).AsPairLocation(); | 6284 PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
| 6285 Register left_lo = left_pair->At(0).reg(); | 6285 Register left_lo = left_pair->At(0).reg(); |
| 6286 Register left_hi = left_pair->At(1).reg(); | 6286 Register left_hi = left_pair->At(1).reg(); |
| 6287 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6287 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 6288 Register out_lo = out_pair->At(0).reg(); | 6288 Register out_lo = out_pair->At(0).reg(); |
| 6289 Register out_hi = out_pair->At(1).reg(); | 6289 Register out_hi = out_pair->At(1).reg(); |
| 6290 | 6290 |
| 6291 Label* deopt = NULL; | 6291 Label* deopt = NULL; |
| 6292 if (CanDeoptimize()) { | 6292 if (CanDeoptimize()) { |
| 6293 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 6293 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); |
| 6294 } | 6294 } |
| 6295 if (locs()->in(1).IsConstant()) { | 6295 if (locs()->in(1).IsConstant()) { |
| 6296 // Code for a constant shift amount. | 6296 // Code for a constant shift amount. |
| 6297 ASSERT(locs()->in(1).constant().IsSmi()); | 6297 ASSERT(locs()->in(1).constant().IsSmi()); |
| 6298 const int32_t shift = Smi::Cast(locs()->in(1).constant()).Value(); | 6298 const int32_t shift = Smi::Cast(locs()->in(1).constant()).Value(); |
| 6299 ASSERT(shift >= 0); | 6299 ASSERT(shift >= 0); |
| 6300 switch (op_kind()) { | 6300 switch (op_kind()) { |
| 6301 case Token::kSHR: { | 6301 case Token::kSHR: { |
| 6302 if (shift < 32) { | 6302 if (shift < 32) { |
| 6303 __ Lsl(out_lo, left_hi, Operand(32 - shift)); | 6303 __ Lsl(out_lo, left_hi, Operand(32 - shift)); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6394 __ b(deopt, NE); | 6394 __ b(deopt, NE); |
| 6395 } | 6395 } |
| 6396 break; | 6396 break; |
| 6397 } | 6397 } |
| 6398 default: | 6398 default: |
| 6399 UNREACHABLE(); | 6399 UNREACHABLE(); |
| 6400 } | 6400 } |
| 6401 } | 6401 } |
| 6402 } | 6402 } |
| 6403 | 6403 |
| 6404 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone, | 6404 LocationSummary* UnaryInt64OpInstr::MakeLocationSummary(Zone* zone, |
| 6405 bool opt) const { | 6405 bool opt) const { |
| 6406 const intptr_t kNumInputs = 1; | 6406 const intptr_t kNumInputs = 1; |
| 6407 const intptr_t kNumTemps = 0; | 6407 const intptr_t kNumTemps = 0; |
| 6408 LocationSummary* summary = new (zone) | 6408 LocationSummary* summary = new (zone) |
| 6409 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6409 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6410 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 6410 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 6411 Location::RequiresRegister())); | 6411 Location::RequiresRegister())); |
| 6412 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | 6412 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
| 6413 Location::RequiresRegister())); | 6413 Location::RequiresRegister())); |
| 6414 return summary; | 6414 return summary; |
| 6415 } | 6415 } |
| 6416 | 6416 |
| 6417 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6417 void UnaryInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6418 ASSERT(op_kind() == Token::kBIT_NOT); | 6418 ASSERT(op_kind() == Token::kBIT_NOT); |
| 6419 PairLocation* left_pair = locs()->in(0).AsPairLocation(); | 6419 PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
| 6420 Register left_lo = left_pair->At(0).reg(); | 6420 Register left_lo = left_pair->At(0).reg(); |
| 6421 Register left_hi = left_pair->At(1).reg(); | 6421 Register left_hi = left_pair->At(1).reg(); |
| 6422 | 6422 |
| 6423 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6423 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 6424 Register out_lo = out_pair->At(0).reg(); | 6424 Register out_lo = out_pair->At(0).reg(); |
| 6425 Register out_hi = out_pair->At(1).reg(); | 6425 Register out_hi = out_pair->At(1).reg(); |
| 6426 __ mvn(out_lo, Operand(left_lo)); | 6426 __ mvn(out_lo, Operand(left_lo)); |
| 6427 __ mvn(out_hi, Operand(left_hi)); | 6427 __ mvn(out_hi, Operand(left_hi)); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6495 | 6495 |
| 6496 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6496 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6497 const intptr_t kShifterLimit = 31; | 6497 const intptr_t kShifterLimit = 31; |
| 6498 | 6498 |
| 6499 Register left = locs()->in(0).reg(); | 6499 Register left = locs()->in(0).reg(); |
| 6500 Register out = locs()->out(0).reg(); | 6500 Register out = locs()->out(0).reg(); |
| 6501 Register temp = locs()->temp(0).reg(); | 6501 Register temp = locs()->temp(0).reg(); |
| 6502 | 6502 |
| 6503 ASSERT(left != out); | 6503 ASSERT(left != out); |
| 6504 | 6504 |
| 6505 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 6505 Label* deopt = |
| 6506 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); |
| 6506 | 6507 |
| 6507 if (locs()->in(1).IsConstant()) { | 6508 if (locs()->in(1).IsConstant()) { |
| 6508 // Shifter is constant. | 6509 // Shifter is constant. |
| 6509 | 6510 |
| 6510 const Object& constant = locs()->in(1).constant(); | 6511 const Object& constant = locs()->in(1).constant(); |
| 6511 ASSERT(constant.IsSmi()); | 6512 ASSERT(constant.IsSmi()); |
| 6512 const intptr_t shift_value = Smi::Cast(constant).Value(); | 6513 const intptr_t shift_value = Smi::Cast(constant).Value(); |
| 6513 | 6514 |
| 6514 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). | 6515 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). |
| 6515 switch (op_kind()) { | 6516 switch (op_kind()) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6568 | 6569 |
| 6569 __ mvn(out, Operand(left)); | 6570 __ mvn(out, Operand(left)); |
| 6570 } | 6571 } |
| 6571 | 6572 |
| 6572 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone, | 6573 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone, |
| 6573 bool opt) const { | 6574 bool opt) const { |
| 6574 const intptr_t kNumInputs = 1; | 6575 const intptr_t kNumInputs = 1; |
| 6575 const intptr_t kNumTemps = 0; | 6576 const intptr_t kNumTemps = 0; |
| 6576 LocationSummary* summary = new (zone) | 6577 LocationSummary* summary = new (zone) |
| 6577 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6578 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6578 if (from() == kUnboxedMint) { | 6579 if (from() == kUnboxedInt64) { |
| 6579 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); | 6580 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); |
| 6580 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 6581 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 6581 Location::RequiresRegister())); | 6582 Location::RequiresRegister())); |
| 6582 summary->set_out(0, Location::RequiresRegister()); | 6583 summary->set_out(0, Location::RequiresRegister()); |
| 6583 } else if (to() == kUnboxedMint) { | 6584 } else if (to() == kUnboxedInt64) { |
| 6584 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); | 6585 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); |
| 6585 summary->set_in(0, Location::RequiresRegister()); | 6586 summary->set_in(0, Location::RequiresRegister()); |
| 6586 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | 6587 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
| 6587 Location::RequiresRegister())); | 6588 Location::RequiresRegister())); |
| 6588 } else { | 6589 } else { |
| 6589 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); | 6590 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); |
| 6590 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); | 6591 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); |
| 6591 summary->set_in(0, Location::RequiresRegister()); | 6592 summary->set_in(0, Location::RequiresRegister()); |
| 6592 summary->set_out(0, Location::SameAsFirstInput()); | 6593 summary->set_out(0, Location::SameAsFirstInput()); |
| 6593 } | 6594 } |
| 6594 return summary; | 6595 return summary; |
| 6595 } | 6596 } |
| 6596 | 6597 |
| 6597 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6598 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6598 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) { | 6599 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) { |
| 6599 const Register out = locs()->out(0).reg(); | 6600 const Register out = locs()->out(0).reg(); |
| 6600 // Representations are bitwise equivalent. | 6601 // Representations are bitwise equivalent. |
| 6601 ASSERT(out == locs()->in(0).reg()); | 6602 ASSERT(out == locs()->in(0).reg()); |
| 6602 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { | 6603 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { |
| 6603 const Register out = locs()->out(0).reg(); | 6604 const Register out = locs()->out(0).reg(); |
| 6604 // Representations are bitwise equivalent. | 6605 // Representations are bitwise equivalent. |
| 6605 ASSERT(out == locs()->in(0).reg()); | 6606 ASSERT(out == locs()->in(0).reg()); |
| 6606 if (CanDeoptimize()) { | 6607 if (CanDeoptimize()) { |
| 6607 Label* deopt = | 6608 Label* deopt = |
| 6608 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | 6609 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 6609 __ tst(out, Operand(out)); | 6610 __ tst(out, Operand(out)); |
| 6610 __ b(deopt, MI); | 6611 __ b(deopt, MI); |
| 6611 } | 6612 } |
| 6612 } else if (from() == kUnboxedMint) { | 6613 } else if (from() == kUnboxedInt64) { |
| 6613 ASSERT(to() == kUnboxedUint32 || to() == kUnboxedInt32); | 6614 ASSERT(to() == kUnboxedUint32 || to() == kUnboxedInt32); |
| 6614 PairLocation* in_pair = locs()->in(0).AsPairLocation(); | 6615 PairLocation* in_pair = locs()->in(0).AsPairLocation(); |
| 6615 Register in_lo = in_pair->At(0).reg(); | 6616 Register in_lo = in_pair->At(0).reg(); |
| 6616 Register in_hi = in_pair->At(1).reg(); | 6617 Register in_hi = in_pair->At(1).reg(); |
| 6617 Register out = locs()->out(0).reg(); | 6618 Register out = locs()->out(0).reg(); |
| 6618 // Copy low word. | 6619 // Copy low word. |
| 6619 __ mov(out, Operand(in_lo)); | 6620 __ mov(out, Operand(in_lo)); |
| 6620 if (CanDeoptimize()) { | 6621 if (CanDeoptimize()) { |
| 6621 Label* deopt = | 6622 Label* deopt = |
| 6622 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | 6623 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 6623 ASSERT(to() == kUnboxedInt32); | 6624 ASSERT(to() == kUnboxedInt32); |
| 6624 __ cmp(in_hi, Operand(in_lo, ASR, kBitsPerWord - 1)); | 6625 __ cmp(in_hi, Operand(in_lo, ASR, kBitsPerWord - 1)); |
| 6625 __ b(deopt, NE); | 6626 __ b(deopt, NE); |
| 6626 } | 6627 } |
| 6627 } else if (from() == kUnboxedUint32 || from() == kUnboxedInt32) { | 6628 } else if (from() == kUnboxedUint32 || from() == kUnboxedInt32) { |
| 6628 ASSERT(to() == kUnboxedMint); | 6629 ASSERT(to() == kUnboxedInt64); |
| 6629 Register in = locs()->in(0).reg(); | 6630 Register in = locs()->in(0).reg(); |
| 6630 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6631 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 6631 Register out_lo = out_pair->At(0).reg(); | 6632 Register out_lo = out_pair->At(0).reg(); |
| 6632 Register out_hi = out_pair->At(1).reg(); | 6633 Register out_hi = out_pair->At(1).reg(); |
| 6633 // Copy low word. | 6634 // Copy low word. |
| 6634 __ mov(out_lo, Operand(in)); | 6635 __ mov(out_lo, Operand(in)); |
| 6635 if (from() == kUnboxedUint32) { | 6636 if (from() == kUnboxedUint32) { |
| 6636 __ eor(out_hi, out_hi, Operand(out_hi)); | 6637 __ eor(out_hi, out_hi, Operand(out_hi)); |
| 6637 } else { | 6638 } else { |
| 6638 ASSERT(from() == kUnboxedInt32); | 6639 ASSERT(from() == kUnboxedInt32); |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6866 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6867 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6867 ASSERT(!compiler->is_optimizing()); | 6868 ASSERT(!compiler->is_optimizing()); |
| 6868 __ BranchLinkPatchable(*StubCode::DebugStepCheck_entry()); | 6869 __ BranchLinkPatchable(*StubCode::DebugStepCheck_entry()); |
| 6869 compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos()); | 6870 compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos()); |
| 6870 compiler->RecordSafepoint(locs()); | 6871 compiler->RecordSafepoint(locs()); |
| 6871 } | 6872 } |
| 6872 | 6873 |
| 6873 } // namespace dart | 6874 } // namespace dart |
| 6874 | 6875 |
| 6875 #endif // defined TARGET_ARCH_ARM | 6876 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |