| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 } | 595 } |
| 596 | 596 |
| 597 | 597 |
| 598 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 598 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 599 BranchLabels labels) { | 599 BranchLabels labels) { |
| 600 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); | 600 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); |
| 601 Register val_reg = locs()->in(0).reg(); | 601 Register val_reg = locs()->in(0).reg(); |
| 602 Register cid_reg = locs()->temp(0).reg(); | 602 Register cid_reg = locs()->temp(0).reg(); |
| 603 | 603 |
| 604 Label* deopt = CanDeoptimize() ? | 604 Label* deopt = CanDeoptimize() ? |
| 605 compiler->AddDeoptStub(deopt_id(), kDeoptTestCids) : NULL; | 605 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL; |
| 606 | 606 |
| 607 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; | 607 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; |
| 608 const ZoneGrowableArray<intptr_t>& data = cid_results(); | 608 const ZoneGrowableArray<intptr_t>& data = cid_results(); |
| 609 ASSERT(data[0] == kSmiCid); | 609 ASSERT(data[0] == kSmiCid); |
| 610 bool result = data[1] == true_result; | 610 bool result = data[1] == true_result; |
| 611 __ testl(val_reg, Immediate(kSmiTagMask)); | 611 __ testl(val_reg, Immediate(kSmiTagMask)); |
| 612 __ j(ZERO, result ? labels.true_label : labels.false_label); | 612 __ j(ZERO, result ? labels.true_label : labels.false_label); |
| 613 __ LoadClassId(cid_reg, val_reg); | 613 __ LoadClassId(cid_reg, val_reg); |
| 614 for (intptr_t i = 2; i < data.length(); i += 2) { | 614 for (intptr_t i = 2; i < data.length(); i += 2) { |
| 615 const intptr_t test_cid = data[i]; | 615 const intptr_t test_cid = data[i]; |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1073 case kTypedDataInt16ArrayCid: | 1073 case kTypedDataInt16ArrayCid: |
| 1074 __ movsxw(result, element_address); | 1074 __ movsxw(result, element_address); |
| 1075 __ SmiTag(result); | 1075 __ SmiTag(result); |
| 1076 break; | 1076 break; |
| 1077 case kTypedDataUint16ArrayCid: | 1077 case kTypedDataUint16ArrayCid: |
| 1078 case kTwoByteStringCid: | 1078 case kTwoByteStringCid: |
| 1079 __ movzxw(result, element_address); | 1079 __ movzxw(result, element_address); |
| 1080 __ SmiTag(result); | 1080 __ SmiTag(result); |
| 1081 break; | 1081 break; |
| 1082 case kTypedDataInt32ArrayCid: { | 1082 case kTypedDataInt32ArrayCid: { |
| 1083 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load); | 1083 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 1084 ICData::kDeoptInt32Load); |
| 1084 __ movl(result, element_address); | 1085 __ movl(result, element_address); |
| 1085 // Verify that the signed value in 'result' can fit inside a Smi. | 1086 // Verify that the signed value in 'result' can fit inside a Smi. |
| 1086 __ cmpl(result, Immediate(0xC0000000)); | 1087 __ cmpl(result, Immediate(0xC0000000)); |
| 1087 __ j(NEGATIVE, deopt); | 1088 __ j(NEGATIVE, deopt); |
| 1088 __ SmiTag(result); | 1089 __ SmiTag(result); |
| 1089 } | 1090 } |
| 1090 break; | 1091 break; |
| 1091 case kTypedDataUint32ArrayCid: { | 1092 case kTypedDataUint32ArrayCid: { |
| 1092 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load); | 1093 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 1094 ICData::kDeoptUint32Load); |
| 1093 __ movl(result, element_address); | 1095 __ movl(result, element_address); |
| 1094 // Verify that the unsigned value in 'result' can fit inside a Smi. | 1096 // Verify that the unsigned value in 'result' can fit inside a Smi. |
| 1095 __ testl(result, Immediate(0xC0000000)); | 1097 __ testl(result, Immediate(0xC0000000)); |
| 1096 __ j(NOT_ZERO, deopt); | 1098 __ j(NOT_ZERO, deopt); |
| 1097 __ SmiTag(result); | 1099 __ SmiTag(result); |
| 1098 } | 1100 } |
| 1099 break; | 1101 break; |
| 1100 default: | 1102 default: |
| 1101 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1103 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1102 __ movl(result, element_address); | 1104 __ movl(result, element_address); |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1367 | 1369 |
| 1368 Register value_cid_reg = needs_value_temp_reg ? | 1370 Register value_cid_reg = needs_value_temp_reg ? |
| 1369 locs()->temp(0).reg() : kNoRegister; | 1371 locs()->temp(0).reg() : kNoRegister; |
| 1370 | 1372 |
| 1371 Register field_reg = needs_field_temp_reg ? | 1373 Register field_reg = needs_field_temp_reg ? |
| 1372 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; | 1374 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; |
| 1373 | 1375 |
| 1374 Label ok, fail_label; | 1376 Label ok, fail_label; |
| 1375 | 1377 |
| 1376 Label* deopt = compiler->is_optimizing() ? | 1378 Label* deopt = compiler->is_optimizing() ? |
| 1377 compiler->AddDeoptStub(deopt_id(), kDeoptGuardField) : NULL; | 1379 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL; |
| 1378 | 1380 |
| 1379 Label* fail = (deopt != NULL) ? deopt : &fail_label; | 1381 Label* fail = (deopt != NULL) ? deopt : &fail_label; |
| 1380 | 1382 |
| 1381 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) { | 1383 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) { |
| 1382 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) { | 1384 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) { |
| 1383 // Currently we can't have different location summaries for optimized | 1385 // Currently we can't have different location summaries for optimized |
| 1384 // and non-optimized code. So instead we manually pick up a register | 1386 // and non-optimized code. So instead we manually pick up a register |
| 1385 // that is known to be free because we know how non-optimizing compiler | 1387 // that is known to be free because we know how non-optimizing compiler |
| 1386 // allocates registers. | 1388 // allocates registers. |
| 1387 field_reg = EBX; | 1389 field_reg = EBX; |
| (...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2679 | 2681 |
| 2680 | 2682 |
| 2681 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2683 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| 2682 BinarySmiOpInstr* shift_left) { | 2684 BinarySmiOpInstr* shift_left) { |
| 2683 const bool is_truncating = shift_left->is_truncating(); | 2685 const bool is_truncating = shift_left->is_truncating(); |
| 2684 const LocationSummary& locs = *shift_left->locs(); | 2686 const LocationSummary& locs = *shift_left->locs(); |
| 2685 Register left = locs.in(0).reg(); | 2687 Register left = locs.in(0).reg(); |
| 2686 Register result = locs.out(0).reg(); | 2688 Register result = locs.out(0).reg(); |
| 2687 ASSERT(left == result); | 2689 ASSERT(left == result); |
| 2688 Label* deopt = shift_left->CanDeoptimize() ? | 2690 Label* deopt = shift_left->CanDeoptimize() ? |
| 2689 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; | 2691 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) |
| 2692 : NULL; |
| 2690 if (locs.in(1).IsConstant()) { | 2693 if (locs.in(1).IsConstant()) { |
| 2691 const Object& constant = locs.in(1).constant(); | 2694 const Object& constant = locs.in(1).constant(); |
| 2692 ASSERT(constant.IsSmi()); | 2695 ASSERT(constant.IsSmi()); |
| 2693 // shll operation masks the count to 5 bits. | 2696 // shll operation masks the count to 5 bits. |
| 2694 const intptr_t kCountLimit = 0x1F; | 2697 const intptr_t kCountLimit = 0x1F; |
| 2695 const intptr_t value = Smi::Cast(constant).Value(); | 2698 const intptr_t value = Smi::Cast(constant).Value(); |
| 2696 if (value == 0) { | 2699 if (value == 0) { |
| 2697 // No code needed. | 2700 // No code needed. |
| 2698 } else if ((value < 0) || (value >= kCountLimit)) { | 2701 } else if ((value < 0) || (value >= kCountLimit)) { |
| 2699 // This condition may not be known earlier in some cases because | 2702 // This condition may not be known earlier in some cases because |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2873 EmitSmiShiftLeft(compiler, this); | 2876 EmitSmiShiftLeft(compiler, this); |
| 2874 return; | 2877 return; |
| 2875 } | 2878 } |
| 2876 | 2879 |
| 2877 ASSERT(!is_truncating()); | 2880 ASSERT(!is_truncating()); |
| 2878 Register left = locs()->in(0).reg(); | 2881 Register left = locs()->in(0).reg(); |
| 2879 Register result = locs()->out(0).reg(); | 2882 Register result = locs()->out(0).reg(); |
| 2880 ASSERT(left == result); | 2883 ASSERT(left == result); |
| 2881 Label* deopt = NULL; | 2884 Label* deopt = NULL; |
| 2882 if (CanDeoptimize()) { | 2885 if (CanDeoptimize()) { |
| 2883 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); | 2886 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
| 2884 } | 2887 } |
| 2885 | 2888 |
| 2886 if (locs()->in(1).IsConstant()) { | 2889 if (locs()->in(1).IsConstant()) { |
| 2887 const Object& constant = locs()->in(1).constant(); | 2890 const Object& constant = locs()->in(1).constant(); |
| 2888 ASSERT(constant.IsSmi()); | 2891 ASSERT(constant.IsSmi()); |
| 2889 const int32_t imm = | 2892 const int32_t imm = |
| 2890 reinterpret_cast<int32_t>(constant.raw()); | 2893 reinterpret_cast<int32_t>(constant.raw()); |
| 2891 switch (op_kind()) { | 2894 switch (op_kind()) { |
| 2892 case Token::kADD: | 2895 case Token::kADD: |
| 2893 __ addl(left, Immediate(imm)); | 2896 __ addl(left, Immediate(imm)); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3179 LocationSummary* summary = | 3182 LocationSummary* summary = |
| 3180 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3183 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3181 summary->set_in(0, Location::RequiresRegister()); | 3184 summary->set_in(0, Location::RequiresRegister()); |
| 3182 summary->set_in(1, Location::RequiresRegister()); | 3185 summary->set_in(1, Location::RequiresRegister()); |
| 3183 if (need_temp) summary->set_temp(0, Location::RequiresRegister()); | 3186 if (need_temp) summary->set_temp(0, Location::RequiresRegister()); |
| 3184 return summary; | 3187 return summary; |
| 3185 } | 3188 } |
| 3186 | 3189 |
| 3187 | 3190 |
| 3188 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3191 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3189 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp); | 3192 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 3193 ICData::kDeoptBinaryDoubleOp); |
| 3190 intptr_t left_cid = left()->Type()->ToCid(); | 3194 intptr_t left_cid = left()->Type()->ToCid(); |
| 3191 intptr_t right_cid = right()->Type()->ToCid(); | 3195 intptr_t right_cid = right()->Type()->ToCid(); |
| 3192 Register left = locs()->in(0).reg(); | 3196 Register left = locs()->in(0).reg(); |
| 3193 Register right = locs()->in(1).reg(); | 3197 Register right = locs()->in(1).reg(); |
| 3194 if (left_cid == kSmiCid) { | 3198 if (left_cid == kSmiCid) { |
| 3195 __ testl(right, Immediate(kSmiTagMask)); | 3199 __ testl(right, Immediate(kSmiTagMask)); |
| 3196 } else if (right_cid == kSmiCid) { | 3200 } else if (right_cid == kSmiCid) { |
| 3197 __ testl(left, Immediate(kSmiTagMask)); | 3201 __ testl(left, Immediate(kSmiTagMask)); |
| 3198 } else { | 3202 } else { |
| 3199 Register temp = locs()->temp(0).reg(); | 3203 Register temp = locs()->temp(0).reg(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3259 const intptr_t value_cid = value()->Type()->ToCid(); | 3263 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3260 const Register value = locs()->in(0).reg(); | 3264 const Register value = locs()->in(0).reg(); |
| 3261 const XmmRegister result = locs()->out(0).fpu_reg(); | 3265 const XmmRegister result = locs()->out(0).fpu_reg(); |
| 3262 | 3266 |
| 3263 if (value_cid == kDoubleCid) { | 3267 if (value_cid == kDoubleCid) { |
| 3264 __ movsd(result, FieldAddress(value, Double::value_offset())); | 3268 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 3265 } else if (value_cid == kSmiCid) { | 3269 } else if (value_cid == kSmiCid) { |
| 3266 __ SmiUntag(value); // Untag input before conversion. | 3270 __ SmiUntag(value); // Untag input before conversion. |
| 3267 __ cvtsi2sd(result, value); | 3271 __ cvtsi2sd(result, value); |
| 3268 } else { | 3272 } else { |
| 3269 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); | 3273 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
| 3274 ICData::kDeoptBinaryDoubleOp); |
| 3270 Register temp = locs()->temp(0).reg(); | 3275 Register temp = locs()->temp(0).reg(); |
| 3271 Label is_smi, done; | 3276 Label is_smi, done; |
| 3272 __ testl(value, Immediate(kSmiTagMask)); | 3277 __ testl(value, Immediate(kSmiTagMask)); |
| 3273 __ j(ZERO, &is_smi); | 3278 __ j(ZERO, &is_smi); |
| 3274 __ CompareClassId(value, kDoubleCid, temp); | 3279 __ CompareClassId(value, kDoubleCid, temp); |
| 3275 __ j(NOT_EQUAL, deopt); | 3280 __ j(NOT_EQUAL, deopt); |
| 3276 __ movsd(result, FieldAddress(value, Double::value_offset())); | 3281 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 3277 __ jmp(&done); | 3282 __ jmp(&done); |
| 3278 __ Bind(&is_smi); | 3283 __ Bind(&is_smi); |
| 3279 __ movl(temp, value); | 3284 __ movl(temp, value); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3330 } | 3335 } |
| 3331 | 3336 |
| 3332 | 3337 |
| 3333 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3338 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3334 const intptr_t value_cid = value()->Type()->ToCid(); | 3339 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3335 const Register value = locs()->in(0).reg(); | 3340 const Register value = locs()->in(0).reg(); |
| 3336 const XmmRegister result = locs()->out(0).fpu_reg(); | 3341 const XmmRegister result = locs()->out(0).fpu_reg(); |
| 3337 | 3342 |
| 3338 if (value_cid != kFloat32x4Cid) { | 3343 if (value_cid != kFloat32x4Cid) { |
| 3339 const Register temp = locs()->temp(0).reg(); | 3344 const Register temp = locs()->temp(0).reg(); |
| 3340 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3345 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); |
| 3341 __ testl(value, Immediate(kSmiTagMask)); | 3346 __ testl(value, Immediate(kSmiTagMask)); |
| 3342 __ j(ZERO, deopt); | 3347 __ j(ZERO, deopt); |
| 3343 __ CompareClassId(value, kFloat32x4Cid, temp); | 3348 __ CompareClassId(value, kFloat32x4Cid, temp); |
| 3344 __ j(NOT_EQUAL, deopt); | 3349 __ j(NOT_EQUAL, deopt); |
| 3345 } | 3350 } |
| 3346 __ movups(result, FieldAddress(value, Float32x4::value_offset())); | 3351 __ movups(result, FieldAddress(value, Float32x4::value_offset())); |
| 3347 } | 3352 } |
| 3348 | 3353 |
| 3349 | 3354 |
| 3350 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { | 3355 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3393 } | 3398 } |
| 3394 | 3399 |
| 3395 | 3400 |
| 3396 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3401 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3397 const intptr_t value_cid = value()->Type()->ToCid(); | 3402 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3398 const Register value = locs()->in(0).reg(); | 3403 const Register value = locs()->in(0).reg(); |
| 3399 const XmmRegister result = locs()->out(0).fpu_reg(); | 3404 const XmmRegister result = locs()->out(0).fpu_reg(); |
| 3400 | 3405 |
| 3401 if (value_cid != kFloat64x2Cid) { | 3406 if (value_cid != kFloat64x2Cid) { |
| 3402 const Register temp = locs()->temp(0).reg(); | 3407 const Register temp = locs()->temp(0).reg(); |
| 3403 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3408 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); |
| 3404 __ testl(value, Immediate(kSmiTagMask)); | 3409 __ testl(value, Immediate(kSmiTagMask)); |
| 3405 __ j(ZERO, deopt); | 3410 __ j(ZERO, deopt); |
| 3406 __ CompareClassId(value, kFloat64x2Cid, temp); | 3411 __ CompareClassId(value, kFloat64x2Cid, temp); |
| 3407 __ j(NOT_EQUAL, deopt); | 3412 __ j(NOT_EQUAL, deopt); |
| 3408 } | 3413 } |
| 3409 __ movups(result, FieldAddress(value, Float64x2::value_offset())); | 3414 __ movups(result, FieldAddress(value, Float64x2::value_offset())); |
| 3410 } | 3415 } |
| 3411 | 3416 |
| 3412 | 3417 |
| 3413 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { | 3418 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3488 } | 3493 } |
| 3489 | 3494 |
| 3490 | 3495 |
| 3491 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3496 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3492 const intptr_t value_cid = value()->Type()->ToCid(); | 3497 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3493 const Register value = locs()->in(0).reg(); | 3498 const Register value = locs()->in(0).reg(); |
| 3494 const XmmRegister result = locs()->out(0).fpu_reg(); | 3499 const XmmRegister result = locs()->out(0).fpu_reg(); |
| 3495 | 3500 |
| 3496 if (value_cid != kInt32x4Cid) { | 3501 if (value_cid != kInt32x4Cid) { |
| 3497 const Register temp = locs()->temp(0).reg(); | 3502 const Register temp = locs()->temp(0).reg(); |
| 3498 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3503 Label* deopt = compiler->AddDeoptStub(deopt_id_, ICData::kDeoptCheckClass); |
| 3499 __ testl(value, Immediate(kSmiTagMask)); | 3504 __ testl(value, Immediate(kSmiTagMask)); |
| 3500 __ j(ZERO, deopt); | 3505 __ j(ZERO, deopt); |
| 3501 __ CompareClassId(value, kInt32x4Cid, temp); | 3506 __ CompareClassId(value, kInt32x4Cid, temp); |
| 3502 __ j(NOT_EQUAL, deopt); | 3507 __ j(NOT_EQUAL, deopt); |
| 3503 } | 3508 } |
| 3504 __ movups(result, FieldAddress(value, Int32x4::value_offset())); | 3509 __ movups(result, FieldAddress(value, Int32x4::value_offset())); |
| 3505 } | 3510 } |
| 3506 | 3511 |
| 3507 | 3512 |
| 3508 | 3513 |
| (...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4631 Location::SameAsFirstInput(), | 4636 Location::SameAsFirstInput(), |
| 4632 LocationSummary::kNoCall); | 4637 LocationSummary::kNoCall); |
| 4633 } | 4638 } |
| 4634 | 4639 |
| 4635 | 4640 |
| 4636 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4641 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4637 Register value = locs()->in(0).reg(); | 4642 Register value = locs()->in(0).reg(); |
| 4638 ASSERT(value == locs()->out(0).reg()); | 4643 ASSERT(value == locs()->out(0).reg()); |
| 4639 switch (op_kind()) { | 4644 switch (op_kind()) { |
| 4640 case Token::kNEGATE: { | 4645 case Token::kNEGATE: { |
| 4641 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4646 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp); |
| 4642 kDeoptUnaryOp); | |
| 4643 __ negl(value); | 4647 __ negl(value); |
| 4644 __ j(OVERFLOW, deopt); | 4648 __ j(OVERFLOW, deopt); |
| 4645 break; | 4649 break; |
| 4646 } | 4650 } |
| 4647 case Token::kBIT_NOT: | 4651 case Token::kBIT_NOT: |
| 4648 __ notl(value); | 4652 __ notl(value); |
| 4649 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. | 4653 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. |
| 4650 break; | 4654 break; |
| 4651 default: | 4655 default: |
| 4652 UNREACHABLE(); | 4656 UNREACHABLE(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4740 const intptr_t kNumTemps = 0; | 4744 const intptr_t kNumTemps = 0; |
| 4741 LocationSummary* result = new LocationSummary( | 4745 LocationSummary* result = new LocationSummary( |
| 4742 kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4746 kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4743 result->set_in(0, Location::RequiresFpuRegister()); | 4747 result->set_in(0, Location::RequiresFpuRegister()); |
| 4744 result->set_out(0, Location::RequiresRegister()); | 4748 result->set_out(0, Location::RequiresRegister()); |
| 4745 return result; | 4749 return result; |
| 4746 } | 4750 } |
| 4747 | 4751 |
| 4748 | 4752 |
| 4749 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4753 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4750 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); | 4754 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptDoubleToSmi); |
| 4751 Register result = locs()->out(0).reg(); | 4755 Register result = locs()->out(0).reg(); |
| 4752 XmmRegister value = locs()->in(0).fpu_reg(); | 4756 XmmRegister value = locs()->in(0).fpu_reg(); |
| 4753 __ cvttsd2si(result, value); | 4757 __ cvttsd2si(result, value); |
| 4754 // Check for overflow and that it fits into Smi. | 4758 // Check for overflow and that it fits into Smi. |
| 4755 __ cmpl(result, Immediate(0xC0000000)); | 4759 __ cmpl(result, Immediate(0xC0000000)); |
| 4756 __ j(NEGATIVE, deopt); | 4760 __ j(NEGATIVE, deopt); |
| 4757 __ SmiTag(result); | 4761 __ SmiTag(result); |
| 4758 } | 4762 } |
| 4759 | 4763 |
| 4760 | 4764 |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5015 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); | 5019 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); |
| 5016 | 5020 |
| 5017 extern const RuntimeEntry kSinCosRuntimeEntry( | 5021 extern const RuntimeEntry kSinCosRuntimeEntry( |
| 5018 "libc_sincos", reinterpret_cast<RuntimeFunction>( | 5022 "libc_sincos", reinterpret_cast<RuntimeFunction>( |
| 5019 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); | 5023 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); |
| 5020 | 5024 |
| 5021 | 5025 |
| 5022 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5026 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5023 Label* deopt = NULL; | 5027 Label* deopt = NULL; |
| 5024 if (CanDeoptimize()) { | 5028 if (CanDeoptimize()) { |
| 5025 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); | 5029 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
| 5026 } | 5030 } |
| 5027 | 5031 |
| 5028 if (kind() == MergedMathInstr::kTruncDivMod) { | 5032 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 5029 Register left = locs()->in(0).reg(); | 5033 Register left = locs()->in(0).reg(); |
| 5030 Register right = locs()->in(1).reg(); | 5034 Register right = locs()->in(1).reg(); |
| 5031 ASSERT(locs()->out(0).IsPairLocation()); | 5035 ASSERT(locs()->out(0).IsPairLocation()); |
| 5032 PairLocation* pair = locs()->out(0).AsPairLocation(); | 5036 PairLocation* pair = locs()->out(0).AsPairLocation(); |
| 5033 Register result1 = pair->At(0).reg(); | 5037 Register result1 = pair->At(0).reg(); |
| 5034 Register result2 = pair->At(1).reg(); | 5038 Register result2 = pair->At(1).reg(); |
| 5035 Range* right_range = InputAt(1)->definition()->range(); | 5039 Range* right_range = InputAt(1)->definition()->range(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5114 } | 5118 } |
| 5115 | 5119 |
| 5116 | 5120 |
| 5117 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( | 5121 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary( |
| 5118 bool opt) const { | 5122 bool opt) const { |
| 5119 return MakeCallSummary(); | 5123 return MakeCallSummary(); |
| 5120 } | 5124 } |
| 5121 | 5125 |
| 5122 | 5126 |
| 5123 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5127 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5124 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 5128 Label* deopt = compiler->AddDeoptStub( |
| 5125 kDeoptPolymorphicInstanceCallTestFail); | 5129 deopt_id(), ICData::kDeoptPolymorphicInstanceCallTestFail); |
| 5126 if (ic_data().NumberOfChecks() == 0) { | 5130 if (ic_data().NumberOfChecks() == 0) { |
| 5127 __ jmp(deopt); | 5131 __ jmp(deopt); |
| 5128 return; | 5132 return; |
| 5129 } | 5133 } |
| 5130 ASSERT(ic_data().num_args_tested() == 1); | 5134 ASSERT(ic_data().NumArgsTested() == 1); |
| 5131 if (!with_checks()) { | 5135 if (!with_checks()) { |
| 5132 ASSERT(ic_data().HasOneTarget()); | 5136 ASSERT(ic_data().HasOneTarget()); |
| 5133 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 5137 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
| 5134 compiler->GenerateStaticCall(deopt_id(), | 5138 compiler->GenerateStaticCall(deopt_id(), |
| 5135 instance_call()->token_pos(), | 5139 instance_call()->token_pos(), |
| 5136 target, | 5140 target, |
| 5137 instance_call()->ArgumentCount(), | 5141 instance_call()->ArgumentCount(), |
| 5138 instance_call()->argument_names(), | 5142 instance_call()->argument_names(), |
| 5139 locs()); | 5143 locs()); |
| 5140 return; | 5144 return; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5178 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5182 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5179 summary->set_in(0, Location::RequiresRegister()); | 5183 summary->set_in(0, Location::RequiresRegister()); |
| 5180 if (!IsNullCheck()) { | 5184 if (!IsNullCheck()) { |
| 5181 summary->AddTemp(Location::RequiresRegister()); | 5185 summary->AddTemp(Location::RequiresRegister()); |
| 5182 } | 5186 } |
| 5183 return summary; | 5187 return summary; |
| 5184 } | 5188 } |
| 5185 | 5189 |
| 5186 | 5190 |
| 5187 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5191 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5188 const DeoptReasonId deopt_reason = | 5192 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 5189 licm_hoisted_ ? kDeoptHoistedCheckClass : kDeoptCheckClass; | 5193 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 5190 if (IsNullCheck()) { | 5194 if (IsNullCheck()) { |
| 5191 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 5195 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| 5192 const Immediate& raw_null = | 5196 const Immediate& raw_null = |
| 5193 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 5197 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 5194 __ cmpl(locs()->in(0).reg(), raw_null); | 5198 __ cmpl(locs()->in(0).reg(), raw_null); |
| 5195 __ j(EQUAL, deopt); | 5199 __ j(EQUAL, deopt); |
| 5196 return; | 5200 return; |
| 5197 } | 5201 } |
| 5198 | 5202 |
| 5199 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | 5203 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5236 const intptr_t kNumTemps = 0; | 5240 const intptr_t kNumTemps = 0; |
| 5237 LocationSummary* summary = | 5241 LocationSummary* summary = |
| 5238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5242 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5239 summary->set_in(0, Location::RequiresRegister()); | 5243 summary->set_in(0, Location::RequiresRegister()); |
| 5240 return summary; | 5244 return summary; |
| 5241 } | 5245 } |
| 5242 | 5246 |
| 5243 | 5247 |
| 5244 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5248 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5245 Register value = locs()->in(0).reg(); | 5249 Register value = locs()->in(0).reg(); |
| 5246 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 5250 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); |
| 5247 kDeoptCheckSmi); | |
| 5248 __ testl(value, Immediate(kSmiTagMask)); | 5251 __ testl(value, Immediate(kSmiTagMask)); |
| 5249 __ j(NOT_ZERO, deopt); | 5252 __ j(NOT_ZERO, deopt); |
| 5250 } | 5253 } |
| 5251 | 5254 |
| 5252 | 5255 |
| 5253 // Length: register or constant. | 5256 // Length: register or constant. |
| 5254 // Index: register, constant or stack slot. | 5257 // Index: register, constant or stack slot. |
| 5255 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { | 5258 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { |
| 5256 const intptr_t kNumInputs = 2; | 5259 const intptr_t kNumInputs = 2; |
| 5257 const intptr_t kNumTemps = 0; | 5260 const intptr_t kNumTemps = 0; |
| 5258 LocationSummary* locs = | 5261 LocationSummary* locs = |
| 5259 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5262 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5260 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 5263 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 5261 ConstantInstr* index_constant = index()->definition()->AsConstant(); | 5264 ConstantInstr* index_constant = index()->definition()->AsConstant(); |
| 5262 if (index_constant != NULL) { | 5265 if (index_constant != NULL) { |
| 5263 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 5266 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
| 5264 } else { | 5267 } else { |
| 5265 locs->set_in(kIndexPos, Location::PrefersRegister()); | 5268 locs->set_in(kIndexPos, Location::PrefersRegister()); |
| 5266 } | 5269 } |
| 5267 return locs; | 5270 return locs; |
| 5268 } | 5271 } |
| 5269 | 5272 |
| 5270 | 5273 |
| 5271 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5274 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5272 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptCheckArrayBound); | 5275 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 5276 ICData::kDeoptCheckArrayBound); |
| 5273 | 5277 |
| 5274 Location length_loc = locs()->in(kLengthPos); | 5278 Location length_loc = locs()->in(kLengthPos); |
| 5275 Location index_loc = locs()->in(kIndexPos); | 5279 Location index_loc = locs()->in(kIndexPos); |
| 5276 | 5280 |
| 5277 if (length_loc.IsConstant() && index_loc.IsConstant()) { | 5281 if (length_loc.IsConstant() && index_loc.IsConstant()) { |
| 5278 // TODO(srdjan): remove this code once failures are fixed. | 5282 // TODO(srdjan): remove this code once failures are fixed. |
| 5279 if ((Smi::Cast(length_loc.constant()).Value() > | 5283 if ((Smi::Cast(length_loc.constant()).Value() > |
| 5280 Smi::Cast(index_loc.constant()).Value()) && | 5284 Smi::Cast(index_loc.constant()).Value()) && |
| 5281 (Smi::Cast(index_loc.constant()).Value() >= 0)) { | 5285 (Smi::Cast(index_loc.constant()).Value() >= 0)) { |
| 5282 // This CheckArrayBoundInstr should have been eliminated. | 5286 // This CheckArrayBoundInstr should have been eliminated. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5345 const XmmRegister result = locs()->out(0).fpu_reg(); | 5349 const XmmRegister result = locs()->out(0).fpu_reg(); |
| 5346 | 5350 |
| 5347 if (value_cid == kMintCid) { | 5351 if (value_cid == kMintCid) { |
| 5348 __ movsd(result, FieldAddress(value, Mint::value_offset())); | 5352 __ movsd(result, FieldAddress(value, Mint::value_offset())); |
| 5349 } else if (value_cid == kSmiCid) { | 5353 } else if (value_cid == kSmiCid) { |
| 5350 __ SmiUntag(value); // Untag input before conversion. | 5354 __ SmiUntag(value); // Untag input before conversion. |
| 5351 __ movd(result, value); | 5355 __ movd(result, value); |
| 5352 __ pmovsxdq(result, result); | 5356 __ pmovsxdq(result, result); |
| 5353 } else { | 5357 } else { |
| 5354 Register temp = locs()->temp(0).reg(); | 5358 Register temp = locs()->temp(0).reg(); |
| 5355 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptUnboxInteger); | 5359 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
| 5360 ICData::kDeoptUnboxInteger); |
| 5356 Label is_smi, done; | 5361 Label is_smi, done; |
| 5357 __ testl(value, Immediate(kSmiTagMask)); | 5362 __ testl(value, Immediate(kSmiTagMask)); |
| 5358 __ j(ZERO, &is_smi); | 5363 __ j(ZERO, &is_smi); |
| 5359 __ CompareClassId(value, kMintCid, temp); | 5364 __ CompareClassId(value, kMintCid, temp); |
| 5360 __ j(NOT_EQUAL, deopt); | 5365 __ j(NOT_EQUAL, deopt); |
| 5361 __ movsd(result, FieldAddress(value, Mint::value_offset())); | 5366 __ movsd(result, FieldAddress(value, Mint::value_offset())); |
| 5362 __ jmp(&done); | 5367 __ jmp(&done); |
| 5363 __ Bind(&is_smi); | 5368 __ Bind(&is_smi); |
| 5364 __ movl(temp, value); | 5369 __ movl(temp, value); |
| 5365 __ SmiUntag(temp); | 5370 __ SmiUntag(temp); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5497 | 5502 |
| 5498 | 5503 |
| 5499 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5504 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5500 XmmRegister left = locs()->in(0).fpu_reg(); | 5505 XmmRegister left = locs()->in(0).fpu_reg(); |
| 5501 XmmRegister right = locs()->in(1).fpu_reg(); | 5506 XmmRegister right = locs()->in(1).fpu_reg(); |
| 5502 | 5507 |
| 5503 ASSERT(locs()->out(0).fpu_reg() == left); | 5508 ASSERT(locs()->out(0).fpu_reg() == left); |
| 5504 | 5509 |
| 5505 Label* deopt = NULL; | 5510 Label* deopt = NULL; |
| 5506 if (FLAG_throw_on_javascript_int_overflow) { | 5511 if (FLAG_throw_on_javascript_int_overflow) { |
| 5507 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp); | 5512 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); |
| 5508 } | 5513 } |
| 5509 switch (op_kind()) { | 5514 switch (op_kind()) { |
| 5510 case Token::kBIT_AND: __ andpd(left, right); break; | 5515 case Token::kBIT_AND: __ andpd(left, right); break; |
| 5511 case Token::kBIT_OR: __ orpd(left, right); break; | 5516 case Token::kBIT_OR: __ orpd(left, right); break; |
| 5512 case Token::kBIT_XOR: __ xorpd(left, right); break; | 5517 case Token::kBIT_XOR: __ xorpd(left, right); break; |
| 5513 case Token::kADD: | 5518 case Token::kADD: |
| 5514 case Token::kSUB: { | 5519 case Token::kSUB: { |
| 5515 Register lo = locs()->temp(0).reg(); | 5520 Register lo = locs()->temp(0).reg(); |
| 5516 Register hi = locs()->temp(1).reg(); | 5521 Register hi = locs()->temp(1).reg(); |
| 5517 if (!FLAG_throw_on_javascript_int_overflow) { | 5522 if (!FLAG_throw_on_javascript_int_overflow) { |
| 5518 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp); | 5523 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); |
| 5519 } | 5524 } |
| 5520 | 5525 |
| 5521 Label done, overflow; | 5526 Label done, overflow; |
| 5522 __ pextrd(lo, right, Immediate(0)); // Lower half | 5527 __ pextrd(lo, right, Immediate(0)); // Lower half |
| 5523 __ pextrd(hi, right, Immediate(1)); // Upper half | 5528 __ pextrd(hi, right, Immediate(1)); // Upper half |
| 5524 __ subl(ESP, Immediate(2 * kWordSize)); | 5529 __ subl(ESP, Immediate(2 * kWordSize)); |
| 5525 __ movq(Address(ESP, 0), left); | 5530 __ movq(Address(ESP, 0), left); |
| 5526 if (op_kind() == Token::kADD) { | 5531 if (op_kind() == Token::kADD) { |
| 5527 __ addl(Address(ESP, 0), lo); | 5532 __ addl(Address(ESP, 0), lo); |
| 5528 __ adcl(Address(ESP, 1 * kWordSize), hi); | 5533 __ adcl(Address(ESP, 1 * kWordSize), hi); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5563 summary->set_out(0, Location::SameAsFirstInput()); | 5568 summary->set_out(0, Location::SameAsFirstInput()); |
| 5564 return summary; | 5569 return summary; |
| 5565 } | 5570 } |
| 5566 | 5571 |
| 5567 | 5572 |
| 5568 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5573 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5569 XmmRegister left = locs()->in(0).fpu_reg(); | 5574 XmmRegister left = locs()->in(0).fpu_reg(); |
| 5570 ASSERT(locs()->in(1).reg() == ECX); | 5575 ASSERT(locs()->in(1).reg() == ECX); |
| 5571 ASSERT(locs()->out(0).fpu_reg() == left); | 5576 ASSERT(locs()->out(0).fpu_reg() == left); |
| 5572 | 5577 |
| 5573 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 5578 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); |
| 5574 kDeoptShiftMintOp); | |
| 5575 Label done; | 5579 Label done; |
| 5576 __ testl(ECX, ECX); | 5580 __ testl(ECX, ECX); |
| 5577 __ j(ZERO, &done); // Shift by 0 is a nop. | 5581 __ j(ZERO, &done); // Shift by 0 is a nop. |
| 5578 __ subl(ESP, Immediate(2 * kWordSize)); | 5582 __ subl(ESP, Immediate(2 * kWordSize)); |
| 5579 __ movq(Address(ESP, 0), left); | 5583 __ movq(Address(ESP, 0), left); |
| 5580 // Deoptimize if shift count is > 31. | 5584 // Deoptimize if shift count is > 31. |
| 5581 // sarl operation masks the count to 5 bits and | 5585 // sarl operation masks the count to 5 bits and |
| 5582 // shrd is undefined with count > operand size (32) | 5586 // shrd is undefined with count > operand size (32) |
| 5583 // TODO(fschneider): Support shift counts > 31 without deoptimization. | 5587 // TODO(fschneider): Support shift counts > 31 without deoptimization. |
| 5584 __ SmiUntag(ECX); | 5588 __ SmiUntag(ECX); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5637 return summary; | 5641 return summary; |
| 5638 } | 5642 } |
| 5639 | 5643 |
| 5640 | 5644 |
| 5641 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5645 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5642 ASSERT(op_kind() == Token::kBIT_NOT); | 5646 ASSERT(op_kind() == Token::kBIT_NOT); |
| 5643 XmmRegister value = locs()->in(0).fpu_reg(); | 5647 XmmRegister value = locs()->in(0).fpu_reg(); |
| 5644 ASSERT(value == locs()->out(0).fpu_reg()); | 5648 ASSERT(value == locs()->out(0).fpu_reg()); |
| 5645 Label* deopt = NULL; | 5649 Label* deopt = NULL; |
| 5646 if (FLAG_throw_on_javascript_int_overflow) { | 5650 if (FLAG_throw_on_javascript_int_overflow) { |
| 5647 deopt = compiler->AddDeoptStub(deopt_id(), | 5651 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); |
| 5648 kDeoptUnaryMintOp); | |
| 5649 } | 5652 } |
| 5650 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. | 5653 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. |
| 5651 __ pxor(value, XMM0); | 5654 __ pxor(value, XMM0); |
| 5652 if (FLAG_throw_on_javascript_int_overflow) { | 5655 if (FLAG_throw_on_javascript_int_overflow) { |
| 5653 Register tmp = locs()->temp(0).reg(); | 5656 Register tmp = locs()->temp(0).reg(); |
| 5654 EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp); | 5657 EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp); |
| 5655 } | 5658 } |
| 5656 } | 5659 } |
| 5657 | 5660 |
| 5658 | 5661 |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5981 PcDescriptors::kOther, | 5984 PcDescriptors::kOther, |
| 5982 locs()); | 5985 locs()); |
| 5983 __ Drop(ArgumentCount()); // Discard arguments. | 5986 __ Drop(ArgumentCount()); // Discard arguments. |
| 5984 } | 5987 } |
| 5985 | 5988 |
| 5986 } // namespace dart | 5989 } // namespace dart |
| 5987 | 5990 |
| 5988 #undef __ | 5991 #undef __ |
| 5989 | 5992 |
| 5990 #endif // defined TARGET_ARCH_IA32 | 5993 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |