Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 254723003: Remember all deopt reasons in ic_data, not just the last one. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698