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_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |