Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: runtime/vm/intermediate_language_x64.cc

Issue 552303005: Fix StoreIndexedInstr input representation requirements for Int32/Uint32 arrays. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698