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