| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 case kOneByteStringCid: | 921 case kOneByteStringCid: |
| 922 case kTwoByteStringCid: | 922 case kTwoByteStringCid: |
| 923 case kExternalOneByteStringCid: | 923 case kExternalOneByteStringCid: |
| 924 case kExternalTwoByteStringCid: | 924 case kExternalTwoByteStringCid: |
| 925 return kTagged; | 925 return kTagged; |
| 926 case kTypedDataInt32ArrayCid: | 926 case kTypedDataInt32ArrayCid: |
| 927 return kUnboxedInt32; | 927 return kUnboxedInt32; |
| 928 case kTypedDataUint32ArrayCid: | 928 case kTypedDataUint32ArrayCid: |
| 929 return kUnboxedUint32; | 929 return kUnboxedUint32; |
| 930 case kTypedDataInt64ArrayCid: | 930 case kTypedDataInt64ArrayCid: |
| 931 return kUnboxedMint; | 931 return kUnboxedInt64; |
| 932 case kTypedDataFloat32ArrayCid: | 932 case kTypedDataFloat32ArrayCid: |
| 933 case kTypedDataFloat64ArrayCid: | 933 case kTypedDataFloat64ArrayCid: |
| 934 return kUnboxedDouble; | 934 return kUnboxedDouble; |
| 935 case kTypedDataInt32x4ArrayCid: | 935 case kTypedDataInt32x4ArrayCid: |
| 936 return kUnboxedInt32x4; | 936 return kUnboxedInt32x4; |
| 937 case kTypedDataFloat32x4ArrayCid: | 937 case kTypedDataFloat32x4ArrayCid: |
| 938 return kUnboxedFloat32x4; | 938 return kUnboxedFloat32x4; |
| 939 case kTypedDataFloat64x2ArrayCid: | 939 case kTypedDataFloat64x2ArrayCid: |
| 940 return kUnboxedFloat64x2; | 940 return kUnboxedFloat64x2; |
| 941 default: | 941 default: |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 case kTypedDataUint32ArrayCid: | 1025 case kTypedDataUint32ArrayCid: |
| 1026 ASSERT(representation() == kUnboxedUint32); | 1026 ASSERT(representation() == kUnboxedUint32); |
| 1027 __ movl(result, element_address); | 1027 __ movl(result, element_address); |
| 1028 break; | 1028 break; |
| 1029 default: | 1029 default: |
| 1030 UNREACHABLE(); | 1030 UNREACHABLE(); |
| 1031 } | 1031 } |
| 1032 return; | 1032 return; |
| 1033 } | 1033 } |
| 1034 | 1034 |
| 1035 if (representation() == kUnboxedMint) { | 1035 if (representation() == kUnboxedInt64) { |
| 1036 ASSERT(class_id() == kTypedDataInt64ArrayCid); | 1036 ASSERT(class_id() == kTypedDataInt64ArrayCid); |
| 1037 if ((index_scale() == 1) && index.IsRegister()) { | 1037 if ((index_scale() == 1) && index.IsRegister()) { |
| 1038 __ SmiUntag(index.reg()); | 1038 __ SmiUntag(index.reg()); |
| 1039 } | 1039 } |
| 1040 Register result = locs()->out(0).reg(); | 1040 Register result = locs()->out(0).reg(); |
| 1041 __ movq(result, element_address); | 1041 __ movq(result, element_address); |
| 1042 return; | 1042 return; |
| 1043 } | 1043 } |
| 1044 | 1044 |
| 1045 ASSERT(representation() == kTagged); | 1045 ASSERT(representation() == kTagged); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 case kTypedDataUint8ClampedArrayCid: | 1158 case kTypedDataUint8ClampedArrayCid: |
| 1159 case kExternalTypedDataUint8ClampedArrayCid: | 1159 case kExternalTypedDataUint8ClampedArrayCid: |
| 1160 case kTypedDataInt16ArrayCid: | 1160 case kTypedDataInt16ArrayCid: |
| 1161 case kTypedDataUint16ArrayCid: | 1161 case kTypedDataUint16ArrayCid: |
| 1162 return kTagged; | 1162 return kTagged; |
| 1163 case kTypedDataInt32ArrayCid: | 1163 case kTypedDataInt32ArrayCid: |
| 1164 return kUnboxedInt32; | 1164 return kUnboxedInt32; |
| 1165 case kTypedDataUint32ArrayCid: | 1165 case kTypedDataUint32ArrayCid: |
| 1166 return kUnboxedUint32; | 1166 return kUnboxedUint32; |
| 1167 case kTypedDataInt64ArrayCid: | 1167 case kTypedDataInt64ArrayCid: |
| 1168 return kUnboxedMint; | 1168 return kUnboxedInt64; |
| 1169 case kTypedDataFloat32ArrayCid: | 1169 case kTypedDataFloat32ArrayCid: |
| 1170 case kTypedDataFloat64ArrayCid: | 1170 case kTypedDataFloat64ArrayCid: |
| 1171 return kUnboxedDouble; | 1171 return kUnboxedDouble; |
| 1172 case kTypedDataFloat32x4ArrayCid: | 1172 case kTypedDataFloat32x4ArrayCid: |
| 1173 return kUnboxedFloat32x4; | 1173 return kUnboxedFloat32x4; |
| 1174 case kTypedDataInt32x4ArrayCid: | 1174 case kTypedDataInt32x4ArrayCid: |
| 1175 return kUnboxedInt32x4; | 1175 return kUnboxedInt32x4; |
| 1176 case kTypedDataFloat64x2ArrayCid: | 1176 case kTypedDataFloat64x2ArrayCid: |
| 1177 return kUnboxedFloat64x2; | 1177 return kUnboxedFloat64x2; |
| 1178 default: | 1178 default: |
| (...skipping 2280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3459 default: | 3459 default: |
| 3460 UNREACHABLE(); | 3460 UNREACHABLE(); |
| 3461 break; | 3461 break; |
| 3462 } | 3462 } |
| 3463 } | 3463 } |
| 3464 | 3464 |
| 3465 LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, bool opt) const { | 3465 LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, bool opt) const { |
| 3466 const intptr_t kNumInputs = 1; | 3466 const intptr_t kNumInputs = 1; |
| 3467 const intptr_t kNumTemps = 0; | 3467 const intptr_t kNumTemps = 0; |
| 3468 const bool needs_writable_input = | 3468 const bool needs_writable_input = |
| 3469 (representation() != kUnboxedMint) && | 3469 (representation() != kUnboxedInt64) && |
| 3470 (value()->Type()->ToNullableCid() != BoxCid()); | 3470 (value()->Type()->ToNullableCid() != BoxCid()); |
| 3471 LocationSummary* summary = new (zone) | 3471 LocationSummary* summary = new (zone) |
| 3472 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3472 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3473 summary->set_in(0, needs_writable_input ? Location::WritableRegister() | 3473 summary->set_in(0, needs_writable_input ? Location::WritableRegister() |
| 3474 : Location::RequiresRegister()); | 3474 : Location::RequiresRegister()); |
| 3475 if (representation() == kUnboxedMint) { | 3475 if (representation() == kUnboxedInt64) { |
| 3476 summary->set_out(0, Location::SameAsFirstInput()); | 3476 summary->set_out(0, Location::SameAsFirstInput()); |
| 3477 } else { | 3477 } else { |
| 3478 summary->set_out(0, Location::RequiresFpuRegister()); | 3478 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3479 } | 3479 } |
| 3480 return summary; | 3480 return summary; |
| 3481 } | 3481 } |
| 3482 | 3482 |
| 3483 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { | 3483 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { |
| 3484 const Register box = locs()->in(0).reg(); | 3484 const Register box = locs()->in(0).reg(); |
| 3485 | 3485 |
| 3486 switch (representation()) { | 3486 switch (representation()) { |
| 3487 case kUnboxedMint: { | 3487 case kUnboxedInt64: { |
| 3488 const Register result = locs()->out(0).reg(); | 3488 const Register result = locs()->out(0).reg(); |
| 3489 __ movq(result, FieldAddress(box, ValueOffset())); | 3489 __ movq(result, FieldAddress(box, ValueOffset())); |
| 3490 break; | 3490 break; |
| 3491 } | 3491 } |
| 3492 | 3492 |
| 3493 case kUnboxedDouble: { | 3493 case kUnboxedDouble: { |
| 3494 const FpuRegister result = locs()->out(0).fpu_reg(); | 3494 const FpuRegister result = locs()->out(0).fpu_reg(); |
| 3495 __ movsd(result, FieldAddress(box, ValueOffset())); | 3495 __ movsd(result, FieldAddress(box, ValueOffset())); |
| 3496 break; | 3496 break; |
| 3497 } | 3497 } |
| 3498 | 3498 |
| 3499 case kUnboxedFloat32x4: | 3499 case kUnboxedFloat32x4: |
| 3500 case kUnboxedFloat64x2: | 3500 case kUnboxedFloat64x2: |
| 3501 case kUnboxedInt32x4: { | 3501 case kUnboxedInt32x4: { |
| 3502 const FpuRegister result = locs()->out(0).fpu_reg(); | 3502 const FpuRegister result = locs()->out(0).fpu_reg(); |
| 3503 __ movups(result, FieldAddress(box, ValueOffset())); | 3503 __ movups(result, FieldAddress(box, ValueOffset())); |
| 3504 break; | 3504 break; |
| 3505 } | 3505 } |
| 3506 | 3506 |
| 3507 default: | 3507 default: |
| 3508 UNREACHABLE(); | 3508 UNREACHABLE(); |
| 3509 break; | 3509 break; |
| 3510 } | 3510 } |
| 3511 } | 3511 } |
| 3512 | 3512 |
| 3513 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { | 3513 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { |
| 3514 const Register box = locs()->in(0).reg(); | 3514 const Register box = locs()->in(0).reg(); |
| 3515 | 3515 |
| 3516 switch (representation()) { | 3516 switch (representation()) { |
| 3517 case kUnboxedMint: { | 3517 case kUnboxedInt64: { |
| 3518 const Register result = locs()->out(0).reg(); | 3518 const Register result = locs()->out(0).reg(); |
| 3519 ASSERT(result == box); | 3519 ASSERT(result == box); |
| 3520 __ SmiUntag(box); | 3520 __ SmiUntag(box); |
| 3521 break; | 3521 break; |
| 3522 } | 3522 } |
| 3523 | 3523 |
| 3524 case kUnboxedDouble: { | 3524 case kUnboxedDouble: { |
| 3525 const FpuRegister result = locs()->out(0).fpu_reg(); | 3525 const FpuRegister result = locs()->out(0).fpu_reg(); |
| 3526 __ SmiUntag(box); | 3526 __ SmiUntag(box); |
| 3527 __ cvtsi2sdq(result, box); | 3527 __ cvtsi2sdq(result, box); |
| (...skipping 2213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5741 break; | 5741 break; |
| 5742 case Token::kMUL: | 5742 case Token::kMUL: |
| 5743 __ imulq(left, right); | 5743 __ imulq(left, right); |
| 5744 break; | 5744 break; |
| 5745 default: | 5745 default: |
| 5746 UNREACHABLE(); | 5746 UNREACHABLE(); |
| 5747 } | 5747 } |
| 5748 if (deopt != NULL) __ j(OVERFLOW, deopt); | 5748 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 5749 } | 5749 } |
| 5750 | 5750 |
| 5751 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, | 5751 LocationSummary* BinaryInt64OpInstr::MakeLocationSummary(Zone* zone, |
| 5752 bool opt) const { | 5752 bool opt) const { |
| 5753 const intptr_t kNumInputs = 2; | 5753 const intptr_t kNumInputs = 2; |
| 5754 const intptr_t kNumTemps = 0; | 5754 const intptr_t kNumTemps = 0; |
| 5755 LocationSummary* summary = new (zone) | 5755 LocationSummary* summary = new (zone) |
| 5756 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5756 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5757 summary->set_in(0, Location::RequiresRegister()); | 5757 summary->set_in(0, Location::RequiresRegister()); |
| 5758 summary->set_in(1, Location::RequiresRegister()); | 5758 summary->set_in(1, Location::RequiresRegister()); |
| 5759 summary->set_out(0, Location::SameAsFirstInput()); | 5759 summary->set_out(0, Location::SameAsFirstInput()); |
| 5760 return summary; | 5760 return summary; |
| 5761 } | 5761 } |
| 5762 | 5762 |
| 5763 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5763 void BinaryInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5764 const Register left = locs()->in(0).reg(); | 5764 const Register left = locs()->in(0).reg(); |
| 5765 const Register right = locs()->in(1).reg(); | 5765 const Register right = locs()->in(1).reg(); |
| 5766 const Register out = locs()->out(0).reg(); | 5766 const Register out = locs()->out(0).reg(); |
| 5767 | 5767 |
| 5768 ASSERT(out == left); | 5768 ASSERT(out == left); |
| 5769 | 5769 |
| 5770 Label* deopt = NULL; | 5770 Label* deopt = NULL; |
| 5771 if (CanDeoptimize()) { | 5771 if (CanDeoptimize()) { |
| 5772 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 5772 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); |
| 5773 } | 5773 } |
| 5774 | 5774 |
| 5775 EmitInt64Arithmetic(compiler, op_kind(), left, right, deopt); | 5775 EmitInt64Arithmetic(compiler, op_kind(), left, right, deopt); |
| 5776 } | 5776 } |
| 5777 | 5777 |
| 5778 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone, | 5778 LocationSummary* UnaryInt64OpInstr::MakeLocationSummary(Zone* zone, |
| 5779 bool opt) const { | 5779 bool opt) const { |
| 5780 const intptr_t kNumInputs = 1; | 5780 const intptr_t kNumInputs = 1; |
| 5781 const intptr_t kNumTemps = 0; | 5781 const intptr_t kNumTemps = 0; |
| 5782 LocationSummary* summary = new (zone) | 5782 LocationSummary* summary = new (zone) |
| 5783 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5783 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5784 summary->set_in(0, Location::RequiresRegister()); | 5784 summary->set_in(0, Location::RequiresRegister()); |
| 5785 summary->set_out(0, Location::SameAsFirstInput()); | 5785 summary->set_out(0, Location::SameAsFirstInput()); |
| 5786 return summary; | 5786 return summary; |
| 5787 } | 5787 } |
| 5788 | 5788 |
| 5789 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5789 void UnaryInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5790 ASSERT(op_kind() == Token::kBIT_NOT); | 5790 ASSERT(op_kind() == Token::kBIT_NOT); |
| 5791 const Register left = locs()->in(0).reg(); | 5791 const Register left = locs()->in(0).reg(); |
| 5792 const Register out = locs()->out(0).reg(); | 5792 const Register out = locs()->out(0).reg(); |
| 5793 ASSERT(out == left); | 5793 ASSERT(out == left); |
| 5794 __ notq(left); | 5794 __ notq(left); |
| 5795 } | 5795 } |
| 5796 | 5796 |
| 5797 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone, | 5797 LocationSummary* ShiftInt64OpInstr::MakeLocationSummary(Zone* zone, |
| 5798 bool opt) const { | 5798 bool opt) const { |
| 5799 const intptr_t kNumInputs = 2; | 5799 const intptr_t kNumInputs = 2; |
| 5800 const intptr_t kNumTemps = can_overflow() ? 1 : 0; | 5800 const intptr_t kNumTemps = can_overflow() ? 1 : 0; |
| 5801 LocationSummary* summary = new (zone) | 5801 LocationSummary* summary = new (zone) |
| 5802 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5802 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5803 summary->set_in(0, Location::RequiresRegister()); | 5803 summary->set_in(0, Location::RequiresRegister()); |
| 5804 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX)); | 5804 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX)); |
| 5805 if (kNumTemps > 0) { | 5805 if (kNumTemps > 0) { |
| 5806 summary->set_temp(0, Location::RequiresRegister()); | 5806 summary->set_temp(0, Location::RequiresRegister()); |
| 5807 } | 5807 } |
| 5808 summary->set_out(0, Location::SameAsFirstInput()); | 5808 summary->set_out(0, Location::SameAsFirstInput()); |
| 5809 return summary; | 5809 return summary; |
| 5810 } | 5810 } |
| 5811 | 5811 |
| 5812 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5812 void ShiftInt64OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5813 const Register left = locs()->in(0).reg(); | 5813 const Register left = locs()->in(0).reg(); |
| 5814 const Register out = locs()->out(0).reg(); | 5814 const Register out = locs()->out(0).reg(); |
| 5815 ASSERT(left == out); | 5815 ASSERT(left == out); |
| 5816 | 5816 |
| 5817 Label* deopt = NULL; | 5817 Label* deopt = NULL; |
| 5818 if (CanDeoptimize()) { | 5818 if (CanDeoptimize()) { |
| 5819 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 5819 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); |
| 5820 } | 5820 } |
| 5821 if (locs()->in(1).IsConstant()) { | 5821 if (locs()->in(1).IsConstant()) { |
| 5822 // Code for a constant shift amount. | 5822 // Code for a constant shift amount. |
| 5823 ASSERT(locs()->in(1).constant().IsSmi()); | 5823 ASSERT(locs()->in(1).constant().IsSmi()); |
| 5824 const int64_t shift = Smi::Cast(locs()->in(1).constant()).Value(); | 5824 const int64_t shift = Smi::Cast(locs()->in(1).constant()).Value(); |
| 5825 ASSERT(shift >= 0); | 5825 ASSERT(shift >= 0); |
| 5826 switch (op_kind()) { | 5826 switch (op_kind()) { |
| 5827 case Token::kSHR: | 5827 case Token::kSHR: |
| 5828 __ sarq(left, | 5828 __ sarq(left, |
| 5829 Immediate(Utils::Minimum<int64_t>(shift, kBitsPerWord - 1))); | 5829 Immediate(Utils::Minimum<int64_t>(shift, kBitsPerWord - 1))); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5967 return summary; | 5967 return summary; |
| 5968 } | 5968 } |
| 5969 | 5969 |
| 5970 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5970 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5971 const intptr_t kShifterLimit = 31; | 5971 const intptr_t kShifterLimit = 31; |
| 5972 | 5972 |
| 5973 Register left = locs()->in(0).reg(); | 5973 Register left = locs()->in(0).reg(); |
| 5974 Register out = locs()->out(0).reg(); | 5974 Register out = locs()->out(0).reg(); |
| 5975 ASSERT(left == out); | 5975 ASSERT(left == out); |
| 5976 | 5976 |
| 5977 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); | 5977 Label* deopt = |
| 5978 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryInt64Op); |
| 5978 | 5979 |
| 5979 if (locs()->in(1).IsConstant()) { | 5980 if (locs()->in(1).IsConstant()) { |
| 5980 // Shifter is constant. | 5981 // Shifter is constant. |
| 5981 | 5982 |
| 5982 const Object& constant = locs()->in(1).constant(); | 5983 const Object& constant = locs()->in(1).constant(); |
| 5983 ASSERT(constant.IsSmi()); | 5984 ASSERT(constant.IsSmi()); |
| 5984 const intptr_t shift_value = Smi::Cast(constant).Value(); | 5985 const intptr_t shift_value = Smi::Cast(constant).Value(); |
| 5985 | 5986 |
| 5986 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). | 5987 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). |
| 5987 switch (op_kind()) { | 5988 switch (op_kind()) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6057 } | 6058 } |
| 6058 | 6059 |
| 6059 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) | 6060 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) |
| 6060 | 6061 |
| 6061 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone, | 6062 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Zone* zone, |
| 6062 bool opt) const { | 6063 bool opt) const { |
| 6063 const intptr_t kNumInputs = 1; | 6064 const intptr_t kNumInputs = 1; |
| 6064 const intptr_t kNumTemps = 0; | 6065 const intptr_t kNumTemps = 0; |
| 6065 LocationSummary* summary = new (zone) | 6066 LocationSummary* summary = new (zone) |
| 6066 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6067 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6067 if (from() == kUnboxedMint) { | 6068 if (from() == kUnboxedInt64) { |
| 6068 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); | 6069 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); |
| 6069 summary->set_in(0, Location::RequiresRegister()); | 6070 summary->set_in(0, Location::RequiresRegister()); |
| 6070 summary->set_out(0, Location::SameAsFirstInput()); | 6071 summary->set_out(0, Location::SameAsFirstInput()); |
| 6071 } else if (to() == kUnboxedMint) { | 6072 } else if (to() == kUnboxedInt64) { |
| 6072 ASSERT((from() == kUnboxedInt32) || (from() == kUnboxedUint32)); | 6073 ASSERT((from() == kUnboxedInt32) || (from() == kUnboxedUint32)); |
| 6073 summary->set_in(0, Location::RequiresRegister()); | 6074 summary->set_in(0, Location::RequiresRegister()); |
| 6074 summary->set_out(0, Location::SameAsFirstInput()); | 6075 summary->set_out(0, Location::SameAsFirstInput()); |
| 6075 } else { | 6076 } else { |
| 6076 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); | 6077 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); |
| 6077 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); | 6078 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); |
| 6078 summary->set_in(0, Location::RequiresRegister()); | 6079 summary->set_in(0, Location::RequiresRegister()); |
| 6079 summary->set_out(0, Location::SameAsFirstInput()); | 6080 summary->set_out(0, Location::SameAsFirstInput()); |
| 6080 } | 6081 } |
| 6081 return summary; | 6082 return summary; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6094 // Representations are bitwise equivalent. | 6095 // Representations are bitwise equivalent. |
| 6095 const Register value = locs()->in(0).reg(); | 6096 const Register value = locs()->in(0).reg(); |
| 6096 const Register out = locs()->out(0).reg(); | 6097 const Register out = locs()->out(0).reg(); |
| 6097 __ movsxd(out, value); | 6098 __ movsxd(out, value); |
| 6098 if (CanDeoptimize()) { | 6099 if (CanDeoptimize()) { |
| 6099 Label* deopt = | 6100 Label* deopt = |
| 6100 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | 6101 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 6101 __ testl(out, out); | 6102 __ testl(out, out); |
| 6102 __ j(NEGATIVE, deopt); | 6103 __ j(NEGATIVE, deopt); |
| 6103 } | 6104 } |
| 6104 } else if (from() == kUnboxedMint) { | 6105 } else if (from() == kUnboxedInt64) { |
| 6105 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); | 6106 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); |
| 6106 const Register value = locs()->in(0).reg(); | 6107 const Register value = locs()->in(0).reg(); |
| 6107 const Register out = locs()->out(0).reg(); | 6108 const Register out = locs()->out(0).reg(); |
| 6108 if (!CanDeoptimize()) { | 6109 if (!CanDeoptimize()) { |
| 6109 // Copy low. | 6110 // Copy low. |
| 6110 __ movl(out, value); | 6111 __ movl(out, value); |
| 6111 } else { | 6112 } else { |
| 6112 Label* deopt = | 6113 Label* deopt = |
| 6113 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | 6114 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 6114 // Sign extend. | 6115 // Sign extend. |
| 6115 __ movsxd(out, value); | 6116 __ movsxd(out, value); |
| 6116 // Compare with original value. | 6117 // Compare with original value. |
| 6117 __ cmpq(out, value); | 6118 __ cmpq(out, value); |
| 6118 // Value cannot be held in Int32, deopt. | 6119 // Value cannot be held in Int32, deopt. |
| 6119 __ j(NOT_EQUAL, deopt); | 6120 __ j(NOT_EQUAL, deopt); |
| 6120 } | 6121 } |
| 6121 } else if (to() == kUnboxedMint) { | 6122 } else if (to() == kUnboxedInt64) { |
| 6122 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); | 6123 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); |
| 6123 const Register value = locs()->in(0).reg(); | 6124 const Register value = locs()->in(0).reg(); |
| 6124 const Register out = locs()->out(0).reg(); | 6125 const Register out = locs()->out(0).reg(); |
| 6125 if (from() == kUnboxedUint32) { | 6126 if (from() == kUnboxedUint32) { |
| 6126 // Zero extend. | 6127 // Zero extend. |
| 6127 __ movl(out, value); | 6128 __ movl(out, value); |
| 6128 } else { | 6129 } else { |
| 6129 // Sign extend. | 6130 // Sign extend. |
| 6130 ASSERT(from() == kUnboxedInt32); | 6131 ASSERT(from() == kUnboxedInt32); |
| 6131 __ movsxd(out, value); | 6132 __ movsxd(out, value); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6364 __ CallPatchable(*StubCode::DebugStepCheck_entry()); | 6365 __ CallPatchable(*StubCode::DebugStepCheck_entry()); |
| 6365 compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos()); | 6366 compiler->AddCurrentDescriptor(stub_kind_, deopt_id_, token_pos()); |
| 6366 compiler->RecordSafepoint(locs()); | 6367 compiler->RecordSafepoint(locs()); |
| 6367 } | 6368 } |
| 6368 | 6369 |
| 6369 } // namespace dart | 6370 } // namespace dart |
| 6370 | 6371 |
| 6371 #undef __ | 6372 #undef __ |
| 6372 | 6373 |
| 6373 #endif // defined TARGET_ARCH_X64 | 6374 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |