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

Side by Side Diff: runtime/vm/intermediate_language_mips.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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 __ TraceSimMsg("ConstantInstr"); 309 __ TraceSimMsg("ConstantInstr");
310 Register result = locs()->out(0).reg(); 310 Register result = locs()->out(0).reg();
311 __ LoadObject(result, value()); 311 __ LoadObject(result, value());
312 } 312 }
313 } 313 }
314 314
315 315
316 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, 316 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate,
317 bool opt) const { 317 bool opt) const {
318 const intptr_t kNumInputs = 0; 318 const intptr_t kNumInputs = 0;
319 const intptr_t kNumTemps = 1; 319 const intptr_t kNumTemps = (representation_ == kUnboxedInt32) ? 0 : 1;
320 LocationSummary* locs = new(isolate) LocationSummary( 320 LocationSummary* locs = new(isolate) LocationSummary(
321 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 321 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
322 locs->set_out(0, Location::RequiresFpuRegister()); 322 if (representation_ == kUnboxedInt32) {
323 locs->set_temp(0, Location::RequiresRegister()); 323 locs->set_out(0, Location::RequiresRegister());
324 } else {
325 ASSERT(representation_ == kUnboxedDouble);
326 locs->set_out(0, Location::RequiresFpuRegister());
327 }
328 if (kNumTemps > 0) {
329 locs->set_temp(0, Location::RequiresRegister());
330 }
324 return locs; 331 return locs;
325 } 332 }
326 333
327 334
328 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 335 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
329 ASSERT(representation_ == kUnboxedDouble);
330 // The register allocator drops constant definitions that have no uses. 336 // The register allocator drops constant definitions that have no uses.
331 if (!locs()->out(0).IsInvalid()) { 337 if (!locs()->out(0).IsInvalid()) {
332 ASSERT(value().IsDouble()); 338 switch (representation_) {
333 const Register const_value = locs()->temp(0).reg(); 339 case kUnboxedDouble: {
334 const DRegister result = locs()->out(0).fpu_reg(); 340 ASSERT(value().IsDouble());
335 __ LoadObject(const_value, value()); 341 const Register const_value = locs()->temp(0).reg();
336 __ LoadDFromOffset(result, const_value, 342 const DRegister result = locs()->out(0).fpu_reg();
337 Double::value_offset() - kHeapObjectTag); 343 __ LoadObject(const_value, value());
344 __ LoadDFromOffset(result, const_value,
345 Double::value_offset() - kHeapObjectTag);
346 break;
347 }
348
349 case kUnboxedInt32:
350 __ LoadImmediate(locs()->out(0).reg(),
351 Smi::Cast(value()).Value());
352 break;
353
354 default:
355 UNREACHABLE();
356 }
338 } 357 }
339 } 358 }
340 359
341 360
342 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Isolate* isolate, 361 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Isolate* isolate,
343 bool opt) const { 362 bool opt) const {
344 const intptr_t kNumInputs = 3; 363 const intptr_t kNumInputs = 3;
345 const intptr_t kNumTemps = 0; 364 const intptr_t kNumTemps = 0;
346 LocationSummary* summary = new(isolate) LocationSummary( 365 LocationSummary* summary = new(isolate) LocationSummary(
347 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); 366 isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 case kOneByteStringCid: 1264 case kOneByteStringCid:
1246 case kTypedDataInt8ArrayCid: 1265 case kTypedDataInt8ArrayCid:
1247 case kTypedDataUint8ArrayCid: 1266 case kTypedDataUint8ArrayCid:
1248 case kExternalTypedDataUint8ArrayCid: 1267 case kExternalTypedDataUint8ArrayCid:
1249 case kTypedDataUint8ClampedArrayCid: 1268 case kTypedDataUint8ClampedArrayCid:
1250 case kExternalTypedDataUint8ClampedArrayCid: 1269 case kExternalTypedDataUint8ClampedArrayCid:
1251 case kTypedDataInt16ArrayCid: 1270 case kTypedDataInt16ArrayCid:
1252 case kTypedDataUint16ArrayCid: 1271 case kTypedDataUint16ArrayCid:
1253 return kTagged; 1272 return kTagged;
1254 case kTypedDataInt32ArrayCid: 1273 case kTypedDataInt32ArrayCid:
1274 return kUnboxedInt32;
1255 case kTypedDataUint32ArrayCid: 1275 case kTypedDataUint32ArrayCid:
1256 return value()->IsSmiValue() ? kTagged : kUnboxedMint; 1276 return kUnboxedUint32;
1257 case kTypedDataFloat32ArrayCid: 1277 case kTypedDataFloat32ArrayCid:
1258 case kTypedDataFloat64ArrayCid: 1278 case kTypedDataFloat64ArrayCid:
1259 return kUnboxedDouble; 1279 return kUnboxedDouble;
1260 case kTypedDataFloat32x4ArrayCid: 1280 case kTypedDataFloat32x4ArrayCid:
1261 return kUnboxedFloat32x4; 1281 return kUnboxedFloat32x4;
1262 case kTypedDataInt32x4ArrayCid: 1282 case kTypedDataInt32x4ArrayCid:
1263 return kUnboxedInt32x4; 1283 return kUnboxedInt32x4;
1264 default: 1284 default:
1265 UNIMPLEMENTED(); 1285 UNIMPLEMENTED();
1266 return kTagged; 1286 return kTagged;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1382 } 1402 }
1383 case kTypedDataInt16ArrayCid: 1403 case kTypedDataInt16ArrayCid:
1384 case kTypedDataUint16ArrayCid: { 1404 case kTypedDataUint16ArrayCid: {
1385 Register value = locs()->in(2).reg(); 1405 Register value = locs()->in(2).reg();
1386 __ SmiUntag(TMP, value); 1406 __ SmiUntag(TMP, value);
1387 __ sh(TMP, element_address); 1407 __ sh(TMP, element_address);
1388 break; 1408 break;
1389 } 1409 }
1390 case kTypedDataInt32ArrayCid: 1410 case kTypedDataInt32ArrayCid:
1391 case kTypedDataUint32ArrayCid: { 1411 case kTypedDataUint32ArrayCid: {
1392 if (value()->IsSmiValue()) { 1412 __ sw(locs()->in(2).reg(), element_address);
1393 ASSERT(RequiredInputRepresentation(2) == kTagged);
1394 Register value = locs()->in(2).reg();
1395 __ SmiUntag(TMP, value);
1396 __ sw(TMP, element_address);
1397 } else {
1398 UNIMPLEMENTED();
1399 }
1400 break; 1413 break;
1401 } 1414 }
1402 case kTypedDataFloat32ArrayCid: { 1415 case kTypedDataFloat32ArrayCid: {
1403 FRegister value = EvenFRegisterOf(locs()->in(2).fpu_reg()); 1416 FRegister value = EvenFRegisterOf(locs()->in(2).fpu_reg());
1404 __ swc1(value, element_address); 1417 __ swc1(value, element_address);
1405 break; 1418 break;
1406 } 1419 }
1407 case kTypedDataFloat64ArrayCid: 1420 case kTypedDataFloat64ArrayCid:
1408 __ StoreDToOffset(locs()->in(2).fpu_reg(), 1421 __ StoreDToOffset(locs()->in(2).fpu_reg(),
1409 element_address.base(), element_address.offset()); 1422 element_address.base(), element_address.offset());
(...skipping 3152 matching lines...) Expand 10 before | Expand all | Expand 10 after
4562 4575
4563 4576
4564 CompileType UnaryUint32OpInstr::ComputeType() const { 4577 CompileType UnaryUint32OpInstr::ComputeType() const {
4565 return CompileType::Int(); 4578 return CompileType::Int();
4566 } 4579 }
4567 4580
4568 4581
4569 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) 4582 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr)
4570 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) 4583 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr)
4571 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) 4584 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr)
4572 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxInt32Instr)
4573 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnboxInt32Instr)
4574 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) 4585 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
4575 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxUint32Instr) 4586
4576 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnboxUint32Instr) 4587
4577 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnboxedIntConverterInstr) 4588 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate,
4589 bool opt) const {
4590 ASSERT((from_representation() == kUnboxedInt32) ||
4591 (from_representation() == kUnboxedUint32));
4592 const intptr_t kNumInputs = 1;
4593 const intptr_t kNumTemps = 1;
4594 LocationSummary* summary = new(isolate) LocationSummary(
4595 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
4596 summary->set_in(0, Location::RequiresRegister());
4597 summary->set_temp(0, Location::RequiresRegister());
4598 summary->set_out(0, Location::RequiresRegister());
4599 return summary;
4600 }
4601
4602
4603 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4604 Register value = locs()->in(0).reg();
4605 Register out = locs()->out(0).reg();
4606 ASSERT(value != out);
4607
4608 Label done;
4609 __ SmiTag(out, value);
4610 if (!ValueFitsSmi()) {
4611 Register temp = locs()->temp(0).reg();
4612 if (from_representation() == kUnboxedInt32) {
4613 __ SmiUntag(CMPRES1, out);
4614 __ BranchEqual(CMPRES1, value, &done);
4615 } else {
4616 ASSERT(from_representation() == kUnboxedUint32);
4617 __ AndImmediate(CMPRES1, value, 0xC0000000);
4618 __ BranchEqual(CMPRES1, ZR, &done);
4619 }
4620 BoxAllocationSlowPath::Allocate(
4621 compiler,
4622 this,
4623 compiler->mint_class(),
4624 out,
4625 temp);
4626 Register hi;
4627 if (from_representation() == kUnboxedInt32) {
4628 hi = temp;
4629 __ sra(hi, value, kBitsPerWord - 1);
4630 } else {
4631 ASSERT(from_representation() == kUnboxedUint32);
4632 hi = ZR;
4633 }
4634 __ StoreToOffset(value,
4635 out,
4636 Mint::value_offset() - kHeapObjectTag);
4637 __ StoreToOffset(hi,
4638 out,
4639 Mint::value_offset() - kHeapObjectTag + kWordSize);
4640 __ Bind(&done);
4641 }
4642 }
4643
4644
4645 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
4646 bool opt) const {
4647 ASSERT((representation() == kUnboxedInt32) ||
4648 (representation() == kUnboxedUint32));
4649 const intptr_t kNumInputs = 1;
4650 const intptr_t kNumTemps = 0;
4651 LocationSummary* summary = new(isolate) LocationSummary(
4652 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4653 summary->set_in(0, Location::RequiresRegister());
4654 summary->set_out(0, Location::RequiresRegister());
4655 return summary;
4656 }
4657
4658
4659 static void LoadInt32FromMint(FlowGraphCompiler* compiler,
4660 Register mint,
4661 Register result,
4662 Label* deopt) {
4663 __ LoadFromOffset(result,
4664 mint,
4665 Mint::value_offset() - kHeapObjectTag);
4666 if (deopt != NULL) {
4667 __ LoadFromOffset(CMPRES1,
4668 mint,
4669 Mint::value_offset() - kHeapObjectTag + kWordSize);
4670 __ sra(CMPRES2, result, kBitsPerWord - 1);
4671 __ BranchNotEqual(CMPRES1, CMPRES2, deopt);
4672 }
4673 }
4674
4675
4676 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4677 const intptr_t value_cid = value()->Type()->ToCid();
4678 const Register value = locs()->in(0).reg();
4679 const Register out = locs()->out(0).reg();
4680 Label* deopt = CanDeoptimize() ?
4681 compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL;
4682 Label* out_of_range = !is_truncating() ? deopt : NULL;
4683 ASSERT(value != out);
4684
4685 if (value_cid == kSmiCid) {
4686 __ SmiUntag(out, value);
4687 } else if (value_cid == kMintCid) {
4688 LoadInt32FromMint(compiler, value, out, out_of_range);
4689 } else {
4690 Label done;
4691 __ SmiUntag(out, value);
4692 __ andi(CMPRES1, value, Immediate(kSmiTagMask));
4693 __ beq(CMPRES1, ZR, &done);
4694 __ LoadClassId(CMPRES1, value);
4695 __ BranchNotEqual(CMPRES1, kMintCid, deopt);
4696 LoadInt32FromMint(compiler, value, out, out_of_range);
4697 __ Bind(&done);
4698 }
4699 }
4700
4701
4702 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
4703 bool opt) const {
4704 const intptr_t kNumInputs = 1;
4705 const intptr_t kNumTemps = 0;
4706 LocationSummary* summary = new(isolate) LocationSummary(
4707 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4708 if (from() == kUnboxedMint) {
4709 UNREACHABLE();
4710 } else if (to() == kUnboxedMint) {
4711 UNREACHABLE();
4712 } else {
4713 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
4714 ASSERT((from() == kUnboxedUint32) || (from() == kUnboxedInt32));
4715 summary->set_in(0, Location::RequiresRegister());
4716 summary->set_out(0, Location::SameAsFirstInput());
4717 }
4718 return summary;
4719 }
4720
4721
4722 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4723 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) {
4724 const Register out = locs()->out(0).reg();
4725 // Representations are bitwise equivalent.
4726 ASSERT(out == locs()->in(0).reg());
4727 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) {
4728 const Register out = locs()->out(0).reg();
4729 // Representations are bitwise equivalent.
4730 ASSERT(out == locs()->in(0).reg());
4731 if (CanDeoptimize()) {
4732 Label* deopt =
4733 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger);
4734 __ BranchSignedLess(out, 0, deopt);
4735 }
4736 } else if (from() == kUnboxedMint) {
4737 UNREACHABLE();
4738 } else if (to() == kUnboxedMint) {
4739 ASSERT(from() == kUnboxedUint32 || from() == kUnboxedInt32);
4740 UNREACHABLE();
4741 } else {
4742 UNREACHABLE();
4743 }
4744 }
4578 4745
4579 4746
4580 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, 4747 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate,
4581 bool opt) const { 4748 bool opt) const {
4582 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); 4749 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall);
4583 } 4750 }
4584 4751
4585 4752
4586 4753
4587 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4754 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
4816 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 4983 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
4817 #if defined(DEBUG) 4984 #if defined(DEBUG)
4818 __ LoadImmediate(S4, kInvalidObjectPointer); 4985 __ LoadImmediate(S4, kInvalidObjectPointer);
4819 __ LoadImmediate(S5, kInvalidObjectPointer); 4986 __ LoadImmediate(S5, kInvalidObjectPointer);
4820 #endif 4987 #endif
4821 } 4988 }
4822 4989
4823 } // namespace dart 4990 } // namespace dart
4824 4991
4825 #endif // defined TARGET_ARCH_MIPS 4992 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698