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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 } | 542 } |
543 | 543 |
544 | 544 |
545 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 545 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
546 BranchLabels labels) { | 546 BranchLabels labels) { |
547 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); | 547 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); |
548 Register val_reg = locs()->in(0).reg(); | 548 Register val_reg = locs()->in(0).reg(); |
549 Register cid_reg = locs()->temp(0).reg(); | 549 Register cid_reg = locs()->temp(0).reg(); |
550 | 550 |
551 Label* deopt = CanDeoptimize() ? | 551 Label* deopt = CanDeoptimize() ? |
552 compiler->AddDeoptStub(deopt_id(), kDeoptTestCids) : NULL; | 552 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL; |
553 | 553 |
554 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; | 554 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; |
555 const ZoneGrowableArray<intptr_t>& data = cid_results(); | 555 const ZoneGrowableArray<intptr_t>& data = cid_results(); |
556 ASSERT(data[0] == kSmiCid); | 556 ASSERT(data[0] == kSmiCid); |
557 bool result = data[1] == true_result; | 557 bool result = data[1] == true_result; |
558 __ testq(val_reg, Immediate(kSmiTagMask)); | 558 __ testq(val_reg, Immediate(kSmiTagMask)); |
559 __ j(ZERO, result ? labels.true_label : labels.false_label); | 559 __ j(ZERO, result ? labels.true_label : labels.false_label); |
560 __ LoadClassId(cid_reg, val_reg); | 560 __ LoadClassId(cid_reg, val_reg); |
561 for (intptr_t i = 2; i < data.length(); i += 2) { | 561 for (intptr_t i = 2; i < data.length(); i += 2) { |
562 const intptr_t test_cid = data[i]; | 562 const intptr_t test_cid = data[i]; |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1271 | 1271 |
1272 Register value_cid_reg = needs_value_temp_reg ? | 1272 Register value_cid_reg = needs_value_temp_reg ? |
1273 locs()->temp(0).reg() : kNoRegister; | 1273 locs()->temp(0).reg() : kNoRegister; |
1274 | 1274 |
1275 Register field_reg = needs_field_temp_reg ? | 1275 Register field_reg = needs_field_temp_reg ? |
1276 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; | 1276 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; |
1277 | 1277 |
1278 Label ok, fail_label; | 1278 Label ok, fail_label; |
1279 | 1279 |
1280 Label* deopt = compiler->is_optimizing() ? | 1280 Label* deopt = compiler->is_optimizing() ? |
1281 compiler->AddDeoptStub(deopt_id(), kDeoptGuardField) : NULL; | 1281 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL; |
1282 | 1282 |
1283 Label* fail = (deopt != NULL) ? deopt : &fail_label; | 1283 Label* fail = (deopt != NULL) ? deopt : &fail_label; |
1284 | 1284 |
1285 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) { | 1285 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) { |
1286 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) { | 1286 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) { |
1287 // Currently we can't have different location summaries for optimized | 1287 // Currently we can't have different location summaries for optimized |
1288 // and non-optimized code. So instead we manually pick up a register | 1288 // and non-optimized code. So instead we manually pick up a register |
1289 // that is known to be free because we know how non-optimizing compiler | 1289 // that is known to be free because we know how non-optimizing compiler |
1290 // allocates registers. | 1290 // allocates registers. |
1291 field_reg = RBX; | 1291 field_reg = RBX; |
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2477 | 2477 |
2478 | 2478 |
2479 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2479 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
2480 BinarySmiOpInstr* shift_left) { | 2480 BinarySmiOpInstr* shift_left) { |
2481 const bool is_truncating = shift_left->is_truncating(); | 2481 const bool is_truncating = shift_left->is_truncating(); |
2482 const LocationSummary& locs = *shift_left->locs(); | 2482 const LocationSummary& locs = *shift_left->locs(); |
2483 Register left = locs.in(0).reg(); | 2483 Register left = locs.in(0).reg(); |
2484 Register result = locs.out(0).reg(); | 2484 Register result = locs.out(0).reg(); |
2485 ASSERT(left == result); | 2485 ASSERT(left == result); |
2486 Label* deopt = shift_left->CanDeoptimize() ? | 2486 Label* deopt = shift_left->CanDeoptimize() ? |
2487 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; | 2487 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) |
| 2488 : NULL; |
2488 if (locs.in(1).IsConstant()) { | 2489 if (locs.in(1).IsConstant()) { |
2489 const Object& constant = locs.in(1).constant(); | 2490 const Object& constant = locs.in(1).constant(); |
2490 ASSERT(constant.IsSmi()); | 2491 ASSERT(constant.IsSmi()); |
2491 // shlq operation masks the count to 6 bits. | 2492 // shlq operation masks the count to 6 bits. |
2492 const intptr_t kCountLimit = 0x3F; | 2493 const intptr_t kCountLimit = 0x3F; |
2493 const intptr_t value = Smi::Cast(constant).Value(); | 2494 const intptr_t value = Smi::Cast(constant).Value(); |
2494 if (value == 0) { | 2495 if (value == 0) { |
2495 // No code needed. | 2496 // No code needed. |
2496 } else if ((value < 0) || (value >= kCountLimit)) { | 2497 } else if ((value < 0) || (value >= kCountLimit)) { |
2497 // This condition may not be known earlier in some cases because | 2498 // This condition may not be known earlier in some cases because |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2701 EmitSmiShiftLeft(compiler, this); | 2702 EmitSmiShiftLeft(compiler, this); |
2702 return; | 2703 return; |
2703 } | 2704 } |
2704 | 2705 |
2705 ASSERT(!is_truncating()); | 2706 ASSERT(!is_truncating()); |
2706 Register left = locs()->in(0).reg(); | 2707 Register left = locs()->in(0).reg(); |
2707 Register result = locs()->out(0).reg(); | 2708 Register result = locs()->out(0).reg(); |
2708 ASSERT(left == result); | 2709 ASSERT(left == result); |
2709 Label* deopt = NULL; | 2710 Label* deopt = NULL; |
2710 if (CanDeoptimize()) { | 2711 if (CanDeoptimize()) { |
2711 deopt = compiler->AddDeoptStub(deopt_id(), | 2712 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
2712 kDeoptBinarySmiOp); | |
2713 } | 2713 } |
2714 | 2714 |
2715 if (locs()->in(1).IsConstant()) { | 2715 if (locs()->in(1).IsConstant()) { |
2716 const Object& constant = locs()->in(1).constant(); | 2716 const Object& constant = locs()->in(1).constant(); |
2717 ASSERT(constant.IsSmi()); | 2717 ASSERT(constant.IsSmi()); |
2718 const int64_t imm = | 2718 const int64_t imm = |
2719 reinterpret_cast<int64_t>(constant.raw()); | 2719 reinterpret_cast<int64_t>(constant.raw()); |
2720 switch (op_kind()) { | 2720 switch (op_kind()) { |
2721 case Token::kADD: { | 2721 case Token::kADD: { |
2722 __ AddImmediate(left, Immediate(imm), PP); | 2722 __ AddImmediate(left, Immediate(imm), PP); |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3073 LocationSummary* summary = | 3073 LocationSummary* summary = |
3074 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3074 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3075 summary->set_in(0, Location::RequiresRegister()); | 3075 summary->set_in(0, Location::RequiresRegister()); |
3076 summary->set_in(1, Location::RequiresRegister()); | 3076 summary->set_in(1, Location::RequiresRegister()); |
3077 if (need_temp) summary->set_temp(0, Location::RequiresRegister()); | 3077 if (need_temp) summary->set_temp(0, Location::RequiresRegister()); |
3078 return summary; | 3078 return summary; |
3079 } | 3079 } |
3080 | 3080 |
3081 | 3081 |
3082 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3082 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3083 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp); | 3083 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3084 ICData::kDeoptBinaryDoubleOp); |
3084 intptr_t left_cid = left()->Type()->ToCid(); | 3085 intptr_t left_cid = left()->Type()->ToCid(); |
3085 intptr_t right_cid = right()->Type()->ToCid(); | 3086 intptr_t right_cid = right()->Type()->ToCid(); |
3086 Register left = locs()->in(0).reg(); | 3087 Register left = locs()->in(0).reg(); |
3087 Register right = locs()->in(1).reg(); | 3088 Register right = locs()->in(1).reg(); |
3088 if (left_cid == kSmiCid) { | 3089 if (left_cid == kSmiCid) { |
3089 __ testq(right, Immediate(kSmiTagMask)); | 3090 __ testq(right, Immediate(kSmiTagMask)); |
3090 } else if (right_cid == kSmiCid) { | 3091 } else if (right_cid == kSmiCid) { |
3091 __ testq(left, Immediate(kSmiTagMask)); | 3092 __ testq(left, Immediate(kSmiTagMask)); |
3092 } else { | 3093 } else { |
3093 Register temp = locs()->temp(0).reg(); | 3094 Register temp = locs()->temp(0).reg(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3147 const intptr_t value_cid = value()->Type()->ToCid(); | 3148 const intptr_t value_cid = value()->Type()->ToCid(); |
3148 const Register value = locs()->in(0).reg(); | 3149 const Register value = locs()->in(0).reg(); |
3149 const XmmRegister result = locs()->out(0).fpu_reg(); | 3150 const XmmRegister result = locs()->out(0).fpu_reg(); |
3150 | 3151 |
3151 if (value_cid == kDoubleCid) { | 3152 if (value_cid == kDoubleCid) { |
3152 __ movsd(result, FieldAddress(value, Double::value_offset())); | 3153 __ movsd(result, FieldAddress(value, Double::value_offset())); |
3153 } else if (value_cid == kSmiCid) { | 3154 } else if (value_cid == kSmiCid) { |
3154 __ SmiUntag(value); // Untag input before conversion. | 3155 __ SmiUntag(value); // Untag input before conversion. |
3155 __ cvtsi2sd(result, value); | 3156 __ cvtsi2sd(result, value); |
3156 } else { | 3157 } else { |
3157 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); | 3158 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
| 3159 ICData::kDeoptBinaryDoubleOp); |
3158 Label is_smi, done; | 3160 Label is_smi, done; |
3159 __ testq(value, Immediate(kSmiTagMask)); | 3161 __ testq(value, Immediate(kSmiTagMask)); |
3160 __ j(ZERO, &is_smi); | 3162 __ j(ZERO, &is_smi); |
3161 __ CompareClassId(value, kDoubleCid); | 3163 __ CompareClassId(value, kDoubleCid); |
3162 __ j(NOT_EQUAL, deopt); | 3164 __ j(NOT_EQUAL, deopt); |
3163 __ movsd(result, FieldAddress(value, Double::value_offset())); | 3165 __ movsd(result, FieldAddress(value, Double::value_offset())); |
3164 __ jmp(&done); | 3166 __ jmp(&done); |
3165 __ Bind(&is_smi); | 3167 __ Bind(&is_smi); |
3166 __ SmiUntag(value); | 3168 __ SmiUntag(value); |
3167 __ cvtsi2sd(result, value); | 3169 __ cvtsi2sd(result, value); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3207 LocationSummary::kNoCall); | 3209 LocationSummary::kNoCall); |
3208 } | 3210 } |
3209 | 3211 |
3210 | 3212 |
3211 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3213 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3212 const intptr_t value_cid = value()->Type()->ToCid(); | 3214 const intptr_t value_cid = value()->Type()->ToCid(); |
3213 const Register value = locs()->in(0).reg(); | 3215 const Register value = locs()->in(0).reg(); |
3214 const XmmRegister result = locs()->out(0).fpu_reg(); | 3216 const XmmRegister result = locs()->out(0).fpu_reg(); |
3215 | 3217 |
3216 if (value_cid != kFloat32x4Cid) { | 3218 if (value_cid != kFloat32x4Cid) { |
3217 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3219 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); |
3218 __ testq(value, Immediate(kSmiTagMask)); | 3220 __ testq(value, Immediate(kSmiTagMask)); |
3219 __ j(ZERO, deopt); | 3221 __ j(ZERO, deopt); |
3220 __ CompareClassId(value, kFloat32x4Cid); | 3222 __ CompareClassId(value, kFloat32x4Cid); |
3221 __ j(NOT_EQUAL, deopt); | 3223 __ j(NOT_EQUAL, deopt); |
3222 } | 3224 } |
3223 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | 3225 __ movups(result, FieldAddress(value, Float32x4::value_offset())); |
3224 } | 3226 } |
3225 | 3227 |
3226 | 3228 |
3227 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { | 3229 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3265 return summary; | 3267 return summary; |
3266 } | 3268 } |
3267 | 3269 |
3268 | 3270 |
3269 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3271 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3270 const intptr_t value_cid = value()->Type()->ToCid(); | 3272 const intptr_t value_cid = value()->Type()->ToCid(); |
3271 const Register value = locs()->in(0).reg(); | 3273 const Register value = locs()->in(0).reg(); |
3272 const XmmRegister result = locs()->out(0).fpu_reg(); | 3274 const XmmRegister result = locs()->out(0).fpu_reg(); |
3273 | 3275 |
3274 if (value_cid != kFloat64x2Cid) { | 3276 if (value_cid != kFloat64x2Cid) { |
3275 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3277 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); |
3276 __ testq(value, Immediate(kSmiTagMask)); | 3278 __ testq(value, Immediate(kSmiTagMask)); |
3277 __ j(ZERO, deopt); | 3279 __ j(ZERO, deopt); |
3278 __ CompareClassId(value, kFloat64x2Cid); | 3280 __ CompareClassId(value, kFloat64x2Cid); |
3279 __ j(NOT_EQUAL, deopt); | 3281 __ j(NOT_EQUAL, deopt); |
3280 } | 3282 } |
3281 __ movups(result, FieldAddress(value, Float64x2::value_offset())); | 3283 __ movups(result, FieldAddress(value, Float64x2::value_offset())); |
3282 } | 3284 } |
3283 | 3285 |
3284 | 3286 |
3285 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { | 3287 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3354 return summary; | 3356 return summary; |
3355 } | 3357 } |
3356 | 3358 |
3357 | 3359 |
3358 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3360 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
3359 const intptr_t value_cid = value()->Type()->ToCid(); | 3361 const intptr_t value_cid = value()->Type()->ToCid(); |
3360 const Register value = locs()->in(0).reg(); | 3362 const Register value = locs()->in(0).reg(); |
3361 const XmmRegister result = locs()->out(0).fpu_reg(); | 3363 const XmmRegister result = locs()->out(0).fpu_reg(); |
3362 | 3364 |
3363 if (value_cid != kInt32x4Cid) { | 3365 if (value_cid != kInt32x4Cid) { |
3364 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3366 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); |
3365 __ testq(value, Immediate(kSmiTagMask)); | 3367 __ testq(value, Immediate(kSmiTagMask)); |
3366 __ j(ZERO, deopt); | 3368 __ j(ZERO, deopt); |
3367 __ CompareClassId(value, kInt32x4Cid); | 3369 __ CompareClassId(value, kInt32x4Cid); |
3368 __ j(NOT_EQUAL, deopt); | 3370 __ j(NOT_EQUAL, deopt); |
3369 } | 3371 } |
3370 __ movups(result, FieldAddress(value, Int32x4::value_offset())); | 3372 __ movups(result, FieldAddress(value, Int32x4::value_offset())); |
3371 } | 3373 } |
3372 | 3374 |
3373 | 3375 |
3374 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { | 3376 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4426 Location::SameAsFirstInput(), | 4428 Location::SameAsFirstInput(), |
4427 LocationSummary::kNoCall); | 4429 LocationSummary::kNoCall); |
4428 } | 4430 } |
4429 | 4431 |
4430 | 4432 |
4431 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4433 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4432 Register value = locs()->in(0).reg(); | 4434 Register value = locs()->in(0).reg(); |
4433 ASSERT(value == locs()->out(0).reg()); | 4435 ASSERT(value == locs()->out(0).reg()); |
4434 switch (op_kind()) { | 4436 switch (op_kind()) { |
4435 case Token::kNEGATE: { | 4437 case Token::kNEGATE: { |
4436 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4438 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp); |
4437 kDeoptUnaryOp); | |
4438 __ negq(value); | 4439 __ negq(value); |
4439 __ j(OVERFLOW, deopt); | 4440 __ j(OVERFLOW, deopt); |
4440 if (FLAG_throw_on_javascript_int_overflow) { | 4441 if (FLAG_throw_on_javascript_int_overflow) { |
4441 EmitJavascriptOverflowCheck(compiler, range(), deopt, value); | 4442 EmitJavascriptOverflowCheck(compiler, range(), deopt, value); |
4442 } | 4443 } |
4443 break; | 4444 break; |
4444 } | 4445 } |
4445 case Token::kBIT_NOT: | 4446 case Token::kBIT_NOT: |
4446 __ notq(value); | 4447 __ notq(value); |
4447 // Remove inverted smi-tag. | 4448 // Remove inverted smi-tag. |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4636 LocationSummary* result = new LocationSummary( | 4637 LocationSummary* result = new LocationSummary( |
4637 kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4638 kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4638 result->set_in(0, Location::RequiresFpuRegister()); | 4639 result->set_in(0, Location::RequiresFpuRegister()); |
4639 result->set_out(0, Location:: Location::RequiresRegister()); | 4640 result->set_out(0, Location:: Location::RequiresRegister()); |
4640 result->set_temp(0, Location::RequiresRegister()); | 4641 result->set_temp(0, Location::RequiresRegister()); |
4641 return result; | 4642 return result; |
4642 } | 4643 } |
4643 | 4644 |
4644 | 4645 |
4645 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4646 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4646 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 4647 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptDoubleToSmi); |
4647 Register result = locs()->out(0).reg(); | 4648 Register result = locs()->out(0).reg(); |
4648 XmmRegister value = locs()->in(0).fpu_reg(); | 4649 XmmRegister value = locs()->in(0).fpu_reg(); |
4649 Register temp = locs()->temp(0).reg(); | 4650 Register temp = locs()->temp(0).reg(); |
4650 | 4651 |
4651 __ cvttsd2siq(result, value); | 4652 __ cvttsd2siq(result, value); |
4652 // Overflow is signalled with minint. | 4653 // Overflow is signalled with minint. |
4653 Label do_call, done; | 4654 Label do_call, done; |
4654 // Check for overflow and that it fits into Smi. | 4655 // Check for overflow and that it fits into Smi. |
4655 __ movq(temp, result); | 4656 __ movq(temp, result); |
4656 __ shlq(temp, Immediate(1)); | 4657 __ shlq(temp, Immediate(1)); |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4928 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); | 4929 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); |
4929 | 4930 |
4930 extern const RuntimeEntry kSinCosRuntimeEntry( | 4931 extern const RuntimeEntry kSinCosRuntimeEntry( |
4931 "libc_sincos", reinterpret_cast<RuntimeFunction>( | 4932 "libc_sincos", reinterpret_cast<RuntimeFunction>( |
4932 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); | 4933 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); |
4933 | 4934 |
4934 | 4935 |
4935 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4936 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4936 Label* deopt = NULL; | 4937 Label* deopt = NULL; |
4937 if (CanDeoptimize()) { | 4938 if (CanDeoptimize()) { |
4938 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); | 4939 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
4939 } | 4940 } |
4940 if (kind() == MergedMathInstr::kTruncDivMod) { | 4941 if (kind() == MergedMathInstr::kTruncDivMod) { |
4941 Register left = locs()->in(0).reg(); | 4942 Register left = locs()->in(0).reg(); |
4942 Register right = locs()->in(1).reg(); | 4943 Register right = locs()->in(1).reg(); |
4943 ASSERT(locs()->out(0).IsPairLocation()); | 4944 ASSERT(locs()->out(0).IsPairLocation()); |
4944 PairLocation* pair = locs()->out(0).AsPairLocation(); | 4945 PairLocation* pair = locs()->out(0).AsPairLocation(); |
4945 Register result1 = pair->At(0).reg(); | 4946 Register result1 = pair->At(0).reg(); |
4946 Register result2 = pair->At(1).reg(); | 4947 Register result2 = pair->At(1).reg(); |
4947 Label not_32bit, done; | 4948 Label not_32bit, done; |
4948 Register temp = RDX; | 4949 Register temp = RDX; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5065 } | 5066 } |
5066 | 5067 |
5067 | 5068 |
5068 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( | 5069 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
5069 bool opt) const { | 5070 bool opt) const { |
5070 return MakeCallSummary(); | 5071 return MakeCallSummary(); |
5071 } | 5072 } |
5072 | 5073 |
5073 | 5074 |
5074 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5075 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5075 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 5076 Label* deopt = compiler->AddDeoptStub( |
5076 kDeoptPolymorphicInstanceCallTestFail); | 5077 deopt_id(), ICData::kDeoptPolymorphicInstanceCallTestFail); |
5077 if (ic_data().NumberOfChecks() == 0) { | 5078 if (ic_data().NumberOfChecks() == 0) { |
5078 __ jmp(deopt); | 5079 __ jmp(deopt); |
5079 return; | 5080 return; |
5080 } | 5081 } |
5081 ASSERT(ic_data().num_args_tested() == 1); | 5082 ASSERT(ic_data().NumArgsTested() == 1); |
5082 if (!with_checks()) { | 5083 if (!with_checks()) { |
5083 ASSERT(ic_data().HasOneTarget()); | 5084 ASSERT(ic_data().HasOneTarget()); |
5084 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 5085 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
5085 compiler->GenerateStaticCall(deopt_id(), | 5086 compiler->GenerateStaticCall(deopt_id(), |
5086 instance_call()->token_pos(), | 5087 instance_call()->token_pos(), |
5087 target, | 5088 target, |
5088 instance_call()->ArgumentCount(), | 5089 instance_call()->ArgumentCount(), |
5089 instance_call()->argument_names(), | 5090 instance_call()->argument_names(), |
5090 locs()); | 5091 locs()); |
5091 return; | 5092 return; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5127 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5128 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5128 summary->set_in(0, Location::RequiresRegister()); | 5129 summary->set_in(0, Location::RequiresRegister()); |
5129 if (!IsNullCheck()) { | 5130 if (!IsNullCheck()) { |
5130 summary->AddTemp(Location::RequiresRegister()); | 5131 summary->AddTemp(Location::RequiresRegister()); |
5131 } | 5132 } |
5132 return summary; | 5133 return summary; |
5133 } | 5134 } |
5134 | 5135 |
5135 | 5136 |
5136 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5137 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5137 const DeoptReasonId deopt_reason = | 5138 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
5138 licm_hoisted_ ? kDeoptHoistedCheckClass : kDeoptCheckClass; | 5139 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
5139 if (IsNullCheck()) { | 5140 if (IsNullCheck()) { |
5140 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 5141 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
5141 __ CompareObject(locs()->in(0).reg(), | 5142 __ CompareObject(locs()->in(0).reg(), |
5142 Object::null_object(), PP); | 5143 Object::null_object(), PP); |
5143 __ j(EQUAL, deopt); | 5144 __ j(EQUAL, deopt); |
5144 return; | 5145 return; |
5145 } | 5146 } |
5146 | 5147 |
5147 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | 5148 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || |
5148 (unary_checks().NumberOfChecks() > 1)); | 5149 (unary_checks().NumberOfChecks() > 1)); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5184 const intptr_t kNumTemps = 0; | 5185 const intptr_t kNumTemps = 0; |
5185 LocationSummary* summary = | 5186 LocationSummary* summary = |
5186 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5187 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5187 summary->set_in(0, Location::RequiresRegister()); | 5188 summary->set_in(0, Location::RequiresRegister()); |
5188 return summary; | 5189 return summary; |
5189 } | 5190 } |
5190 | 5191 |
5191 | 5192 |
5192 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5193 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5193 Register value = locs()->in(0).reg(); | 5194 Register value = locs()->in(0).reg(); |
5194 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 5195 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); |
5195 kDeoptCheckSmi); | |
5196 __ testq(value, Immediate(kSmiTagMask)); | 5196 __ testq(value, Immediate(kSmiTagMask)); |
5197 __ j(NOT_ZERO, deopt); | 5197 __ j(NOT_ZERO, deopt); |
5198 } | 5198 } |
5199 | 5199 |
5200 | 5200 |
5201 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { | 5201 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { |
5202 const intptr_t kNumInputs = 2; | 5202 const intptr_t kNumInputs = 2; |
5203 const intptr_t kNumTemps = 0; | 5203 const intptr_t kNumTemps = 0; |
5204 LocationSummary* locs = | 5204 LocationSummary* locs = |
5205 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5205 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5206 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 5206 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
5207 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 5207 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
5208 return locs; | 5208 return locs; |
5209 } | 5209 } |
5210 | 5210 |
5211 | 5211 |
5212 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5212 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5213 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptCheckArrayBound); | 5213 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 5214 ICData::kDeoptCheckArrayBound); |
5214 | 5215 |
5215 Location length_loc = locs()->in(kLengthPos); | 5216 Location length_loc = locs()->in(kLengthPos); |
5216 Location index_loc = locs()->in(kIndexPos); | 5217 Location index_loc = locs()->in(kIndexPos); |
5217 | 5218 |
5218 if (length_loc.IsConstant() && index_loc.IsConstant()) { | 5219 if (length_loc.IsConstant() && index_loc.IsConstant()) { |
5219 // TODO(srdjan): remove this code once failures are fixed. | 5220 // TODO(srdjan): remove this code once failures are fixed. |
5220 if ((Smi::Cast(length_loc.constant()).Value() > | 5221 if ((Smi::Cast(length_loc.constant()).Value() > |
5221 Smi::Cast(index_loc.constant()).Value()) && | 5222 Smi::Cast(index_loc.constant()).Value()) && |
5222 (Smi::Cast(index_loc.constant()).Value() >= 0)) { | 5223 (Smi::Cast(index_loc.constant()).Value() >= 0)) { |
5223 // This CheckArrayBoundInstr should have been eliminated. | 5224 // This CheckArrayBoundInstr should have been eliminated. |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5570 PcDescriptors::kOther, | 5571 PcDescriptors::kOther, |
5571 locs()); | 5572 locs()); |
5572 __ Drop(ArgumentCount()); // Discard arguments. | 5573 __ Drop(ArgumentCount()); // Discard arguments. |
5573 } | 5574 } |
5574 | 5575 |
5575 } // namespace dart | 5576 } // namespace dart |
5576 | 5577 |
5577 #undef __ | 5578 #undef __ |
5578 | 5579 |
5579 #endif // defined TARGET_ARCH_X64 | 5580 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |