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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 3677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3688 result, | 3688 result, |
3689 Address(value, TIMES_2, lo_offset), | 3689 Address(value, TIMES_2, lo_offset), |
3690 Address(value, TIMES_2, hi_offset), | 3690 Address(value, TIMES_2, hi_offset), |
3691 temp, | 3691 temp, |
3692 out_of_range); | 3692 out_of_range); |
3693 __ Bind(&done); | 3693 __ Bind(&done); |
3694 } | 3694 } |
3695 } | 3695 } |
3696 | 3696 |
3697 | 3697 |
3698 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Isolate* isolate, | |
3699 bool opt) const { | |
3700 const bool might_box = (representation() == kTagged) && !can_pack_into_smi(); | |
3701 const intptr_t kNumInputs = 2; | |
3702 const intptr_t kNumTemps = might_box ? 1 : 0; | |
3703 LocationSummary* summary = new(isolate) LocationSummary( | |
3704 isolate, kNumInputs, kNumTemps, | |
3705 might_box ? LocationSummary::kCallOnSlowPath : LocationSummary::kNoCall); | |
3706 summary->set_in(0, Location::RequiresRegister()); | |
3707 // The smi index is either untagged (element size == 1), or it is left smi | |
3708 // tagged (for all element sizes > 1). | |
3709 summary->set_in(1, (index_scale() == 1) ? Location::WritableRegister() | |
3710 : Location::RequiresRegister()); | |
3711 if (might_box) { | |
3712 summary->set_temp(0, Location::RequiresRegister()); | |
3713 } | |
3714 | |
3715 if (representation() == kUnboxedMint) { | |
3716 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | |
3717 Location::RequiresRegister())); | |
3718 } else { | |
3719 ASSERT(representation() == kTagged); | |
3720 summary->set_out(0, Location::RequiresRegister()); | |
3721 } | |
3722 | |
3723 return summary; | |
3724 } | |
3725 | |
3726 | |
3727 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
3728 const Register array = locs()->in(0).reg(); | |
3729 const Location index = locs()->in(1); | |
3730 | |
3731 Address element_address = Assembler::ElementAddressForRegIndex( | |
3732 IsExternal(), class_id(), index_scale(), array, index.reg()); | |
3733 | |
3734 if ((index_scale() == 1)) { | |
3735 __ SmiUntag(index.reg()); | |
3736 } | |
3737 | |
3738 if (representation() == kUnboxedMint) { | |
3739 ASSERT(compiler->is_optimizing()); | |
3740 ASSERT(locs()->out(0).IsPairLocation()); | |
3741 PairLocation* result_pair = locs()->out(0).AsPairLocation(); | |
3742 Register result1 = result_pair->At(0).reg(); | |
3743 Register result2 = result_pair->At(1).reg(); | |
3744 | |
3745 switch (class_id()) { | |
3746 case kOneByteStringCid: | |
3747 case kExternalOneByteStringCid: | |
3748 ASSERT(element_count() == 4); | |
3749 __ movl(result1, element_address); | |
3750 __ xorl(result2, result2); | |
3751 break; | |
3752 case kTwoByteStringCid: | |
3753 case kExternalTwoByteStringCid: | |
3754 ASSERT(element_count() == 2); | |
3755 __ movl(result1, element_address); | |
3756 __ xorl(result2, result2); | |
3757 break; | |
3758 default: | |
3759 UNREACHABLE(); | |
3760 } | |
3761 } else { | |
3762 ASSERT(representation() == kTagged); | |
3763 Register result = locs()->out(0).reg(); | |
3764 switch (class_id()) { | |
3765 case kOneByteStringCid: | |
3766 case kExternalOneByteStringCid: | |
3767 switch (element_count()) { | |
3768 case 1: __ movzxb(result, element_address); break; | |
3769 case 2: __ movzxw(result, element_address); break; | |
3770 case 4: __ movl(result, element_address); break; | |
3771 default: UNREACHABLE(); | |
3772 } | |
3773 break; | |
3774 case kTwoByteStringCid: | |
3775 case kExternalTwoByteStringCid: | |
3776 switch (element_count()) { | |
3777 case 1: __ movzxw(result, element_address); break; | |
3778 case 2: __ movl(result, element_address); break; | |
3779 default: UNREACHABLE(); | |
3780 } | |
3781 break; | |
3782 default: | |
3783 UNREACHABLE(); | |
3784 break; | |
3785 } | |
3786 if (can_pack_into_smi()) { | |
3787 __ SmiTag(result); | |
3788 } else { | |
3789 // If the value cannot fit in a smi then allocate a mint box for it. | |
3790 Register temp = locs()->temp(0).reg(); | |
3791 ASSERT(temp != result); | |
3792 __ MoveRegister(temp, result); | |
3793 __ SmiTag(result); | |
3794 | |
3795 Label done; | |
3796 __ testl(temp, Immediate(0xC0000000)); | |
3797 __ j(ZERO, &done); | |
3798 BoxAllocationSlowPath::Allocate( | |
3799 compiler, this, compiler->mint_class(), result, kNoRegister); | |
3800 __ movl(FieldAddress(result, Mint::value_offset()), temp); | |
3801 __ movl(FieldAddress(result, Mint::value_offset() + kWordSize), | |
3802 Immediate(0)); | |
3803 __ Bind(&done); | |
3804 } | |
3805 } | |
3806 } | |
3807 | |
3808 | |
3809 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, | 3698 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, |
3810 bool opt) const { | 3699 bool opt) const { |
3811 const intptr_t kNumInputs = 2; | 3700 const intptr_t kNumInputs = 2; |
3812 const intptr_t kNumTemps = 0; | 3701 const intptr_t kNumTemps = 0; |
3813 LocationSummary* summary = new(isolate) LocationSummary( | 3702 LocationSummary* summary = new(isolate) LocationSummary( |
3814 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3703 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3815 summary->set_in(0, Location::RequiresFpuRegister()); | 3704 summary->set_in(0, Location::RequiresFpuRegister()); |
3816 summary->set_in(1, Location::RequiresFpuRegister()); | 3705 summary->set_in(1, Location::RequiresFpuRegister()); |
3817 summary->set_out(0, Location::SameAsFirstInput()); | 3706 summary->set_out(0, Location::SameAsFirstInput()); |
3818 return summary; | 3707 return summary; |
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4895 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); | 4784 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); |
4896 __ CallRuntime(TargetFunction(), InputCount()); | 4785 __ CallRuntime(TargetFunction(), InputCount()); |
4897 __ fstpl(Address(ESP, 0)); | 4786 __ fstpl(Address(ESP, 0)); |
4898 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0)); | 4787 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0)); |
4899 // Restore ESP. | 4788 // Restore ESP. |
4900 __ movl(ESP, locs()->temp(0).reg()); | 4789 __ movl(ESP, locs()->temp(0).reg()); |
4901 } | 4790 } |
4902 } | 4791 } |
4903 | 4792 |
4904 | 4793 |
4905 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( | |
4906 Isolate* isolate, bool opt) const { | |
4907 const intptr_t kNumTemps = 0; | |
4908 LocationSummary* summary = new(isolate) LocationSummary( | |
4909 isolate, InputCount(), kNumTemps, LocationSummary::kCall); | |
4910 summary->set_in(0, Location::RegisterLocation(EAX)); | |
4911 summary->set_in(1, Location::RegisterLocation(ECX)); | |
4912 summary->set_in(2, Location::RegisterLocation(EDX)); | |
4913 summary->set_in(3, Location::RegisterLocation(EBX)); | |
4914 summary->set_out(0, Location::RegisterLocation(EAX)); | |
4915 return summary; | |
4916 } | |
4917 | |
4918 | |
4919 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( | |
4920 FlowGraphCompiler* compiler) { | |
4921 | |
4922 // Save ESP. EDI is chosen because it is callee saved so we do not need to | |
4923 // back it up before calling into the runtime. | |
4924 static const Register kSavedSPReg = EDI; | |
4925 __ movl(kSavedSPReg, ESP); | |
4926 __ ReserveAlignedFrameSpace(kWordSize * TargetFunction().argument_count()); | |
4927 | |
4928 __ movl(Address(ESP, + 0 * kWordSize), locs()->in(0).reg()); | |
4929 __ movl(Address(ESP, + 1 * kWordSize), locs()->in(1).reg()); | |
4930 __ movl(Address(ESP, + 2 * kWordSize), locs()->in(2).reg()); | |
4931 __ movl(Address(ESP, + 3 * kWordSize), locs()->in(3).reg()); | |
4932 | |
4933 // Call the function. | |
4934 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); | |
4935 | |
4936 // Restore ESP. | |
4937 __ movl(ESP, kSavedSPReg); | |
4938 } | |
4939 | |
4940 | |
4941 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate, | 4794 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate, |
4942 bool opt) const { | 4795 bool opt) const { |
4943 if (result_cid() == kDoubleCid) { | 4796 if (result_cid() == kDoubleCid) { |
4944 const intptr_t kNumInputs = 2; | 4797 const intptr_t kNumInputs = 2; |
4945 const intptr_t kNumTemps = 1; | 4798 const intptr_t kNumTemps = 1; |
4946 LocationSummary* summary = new(isolate) LocationSummary( | 4799 LocationSummary* summary = new(isolate) LocationSummary( |
4947 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4800 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4948 summary->set_in(0, Location::RequiresFpuRegister()); | 4801 summary->set_in(0, Location::RequiresFpuRegister()); |
4949 summary->set_in(1, Location::RequiresFpuRegister()); | 4802 summary->set_in(1, Location::RequiresFpuRegister()); |
4950 // Reuse the left register so that code can be made shorter. | 4803 // Reuse the left register so that code can be made shorter. |
(...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6502 } | 6355 } |
6503 | 6356 |
6504 // We can fall through if the successor is the next block in the list. | 6357 // We can fall through if the successor is the next block in the list. |
6505 // Otherwise, we need a jump. | 6358 // Otherwise, we need a jump. |
6506 if (!compiler->CanFallThroughTo(successor())) { | 6359 if (!compiler->CanFallThroughTo(successor())) { |
6507 __ jmp(compiler->GetJumpLabel(successor())); | 6360 __ jmp(compiler->GetJumpLabel(successor())); |
6508 } | 6361 } |
6509 } | 6362 } |
6510 | 6363 |
6511 | 6364 |
6512 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate, | |
6513 bool opt) const { | |
6514 const intptr_t kNumInputs = 1; | |
6515 const intptr_t kNumTemps = 1; | |
6516 | |
6517 LocationSummary* summary = new(isolate) LocationSummary( | |
6518 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
6519 | |
6520 summary->set_in(0, Location::RequiresRegister()); | |
6521 summary->set_temp(0, Location::RequiresRegister()); | |
6522 | |
6523 return summary; | |
6524 } | |
6525 | |
6526 | |
6527 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6528 Register target_address_reg = locs()->temp_slot(0)->reg(); | |
6529 | |
6530 // Load from [current frame pointer] + kPcMarkerSlotFromFp. | |
6531 __ movl(target_address_reg, Address(EBP, kPcMarkerSlotFromFp * kWordSize)); | |
6532 | |
6533 // Add the offset. | |
6534 Register offset_reg = locs()->in(0).reg(); | |
6535 __ SmiUntag(offset_reg); | |
6536 __ addl(target_address_reg, offset_reg); | |
6537 | |
6538 // Jump to the absolute address. | |
6539 __ jmp(target_address_reg); | |
6540 } | |
6541 | |
6542 | |
6543 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, | 6365 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, |
6544 bool opt) const { | 6366 bool opt) const { |
6545 const intptr_t kNumInputs = 2; | 6367 const intptr_t kNumInputs = 2; |
6546 const intptr_t kNumTemps = 0; | 6368 const intptr_t kNumTemps = 0; |
6547 if (needs_number_check()) { | 6369 if (needs_number_check()) { |
6548 LocationSummary* locs = new(isolate) LocationSummary( | 6370 LocationSummary* locs = new(isolate) LocationSummary( |
6549 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); | 6371 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); |
6550 locs->set_in(0, Location::RegisterLocation(EAX)); | 6372 locs->set_in(0, Location::RegisterLocation(EAX)); |
6551 locs->set_in(1, Location::RegisterLocation(ECX)); | 6373 locs->set_in(1, Location::RegisterLocation(ECX)); |
6552 locs->set_out(0, Location::RegisterLocation(EAX)); | 6374 locs->set_out(0, Location::RegisterLocation(EAX)); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6786 #if defined(DEBUG) | 6608 #if defined(DEBUG) |
6787 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6609 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6788 #endif | 6610 #endif |
6789 } | 6611 } |
6790 | 6612 |
6791 } // namespace dart | 6613 } // namespace dart |
6792 | 6614 |
6793 #undef __ | 6615 #undef __ |
6794 | 6616 |
6795 #endif // defined TARGET_ARCH_IA32 | 6617 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |