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 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 } | 240 } |
241 } | 241 } |
242 | 242 |
243 | 243 |
244 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, | 244 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, |
245 bool opt) const { | 245 bool opt) const { |
246 const intptr_t kNumInputs = 0; | 246 const intptr_t kNumInputs = 0; |
247 const intptr_t kNumTemps = 0; | 247 const intptr_t kNumTemps = 0; |
248 LocationSummary* locs = new(isolate) LocationSummary( | 248 LocationSummary* locs = new(isolate) LocationSummary( |
249 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 249 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
250 locs->set_out(0, Location::RequiresFpuRegister()); | 250 switch (representation()) { |
251 case kUnboxedDouble: | |
252 locs->set_out(0, Location::RequiresFpuRegister()); | |
253 break; | |
254 case kUnboxedInt32: | |
255 locs->set_out(0, Location::RequiresRegister()); | |
256 break; | |
257 default: | |
258 UNREACHABLE(); | |
259 break; | |
260 } | |
251 return locs; | 261 return locs; |
252 } | 262 } |
253 | 263 |
254 | 264 |
255 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 265 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
256 ASSERT(representation_ == kUnboxedDouble); | |
257 // The register allocator drops constant definitions that have no uses. | 266 // The register allocator drops constant definitions that have no uses. |
258 if (!locs()->out(0).IsInvalid()) { | 267 if (!locs()->out(0).IsInvalid()) { |
259 XmmRegister result = locs()->out(0).fpu_reg(); | 268 switch (representation()) { |
260 if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) { | 269 case kUnboxedDouble: { |
261 __ xorps(result, result); | 270 XmmRegister result = locs()->out(0).fpu_reg(); |
262 } else { | 271 if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) { |
263 __ LoadObject(TMP, value(), PP); | 272 __ xorps(result, result); |
264 __ movsd(result, FieldAddress(TMP, Double::value_offset())); | 273 } else { |
274 __ LoadObject(TMP, value(), PP); | |
275 __ movsd(result, FieldAddress(TMP, Double::value_offset())); | |
276 } | |
277 break; | |
278 } | |
279 case kUnboxedInt32: | |
280 __ movl(locs()->out(0).reg(), | |
281 Immediate(static_cast<int32_t>(Smi::Cast(value()).Value()))); | |
282 break; | |
283 default: | |
284 UNREACHABLE(); | |
265 } | 285 } |
266 } | 286 } |
267 } | 287 } |
268 | 288 |
269 | 289 |
270 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Isolate* isolate, | 290 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Isolate* isolate, |
271 bool opt) const { | 291 bool opt) const { |
272 const intptr_t kNumInputs = 3; | 292 const intptr_t kNumInputs = 3; |
273 const intptr_t kNumTemps = 0; | 293 const intptr_t kNumTemps = 0; |
274 LocationSummary* summary = new(isolate) LocationSummary( | 294 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1075 switch (class_id_) { | 1095 switch (class_id_) { |
1076 case kArrayCid: | 1096 case kArrayCid: |
1077 case kOneByteStringCid: | 1097 case kOneByteStringCid: |
1078 case kTypedDataInt8ArrayCid: | 1098 case kTypedDataInt8ArrayCid: |
1079 case kTypedDataUint8ArrayCid: | 1099 case kTypedDataUint8ArrayCid: |
1080 case kExternalTypedDataUint8ArrayCid: | 1100 case kExternalTypedDataUint8ArrayCid: |
1081 case kTypedDataUint8ClampedArrayCid: | 1101 case kTypedDataUint8ClampedArrayCid: |
1082 case kExternalTypedDataUint8ClampedArrayCid: | 1102 case kExternalTypedDataUint8ClampedArrayCid: |
1083 case kTypedDataInt16ArrayCid: | 1103 case kTypedDataInt16ArrayCid: |
1084 case kTypedDataUint16ArrayCid: | 1104 case kTypedDataUint16ArrayCid: |
1105 return kTagged; | |
1085 case kTypedDataInt32ArrayCid: | 1106 case kTypedDataInt32ArrayCid: |
1107 return kUnboxedInt32; | |
1086 case kTypedDataUint32ArrayCid: | 1108 case kTypedDataUint32ArrayCid: |
1087 return kTagged; | 1109 return kUnboxedUint32; |
1088 case kTypedDataFloat32ArrayCid: | 1110 case kTypedDataFloat32ArrayCid: |
1089 case kTypedDataFloat64ArrayCid: | 1111 case kTypedDataFloat64ArrayCid: |
1090 return kUnboxedDouble; | 1112 return kUnboxedDouble; |
1091 case kTypedDataFloat32x4ArrayCid: | 1113 case kTypedDataFloat32x4ArrayCid: |
1092 return kUnboxedFloat32x4; | 1114 return kUnboxedFloat32x4; |
1093 case kTypedDataInt32x4ArrayCid: | 1115 case kTypedDataInt32x4ArrayCid: |
1094 return kUnboxedInt32x4; | 1116 return kUnboxedInt32x4; |
1095 case kTypedDataFloat64x2ArrayCid: | 1117 case kTypedDataFloat64x2ArrayCid: |
1096 return kUnboxedFloat64x2; | 1118 return kUnboxedFloat64x2; |
1097 default: | 1119 default: |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1235 case kTypedDataInt16ArrayCid: | 1257 case kTypedDataInt16ArrayCid: |
1236 case kTypedDataUint16ArrayCid: { | 1258 case kTypedDataUint16ArrayCid: { |
1237 Register value = locs()->in(2).reg(); | 1259 Register value = locs()->in(2).reg(); |
1238 __ SmiUntag(value); | 1260 __ SmiUntag(value); |
1239 __ movw(element_address, value); | 1261 __ movw(element_address, value); |
1240 break; | 1262 break; |
1241 } | 1263 } |
1242 case kTypedDataInt32ArrayCid: | 1264 case kTypedDataInt32ArrayCid: |
1243 case kTypedDataUint32ArrayCid: { | 1265 case kTypedDataUint32ArrayCid: { |
1244 Register value = locs()->in(2).reg(); | 1266 Register value = locs()->in(2).reg(); |
1245 __ SmiUntag(value); | |
1246 __ movl(element_address, value); | 1267 __ movl(element_address, value); |
1247 break; | 1268 break; |
1248 } | 1269 } |
1249 case kTypedDataFloat32ArrayCid: | 1270 case kTypedDataFloat32ArrayCid: |
1250 __ movss(element_address, locs()->in(2).fpu_reg()); | 1271 __ movss(element_address, locs()->in(2).fpu_reg()); |
1251 break; | 1272 break; |
1252 case kTypedDataFloat64ArrayCid: | 1273 case kTypedDataFloat64ArrayCid: |
1253 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1274 __ movsd(element_address, locs()->in(2).fpu_reg()); |
1254 break; | 1275 break; |
1255 case kTypedDataInt32x4ArrayCid: | 1276 case kTypedDataInt32x4ArrayCid: |
(...skipping 4257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5513 | 5534 |
5514 | 5535 |
5515 CompileType UnaryUint32OpInstr::ComputeType() const { | 5536 CompileType UnaryUint32OpInstr::ComputeType() const { |
5516 return CompileType::FromCid(kSmiCid); | 5537 return CompileType::FromCid(kSmiCid); |
5517 } | 5538 } |
5518 | 5539 |
5519 | 5540 |
5520 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) | 5541 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) |
5521 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) | 5542 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) |
5522 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) | 5543 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) |
5523 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxInt32Instr) | |
5524 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnboxInt32Instr) | |
5525 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) | 5544 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) |
5526 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxUint32Instr) | |
5527 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnboxedIntConverterInstr) | |
5528 | 5545 |
5529 | 5546 |
5530 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, | 5547 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, |
5531 bool opt) const { | 5548 bool opt) const { |
5549 const intptr_t kNumInputs = 1; | |
5550 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0; | |
5551 LocationSummary* summary = new(isolate) LocationSummary( | |
5552 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
5553 summary->set_in(0, Location::RequiresRegister()); | |
5554 summary->set_out(0, Location::SameAsFirstInput()); | |
5555 if (kNumTemps > 0) { | |
5556 summary->set_temp(0, Location::RequiresRegister()); | |
5557 } | |
5558 return summary; | |
5559 } | |
5560 | |
5561 | |
5562 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
5563 const intptr_t value_cid = value()->Type()->ToCid(); | |
5564 const Register value = locs()->in(0).reg(); | |
5565 Label* deopt = CanDeoptimize() ? | |
5566 compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL; | |
5567 ASSERT(value == locs()->out(0).reg()); | |
5568 | |
5569 if (value_cid == kSmiCid) { | |
5570 __ SmiUntag(value); | |
5571 } else if (value_cid == kMintCid) { | |
5572 __ movq(value, FieldAddress(value, Mint::value_offset())); | |
5573 } else { | |
5574 Label done; | |
5575 // Optimistically untag value. | |
5576 __ SmiUntagOrCheckClass(value, kMintCid, &done); | |
5577 __ j(NOT_EQUAL, deopt); | |
5578 // Undo untagging by multiplying value with 2. | |
5579 __ movq(value, Address(value, TIMES_2, Mint::value_offset())); | |
5580 __ Bind(&done); | |
5581 } | |
5582 | |
5583 if (!is_truncating() && (deopt != NULL)) { | |
zra
2014/09/10 23:17:22
Maybe copy your comment from arm64 here as well?
Vyacheslav Egorov (Google)
2014/09/11 11:49:17
Done.
| |
5584 ASSERT(representation() == kUnboxedInt32); | |
5585 Register temp = locs()->temp(0).reg(); | |
5586 __ movsxd(temp, value); | |
5587 __ cmpq(temp, value); | |
5588 __ j(NOT_EQUAL, deopt); | |
5589 } | |
5590 } | |
5591 | |
5592 | |
5593 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate, | |
5594 bool opt) const { | |
5595 ASSERT((from_representation() == kUnboxedInt32) || | |
5596 (from_representation() == kUnboxedUint32)); | |
5597 const intptr_t kNumInputs = 1; | |
5598 const intptr_t kNumTemps = 0; | |
5599 LocationSummary* summary = new(isolate) LocationSummary( | |
5600 isolate, | |
5601 kNumInputs, | |
5602 kNumTemps, | |
5603 LocationSummary::kNoCall); | |
5604 summary->set_in(0, Location::RequiresRegister()); | |
5605 summary->set_out(0, Location::RequiresRegister()); | |
5606 return summary; | |
5607 } | |
5608 | |
5609 | |
5610 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
5611 const Register value = locs()->in(0).reg(); | |
5612 const Register out = locs()->out(0).reg(); | |
5613 ASSERT(value != out); | |
5614 | |
5615 ASSERT(kSmiTagSize == 1); | |
5616 if (from_representation() == kUnboxedInt32) { | |
5617 __ movsxd(out, value); | |
5618 } else { | |
5619 ASSERT(from_representation() == kUnboxedUint32); | |
5620 __ movl(out, value); | |
5621 } | |
5622 __ SmiTag(out); | |
5623 } | |
5624 | |
5625 | |
5626 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | |
5627 bool opt) const { | |
5532 const intptr_t kNumInputs = 1; | 5628 const intptr_t kNumInputs = 1; |
5533 const intptr_t kNumTemps = 0; | 5629 const intptr_t kNumTemps = 0; |
5534 LocationSummary* summary = new(isolate) LocationSummary( | 5630 LocationSummary* summary = new(isolate) LocationSummary( |
5535 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5631 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5536 summary->set_in(0, Location::RequiresRegister()); | 5632 if (from() == kUnboxedMint) { |
5537 summary->set_out(0, Location::SameAsFirstInput()); | 5633 UNREACHABLE(); |
5634 } else if (to() == kUnboxedMint) { | |
5635 UNREACHABLE(); | |
5636 } else { | |
5637 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); | |
5638 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); | |
5639 summary->set_in(0, Location::RequiresRegister()); | |
5640 summary->set_out(0, Location::SameAsFirstInput()); | |
5641 } | |
5538 return summary; | 5642 return summary; |
5539 } | 5643 } |
5540 | 5644 |
5541 | 5645 |
5542 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5646 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5543 const intptr_t value_cid = value()->Type()->ToCid(); | 5647 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) { |
5544 const Register value = locs()->in(0).reg(); | 5648 const Register value = locs()->in(0).reg(); |
5545 ASSERT(value == locs()->out(0).reg()); | 5649 const Register out = locs()->out(0).reg(); |
5546 | 5650 // Representations are bitwise equivalent but we want to normalize |
5547 if (value_cid == kSmiCid) { | 5651 // upperbits for safety reasons. |
5548 __ SmiUntag(value); | 5652 // TODO(vegorov) if we ensure that we never use upperbits we could |
5653 // avoid this. | |
5654 __ movl(out, value); | |
5655 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { | |
5656 // Representations are bitwise equivalent. | |
5657 const Register value = locs()->in(0).reg(); | |
5658 const Register out = locs()->out(0).reg(); | |
5659 __ movsxd(out, value); | |
5660 if (CanDeoptimize()) { | |
5661 Label* deopt = | |
5662 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); | |
5663 __ testl(out, out); | |
5664 __ j(NEGATIVE, deopt); | |
5665 } | |
5666 } else if (from() == kUnboxedMint) { | |
5667 UNREACHABLE(); | |
5668 } else if (to() == kUnboxedMint) { | |
5669 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32)); | |
5670 UNREACHABLE(); | |
5549 } else { | 5671 } else { |
5550 Label* deopt = compiler->AddDeoptStub(deopt_id_, | 5672 UNREACHABLE(); |
5551 ICData::kDeoptUnboxInteger); | |
5552 __ testq(value, Immediate(kSmiTagMask)); | |
5553 __ j(NOT_ZERO, deopt); | |
5554 __ SmiUntag(value); | |
5555 } | 5673 } |
5556 } | 5674 } |
5557 | 5675 |
5558 | 5676 |
5559 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, | 5677 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, |
5560 bool opt) const { | 5678 bool opt) const { |
5561 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); | 5679 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); |
5562 } | 5680 } |
5563 | 5681 |
5564 | 5682 |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5844 __ movq(R10, Immediate(kInvalidObjectPointer)); | 5962 __ movq(R10, Immediate(kInvalidObjectPointer)); |
5845 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 5963 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
5846 #endif | 5964 #endif |
5847 } | 5965 } |
5848 | 5966 |
5849 } // namespace dart | 5967 } // namespace dart |
5850 | 5968 |
5851 #undef __ | 5969 #undef __ |
5852 | 5970 |
5853 #endif // defined TARGET_ARCH_X64 | 5971 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |