| 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/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 } | 703 } |
| 704 | 704 |
| 705 | 705 |
| 706 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 706 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 707 BranchLabels labels) { | 707 BranchLabels labels) { |
| 708 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); | 708 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); |
| 709 Register val_reg = locs()->in(0).reg(); | 709 Register val_reg = locs()->in(0).reg(); |
| 710 Register cid_reg = locs()->temp(0).reg(); | 710 Register cid_reg = locs()->temp(0).reg(); |
| 711 | 711 |
| 712 Label* deopt = CanDeoptimize() ? | 712 Label* deopt = CanDeoptimize() ? |
| 713 compiler->AddDeoptStub(deopt_id(), kDeoptTestCids) : NULL; | 713 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL; |
| 714 | 714 |
| 715 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; | 715 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; |
| 716 const ZoneGrowableArray<intptr_t>& data = cid_results(); | 716 const ZoneGrowableArray<intptr_t>& data = cid_results(); |
| 717 ASSERT(data[0] == kSmiCid); | 717 ASSERT(data[0] == kSmiCid); |
| 718 bool result = data[1] == true_result; | 718 bool result = data[1] == true_result; |
| 719 __ tst(val_reg, ShifterOperand(kSmiTagMask)); | 719 __ tst(val_reg, ShifterOperand(kSmiTagMask)); |
| 720 __ b(result ? labels.true_label : labels.false_label, EQ); | 720 __ b(result ? labels.true_label : labels.false_label, EQ); |
| 721 __ LoadClassId(cid_reg, val_reg); | 721 __ LoadClassId(cid_reg, val_reg); |
| 722 | 722 |
| 723 for (intptr_t i = 2; i < data.length(); i += 2) { | 723 for (intptr_t i = 2; i < data.length(); i += 2) { |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 case kTypedDataInt16ArrayCid: | 1239 case kTypedDataInt16ArrayCid: |
| 1240 __ ldrsh(result, element_address); | 1240 __ ldrsh(result, element_address); |
| 1241 __ SmiTag(result); | 1241 __ SmiTag(result); |
| 1242 break; | 1242 break; |
| 1243 case kTypedDataUint16ArrayCid: | 1243 case kTypedDataUint16ArrayCid: |
| 1244 case kTwoByteStringCid: | 1244 case kTwoByteStringCid: |
| 1245 __ ldrh(result, element_address); | 1245 __ ldrh(result, element_address); |
| 1246 __ SmiTag(result); | 1246 __ SmiTag(result); |
| 1247 break; | 1247 break; |
| 1248 case kTypedDataInt32ArrayCid: { | 1248 case kTypedDataInt32ArrayCid: { |
| 1249 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load); | 1249 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 1250 ICData::kDeoptInt32Load); |
| 1250 __ ldr(result, element_address); | 1251 __ ldr(result, element_address); |
| 1251 // Verify that the signed value in 'result' can fit inside a Smi. | 1252 // Verify that the signed value in 'result' can fit inside a Smi. |
| 1252 __ CompareImmediate(result, 0xC0000000); | 1253 __ CompareImmediate(result, 0xC0000000); |
| 1253 __ b(deopt, MI); | 1254 __ b(deopt, MI); |
| 1254 __ SmiTag(result); | 1255 __ SmiTag(result); |
| 1255 } | 1256 } |
| 1256 break; | 1257 break; |
| 1257 case kTypedDataUint32ArrayCid: { | 1258 case kTypedDataUint32ArrayCid: { |
| 1258 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load); | 1259 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 1260 ICData::kDeoptUint32Load); |
| 1259 __ ldr(result, element_address); | 1261 __ ldr(result, element_address); |
| 1260 // Verify that the unsigned value in 'result' can fit inside a Smi. | 1262 // Verify that the unsigned value in 'result' can fit inside a Smi. |
| 1261 __ TestImmediate(result, 0xC0000000); | 1263 __ TestImmediate(result, 0xC0000000); |
| 1262 __ b(deopt, NE); | 1264 __ b(deopt, NE); |
| 1263 __ SmiTag(result); | 1265 __ SmiTag(result); |
| 1264 } | 1266 } |
| 1265 break; | 1267 break; |
| 1266 default: | 1268 default: |
| 1267 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1269 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1268 __ ldr(result, element_address); | 1270 __ ldr(result, element_address); |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 Register value_cid_reg = locs()->temp(0).reg(); | 1548 Register value_cid_reg = locs()->temp(0).reg(); |
| 1547 | 1549 |
| 1548 Register temp_reg = locs()->temp(1).reg(); | 1550 Register temp_reg = locs()->temp(1).reg(); |
| 1549 | 1551 |
| 1550 Register field_reg = needs_field_temp_reg ? | 1552 Register field_reg = needs_field_temp_reg ? |
| 1551 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; | 1553 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; |
| 1552 | 1554 |
| 1553 Label ok, fail_label; | 1555 Label ok, fail_label; |
| 1554 | 1556 |
| 1555 Label* deopt = compiler->is_optimizing() ? | 1557 Label* deopt = compiler->is_optimizing() ? |
| 1556 compiler->AddDeoptStub(deopt_id(), kDeoptGuardField) : NULL; | 1558 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL; |
| 1557 | 1559 |
| 1558 Label* fail = (deopt != NULL) ? deopt : &fail_label; | 1560 Label* fail = (deopt != NULL) ? deopt : &fail_label; |
| 1559 | 1561 |
| 1560 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) { | 1562 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) { |
| 1561 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) { | 1563 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) { |
| 1562 // Currently we can't have different location summaries for optimized | 1564 // Currently we can't have different location summaries for optimized |
| 1563 // and non-optimized code. So instead we manually pick up a register | 1565 // and non-optimized code. So instead we manually pick up a register |
| 1564 // that is known to be free because we know how non-optimizing compiler | 1566 // that is known to be free because we know how non-optimizing compiler |
| 1565 // allocates registers. | 1567 // allocates registers. |
| 1566 field_reg = R2; | 1568 field_reg = R2; |
| (...skipping 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2740 } | 2742 } |
| 2741 | 2743 |
| 2742 | 2744 |
| 2743 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2745 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| 2744 BinarySmiOpInstr* shift_left) { | 2746 BinarySmiOpInstr* shift_left) { |
| 2745 const bool is_truncating = shift_left->is_truncating(); | 2747 const bool is_truncating = shift_left->is_truncating(); |
| 2746 const LocationSummary& locs = *shift_left->locs(); | 2748 const LocationSummary& locs = *shift_left->locs(); |
| 2747 Register left = locs.in(0).reg(); | 2749 Register left = locs.in(0).reg(); |
| 2748 Register result = locs.out(0).reg(); | 2750 Register result = locs.out(0).reg(); |
| 2749 Label* deopt = shift_left->CanDeoptimize() ? | 2751 Label* deopt = shift_left->CanDeoptimize() ? |
| 2750 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; | 2752 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) |
| 2753 : NULL; |
| 2751 if (locs.in(1).IsConstant()) { | 2754 if (locs.in(1).IsConstant()) { |
| 2752 const Object& constant = locs.in(1).constant(); | 2755 const Object& constant = locs.in(1).constant(); |
| 2753 ASSERT(constant.IsSmi()); | 2756 ASSERT(constant.IsSmi()); |
| 2754 // Immediate shift operation takes 5 bits for the count. | 2757 // Immediate shift operation takes 5 bits for the count. |
| 2755 const intptr_t kCountLimit = 0x1F; | 2758 const intptr_t kCountLimit = 0x1F; |
| 2756 const intptr_t value = Smi::Cast(constant).Value(); | 2759 const intptr_t value = Smi::Cast(constant).Value(); |
| 2757 if (value == 0) { | 2760 if (value == 0) { |
| 2758 __ MoveRegister(result, left); | 2761 __ MoveRegister(result, left); |
| 2759 } else if ((value < 0) || (value >= kCountLimit)) { | 2762 } else if ((value < 0) || (value >= kCountLimit)) { |
| 2760 // This condition may not be known earlier in some cases because | 2763 // This condition may not be known earlier in some cases because |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2895 if (op_kind() == Token::kSHL) { | 2898 if (op_kind() == Token::kSHL) { |
| 2896 EmitSmiShiftLeft(compiler, this); | 2899 EmitSmiShiftLeft(compiler, this); |
| 2897 return; | 2900 return; |
| 2898 } | 2901 } |
| 2899 | 2902 |
| 2900 ASSERT(!is_truncating()); | 2903 ASSERT(!is_truncating()); |
| 2901 Register left = locs()->in(0).reg(); | 2904 Register left = locs()->in(0).reg(); |
| 2902 Register result = locs()->out(0).reg(); | 2905 Register result = locs()->out(0).reg(); |
| 2903 Label* deopt = NULL; | 2906 Label* deopt = NULL; |
| 2904 if (CanDeoptimize()) { | 2907 if (CanDeoptimize()) { |
| 2905 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); | 2908 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
| 2906 } | 2909 } |
| 2907 | 2910 |
| 2908 if (locs()->in(1).IsConstant()) { | 2911 if (locs()->in(1).IsConstant()) { |
| 2909 const Object& constant = locs()->in(1).constant(); | 2912 const Object& constant = locs()->in(1).constant(); |
| 2910 ASSERT(constant.IsSmi()); | 2913 ASSERT(constant.IsSmi()); |
| 2911 int32_t imm = reinterpret_cast<int32_t>(constant.raw()); | 2914 int32_t imm = reinterpret_cast<int32_t>(constant.raw()); |
| 2912 switch (op_kind()) { | 2915 switch (op_kind()) { |
| 2913 case Token::kSUB: { | 2916 case Token::kSUB: { |
| 2914 imm = -imm; // TODO(regis): What if deopt != NULL && imm == 0x80000000? | 2917 imm = -imm; // TODO(regis): What if deopt != NULL && imm == 0x80000000? |
| 2915 // Fall through. | 2918 // Fall through. |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3190 const intptr_t kNumTemps = 0; | 3193 const intptr_t kNumTemps = 0; |
| 3191 LocationSummary* summary = | 3194 LocationSummary* summary = |
| 3192 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3195 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3193 summary->set_in(0, Location::RequiresRegister()); | 3196 summary->set_in(0, Location::RequiresRegister()); |
| 3194 summary->set_in(1, Location::RequiresRegister()); | 3197 summary->set_in(1, Location::RequiresRegister()); |
| 3195 return summary; | 3198 return summary; |
| 3196 } | 3199 } |
| 3197 | 3200 |
| 3198 | 3201 |
| 3199 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3202 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3200 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp); | 3203 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3204 ICData::kDeoptBinaryDoubleOp); |
| 3201 intptr_t left_cid = left()->Type()->ToCid(); | 3205 intptr_t left_cid = left()->Type()->ToCid(); |
| 3202 intptr_t right_cid = right()->Type()->ToCid(); | 3206 intptr_t right_cid = right()->Type()->ToCid(); |
| 3203 Register left = locs()->in(0).reg(); | 3207 Register left = locs()->in(0).reg(); |
| 3204 Register right = locs()->in(1).reg(); | 3208 Register right = locs()->in(1).reg(); |
| 3205 if (left_cid == kSmiCid) { | 3209 if (left_cid == kSmiCid) { |
| 3206 __ tst(right, ShifterOperand(kSmiTagMask)); | 3210 __ tst(right, ShifterOperand(kSmiTagMask)); |
| 3207 } else if (right_cid == kSmiCid) { | 3211 } else if (right_cid == kSmiCid) { |
| 3208 __ tst(left, ShifterOperand(kSmiTagMask)); | 3212 __ tst(left, ShifterOperand(kSmiTagMask)); |
| 3209 } else { | 3213 } else { |
| 3210 __ orr(IP, left, ShifterOperand(right)); | 3214 __ orr(IP, left, ShifterOperand(right)); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3266 const Register value = locs()->in(0).reg(); | 3270 const Register value = locs()->in(0).reg(); |
| 3267 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | 3271 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 3268 | 3272 |
| 3269 if (value_cid == kDoubleCid) { | 3273 if (value_cid == kDoubleCid) { |
| 3270 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); | 3274 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); |
| 3271 } else if (value_cid == kSmiCid) { | 3275 } else if (value_cid == kSmiCid) { |
| 3272 __ SmiUntag(value); // Untag input before conversion. | 3276 __ SmiUntag(value); // Untag input before conversion. |
| 3273 __ vmovsr(STMP, value); | 3277 __ vmovsr(STMP, value); |
| 3274 __ vcvtdi(result, STMP); | 3278 __ vcvtdi(result, STMP); |
| 3275 } else { | 3279 } else { |
| 3276 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); | 3280 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
| 3281 ICData::kDeoptBinaryDoubleOp); |
| 3277 Register temp = locs()->temp(0).reg(); | 3282 Register temp = locs()->temp(0).reg(); |
| 3278 Label is_smi, done; | 3283 Label is_smi, done; |
| 3279 __ tst(value, ShifterOperand(kSmiTagMask)); | 3284 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3280 __ b(&is_smi, EQ); | 3285 __ b(&is_smi, EQ); |
| 3281 __ CompareClassId(value, kDoubleCid, temp); | 3286 __ CompareClassId(value, kDoubleCid, temp); |
| 3282 __ b(deopt, NE); | 3287 __ b(deopt, NE); |
| 3283 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); | 3288 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); |
| 3284 __ b(&done); | 3289 __ b(&done); |
| 3285 __ Bind(&is_smi); | 3290 __ Bind(&is_smi); |
| 3286 // TODO(regis): Why do we preserve value here but not above? | 3291 // TODO(regis): Why do we preserve value here but not above? |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3341 } | 3346 } |
| 3342 | 3347 |
| 3343 | 3348 |
| 3344 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3349 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3345 const intptr_t value_cid = value()->Type()->ToCid(); | 3350 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3346 const Register value = locs()->in(0).reg(); | 3351 const Register value = locs()->in(0).reg(); |
| 3347 const QRegister result = locs()->out(0).fpu_reg(); | 3352 const QRegister result = locs()->out(0).fpu_reg(); |
| 3348 | 3353 |
| 3349 if (value_cid != kFloat32x4Cid) { | 3354 if (value_cid != kFloat32x4Cid) { |
| 3350 const Register temp = locs()->temp(0).reg(); | 3355 const Register temp = locs()->temp(0).reg(); |
| 3351 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3356 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); |
| 3352 __ tst(value, ShifterOperand(kSmiTagMask)); | 3357 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3353 __ b(deopt, EQ); | 3358 __ b(deopt, EQ); |
| 3354 __ CompareClassId(value, kFloat32x4Cid, temp); | 3359 __ CompareClassId(value, kFloat32x4Cid, temp); |
| 3355 __ b(deopt, NE); | 3360 __ b(deopt, NE); |
| 3356 } | 3361 } |
| 3357 | 3362 |
| 3358 const DRegister dresult0 = EvenDRegisterOf(result); | 3363 const DRegister dresult0 = EvenDRegisterOf(result); |
| 3359 __ LoadMultipleDFromOffset(dresult0, 2, value, | 3364 __ LoadMultipleDFromOffset(dresult0, 2, value, |
| 3360 Float32x4::value_offset() - kHeapObjectTag); | 3365 Float32x4::value_offset() - kHeapObjectTag); |
| 3361 } | 3366 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3410 } | 3415 } |
| 3411 | 3416 |
| 3412 | 3417 |
| 3413 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3418 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3414 const intptr_t value_cid = value()->Type()->ToCid(); | 3419 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3415 const Register value = locs()->in(0).reg(); | 3420 const Register value = locs()->in(0).reg(); |
| 3416 const QRegister result = locs()->out(0).fpu_reg(); | 3421 const QRegister result = locs()->out(0).fpu_reg(); |
| 3417 | 3422 |
| 3418 if (value_cid != kFloat64x2Cid) { | 3423 if (value_cid != kFloat64x2Cid) { |
| 3419 const Register temp = locs()->temp(0).reg(); | 3424 const Register temp = locs()->temp(0).reg(); |
| 3420 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3425 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); |
| 3421 __ tst(value, ShifterOperand(kSmiTagMask)); | 3426 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3422 __ b(deopt, EQ); | 3427 __ b(deopt, EQ); |
| 3423 __ CompareClassId(value, kFloat64x2Cid, temp); | 3428 __ CompareClassId(value, kFloat64x2Cid, temp); |
| 3424 __ b(deopt, NE); | 3429 __ b(deopt, NE); |
| 3425 } | 3430 } |
| 3426 | 3431 |
| 3427 const DRegister dresult0 = EvenDRegisterOf(result); | 3432 const DRegister dresult0 = EvenDRegisterOf(result); |
| 3428 __ LoadMultipleDFromOffset(dresult0, 2, value, | 3433 __ LoadMultipleDFromOffset(dresult0, 2, value, |
| 3429 Float64x2::value_offset() - kHeapObjectTag); | 3434 Float64x2::value_offset() - kHeapObjectTag); |
| 3430 } | 3435 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3510 } | 3515 } |
| 3511 | 3516 |
| 3512 | 3517 |
| 3513 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3518 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3514 const intptr_t value_cid = value()->Type()->ToCid(); | 3519 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3515 const Register value = locs()->in(0).reg(); | 3520 const Register value = locs()->in(0).reg(); |
| 3516 const QRegister result = locs()->out(0).fpu_reg(); | 3521 const QRegister result = locs()->out(0).fpu_reg(); |
| 3517 | 3522 |
| 3518 if (value_cid != kInt32x4Cid) { | 3523 if (value_cid != kInt32x4Cid) { |
| 3519 const Register temp = locs()->temp(0).reg(); | 3524 const Register temp = locs()->temp(0).reg(); |
| 3520 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3525 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); |
| 3521 __ tst(value, ShifterOperand(kSmiTagMask)); | 3526 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3522 __ b(deopt, EQ); | 3527 __ b(deopt, EQ); |
| 3523 __ CompareClassId(value, kInt32x4Cid, temp); | 3528 __ CompareClassId(value, kInt32x4Cid, temp); |
| 3524 __ b(deopt, NE); | 3529 __ b(deopt, NE); |
| 3525 } | 3530 } |
| 3526 | 3531 |
| 3527 const DRegister dresult0 = EvenDRegisterOf(result); | 3532 const DRegister dresult0 = EvenDRegisterOf(result); |
| 3528 __ LoadMultipleDFromOffset(dresult0, 2, value, | 3533 __ LoadMultipleDFromOffset(dresult0, 2, value, |
| 3529 Int32x4::value_offset() - kHeapObjectTag); | 3534 Int32x4::value_offset() - kHeapObjectTag); |
| 3530 } | 3535 } |
| (...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4821 summary->set_out(0, Location::RequiresRegister()); | 4826 summary->set_out(0, Location::RequiresRegister()); |
| 4822 return summary; | 4827 return summary; |
| 4823 } | 4828 } |
| 4824 | 4829 |
| 4825 | 4830 |
| 4826 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4831 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4827 Register value = locs()->in(0).reg(); | 4832 Register value = locs()->in(0).reg(); |
| 4828 Register result = locs()->out(0).reg(); | 4833 Register result = locs()->out(0).reg(); |
| 4829 switch (op_kind()) { | 4834 switch (op_kind()) { |
| 4830 case Token::kNEGATE: { | 4835 case Token::kNEGATE: { |
| 4831 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4836 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp); |
| 4832 kDeoptUnaryOp); | |
| 4833 __ rsbs(result, value, ShifterOperand(0)); | 4837 __ rsbs(result, value, ShifterOperand(0)); |
| 4834 __ b(deopt, VS); | 4838 __ b(deopt, VS); |
| 4835 break; | 4839 break; |
| 4836 } | 4840 } |
| 4837 case Token::kBIT_NOT: | 4841 case Token::kBIT_NOT: |
| 4838 __ mvn(result, ShifterOperand(value)); | 4842 __ mvn(result, ShifterOperand(value)); |
| 4839 // Remove inverted smi-tag. | 4843 // Remove inverted smi-tag. |
| 4840 __ bic(result, result, ShifterOperand(kSmiTagMask)); | 4844 __ bic(result, result, ShifterOperand(kSmiTagMask)); |
| 4841 break; | 4845 break; |
| 4842 default: | 4846 default: |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4940 const intptr_t kNumTemps = 0; | 4944 const intptr_t kNumTemps = 0; |
| 4941 LocationSummary* result = new LocationSummary( | 4945 LocationSummary* result = new LocationSummary( |
| 4942 kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4946 kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4943 result->set_in(0, Location::RequiresFpuRegister()); | 4947 result->set_in(0, Location::RequiresFpuRegister()); |
| 4944 result->set_out(0, Location::RequiresRegister()); | 4948 result->set_out(0, Location::RequiresRegister()); |
| 4945 return result; | 4949 return result; |
| 4946 } | 4950 } |
| 4947 | 4951 |
| 4948 | 4952 |
| 4949 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4953 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4950 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 4954 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptDoubleToSmi); |
| 4951 Register result = locs()->out(0).reg(); | 4955 Register result = locs()->out(0).reg(); |
| 4952 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4956 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
| 4953 // First check for NaN. Checking for minint after the conversion doesn't work | 4957 // First check for NaN. Checking for minint after the conversion doesn't work |
| 4954 // on ARM because vcvtid gives 0 for NaN. | 4958 // on ARM because vcvtid gives 0 for NaN. |
| 4955 __ vcmpd(value, value); | 4959 __ vcmpd(value, value); |
| 4956 __ vmstat(); | 4960 __ vmstat(); |
| 4957 __ b(deopt, VS); | 4961 __ b(deopt, VS); |
| 4958 | 4962 |
| 4959 __ vcvtid(STMP, value); | 4963 __ vcvtid(STMP, value); |
| 4960 __ vmovrs(result, STMP); | 4964 __ vmovrs(result, STMP); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5202 return summary; | 5206 return summary; |
| 5203 } | 5207 } |
| 5204 UNIMPLEMENTED(); | 5208 UNIMPLEMENTED(); |
| 5205 return NULL; | 5209 return NULL; |
| 5206 } | 5210 } |
| 5207 | 5211 |
| 5208 | 5212 |
| 5209 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5213 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5210 Label* deopt = NULL; | 5214 Label* deopt = NULL; |
| 5211 if (CanDeoptimize()) { | 5215 if (CanDeoptimize()) { |
| 5212 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); | 5216 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
| 5213 } | 5217 } |
| 5214 if (kind() == MergedMathInstr::kTruncDivMod) { | 5218 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 5215 Register left = locs()->in(0).reg(); | 5219 Register left = locs()->in(0).reg(); |
| 5216 Register right = locs()->in(1).reg(); | 5220 Register right = locs()->in(1).reg(); |
| 5217 ASSERT(locs()->out(0).IsPairLocation()); | 5221 ASSERT(locs()->out(0).IsPairLocation()); |
| 5218 PairLocation* pair = locs()->out(0).AsPairLocation(); | 5222 PairLocation* pair = locs()->out(0).AsPairLocation(); |
| 5219 Register result_div = pair->At(0).reg(); | 5223 Register result_div = pair->At(0).reg(); |
| 5220 Register result_mod = pair->At(1).reg(); | 5224 Register result_mod = pair->At(1).reg(); |
| 5221 Range* right_range = InputAt(1)->definition()->range(); | 5225 Range* right_range = InputAt(1)->definition()->range(); |
| 5222 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 5226 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5268 } | 5272 } |
| 5269 | 5273 |
| 5270 | 5274 |
| 5271 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( | 5275 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
| 5272 bool opt) const { | 5276 bool opt) const { |
| 5273 return MakeCallSummary(); | 5277 return MakeCallSummary(); |
| 5274 } | 5278 } |
| 5275 | 5279 |
| 5276 | 5280 |
| 5277 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5281 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5278 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 5282 Label* deopt = compiler->AddDeoptStub( |
| 5279 kDeoptPolymorphicInstanceCallTestFail); | 5283 deopt_id(), ICData::kDeoptPolymorphicInstanceCallTestFail); |
| 5280 if (ic_data().NumberOfChecks() == 0) { | 5284 if (ic_data().NumberOfChecks() == 0) { |
| 5281 __ b(deopt); | 5285 __ b(deopt); |
| 5282 return; | 5286 return; |
| 5283 } | 5287 } |
| 5284 ASSERT(ic_data().num_args_tested() == 1); | 5288 ASSERT(ic_data().NumArgsTested() == 1); |
| 5285 if (!with_checks()) { | 5289 if (!with_checks()) { |
| 5286 ASSERT(ic_data().HasOneTarget()); | 5290 ASSERT(ic_data().HasOneTarget()); |
| 5287 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 5291 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
| 5288 compiler->GenerateStaticCall(deopt_id(), | 5292 compiler->GenerateStaticCall(deopt_id(), |
| 5289 instance_call()->token_pos(), | 5293 instance_call()->token_pos(), |
| 5290 target, | 5294 target, |
| 5291 instance_call()->ArgumentCount(), | 5295 instance_call()->ArgumentCount(), |
| 5292 instance_call()->argument_names(), | 5296 instance_call()->argument_names(), |
| 5293 locs()); | 5297 locs()); |
| 5294 return; | 5298 return; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5332 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5336 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5333 summary->set_in(0, Location::RequiresRegister()); | 5337 summary->set_in(0, Location::RequiresRegister()); |
| 5334 if (!IsNullCheck()) { | 5338 if (!IsNullCheck()) { |
| 5335 summary->AddTemp(Location::RequiresRegister()); | 5339 summary->AddTemp(Location::RequiresRegister()); |
| 5336 } | 5340 } |
| 5337 return summary; | 5341 return summary; |
| 5338 } | 5342 } |
| 5339 | 5343 |
| 5340 | 5344 |
| 5341 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5345 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5342 const DeoptReasonId deopt_reason = | 5346 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 5343 licm_hoisted_ ? kDeoptHoistedCheckClass : kDeoptCheckClass; | 5347 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 5344 if (IsNullCheck()) { | 5348 if (IsNullCheck()) { |
| 5345 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 5349 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| 5346 __ CompareImmediate(locs()->in(0).reg(), | 5350 __ CompareImmediate(locs()->in(0).reg(), |
| 5347 reinterpret_cast<intptr_t>(Object::null())); | 5351 reinterpret_cast<intptr_t>(Object::null())); |
| 5348 __ b(deopt, EQ); | 5352 __ b(deopt, EQ); |
| 5349 return; | 5353 return; |
| 5350 } | 5354 } |
| 5351 | 5355 |
| 5352 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | 5356 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || |
| 5353 (unary_checks().NumberOfChecks() > 1)); | 5357 (unary_checks().NumberOfChecks() > 1)); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 5384 const intptr_t kNumTemps = 0; | 5388 const intptr_t kNumTemps = 0; |
| 5385 LocationSummary* summary = | 5389 LocationSummary* summary = |
| 5386 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5390 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5387 summary->set_in(0, Location::RequiresRegister()); | 5391 summary->set_in(0, Location::RequiresRegister()); |
| 5388 return summary; | 5392 return summary; |
| 5389 } | 5393 } |
| 5390 | 5394 |
| 5391 | 5395 |
| 5392 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5396 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5393 Register value = locs()->in(0).reg(); | 5397 Register value = locs()->in(0).reg(); |
| 5394 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 5398 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); |
| 5395 kDeoptCheckSmi); | |
| 5396 __ tst(value, ShifterOperand(kSmiTagMask)); | 5399 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 5397 __ b(deopt, NE); | 5400 __ b(deopt, NE); |
| 5398 } | 5401 } |
| 5399 | 5402 |
| 5400 | 5403 |
| 5401 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { | 5404 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { |
| 5402 const intptr_t kNumInputs = 2; | 5405 const intptr_t kNumInputs = 2; |
| 5403 const intptr_t kNumTemps = 0; | 5406 const intptr_t kNumTemps = 0; |
| 5404 LocationSummary* locs = | 5407 LocationSummary* locs = |
| 5405 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5408 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5406 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 5409 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 5407 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 5410 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
| 5408 return locs; | 5411 return locs; |
| 5409 } | 5412 } |
| 5410 | 5413 |
| 5411 | 5414 |
| 5412 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5415 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5413 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptCheckArrayBound); | 5416 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 5417 ICData::kDeoptCheckArrayBound); |
| 5414 | 5418 |
| 5415 Location length_loc = locs()->in(kLengthPos); | 5419 Location length_loc = locs()->in(kLengthPos); |
| 5416 Location index_loc = locs()->in(kIndexPos); | 5420 Location index_loc = locs()->in(kIndexPos); |
| 5417 | 5421 |
| 5418 if (length_loc.IsConstant() && index_loc.IsConstant()) { | 5422 if (length_loc.IsConstant() && index_loc.IsConstant()) { |
| 5419 // TODO(srdjan): remove this code once failures are fixed. | 5423 // TODO(srdjan): remove this code once failures are fixed. |
| 5420 if ((Smi::Cast(length_loc.constant()).Value() > | 5424 if ((Smi::Cast(length_loc.constant()).Value() > |
| 5421 Smi::Cast(index_loc.constant()).Value()) && | 5425 Smi::Cast(index_loc.constant()).Value()) && |
| 5422 (Smi::Cast(index_loc.constant()).Value() >= 0)) { | 5426 (Smi::Cast(index_loc.constant()).Value() >= 0)) { |
| 5423 // This CheckArrayBoundInstr should have been eliminated. | 5427 // This CheckArrayBoundInstr should have been eliminated. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5503 __ LoadDFromOffset(EvenDRegisterOf(result), value, | 5507 __ LoadDFromOffset(EvenDRegisterOf(result), value, |
| 5504 Mint::value_offset() - kHeapObjectTag); | 5508 Mint::value_offset() - kHeapObjectTag); |
| 5505 } else if (value_cid == kSmiCid) { | 5509 } else if (value_cid == kSmiCid) { |
| 5506 Register temp = locs()->temp(0).reg(); | 5510 Register temp = locs()->temp(0).reg(); |
| 5507 __ SmiUntag(value); | 5511 __ SmiUntag(value); |
| 5508 // Sign extend value into temp. | 5512 // Sign extend value into temp. |
| 5509 __ Asr(temp, value, 31); | 5513 __ Asr(temp, value, 31); |
| 5510 __ vmovdrr(EvenDRegisterOf(result), value, temp); | 5514 __ vmovdrr(EvenDRegisterOf(result), value, temp); |
| 5511 } else { | 5515 } else { |
| 5512 Register temp = locs()->temp(0).reg(); | 5516 Register temp = locs()->temp(0).reg(); |
| 5513 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptUnboxInteger); | 5517 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
| 5518 ICData::kDeoptUnboxInteger); |
| 5514 Label is_smi, done; | 5519 Label is_smi, done; |
| 5515 __ tst(value, ShifterOperand(kSmiTagMask)); | 5520 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 5516 __ b(&is_smi, EQ); | 5521 __ b(&is_smi, EQ); |
| 5517 __ CompareClassId(value, kMintCid, temp); | 5522 __ CompareClassId(value, kMintCid, temp); |
| 5518 __ b(deopt, NE); | 5523 __ b(deopt, NE); |
| 5519 | 5524 |
| 5520 // It's a Mint. | 5525 // It's a Mint. |
| 5521 __ LoadDFromOffset(EvenDRegisterOf(result), value, | 5526 __ LoadDFromOffset(EvenDRegisterOf(result), value, |
| 5522 Mint::value_offset() - kHeapObjectTag); | 5527 Mint::value_offset() - kHeapObjectTag); |
| 5523 __ b(&done); | 5528 __ b(&done); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5655 } | 5660 } |
| 5656 | 5661 |
| 5657 | 5662 |
| 5658 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5663 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5659 QRegister left = locs()->in(0).fpu_reg(); | 5664 QRegister left = locs()->in(0).fpu_reg(); |
| 5660 QRegister right = locs()->in(1).fpu_reg(); | 5665 QRegister right = locs()->in(1).fpu_reg(); |
| 5661 QRegister out = locs()->out(0).fpu_reg(); | 5666 QRegister out = locs()->out(0).fpu_reg(); |
| 5662 | 5667 |
| 5663 Label* deopt = NULL; | 5668 Label* deopt = NULL; |
| 5664 if (FLAG_throw_on_javascript_int_overflow) { | 5669 if (FLAG_throw_on_javascript_int_overflow) { |
| 5665 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp); | 5670 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); |
| 5666 } | 5671 } |
| 5667 switch (op_kind()) { | 5672 switch (op_kind()) { |
| 5668 case Token::kBIT_AND: __ vandq(out, left, right); break; | 5673 case Token::kBIT_AND: __ vandq(out, left, right); break; |
| 5669 case Token::kBIT_OR: __ vorrq(out, left, right); break; | 5674 case Token::kBIT_OR: __ vorrq(out, left, right); break; |
| 5670 case Token::kBIT_XOR: __ veorq(out, left, right); break; | 5675 case Token::kBIT_XOR: __ veorq(out, left, right); break; |
| 5671 case Token::kADD: | 5676 case Token::kADD: |
| 5672 case Token::kSUB: { | 5677 case Token::kSUB: { |
| 5673 const intptr_t tmpidx = FLAG_throw_on_javascript_int_overflow ? 2 : 0; | 5678 const intptr_t tmpidx = FLAG_throw_on_javascript_int_overflow ? 2 : 0; |
| 5674 QRegister tmp = locs()->temp(tmpidx).fpu_reg(); | 5679 QRegister tmp = locs()->temp(tmpidx).fpu_reg(); |
| 5675 QRegister ro = locs()->temp(tmpidx + 1).fpu_reg(); | 5680 QRegister ro = locs()->temp(tmpidx + 1).fpu_reg(); |
| 5676 ASSERT(ro == Q7); | 5681 ASSERT(ro == Q7); |
| 5677 if (!FLAG_throw_on_javascript_int_overflow) { | 5682 if (!FLAG_throw_on_javascript_int_overflow) { |
| 5678 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp); | 5683 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); |
| 5679 } | 5684 } |
| 5680 if (op_kind() == Token::kADD) { | 5685 if (op_kind() == Token::kADD) { |
| 5681 __ vaddqi(kWordPair, out, left, right); | 5686 __ vaddqi(kWordPair, out, left, right); |
| 5682 } else { | 5687 } else { |
| 5683 ASSERT(op_kind() == Token::kSUB); | 5688 ASSERT(op_kind() == Token::kSUB); |
| 5684 __ vsubqi(kWordPair, out, left, right); | 5689 __ vsubqi(kWordPair, out, left, right); |
| 5685 } | 5690 } |
| 5686 __ veorq(ro, out, left); | 5691 __ veorq(ro, out, left); |
| 5687 __ veorq(tmp, left, right); | 5692 __ veorq(tmp, left, right); |
| 5688 __ vandq(ro, tmp, ro); | 5693 __ vandq(ro, tmp, ro); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5722 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5727 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5723 QRegister value = locs()->in(0).fpu_reg(); | 5728 QRegister value = locs()->in(0).fpu_reg(); |
| 5724 Register shift = locs()->in(1).reg(); | 5729 Register shift = locs()->in(1).reg(); |
| 5725 QRegister temp = locs()->temp(0).fpu_reg(); | 5730 QRegister temp = locs()->temp(0).fpu_reg(); |
| 5726 ASSERT(temp == Q7); | 5731 ASSERT(temp == Q7); |
| 5727 QRegister out = locs()->out(0).fpu_reg(); | 5732 QRegister out = locs()->out(0).fpu_reg(); |
| 5728 DRegister dtemp0 = EvenDRegisterOf(temp); | 5733 DRegister dtemp0 = EvenDRegisterOf(temp); |
| 5729 SRegister stemp0 = EvenSRegisterOf(dtemp0); | 5734 SRegister stemp0 = EvenSRegisterOf(dtemp0); |
| 5730 SRegister stemp1 = OddSRegisterOf(dtemp0); | 5735 SRegister stemp1 = OddSRegisterOf(dtemp0); |
| 5731 | 5736 |
| 5732 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptShiftMintOp); | 5737 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); |
| 5733 Label done; | 5738 Label done; |
| 5734 | 5739 |
| 5735 __ CompareImmediate(shift, 0); | 5740 __ CompareImmediate(shift, 0); |
| 5736 __ vmovq(out, value); | 5741 __ vmovq(out, value); |
| 5737 __ b(&done, EQ); | 5742 __ b(&done, EQ); |
| 5738 __ SmiUntag(shift); | 5743 __ SmiUntag(shift); |
| 5739 | 5744 |
| 5740 // vshlq takes the shift value from low byte. Deopt if shift is | 5745 // vshlq takes the shift value from low byte. Deopt if shift is |
| 5741 // outside of [0, 127]. | 5746 // outside of [0, 127]. |
| 5742 __ CompareImmediate(shift, 127); | 5747 __ CompareImmediate(shift, 127); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5800 return summary; | 5805 return summary; |
| 5801 } | 5806 } |
| 5802 | 5807 |
| 5803 | 5808 |
| 5804 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5809 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5805 ASSERT(op_kind() == Token::kBIT_NOT); | 5810 ASSERT(op_kind() == Token::kBIT_NOT); |
| 5806 QRegister value = locs()->in(0).fpu_reg(); | 5811 QRegister value = locs()->in(0).fpu_reg(); |
| 5807 QRegister out = locs()->out(0).fpu_reg(); | 5812 QRegister out = locs()->out(0).fpu_reg(); |
| 5808 Label* deopt = NULL; | 5813 Label* deopt = NULL; |
| 5809 if (FLAG_throw_on_javascript_int_overflow) { | 5814 if (FLAG_throw_on_javascript_int_overflow) { |
| 5810 deopt = compiler->AddDeoptStub(deopt_id(), | 5815 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); |
| 5811 kDeoptUnaryMintOp); | |
| 5812 } | 5816 } |
| 5813 __ vmvnq(out, value); | 5817 __ vmvnq(out, value); |
| 5814 if (FLAG_throw_on_javascript_int_overflow) { | 5818 if (FLAG_throw_on_javascript_int_overflow) { |
| 5815 Register tmp1 = locs()->temp(0).reg(); | 5819 Register tmp1 = locs()->temp(0).reg(); |
| 5816 Register tmp2 = locs()->temp(1).reg(); | 5820 Register tmp2 = locs()->temp(1).reg(); |
| 5817 EmitJavascriptIntOverflowCheck(compiler, deopt, out, tmp1, tmp2); | 5821 EmitJavascriptIntOverflowCheck(compiler, deopt, out, tmp1, tmp2); |
| 5818 } | 5822 } |
| 5819 } | 5823 } |
| 5820 | 5824 |
| 5821 | 5825 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6017 compiler->GenerateCall(token_pos(), | 6021 compiler->GenerateCall(token_pos(), |
| 6018 &label, | 6022 &label, |
| 6019 PcDescriptors::kOther, | 6023 PcDescriptors::kOther, |
| 6020 locs()); | 6024 locs()); |
| 6021 __ Drop(ArgumentCount()); // Discard arguments. | 6025 __ Drop(ArgumentCount()); // Discard arguments. |
| 6022 } | 6026 } |
| 6023 | 6027 |
| 6024 } // namespace dart | 6028 } // namespace dart |
| 6025 | 6029 |
| 6026 #endif // defined TARGET_ARCH_ARM | 6030 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |