| 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 |